使用Linuxserver Swag作为Docker Compose中SpringBoot应用反向代理遇阻
树莓派部署SpringBoot应用至公网的问题
已完成的部署步骤
- 在DuckDNS申请域名,通过Docker镜像自动更新IP地址
- SpringBoot应用通过Docker容器运行,docker-compose配置如下:
version: "3" services: my-app: container_name: my-app image: my-app:latest restart: unless-stopped ports: - "8080:8080" env_file: - .env networks: - postgres - swag networks: postgres: external: name: postgres-network swag: external: name: swag-network
- 通过Docker运行Swag(用于Let's Encrypt证书生成和反向代理),其docker-compose配置如下:
version: "2.1" services: swag: image: linuxserver/swag:arm64v8-1.32.0 container_name: swag cap_add: - NET_ADMIN environment: - PUID=1000 - PGID=1000 - TZ=Europe/Berlin - URL=my-domain.duckdns.org - SUBDOMAINS=wildcard - VALIDATION=duckdns - DUCKDNSTOKEN=my-token volumes: - ./config:/config ports: - 443:443 restart: unless-stopped networks: - swag networks: swag: name: swag-network
- 在
config/nginx/proxy-confs/my-domain.subdomain.conf中配置反向代理:
server { listen 443 ssl; server_name my-domain.duckdns.org; location / { proxy_set_header Host $host:$server_port; 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_pass http://my-app:8080; proxy_redirect off; } }
疑问
- 是否需要在SpringBoot应用内部添加HTTPS相关配置,还是所有HTTPS处理都在外部完成?
- 针对当前方案的建议:
- 当前方案的概念是否正确?
- 当前配置执行是否存在问题?
- 是否有更优的实践方案?
问题解答
关于HTTPS配置的疑问
不需要在SpringBoot应用内部做HTTPS配置。Swag作为反向代理已经接管了公网的HTTPS请求,它会把加密后的请求解密成HTTP转发给你的SpringBoot应用,应用只需要处理HTTP请求即可。不过要注意在SpringBoot的配置里开启server.forward-headers-strategy=framework或者native,确保应用能正确识别代理传递的X-Forwarded-*头(比如获取客户端真实IP、判断请求是否来自HTTPS等)。
当前方案的合理性与问题排查
方案概念是否正确?
整体思路是对的:用DuckDNS做动态域名解析,Swag做反向代理+SSL证书管理,SpringBoot容器化部署并接入Swag的网络,这个架构是公网发布小型应用的常用方案,逻辑没问题。
当前配置的潜在问题
- 端口映射冗余:你的SpringBoot容器映射了
8080:8080到宿主机,但在Swag同网络下,直接用容器名my-app:8080就能访问,暴露端口反而可能带来安全风险,建议去掉ports: - "8080:8080"。 - Host头配置不当:你配置的
proxy_set_header Host $host:$server_port会把Host设为my-domain.duckdns.org:443,部分SpringBoot应用依赖Host头时可能出现异常,建议改成proxy_set_header Host $host即可。 - Swag配置未生效:Swag启动时会自动加载
proxy-confs目录下的配置文件,但如果是启动后新增的配置,需要重启Swag容器才能生效。另外要确认my-domain.subdomain.conf文件名符合规则,且没有被注释。 - 端口转发与防火墙遗漏:树莓派所在路由器需要把外部443端口映射到树莓派的443端口;同时树莓派本地防火墙(如ufw)要允许443端口的入站流量,这是无法访问的常见原因。
- 证书生成失败:用
docker logs swag查看容器日志,确认Let's Encrypt证书是否生成成功,证书失败会直接导致HTTPS请求被拒绝。
更优的实践方案
- 统一网络配置:把Postgres也加入Swag的网络,或者创建一个统一的应用网络,减少外部网络依赖,让容器间通信更安全。
- 替换为Traefik:Traefik是更现代化的反向代理,支持自动发现Docker容器、自动配置SSL证书,无需手动编写Nginx配置,对Docker环境更友好。
- 添加健康检查:在SpringBoot和Swag的docker-compose中加入健康检查,确保容器异常时自动重启,提升可用性。比如给SpringBoot添加:
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 30s timeout: 10s retries: 3
- 降低Swag权限:如果不需要VPN等功能,可去掉
cap_add: - NET_ADMIN,减少安全风险。
内容的提问来源于stack exchange,提问作者Maddin
相关产品推荐
相关产品推荐

