NOTE: This page is marked "earlydoc", or "early documentation", which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the support page for options.
How to add Nginx as a reverse proxy
The following commands are tailored for Ubuntu/Debian systems. If you're using a different Linux distribution, you may need to adjust package management commands accordingly (e.g., yum
for CentOS, brew
for macOS).
Install Nginx:
sudo apt update && sudo apt install nginx -y
sudo systemctl start nginx && sudo systemctl enable nginx
Install Certbot for SSL:
sudo apt update && sudo apt install python3-certbot-nginx -y
Create the Webroot Directory:
sudo mkdir -p /var/www/certbot/.well-known/acme-challenge && sudo chown -R www-data:www-data /var/www/certbot
Create a temporary Nginx config for creating SSL certificates
Make sure to change subdomain.domain.tld to your actual subdomain and ensure that it is pointed to your server's IP address.
Edit the file /etc/nginx/sites-available/subdomain.domain.tld
(e.g., use sudo nano /etc/nginx/sites-available/subdomain.domain.tld
if you're using nano
).
server {
listen 80;
listen [::]:80; # IPv6 support
server_name <subdomain.domain.tld>; # CHANGE HERE
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
# Hide NGINX version for security reasons
server_tokens off;
}
sudo ln -s /etc/nginx/sites-available/<subdomain.domain.tld> /etc/nginx/sites-enabled/
Obtain SSL Certificates Using Webroot method:
sudo certbot certonly --webroot -w /var/www/certbot -d <subdomain.domain.tld> --email your-email@example.com --agree-tos --no-eff-email
Edit the Nginx config:
Edit the file /etc/nginx/sites-available/subdomain.domain.tld
(e.g., use sudo nano /etc/nginx/sites-available/subdomain.domain.tld
if you're using nano
).
Copy your config from here:
# HTTP -> HTTPS Redirection
server {
listen 80;
listen [::]:80; # IPv6 support
server_name <subdomain.domain.tld>; # CHANGE HERE
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
# Hide NGINX version for security reasons
server_tokens off;
}
# HTTPS Configuration
server {
listen 443 ssl http2;
listen [::]:443 ssl http2; # Enable HTTP/2 and IPv6 support if you need
server_name <subdomain.domain.tld>; # CHANGE HERE
# Hide NGINX version
server_tokens off;
# SSL Certificates
ssl_certificate /etc/letsencrypt/live/<subdomain.domain.tld>/fullchain.pem; # CHANGE HERE
ssl_certificate_key /etc/letsencrypt/live/<subdomain.domain.tld>/privkey.pem; # CHANGE HERE
ssl_trusted_certificate /etc/letsencrypt/live/<subdomain.domain.tld>/chain.pem; # CHANGE HERE
# Security: Stronger SSL Configuration
ssl_session_cache shared:SSL:10m; # Cache SSL sessions
ssl_session_timeout 1d; # Set session timeout to 1 day
ssl_session_tickets off; # Disable SSL session tickets
# Use only modern SSL/TLS protocols (disables older insecure ones)
ssl_protocols TLSv1.2 TLSv1.3;
# Configure SSL ciphers (strong encryption algorithms)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off; # Allow clients to prefer their ciphers
# Diffie-Hellman parameter for Perfect Forward Secrecy (PFS)
ssl_dhparam /etc/ssl/certs/dhparam.pem; # Generate with `sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048`
# OCSP Stapling for improved SSL/TLS performance
ssl_stapling on;
ssl_stapling_verify on;
# DNS resolver for OCSP
resolver 1.1.1.1 1.0.0.1 valid=300s;
resolver_timeout 5s;
# some HTTP Security Headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # HSTS
add_header X-Frame-Options "SAMEORIGIN" always; # Prevent Clickjacking
add_header X-Content-Type-Options "nosniff" always; # Prevent MIME-type sniffing
add_header X-XSS-Protection "1; mode=block" always; # XSS Protection
add_header Referrer-Policy "no-referrer" always; # Better privacy control
add_header Permissions-Policy "geolocation=(self), microphone=(), camera=()" always; # Limit browser permissions
# Reverse Proxy to Postiz application
location / {
proxy_pass http://localhost:5000;
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;
# WebSocket Support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Disable directory listing for security
autoindex off;
# Enable Gzip compression for better performance
gzip on;
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_proxied any;
gzip_types text/plain text/css text/javascript application/json application/xml image/svg+xml;
# Optional Access/Error Logging
access_log /var/log/nginx/<subdomain.domain.tld>.log; # CHANGE HERE
error_log /var/log/nginx/<subdomain.domain.tld>.log; # CHANGE HERE
}
Generate DH Parameters:
(Needed if you are using the "robust" nginx config option)
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Test your Nginx configuration:
sudo nginx -t
Automatic reload Nginx when SSL Certificates are renewed:
echo -e '#!/bin/bash\nnginx -t && systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh && sudo chmod a+x /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
Reload Nginx
sudo systemctl reload nginx
Vuola!
Your Nginx reverse proxy is now running, securely serving your Postiz instance at your subdomain.domain.tld. 🎉