Nginx Reverse Proxy Setup
Nginx is a high-performance reverse proxy. This guide explains how to configure Nginx to forward incoming web requests, Fastify API endpoints, file uploads, and WebSocket connections to Cyrus Panel (running by default on 127.0.0.1:57777), followed by using Certbot to automatically configure SSL.
Prerequisites
- Cyrus Panel installed and running locally on port
57777(127.0.0.1:57777). - A registered domain or subdomain with a DNS A record pointing directly to your server's public IPv4 address (DNS-only / unproxied).
- Ports
80(HTTP) and443(HTTPS) open on your firewall.
Make sure your domain resolves to your server's IP address before requesting certificates to avoid Certbot ACME challenge failures:
dig +short panel.example.com
If this does not return your server's public IP address, wait for your DNS records to finish propagating before proceeding.
Step 1: Install Nginx and Certbot
Install Nginx alongside the Certbot Nginx plugin:
Debian / Ubuntu
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
RHEL / AlmaLinux / Rocky Linux
sudo dnf install -y epel-release
sudo dnf install -y nginx certbot python3-certbot-nginx
sudo systemctl enable --now nginx
Step 2: Configure Initial Nginx Site
- Create a new Nginx configuration file for Cyrus Panel:
sudo nano /etc/nginx/sites-available/cyruspanel.conf
(On RHEL/CentOS/AlmaLinux, create /etc/nginx/conf.d/cyruspanel.conf instead)
- Paste the initial HTTP configuration below. Replace
panel.example.comwith your actual domain:
# Map for WebSocket Upgrade Headers
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name panel.example.com;
# File Upload Limits
client_max_body_size 1024M;
client_body_buffer_size 128k;
location / {
# Proxy to Cyrus Panel Default Port
proxy_pass http://127.0.0.1:57777;
# Standard Proxy Headers
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_set_header X-Forwarded-Port $server_port;
# WebSocket Support (Required for Terminal & Live Stats)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Disable Buffering for Realtime Fastify Streaming
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
If you configured Cyrus Panel to use a port other than 57777 in your .env, update the proxy_pass http://127.0.0.1:57777; directive to match your custom port.
- If you are on Debian or Ubuntu, enable the site configuration:
sudo ln -s /etc/nginx/sites-available/cyruspanel.conf /etc/nginx/sites-enabled/
- Test your Nginx configuration syntax:
sudo nginx -t
- Restart Nginx:
sudo systemctl restart nginx
Step 3: Automatically Configure SSL with Certbot
Run Certbot with the --nginx plugin. Certbot will obtain a certificate from Let's Encrypt, configure the SSL certificate paths inside your Nginx configuration automatically, and set up HTTP to HTTPS redirection:
sudo certbot --nginx -d panel.example.com
(Replace panel.example.com with your actual domain)
During the prompt, enter your email address for certificate renewal notices and agree to the terms of service. When asked whether to automatically redirect HTTP traffic to HTTPS, choose Redirect.
Manual SSL Configuration (Fallback)
If Certbot did not modify your Nginx file automatically (for instance, if you used certbot certonly, which only downloads certificates without touching Nginx configs), you can manually apply the complete production HTTPS configuration.
- Obtain your certificates with
certonly:
sudo certbot certonly --nginx -d panel.example.com
- Open
/etc/nginx/sites-available/cyruspanel.conf(or/etc/nginx/conf.d/cyruspanel.conf) and replace its entire content with the following:
# Map for WebSocket Upgrade Headers
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# HTTP - Redirect all traffic to HTTPS
server {
listen 80;
listen [::]:80;
server_name panel.example.com;
# Allow Let's Encrypt HTTP-01 challenges
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS - Reverse Proxy to Cyrus Panel
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name panel.example.com;
# SSL Certificates
ssl_certificate /etc/letsencrypt/live/panel.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem;
# Modern TLS Security Protocols
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# File Upload Limits
client_max_body_size 1024M;
client_body_buffer_size 128k;
location / {
# Proxy to Cyrus Panel Default Port
proxy_pass http://127.0.0.1:57777;
# Standard Proxy Headers
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_set_header X-Forwarded-Port $server_port;
# WebSocket Support (Required for Terminal & Live Stats)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Disable Buffering for Realtime Fastify Streaming
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
- Test syntax and reload Nginx:
sudo nginx -t
sudo systemctl restart nginx
Step 4: Update Cyrus Panel .env
Update your panel environment file so internal callbacks, OAuth logins, and WebSocket connections use your secure domain:
- Open
.env:
nano /home/user/cyrus-panel/.env # Or whatever your panel folder is.
- Set
PANEL_URL:
PANEL_URL=https://panel.example.com
- Restart Cyrus Panel:
sudo systemctl restart cyrus-panel
# Or if running via PM2:
pm2 restart cyrus-panel
SSL Auto-Renewal
Let's Encrypt certificates expire after 90 days. Certbot automatically installs and activates a systemd timer to renew certificates before expiration.
To verify that the automatic renewal test passes:
sudo certbot renew --dry-run