background: var(--bg); padding: 0.25rem 0.5rem; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 0.875em; } pre { background: var(--bg); padding: 1rem; border-radius: 6px; overflow-x: auto; font-size: 0.875rem; } .tip { background: #e8f5e9; border-left: 4px solid #4caf50; padding: 1rem; margin: 1rem 0; border-radius: 4px; } .warning { background: #fff3e0; border-left: 4px solid #ff9800; padding: 1rem; margin: 1rem 0; border-radius: 4px; } .security-card { background: #e3f2fd; border-left: 4px solid #2196f3; padding: 1rem; margin: 1rem 0; border-radius: 4px; }

Self-Hosting Guide

Host Calcora on your own server with full control over deployment, privacy, and customization.

Overview

Calcora can be self-hosted for maximum privacy, control, and customization. Perfect for:

💡 Quick Start: For the simplest setup, use the Python package method with pip install calcora && calcora serve

Method 1: Python Package (Recommended)

The easiest way to self-host Calcora. Requires Python 3.10 or later.

Installation

# Install Calcora with API server dependencies
pip install calcora[api]

# Or install from GitHub (latest development version)
pip install git+https://github.com/Dumbo-programmer/Calcora.git

Running the Server

# Start the API server (defaults to port 5000)
calcora serve

# Specify custom port and host
calcora serve --port 8080 --host 0.0.0.0

# Production mode with Gunicorn (recommended)
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 api_server:app

Environment Variables

Variable Default Description
CALCORA_STATIC_FOLDER src/calcora/web Path to static web files
FLASK_ENV production Flask environment mode
CALCORA_MAX_TIMEOUT 10 Maximum computation timeout (seconds)

Example: Production Setup

# Create a systemd service (Linux)
# Save as /etc/systemd/system/calcora.service

[Unit]
Description=Calcora API Server
After=network.target

[Service]
Type=simple
User=calcora
WorkingDirectory=/opt/calcora
Environment="FLASK_ENV=production"
Environment="CALCORA_STATIC_FOLDER=/opt/calcora/site"
ExecStart=/usr/bin/gunicorn -w 4 -b 127.0.0.1:5000 api_server:app
Restart=always

[Install]
WantedBy=multi-user.target
# Enable and start the service
sudo systemctl enable calcora
sudo systemctl start calcora
sudo systemctl status calcora

Method 2: Docker Deployment

Containerized deployment for consistent, isolated environments.

Create Dockerfile

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# Install dependencies
COPY requirements-api.txt .
RUN pip install --no-cache-dir -r requirements-api.txt && \
    pip install --no-cache-dir gunicorn

# Copy application
COPY api_server.py .
COPY src/ src/
COPY site/ site/

# Set environment variables
ENV FLASK_ENV=production
ENV CALCORA_STATIC_FOLDER=/app/site

# Expose port
EXPOSE 5000

# Run with Gunicorn
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "api_server:app"]

Build and Run

# Build the Docker image
docker build -t calcora:latest .

# Run the container
docker run -d -p 5000:5000 --name calcora-server calcora:latest

# Check logs
docker logs calcora-server

# Stop the container
docker stop calcora-server

Docker Compose

# docker-compose.yml
version: '3.8'

services:
  calcora:
    build: .
    ports:
      - "5000:5000"
    environment:
      - FLASK_ENV=production
      - CALCORA_STATIC_FOLDER=/app/site
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/"]
      interval: 30s
      timeout: 10s
      retries: 3
# Start with Docker Compose
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

Method 3: Running from Source

For development or when you need the latest features.

# Clone the repository
git clone https://github.com/Dumbo-programmer/Calcora.git
cd Calcora

# Create virtual environment
python -m venv .venv
.venv\Scripts\Activate.ps1  # Windows
source .venv/bin/activate   # Linux/Mac

# Install dependencies
pip install -r requirements-api.txt

# Run the server
python api_server.py

For detailed build instructions, see the Build from Source Guide.

Reverse Proxy Configuration

Setup HTTPS and domain routing with nginx or Apache.

nginx Configuration

# /etc/nginx/sites-available/calcora

server {
    listen 80;
    server_name calcora.yourdomain.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name calcora.yourdomain.com;

    # SSL certificates (use Let's Encrypt: certbot --nginx)
    ssl_certificate /etc/letsencrypt/live/calcora.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/calcora.yourdomain.com/privkey.pem;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Proxy to Calcora
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts for long computations
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Rate limiting (optional)
    limit_req_zone $binary_remote_addr zone=calcora_limit:10m rate=10r/s;
    limit_req zone=calcora_limit burst=20 nodelay;
}
# Enable the site
sudo ln -s /etc/nginx/sites-available/calcora /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Apache Configuration

