跳转至

应用接入指南

本指南用于指导如何将新应用或现有应用接入双区域网关架构。

1. 核心逻辑 (Twin Hub Architecture)

不管是哪个节点(春川或伦敦),接入流程只取决于 “应用在哪”

部署位置 接入网关 Docker 网络 关键配置
伦敦区域 (London 1/2/3) Traefik-UK proxy-uk 同样在伦敦,直接加入网络,无需映射端口
春川区域 (Chuncheon 1/2) Traefik-KR proxy-kr 同样在春川,直接加入网络,无需映射端口
跨区域 (e.g. 伦敦应用挂春川网关) 远程 Traefik host 通讯 必须映射端口 供 Tailscale 访问

1.1 部署模式差异 (Standalone vs Swarm)

非常重要:Traefik 在处理单机 Docker 和 Swarm 集群时,读取标签 (Labels) 的位置完全不同。混用会导致服务无法被发现 (404 Not Found)。

模式 命令 Labels 位置 示例
Standalone (单机) docker-compose up -d Service 顶层 image 同级
Swarm (集群) docker stack deploy Deploy 块内部 deploy.labels

错误示范 (单机环境误用 Swarm 写法):

services:
  app:
    # 单机模式下,Traefik 看不到这里的标签!
    deploy:
      labels:
        - "traefik.enable=true"

正确示范 (单机环境):

services:
  app:
    image: xxx
    labels:  # <--- 必须放在这里
      - "traefik.enable=true"


2. 场景 A: 伦敦 Swarm 集群应用 (默认推荐)

情况: 应用部署在伦敦 Swarm 集群,使用伦敦 Traefik-UK 暴露。

部署方式: 使用 docker stack deploy

Compose 配置 (app-blog.yml):

[!IMPORTANT] 必须包含头部注释:所有 Compose 文件必须在头部包含元数据注释,注明服务名称、关联域名和维护者。

# ==========================================
# 项目:Blog Application
# 作用:博客系统(Ghost),通过 Traefik 暴露给外网
# 端口:占用 2368,不映射宿主机端口
# 维护注意:数据持久化在 /opt/data/blog
# 上次更新:2026-02-09 by Suztomo
# ==========================================

services:
  app-blog:
    image: ghost:latest
    networks:
      - proxy-uk  # 直接加入网关网络
    deploy:
      replicas: 2 # <--- Swarm 优势:多副本高可用
      placement:
        constraints: [node.role == worker] # 均摊到工作节点
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.app-blog.rule=Host(`blog.120224.xyz`)"
        - "traefik.http.routers.app-blog.entrypoints=websecure"
        - "traefik.http.routers.app-blog.tls.certresolver=letsencrypt"
        # 仅当容器暴露多个端口时才需要显式指定,单端口应用通不需要
        - "traefik.http.services.app-blog.loadbalancer.server.port=2368"
networks:
  proxy-uk:
    external: true

注意: 对于有状态应用 (如数据库),请务必添加 constraints: [node.hostname == london3] 以防止容器漂移导致数据丢失 (除非使用了共享存储)。


3. 场景 B: 跨区域接入 (例外情况)

情况: 应用部署在伦敦 (London 1),但必须挂载到春川 (Chuncheon 1) 的 Traefik-KR 下(例如统一管理面板)。

原理: Traefik (KR) -> Tailscale Tunnel -> London Host IP -> App Port

Docker Compose 配置 (London 1):

services:
  app-alist:
    image: xhofe/alist:latest
    # 注意:跨区域无法直接加入 proxy-kr 网络 (它们在不同机器)
    ports:
      - "100.88.x.x:5244:5244" # <--- 关键:绑定到本机 Tailscale IP
    # 无需 Traefik 标签,因为本机 Traefik 根本看不见它

# 无需 networks 配置

Traefik 配置 (Chuncheon 1): 需要在春川主节点手动添加动态配置。

文件: /opt/infra/stacks/net-traefik-kr/dynamic/remote-apps.yml

http:
  routers:
    remote-alist:
      rule: "Host(`info.120224.xyz`)"
      service: remote-alist-svc
      entryPoints: [websecure]
      tls: { certResolver: letsencrypt }

  services:
    remote-alist-svc:
      loadBalancer:
        servers:
          - url: "http://100.88.x.x:5244" # 指向伦敦节点的 Tailscale IP

4. 场景 C: 纯内网应用 (Private)

适用于数据库、私有仓库等不应暴露到公网的服务。

推荐方案: 仅通过 Tailscale IP 访问,不经过 Traefik。

services:
  db-postgres:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    ports:
      - "100.x.y.z:5432:5432" # 仅绑定 Tailscale IP

5. Homepage 门户配置

所有应用部署完后,添加到春川1的 Homepage 统一入口。

文件位置: 春川1 -> /opt/infra/stacks/hub-homepage/config/services.yaml

- 核心管理:
    - Portainer:
        href: https://portainer.120224.xyz
        description: 容器管理 (KR)
    - Beszel:
        href: https://beszel.120224.xyz
        description: 资源监控 (KR)

- 伦敦主要应用:
    - Blog:
        href: https://blog.120224.xyz
        description: 博客 (UK)