diff --git a/Dockerfile b/Dockerfile index e0fd0da..8c7607e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,27 @@ -# --- 网关运行阶段 --- -FROM 106.52.199.114:5000/nginx:latest AS gateway -# 复制自定义的 Nginx 配置文件 -# 假设 Nginx 配置在 gateway 项目的根目录,名为 nginx.conf.gateway -COPY nginx.conf.gateway /etc/nginx/nginx.conf +# 基于官方 Traefik v3 镜像 +FROM traefik:v3.0 -# 暴露 Nginx 监听的端口 -# 在 nginx.conf.gateway 中配置了 8000 和 8001 端口 -EXPOSE 8000 -EXPOSE 8002 +# 维护者 +LABEL maintainer="you@example.com" -# 启动 Nginx 服务器 -CMD ["nginx", "-g", "daemon off;"] +# 拷贝静态配置 (traefik.yml) +COPY traefik.yml /etc/traefik/traefik.yml + +# 拷贝动态配置 (dynamic.yml) +COPY dynamic.yml /etc/traefik/dynamic.yml + +# 创建证书目录(可挂载) +RUN mkdir -p /etc/certs + +# 暴露你需要的端口 +# - 8000: Sys 系统 +# - 8002: LMG 系统 +# - 8003: Healthy 系统 +# - 8080: Traefik Dashboard (可选) +EXPOSE 8000 8002 8003 8080 + +# 启动 Traefik +ENTRYPOINT ["traefik"] + +# 默认命令:启动并加载静态配置 +CMD ["--configFile=/etc/traefik/traefik.yml"] \ No newline at end of file diff --git a/README.md b/README.md index ac732fd..e0d8111 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,25 @@ # gateway -nginx 网关 \ No newline at end of file +nginx 网关 + + +version: '3.9' +services: + traefik: + image: my-traefik:latest + container_name: traefik + ports: + - "8000:8000" + - "8002:8002" + - "8003:8003" + - "8080:8080" + volumes: + - ./traefik.yml:/etc/traefik/traefik.yml + - ./dynamic.yml:/etc/traefik/dynamic.yml + - ./certs:/etc/certs + restart: unless-stopped + + + + 参考地址 + https://askmany.cn/chat/c970ddff-b553-4491-b4d3-a1572ed55db5 \ No newline at end of file diff --git a/dynamic.yml b/dynamic.yml new file mode 100644 index 0000000..df124d0 --- /dev/null +++ b/dynamic.yml @@ -0,0 +1,145 @@ +http: + routers: + # Sys Auth + sys-auth: + entryPoints: ["sys"] + rule: "PathPrefix(`/auth`)" + service: ids4 + middlewares: [strip-auth, cors, ids4-hostfix] + + sys-connect: + entryPoints: ["sys"] + rule: "PathPrefix(`/connect`)" + service: ids4 + middlewares: [cors, ids4-hostfix] + + sys-api: + entryPoints: ["sys"] + rule: "PathPrefix(`/api/sys`)" + service: sys-api + middlewares: [cors, auth-header, strip-api-sys] + + sys-ui: + entryPoints: ["sys"] + rule: "PathPrefix(`/`)" + service: sys-ui + middlewares: [cors] + + # LMG Auth + lmg-auth: + entryPoints: ["lmg"] + rule: "PathPrefix(`/auth`)" + service: ids4 + middlewares: [strip-auth, cors, ids4-hostfix] + + lmg-api: + entryPoints: ["lmg"] + rule: "PathPrefix(`/api/lmg`)" + service: lmg-api + middlewares: [cors, auth-header, strip-api-lmg] + + lmg-ui: + entryPoints: ["lmg"] + rule: "PathPrefix(`/`)" + service: lmg-ui + middlewares: [cors] + + # Healthy Auth + healthy-auth: + entryPoints: ["healthy"] + rule: "PathPrefix(`/auth`)" + service: ids4 + middlewares: [strip-auth, cors, ids4-hostfix] + + healthy-api: + entryPoints: ["healthy"] + rule: "PathPrefix(`/api/healthy`)" + service: healthy-api + middlewares: [cors, auth-header, strip-api-healthy] + + healthy-ui: + entryPoints: ["healthy"] + rule: "PathPrefix(`/`)" + service: healthy-ui + middlewares: [cors] + + services: + ids4: + loadBalancer: + servers: + - url: "https://sys-api:8001" + serversTransport: ids4-transport + + sys-api: + loadBalancer: + servers: + - url: "https://sys-api:8001" + serversTransport: ids4-transport + + sys-ui: + loadBalancer: + servers: + - url: "http://sys-ui:80" + + lmg-api: + loadBalancer: + servers: + - url: "https://lmg-api:19904" + serversTransport: ids4-transport + + lmg-ui: + loadBalancer: + servers: + - url: "http://lmg-ui:80" + + healthy-api: + loadBalancer: + servers: + - url: "https://healthy-api:19906" + serversTransport: ids4-transport + + healthy-ui: + loadBalancer: + servers: + - url: "http://healthy-ui:80" + + serversTransports: + ids4-transport: + insecureSkipVerify: true + + middlewares: + cors: + headers: + accessControlAllowOriginList: ["*"] + accessControlAllowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"] + accessControlAllowHeaders: ["Authorization", "Content-Type"] + accessControlAllowCredentials: true + addVaryHeader: true + + strip-auth: + stripPrefix: + prefixes: ["/auth"] + + strip-api-sys: + stripPrefix: + prefixes: ["/api/sys"] + + strip-api-lmg: + stripPrefix: + prefixes: ["/api/lmg"] + + strip-api-healthy: + stripPrefix: + prefixes: ["/api/healthy"] + + ids4-hostfix: + headers: + customRequestHeaders: + Host: "106.52.199.114:8001" + X-Forwarded-Host: "106.52.199.114:8001" + X-Forwarded-Proto: "https" + + auth-header: + headers: + customRequestHeaders: + Authorization: "{header:Authorization}" \ No newline at end of file diff --git a/nginx.conf.gateway b/nginx.conf.gateway deleted file mode 100644 index a1bd5f3..0000000 --- a/nginx.conf.gateway +++ /dev/null @@ -1,331 +0,0 @@ -error_log /var/log/nginx/error.log debug; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - - sendfile on; - keepalive_timeout 65; - # Gzip 压缩1 - gzip on; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; - - # Sys 系统 API - upstream sys_api { - server sys-api:8001; - } - - # Lmg 系统 API - upstream lmg_api { - server lmg-api:19904; - } - - # Sys 系统 UI - upstream sys_ui { - server sys-ui:80; - } - - # Lmg 系统 UI - upstream lmg_ui { - server lmg-ui:80; - } - - # healthy - upstream healthy_ui { - server healthy-ui:80; - } - - upstream healthy_api { - server healthy-api:19906; - } - - # ------------------------------- - # 2. Sys系统服务 (8000) - # ------------------------------- - server { - listen 8000 ssl; - server_name 106.52.199.114; - client_max_body_size 100M; # 允许最大 100MB 的请求体 - - ssl_certificate /etc/nginx/certs/gateway.crt; - ssl_certificate_key /etc/nginx/certs/gateway.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - ssl_verify_client off; # ↓ 允许自签名证书 - ssl_verify_depth 0; - # API路由 - location /api/sys/ { - proxy_pass https://sys_api/api/; - proxy_ssl_server_name on; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; - } - # 认证服务代理 - location /auth/ { - # 关键 1: 移除路径中的 /auth/ 前缀 - proxy_pass https://sys_api/; # 末尾的 / 确保路径替换 - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - # 关键 2: 覆盖 Host 头,模拟 Vite 的 changeOrigin=true - - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - # 其他标准代理头 - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - # 关键 4: 重写后端返回的 Location 头(解决重定向端口丢失) - proxy_redirect https://sys_api:19902/ http://$host:$server_port/auth/; - proxy_redirect https://sys_api/ http://$host:$server_port/auth/; - } - location /connect/ { - # 关键 1: 移除路径中的 /auth/ 前缀 - proxy_pass https://sys_api/; # 末尾的 / 确保路径替换 - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - # 关键 2: 覆盖 Host 头,模拟 Vite 的 changeOrigin=true - - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - # 其他标准代理头 - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - # 关键 4: 重写后端返回的 Location 头(解决重定向端口丢失) - proxy_redirect https://sys_api:19902/ http://$host:$server_port/auth/; - proxy_redirect https://sys_api/ http://$host:$server_port/auth/; - } - - location = /auth/.well-known/openid-configuration { - proxy_pass https://sys_api/.well-known/openid-configuration; - # 核心: - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - # 动态修改返回的JSON中的URL - proxy_set_header Accept-Encoding ""; - sub_filter_types application/json; - sub_filter_once off; - sub_filter 'https://sys-api:19902' 'https://$host:8001'; - sub_filter 'https://sys_api' 'https://$host:8001'; - } - # UI前端路由 - location / { - proxy_pass http://sys_ui; - proxy_set_header Host $host; - } - - location ~* ^/Upload/(.*)$ { - - # 代理到后端,此时的请求路径已经是重写后的(即没有 /Upload/ 前缀的) - proxy_pass https://sys_api; # 注意:如果 sys_api 后端期望收到 /upload/ 前缀,这里加上。如果后端只期望收到 /path/to/file.jpg,这里就写 https://sys_api; - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - } - } - - - # ------------------------------- - # 3. Lmg系统服务 (8002) - # ------------------------------- - server { - listen 8002 ssl; - server_name 106.52.199.114; - client_max_body_size 100M; # 允许最大 100MB 的请求体 - ssl_certificate /etc/nginx/certs/gateway.crt; - ssl_certificate_key /etc/nginx/certs/gateway.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - ssl_verify_client off; # ↓ 允许自签名证书 - ssl_verify_depth 0; - # API路由 - location /api/lmg/ { - proxy_pass https://lmg_api/api/; - proxy_ssl_server_name on; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; - } - - # UI前端路由 - location /{ - proxy_pass http://lmg_ui/; # 注意末尾的/ - proxy_set_header Host $host; - } - - location /auth/ { - # 关键 1: 移除路径中的 /auth/ 前缀 - proxy_pass https://sys_api/; # 末尾的 / 确保路径替换 - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - # 关键 2: 覆盖 Host 头,模拟 Vite 的 changeOrigin=true - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - # 其他标准代理头 - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - # 关键 4: 重写后端返回的 Location 头(解决重定向端口丢失) - proxy_redirect https://sys_api:19902/ http://$host:$server_port/auth/; - proxy_redirect https://sys_api/ http://$host:$server_port/auth/; - } - location = /auth/.well-known/openid-configuration { - proxy_pass https://sys_api/.well-known/openid-configuration; - - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - # 动态修改返回的JSON中的URL - proxy_set_header Accept-Encoding ""; - sub_filter_types application/json; - sub_filter_once off; - sub_filter 'https://sys-api:19902' 'https://$host:8001'; - sub_filter 'https://sys_api' 'https://$host:8001'; - } - - location /api/sys/ { - proxy_pass https://sys_api/api/; - proxy_ssl_server_name on; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; - } - location ~* ^/Upload/(.*)$ { - - proxy_pass https://sys_api; - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - } - - location ~* ^/LMGUpload/(.*)$ { - - proxy_pass https://lmg_api; - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - } - } - - - # ------------------------------- - # 3. Healthy系统服务 (8003) - # ------------------------------- - server { - listen 8003 ssl; - server_name 106.52.199.114; - client_max_body_size 100M; # 允许最大 100MB 的请求体 - ssl_certificate /etc/nginx/certs/gateway.crt; - ssl_certificate_key /etc/nginx/certs/gateway.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - ssl_verify_client off; # ↓ 允许自签名证书 - ssl_verify_depth 0; - # API路由 - location /api/healthy/ { - proxy_pass https://healthy_api/api/; - proxy_ssl_server_name on; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; - } - - # UI前端路由 - location /{ - proxy_pass http://healthy_ui/; # 注意末尾的/ - proxy_set_header Host $host; - } - - location /auth/ { - # 关键 1: 移除路径中的 /auth/ 前缀 - proxy_pass https://sys_api/; # 末尾的 / 确保路径替换 - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - # 关键 2: 覆盖 Host 头,模拟 Vite 的 changeOrigin=true - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - # 其他标准代理头 - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - # 关键 4: 重写后端返回的 Location 头(解决重定向端口丢失) - proxy_redirect https://sys_api:19902/ http://$host:$server_port/auth/; - proxy_redirect https://sys_api/ http://$host:$server_port/auth/; - } - location = /auth/.well-known/openid-configuration { - proxy_pass https://sys_api/.well-known/openid-configuration; - - proxy_set_header Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Host 106.52.199.114:8001; - proxy_set_header X-Forwarded-Proto $scheme; - # 动态修改返回的JSON中的URL - proxy_set_header Accept-Encoding ""; - sub_filter_types application/json; - sub_filter_once off; - sub_filter 'https://sys-api:19902' 'https://$host:8001'; - sub_filter 'https://sys_api' 'https://$host:8001'; - } - - location /api/sys/ { - proxy_pass https://sys_api/api/; - proxy_ssl_server_name on; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; - } - location ~* ^/Upload/(.*)$ { - - proxy_pass https://sys_api; - - proxy_ssl_server_name on; - proxy_ssl_session_reuse off; - proxy_ssl_verify off; - proxy_set_header Authorization $http_authorization; # 传递 Authorization 头 - } - } -} diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 0000000..4ef9eb6 --- /dev/null +++ b/traefik.yml @@ -0,0 +1,27 @@ +entryPoints: + sys: + address: ":8000" + http: + maxRequestBodyBytes: 104857600 # 100MB + lmg: + address: ":8002" + http: + maxRequestBodyBytes: 104857600 + healthy: + address: ":8003" + http: + maxRequestBodyBytes: 104857600 + +api: + dashboard: true + insecure: true + +providers: + file: + filename: /etc/traefik/dynamic.yml + watch: true + +tls: + certificates: + - certFile: /etc/certs/gateway.crt + keyFile: /etc/certs/gateway.key \ No newline at end of file