You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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;
    }
}

疑问

  1. 是否需要在SpringBoot应用内部添加HTTPS相关配置,还是所有HTTPS处理都在外部完成?
  2. 针对当前方案的建议:
    • 当前方案的概念是否正确?
    • 当前配置执行是否存在问题?
    • 是否有更优的实践方案?

问题解答

关于HTTPS配置的疑问

不需要在SpringBoot应用内部做HTTPS配置。Swag作为反向代理已经接管了公网的HTTPS请求,它会把加密后的请求解密成HTTP转发给你的SpringBoot应用,应用只需要处理HTTP请求即可。不过要注意在SpringBoot的配置里开启server.forward-headers-strategy=framework或者native,确保应用能正确识别代理传递的X-Forwarded-*头(比如获取客户端真实IP、判断请求是否来自HTTPS等)。

当前方案的合理性与问题排查

方案概念是否正确?

整体思路是对的:用DuckDNS做动态域名解析,Swag做反向代理+SSL证书管理,SpringBoot容器化部署并接入Swag的网络,这个架构是公网发布小型应用的常用方案,逻辑没问题。

当前配置的潜在问题

  1. 端口映射冗余:你的SpringBoot容器映射了8080:8080到宿主机,但在Swag同网络下,直接用容器名my-app:8080就能访问,暴露端口反而可能带来安全风险,建议去掉ports: - "8080:8080"。
  2. Host头配置不当:你配置的proxy_set_header Host $host:$server_port会把Host设为my-domain.duckdns.org:443,部分SpringBoot应用依赖Host头时可能出现异常,建议改成proxy_set_header Host $host即可。
  3. Swag配置未生效:Swag启动时会自动加载proxy-confs目录下的配置文件,但如果是启动后新增的配置,需要重启Swag容器才能生效。另外要确认my-domain.subdomain.conf文件名符合规则,且没有被注释。
  4. 端口转发与防火墙遗漏:树莓派所在路由器需要把外部443端口映射到树莓派的443端口;同时树莓派本地防火墙(如ufw)要允许443端口的入站流量,这是无法访问的常见原因。
  5. 证书生成失败:用docker logs swag查看容器日志,确认Let's Encrypt证书是否生成成功,证书失败会直接导致HTTPS请求被拒绝。

更优的实践方案

  1. 统一网络配置:把Postgres也加入Swag的网络,或者创建一个统一的应用网络,减少外部网络依赖,让容器间通信更安全。
  2. 替换为Traefik:Traefik是更现代化的反向代理,支持自动发现Docker容器、自动配置SSL证书,无需手动编写Nginx配置,对Docker环境更友好。
  3. 添加健康检查:在SpringBoot和Swag的docker-compose中加入健康检查,确保容器异常时自动重启,提升可用性。比如给SpringBoot添加:
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  1. 降低Swag权限:如果不需要VPN等功能,可去掉cap_add: - NET_ADMIN,减少安全风险。

内容的提问来源于stack exchange,提问作者Maddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:35:40