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​