如何配置Nginx实现路径访问Docker服务并强制SSL跳转
配置调整方案
先修正现有配置的已知问题
- 你当前配置文件中的域名存在拼写错误:
myfreedomanin.ddns.net多了多余字母n,需统一替换为你的真实域名myfreedomain.ddns.net - 缺少80端口监听规则,无法处理HTTP请求的强制跳转
- 路径代理规则未处理前缀,会导致后端服务收到带/portainer、/node-red前缀的请求,返回404错误
- 反向代理缺少必要的请求头传递,会导致服务识别客户端信息异常
场景1:完全匹配你的需求(访问路径直接跳转至带端口的HTTPS服务地址)
如果你需要访问http://myfreedomain.ddns.net/portainer时,地址栏直接跳转为https://myfreedomain.ddns.net:9000,使用以下配置即可:
# 80端口HTTP请求强制跳转HTTPS server { listen 80; server_name myfreedomain.ddns.net; # 匹配路径直接跳转对应服务端口 location ~ ^/(portainer|node-red)(.*)$ { if ($1 = 'portainer') { return 301 https://$host:9000$2; } if ($1 = 'node-red') { return 301 https://$host:1880$2; } } # 其他所有HTTP请求跳转HTTPS根路径 location / { return 301 https://$host$request_uri; } } # 443端口HTTPS配置 server { listen 443 ssl; server_name myfreedomain.ddns.net; ssl_certificate /etc/letsencrypt/live/myfreedomain.ddns.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myfreedomain.ddns.net/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # HTTPS下访问路径也直接跳转对应端口 location ~ ^/(portainer|node-red)(.*)$ { if ($1 = 'portainer') { return 301 https://$host:9000$2; } if ($1 = 'node-red') { return 301 https://$host:1880$2; } } }
场景2:更推荐的路径代理方案(地址栏不变,无需暴露服务端口)
如果你不需要跳转到带端口的地址,直接用https://myfreedomain.ddns.net/portainer就能访问服务,隐藏服务端口更安全,使用以下配置:
# 80端口HTTP请求强制跳转HTTPS server { listen 80; server_name myfreedomain.ddns.net; return 301 https://$host$request_uri; } # 443端口HTTPS配置 server { listen 443 ssl; server_name myfreedomain.ddns.net; ssl_certificate /etc/letsencrypt/live/myfreedomain.ddns.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myfreedomain.ddns.net/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location /portainer/ { # 去掉路径前缀再转发到后端 rewrite ^/portainer(/.*)$ $1 break; proxy_pass https://127.0.0.1:9000; # 传递必要请求头 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_ssl_verify off; # 支持WebSocket(Portainer和Node-Red都需要) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /node-red/ { rewrite ^/node-red(/.*)$ $1 break; proxy_pass https://127.0.0.1:1880; 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_ssl_verify off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
生效步骤
- 修改配置文件后,执行
nginx -t测试配置是否正确,提示test is successful再进行下一步 - 执行
systemctl reload nginx重载Nginx配置即可生效
内容的提问来源于stack exchange,提问作者Giuseppe Lisi
相关产品推荐
相关产品推荐

