Deployment & HTTPS

3 min read

Deployment & HTTPS

PgArachne is designed to perform one job well: API Gateway. For SSL/TLS (HTTPS), header security, and public routing, you should place a Reverse Proxy in front of it.

Option A: Caddy Server

Best for: Modern production deployments, ease of use.

Caddy is the only web server that obtains and renews SSL certificates (Let’s Encrypt) automatically by default. It requires almost zero configuration.

# Caddyfile
example.com {
    reverse_proxy localhost:8080
}

Option B: Nginx

Best for: Enterprise environments, complex routing.

Nginx is the industry standard for high-performance load balancing. Use this if you already have an Nginx infrastructure. You will need to manage Certbot manually.

server {
    server_name example.com;
    location / {
        proxy_pass http://localhost:8080;
    }
}

Option C: Ngrok

Best for: Local development, demos, webhook testing.

Ngrok creates a secure tunnel from the public internet directly to your laptop without configuring firewalls. Ideal for showing your work to colleagues instantly.

./ngrok http 8080

Production checklist

  • Terminate TLS on the reverse proxy and forward X-Forwarded-Proto and X-Forwarded-For.
  • Set TRUSTED_PROXIES in PgArachne to your proxy IP/CIDR ranges.
  • Disable buffering for SSE routes and keep read timeouts long enough for streaming.
  • Expose metrics only internally (default 127.0.0.1:9090) and scrape from your monitoring network.

Nginx hardening example (SSE, file downloads, forwarded headers)

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# SSE: /{API_PREFIX}/{database}/sse — long-lived stream, must not be buffered
location ~ ^/db/[^/]+/sse$ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;
    proxy_read_timeout 1h;
}

# File downloads: /{API_PREFIX}/{database}/file — large files and ZIP archives
location ~ ^/db/[^/]+/file/?$ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;
    proxy_read_timeout 300s;
}

Replace db with your API_PREFIX if you changed it.

Large downloads (/file) behind a reverse proxy

  • Disable response buffering (proxy_buffering off in Nginx). A single file is sent with a Content-Length, a ZIP archive is streamed without one. With buffering on, Nginx first spools the whole response to a temporary file, which delays the start of the download and costs disk space.
  • Raise the read timeout (proxy_read_timeout, default 60 s) if the database function that builds the files can run longer — PgArachne sends nothing until the function has returned all rows.
  • Do not compress application/zip or already compressed media types (gzip on a ZIP only burns CPU).
  • Memory limit: PgArachne buffers the rows of one response in memory (capped by FILE_MAX_BYTES, default 64 MiB, and FILE_MAX_ENTRIES); size the limits for the number of concurrent downloads you expect. client_max_body_size only concerns the small JSON request, not the download.
  • Caddy streams responses by default; no extra configuration is needed.