HTTPS & Reverse Proxy
If the frontend is served over HTTPS and calls the API directly by IP/port over plain HTTP, the browser blocks the request as mixed content. The fix: put Nginx in front of the API container, terminate TLS there using a free origin certificate from your CDN provider (e.g. Cloudflare), and proxy to Nginx over HTTPS instead of hitting the API container directly.
These are one-time manual commands run directly on the server — not part of any CI workflow or compose file.
Generate an origin certificate
In your CDN provider’s dashboard (e.g. Cloudflare: SSL/TLS → Origin Server
→ Create Certificate), generate a certificate/key pair. Save the two
outputs locally as origin-cert.pem and origin-key.pem.
Copy both files to the server
scp -i "path/to/your.key" origin-cert.pem origin-key.pem <user>@<host>:/home/<user>/Note the trailing : before the remote path — omitting it makes scp
fail with a confusing “No such file or directory” instead of a clear
syntax error.
Install Nginx
ssh -i "path/to/your.key" <user>@<host>
sudo apt-get update -y
sudo apt-get install -y nginxInstall Nginx before the next step — the SSL config directory it needs only exists once Nginx itself is installed.
Move the cert/key into place
sudo mkdir -p /etc/nginx/ssl
sudo mv ~/origin-cert.pem /etc/nginx/ssl/origin-cert.pem
sudo mv ~/origin-key.pem /etc/nginx/ssl/origin-key.pem
sudo chmod 600 /etc/nginx/ssl/origin-key.pemCreate the Nginx site config
sudo tee /etc/nginx/sites-available/your-api > /dev/null <<'EOF'
server {
listen 443 ssl;
server_name api.yourdomain.com;
ssl_certificate /etc/nginx/ssl/origin-cert.pem;
ssl_certificate_key /etc/nginx/ssl/origin-key.pem;
location / {
proxy_pass http://localhost:8080;
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;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/your-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxAlways use sudo nginx -t to test config syntax before reloading — a
plain nginx -t without sudo fails on log/pid file permissions and gives
a misleading error unrelated to your actual config.
Configure DNS and TLS mode
Add an A record for the API subdomain pointing at the instance’s public
IP, with the CDN’s proxy enabled. In the CDN’s SSL/TLS settings, use Full
(strict) encryption mode — this requires the origin certificate from step
1, which is exactly what’s now installed on the server.
Open the HTTPS port
Open port 443 in the cloud provider’s firewall console, alongside whatever ports were already open (SSH, and temporarily the API’s own port for direct testing).
Point the frontend at the HTTPS domain
Update the frontend’s API base URL to the HTTPS domain instead of the bare IP/port — this is what actually resolves the mixed-content error, since the browser needs the API called over HTTPS to match an HTTPS-hosted frontend.
Verify
curl -I https://api.yourdomain.com/swagger-ui/index.htmlShould return 200 OK with no certificate warnings.
If it doesn’t, work through Networking & Firewalls — an “origin unreachable” class of error at this point almost always means one of the two firewall layers (cloud-level and OS-level) still needs a rule for port 443.