Skip to content

Nginx configuration ​

Download the example configuration file

Nginx serves as the reverse proxy and SSL termination point for all application components. In a Standalone installation, nginx runs as a container from docker-compose; in an HA installation and in Kubernetes, the proxy role is handled by an external web server or an Ingress controller.

Domains and certificates ​

DomainPurposeCertificate
example.flip-chart.ruApplication (frontend, API, WebSocket, S3)/etc/nginx/certificates/crt.pem, key.pem
mcp.example.flip-chart.ruMCP server/etc/nginx/certificates/mcp-crt.pem, mcp-key.pem

If you use one certificate for both domains (wildcard or SAN), specify the same files in both server blocks.

Routes ​

RoutePurposeUpstreamNotes
/Redirect to /app—
/app/api/v1/wsWebSocketflip-backend:9000proxy_read_timeout 86400s
/app/api/v1/flip/backup/uploadImporting boards from backupsflip-backend:9000client_max_body_size 6G, 3600s timeouts
/app/apiREST APIflip-backend:9000
/app/s3/Proxying to S3 storageflip-minio:9000the /app/s3/ prefix is stripped
/appFrontendflip-frontend:80
mcp.example.flip-chart.ru/MCP serverflip-mcp-server:8090separate server block

Important

The upstream names (flip-backend, flip-frontend, flip-minio, flip-mcp-server) must match the docker-compose container names or the DNS names of the services in your environment. The backend port must match Server.Port in the backend configuration.

Example configuration ​

nginx
# flip reverse proxy (on-premise)
# example.flip-chart.ru, mcp.example.flip-chart.ru — replace with the domains of your installation.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# Docker DNS: re-resolve upstream addresses when containers restart
resolver 127.0.0.11 valid=10s ipv6=off;

# HTTP -> HTTPS
server {
    listen                          80;
    listen                          [::]:80;
    server_name                     example.flip-chart.ru mcp.example.flip-chart.ru;

    location / {
        return 301 https://$host$request_uri;
    }
}

# Main application
server {
    listen                          443 ssl;
    listen                          [::]:443 ssl;
    http2                           on;
    server_name                     example.flip-chart.ru;

    ssl_certificate                 /etc/nginx/certificates/crt.pem;
    ssl_certificate_key             /etc/nginx/certificates/key.pem;

    client_max_body_size            500M;

    set $backend   http://flip-backend:9000;
    set $frontend  http://flip-frontend:80;
    set $minio     http://flip-minio:9000;

    location = / {
        return 302 https://$host/app;
    }

    # WebSocket
    location = /app/api/v1/ws {
        proxy_pass                  $backend;
        proxy_http_version          1.1;
        proxy_set_header            Upgrade             $http_upgrade;
        proxy_set_header            Connection          $connection_upgrade;
        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;
        proxy_set_header            X-Forwarded-Host    $host;
        proxy_read_timeout          86400s;
        proxy_send_timeout          86400s;
        proxy_connect_timeout       60s;
    }

    # Import of board backups (.board)
    location = /app/api/v1/flip/backup/upload {
        proxy_pass                  $backend;
        proxy_http_version          1.1;
        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;
        proxy_set_header            X-Forwarded-Host    $host;
        client_max_body_size        6G;
        proxy_request_buffering     off;
        proxy_read_timeout          3600s;
        proxy_send_timeout          3600s;
        proxy_connect_timeout       3600s;
    }

    # REST API
    location /app/api {
        proxy_pass                  $backend;
        proxy_http_version          1.1;
        proxy_set_header            Connection          "";
        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;
        proxy_set_header            X-Forwarded-Host    $host;
        proxy_read_timeout          120s;
        proxy_send_timeout          60s;
        proxy_connect_timeout       60s;
    }

    # S3 storage via the application domain
    location /app/s3/ {
        rewrite                     ^/app/s3/(.*)$ /$1 break;
        proxy_pass                  $minio;
        proxy_http_version          1.1;
        proxy_redirect              off;
        proxy_set_header            Connection          "";
        proxy_set_header            Authorization       "";
        proxy_set_header            X-Real-IP           $remote_addr;
        proxy_set_header            X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_hide_header           Set-Cookie;
        proxy_ignore_headers        Set-Cookie;
        proxy_buffering             off;
        proxy_max_temp_file_size    0;
        add_header                  Cache-Control       max-age=31536000;
    }

    # Frontend
    location /app {
        proxy_pass                  $frontend;
        proxy_http_version          1.1;
        proxy_set_header            Connection          "";
        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;
        proxy_read_timeout          240s;
        proxy_send_timeout          60s;
        proxy_connect_timeout       60s;
    }
}

# MCP server — a separate domain
server {
    listen                          443 ssl;
    listen                          [::]:443 ssl;
    http2                           on;
    server_name                     mcp.example.flip-chart.ru;

    ssl_certificate                 /etc/nginx/certificates/mcp-crt.pem;
    ssl_certificate_key             /etc/nginx/certificates/mcp-key.pem;

    set $mcp http://flip-mcp-server:8090;

    location / {
        proxy_pass                  $mcp;
        proxy_http_version          1.1;
        proxy_set_header            Connection          "";
        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;
        proxy_set_header            X-Forwarded-Host    $host;
        proxy_buffering             off;
        proxy_read_timeout          120s;
        proxy_send_timeout          60s;
        proxy_connect_timeout       60s;
    }
}

flip on-premise and cloud documentation