# /etc/apache2/sites-available/calcora.conf

<VirtualHost *:80>
    ServerName calcora.yourdomain.com
    Redirect permanent / https://calcora.yourdomain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName calcora.yourdomain.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/calcora.yourdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/calcora.yourdomain.com/privkey.pem

    # Security headers
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"

    # Proxy to Calcora
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>
# Enable required modules and site
sudo a2enmod ssl proxy proxy_http headers
sudo a2ensite calcora
sudo systemctl reload apache2

Security Considerations

🔒 Essential Security Measures

  • HTTPS Required: Always use SSL/TLS in production (use Let's Encrypt for free certificates)
  • Rate Limiting: Implement request rate limits to prevent abuse (shown in nginx config above)
  • Firewall: Only expose necessary ports (443/80 for web, not 5000 directly)
  • Updates: Keep Calcora and dependencies up to date with security patches
  • Resource Limits: Configure computation timeouts to prevent resource exhaustion

Rate Limiting Configuration

# Using Flask-Limiter (install: pip install Flask-Limiter)
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)

@app.route('/differentiate')
@limiter.limit("10 per minute")
def differentiate_get():
    # ... existing code ...

Input Validation

Calcora includes built-in input validation and timeout protection:

⚠️ Security Warning: While Calcora uses safe symbolic computation, always run it in a sandboxed environment (Docker, VM, or isolated user) when exposing to the internet.

Performance Optimization

Production Server Configuration

# Gunicorn with 4 workers (adjust based on CPU cores)
gunicorn -w 4 \
  --worker-class sync \
  --timeout 60 \
  --keep-alive 5 \
  --max-requests 1000 \
  --max-requests-jitter 100 \
  -b 0.0.0.0:5000 \
  api_server:app

Worker Count Formula

Recommended workers: (2 × CPU cores) + 1

# Auto-calculate workers
WORKERS=$(( $(nproc) * 2 + 1 ))
gunicorn -w $WORKERS -b 0.0.0.0:5000 api_server:app
💡 Performance Tips:
  • Use a reverse proxy (nginx/Apache) for static file serving
  • Enable gzip compression for API responses
  • Consider Redis caching for frequently requested computations
  • Monitor resource usage with tools like htop or Prometheus

Monitoring & Logging

Basic Logging Setup

# Configure Python logging in api_server.py
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/var/log/calcora/api.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

Health Check Endpoint

Add a health check endpoint for monitoring:

@app.route('/health')
def health():
    return jsonify({
        'status': 'healthy',
        'version': '0.2.0',
        'timestamp': datetime.now().isoformat()
    })

Monitoring Tools

Troubleshooting

Server won't start

  • Check if port 5000 is already in use: netstat -tulpn | grep 5000
  • Verify Python version: python --version (requires 3.10+)
  • Check dependencies: pip list | grep -E "flask|sympy|numpy"

502 Bad Gateway (nginx)

  • Ensure Calcora is running: systemctl status calcora
  • Check proxy_pass URL matches Calcora's host:port
  • Verify firewall allows internal connections to port 5000

Slow computations / timeouts

  • Increase timeout in nginx/Apache config (see proxy_read_timeout)
  • Add more Gunicorn workers for parallel processing
  • Check system resources: htop or top

CORS errors in browser

  • Verify Flask-CORS is installed: pip show flask-cors
  • Check CORS configuration in api_server.py
  • Ensure reverse proxy passes headers correctly

Cloud Deployment Options

Quick deployment on popular cloud platforms:

Render.com

# render.yaml (included in repository)
services:
  - type: web
    name: calcora
    env: python
    buildCommand: pip install -r requirements-api.txt
    startCommand: gunicorn -w 4 -b 0.0.0.0:$PORT api_server:app

Deploy: Connect GitHub repo → Render auto-deploys on push

Railway.app

# railway.json
{
  "build": {
    "builder": "nixpacks"
  },
  "deploy": {
    "startCommand": "gunicorn -w 4 -b 0.0.0.0:$PORT api_server:app"
  }
}

DigitalOcean App Platform

Use the Dockerfile method shown above, or:

# .do/app.yaml
name: calcora
services:
  - name: api
    github:
      repo: Dumbo-programmer/Calcora
      branch: main
    run_command: gunicorn -w 4 -b 0.0.0.0:8080 api_server:app
    http_port: 8080

Need Help?

Self-hosting support resources: