# Example external Nginx reverse proxy for Remnawave Minishop. # # The config assumes this Nginx can resolve Docker service names from the same # Compose network. If Nginx runs on the host with the default compose file, use # the host-published ports instead: # WEBHOOK_BASE_URL -> 127.0.0.1:8080 # SUBSCRIPTION_MINI_APP_URL -> 127.0.0.1:8082 # The frontend nginx already proxies internal Web App API/auth requests to # backend:8081, so the external proxy does not need path-based locations. upstream remnawave_backend_webhooks { server backend:8080; keepalive 16; } upstream remnawave_frontend { server frontend:80; keepalive 16; } # TLS certificates. # # Option 1: separate Let's Encrypt certificates per domain. Keep port 80 open # and point DNS A/AAAA records to the host that terminates TLS. If Certbot can # manage that Nginx directly, run: # certbot certonly --nginx -d webhooks.example.com # certbot certonly --nginx -d app.example.com # Certbot stores them as: # /etc/letsencrypt/live/webhooks.example.com/fullchain.pem # /etc/letsencrypt/live/webhooks.example.com/privkey.pem # /etc/letsencrypt/live/app.example.com/fullchain.pem # /etc/letsencrypt/live/app.example.com/privkey.pem # If this Nginx is a container, mount /etc/letsencrypt into it read-only or copy # the issued certificates into the per-domain folders shown below. # # Option 2: keep copied certificates in per-domain folders mounted into Nginx # as shown in the server blocks below: # /etc/nginx/ssl/webhooks.example.com/fullchain.pem # /etc/nginx/ssl/webhooks.example.com/privkey.pem # /etc/nginx/ssl/app.example.com/fullchain.pem # /etc/nginx/ssl/app.example.com/privkey.pem # # Option 3: use one wildcard certificate for both domains. Wildcards require a # DNS-01 challenge, for example with Certbot manual mode or a DNS provider plugin # that can renew automatically: # certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com" # Then both server blocks can point to the same certificate: # /etc/letsencrypt/live/example.com/fullchain.pem # /etc/letsencrypt/live/example.com/privkey.pem server { listen 80; server_name webhooks.example.com app.example.com; return 301 https://$host$request_uri; } # WEBHOOK_BASE_URL. # Telegram, payment providers and Remnawave panel webhooks go here. server { listen 443 ssl; http2 on; server_name webhooks.example.com; ssl_certificate /etc/nginx/ssl/webhooks.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/webhooks.example.com/privkey.pem; client_max_body_size 20m; location / { proxy_pass http://remnawave_backend_webhooks; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # Required for payment provider IP allowlists in webhook handlers. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; } } # SUBSCRIPTION_MINI_APP_URL. # The frontend nginx proxies /api, /auth and theme/logo assets to backend:8081. server { listen 443 ssl; http2 on; server_name app.example.com; ssl_certificate /etc/nginx/ssl/app.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/app.example.com/privkey.pem; client_max_body_size 20m; location / { proxy_pass http://remnawave_frontend; 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-Host $host; proxy_set_header X-Forwarded-Proto $scheme; } }