Skip to main content

Deploy SkillFlaw behind Nginx and HTTPS

Deploy SkillFlaw on a Linux server by keeping the service split intact and placing Nginx in front of it.

This guide assumes the same runtime contract already used by docker/docker-compose.yml:

  • backend API on 7860
  • frontend UI on 3001
  • optional standalone docs on 3002

Nginx then becomes the public edge for HTTPS, hostname routing, and request limits.

When this guide fits

Use this pattern when you want one of these deployment shapes:

  1. Full web deployment: frontend + backend, with docs on a separate hostname when required
  2. API-first deployment: backend only, optionally with docs exposed separately

If you are still bringing up the stack itself, start with Install SkillFlaw for deployment and SkillFlaw deployment architecture.

Prerequisites

  • A running SkillFlaw deployment on the target machine
  • A Debian- or Ubuntu-like Linux host with Nginx support
  • A public domain name and permission to update DNS records
  • DNS records that already point to the server's public IP
  • Certbot available from your operating system packages

For the reference compose stack, the local upstreams are:

ServiceLocal addressPurpose
Frontendhttp://127.0.0.1:3001Web UI and shareable playground routes such as /playground/:id/
Backendhttp://127.0.0.1:7860/health, /api/*, /api/v1/mcp/streamable, webhook and run endpoints
Docshttp://127.0.0.1:3002Optional standalone documentation host

Choose your public routing model

The cleanest production setup is to use separate hostnames:

  • app.example.com -> frontend
  • api.example.com -> backend
  • docs.example.com -> docs (optional)

This keeps browser UI traffic, programmatic API traffic, and docs traffic clearly separated.

Install Nginx and enable it

  1. Install Nginx.


    _10
    sudo apt update
    _10
    sudo apt install nginx -y

  2. Start and enable the service.


    _10
    sudo systemctl enable --now nginx

Configure Nginx for SkillFlaw

The following example uses three virtual hosts. Remove the ones you do not need.

  1. Create a site configuration file.


    _10
    sudo nano /etc/nginx/sites-available/skillflaw.conf

  2. Paste a configuration like the following and replace the example domains with your real hostnames.


    _53
    server {
    _53
    listen 80;
    _53
    server_name app.example.com;
    _53
    _53
    client_max_body_size 100M;
    _53
    _53
    location / {
    _53
    proxy_pass http://127.0.0.1:3001;
    _53
    proxy_http_version 1.1;
    _53
    proxy_set_header Host $host;
    _53
    proxy_set_header X-Real-IP $remote_addr;
    _53
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    _53
    proxy_set_header X-Forwarded-Proto $scheme;
    _53
    proxy_set_header Upgrade $http_upgrade;
    _53
    proxy_set_header Connection "upgrade";
    _53
    }
    _53
    }
    _53
    _53
    server {
    _53
    listen 80;
    _53
    server_name api.example.com;
    _53
    _53
    client_max_body_size 100M;
    _53
    _53
    location / {
    _53
    proxy_pass http://127.0.0.1:7860;
    _53
    proxy_http_version 1.1;
    _53
    proxy_set_header Host $host;
    _53
    proxy_set_header X-Real-IP $remote_addr;
    _53
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    _53
    proxy_set_header X-Forwarded-Proto $scheme;
    _53
    proxy_set_header Upgrade $http_upgrade;
    _53
    proxy_set_header Connection "upgrade";
    _53
    proxy_connect_timeout 60s;
    _53
    proxy_send_timeout 60s;
    _53
    proxy_read_timeout 300s;
    _53
    proxy_buffering off;
    _53
    proxy_request_buffering off;
    _53
    }
    _53
    }
    _53
    _53
    server {
    _53
    listen 80;
    _53
    server_name docs.example.com;
    _53
    _53
    location / {
    _53
    proxy_pass http://127.0.0.1:3002;
    _53
    proxy_set_header Host $host;
    _53
    proxy_set_header X-Real-IP $remote_addr;
    _53
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    _53
    proxy_set_header X-Forwarded-Proto $scheme;
    _53
    }
    _53
    }

  3. Enable the site and validate the syntax.


    _10
    sudo ln -sf /etc/nginx/sites-available/skillflaw.conf /etc/nginx/sites-enabled/skillflaw.conf
    _10
    sudo nginx -t

  4. Reload Nginx.


    _10
    sudo systemctl reload nginx

Obtain TLS certificates with Certbot

  1. Install Certbot and the Nginx plugin.


    _10
    sudo apt install certbot python3-certbot-nginx -y

  2. Request certificates for the hostnames you actually expose.


    _10
    sudo certbot --nginx -d app.example.com -d api.example.com -d docs.example.com

    If you expose fewer hostnames, remove the extra -d arguments.

  3. Let Certbot update the Nginx configuration and choose whether HTTP should redirect to HTTPS.

  4. Verify that automatic renewal is present.


    _10
    systemctl list-timers | grep certbot

Verify the public entrypoints

After TLS is enabled, verify the endpoints that match your deployment shape:

  • https://app.example.com
  • https://api.example.com/health
  • https://api.example.com/api/v1/mcp/streamable
  • https://docs.example.com

Operational notes

  • Keep SKILLFLAW_SECRET_KEY_FILE mounted as a real file in the backend runtime; Nginx does not change that requirement.
  • Keep SKILLFLAW_CONFIG_DIR on persistent storage.
  • If you expose only API traffic, publish the backend hostname and leave the frontend/docs private or disabled.
  • If you expose MCP publicly, secure it with the same authentication controls used for the rest of the backend API.

See also