Docker

當我創建一個單獨的後端網路時,Docker+Synapse+Traefik v2 停止工作

  • October 16, 2021

我正在嘗試使用 Docker 和 Traefik v2 反向代理設置 Matrix Synapse 伺服器。

如果我在 docker-compose 文件中定義一個網路並且 Traefik、Synapse 和 postgres 都使用該網路,我的設置就可以工作。

但是,根據我目前對 Docker 的了解,我應該將 postgres 放在一個單獨的網路上(backed)而不是 Traefik(web)。然後 Synapse 將在兩個網路上。但是,當我這樣做時,我不再能夠連接到 Synapse。它超時最終說Gateway Timeout

就好像 Synapse 只在backend網路上監聽一樣。

version: '3.2'
services:
 synapse:
   container_name: synapse
   hostname: ${MATRIX_HOSTNAME}
   image: docker.io/matrixdotorg/synapse:latest
   restart: unless-stopped
   environment:
     - SYNAPSE_SERVER_NAME=${MATRIX_HOSTNAME}
     - SYNAPSE_REPORT_STATS=yes
     - SYNAPSE_NO_TLS=1
     - SYNAPSE_ENABLE_REGISTRATION=no
     - SYNAPSE_LOG_LEVEL=DEBUG
     - SYNAPSE_REGISTRATION_SHARED_SECRET=${REG_SHARED_SECRET}
     - POSTGRES_DB=synapse
     - POSTGRES_HOST=db
     - POSTGRES_USER=${POSTGRES_USER}
     - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
   # expose: 
   #   - "8008"
   volumes:
     - type: bind
       source: /opt/services/synapse
       target: /data
   depends_on:
     - db
   networks:
     - web
     - backend
   labels:
     - "traefik.enable=true"
     - "traefik.http.routers.synapse.rule=Host(`${MATRIX_HOSTNAME}`)"
     - "traefik.http.services.synapse.loadbalancer.server.port=8008"
     - "traefik.http.routers.synapse.entrypoints=websecure"
     - "traefik.http.routers.synapse.tls.certresolver=myresolver"
     - "traefik.docker.network=web"

 db:
   image: docker.io/postgres:10-alpine
   container_name: "synapse_db"
   restart: unless-stopped
   environment:
     - POSTGRES_DB=synapse
     - POSTGRES_USER=${POSTGRES_USER}
     - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
   volumes:
     - /opt/services/synapse_db:/var/lib/postgresql/data
   networks:
     - backend
   labels:
     - "traefik.enable=false"
 
 traefik:
   image: traefik:v2.5
   container_name: "traefik"
   command: 
     - "--api.insecure=true"
     - "--providers.docker=true"
     - "--providers.docker.exposedbydefault=false"
     - "--providers.docker.network=web"
     - "--entrypoints.websecure.address=:443"
     - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
     - "--certificatesresolvers.myresolver.acme.email=${CERTBOT_EMAIL}"
     - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
   ports:
     # Router forwards 443 on WAN to 8443 on host so we don't need root permissions
     - "8443:443"
     - "8080:8080"
   networks:
     - web
   volumes:
     - "/var/run/docker.sock:/var/run/docker.sock:ro"
     - "./letsencrypt:/letsencrypt"
   restart:
     unless-stopped

networks:
 web:
 backend:

在 Synapse 的homeserver.yaml文件中,有一個部分可以讓我綁定到特定介面,但我沒有進行任何更改,因此它應該預設監聽所有介面:

listeners:
 - port: 8008
   tls: false
   type: http
   x_forwarded: true

   resources:
     # - names: [client, federation]
     - names: [client]
       compress: false

如果我進入單個網路設置,它就可以工作。兩個網路設置我做錯了什麼?

Traefik 不知道它應該嘗試連接的容器的哪個 IP。你很接近,traefik.docker.network=web但這並不是網路的真正名稱。網路將獲得項目或堆棧名稱的前綴。

要對網路名稱進行硬編碼,您可以使用最終網路部分中的名稱欄位(這是特定於 3.5 或更高版本的):

version '3.5'
services:
 ...
networks:
 web:
   name: web
 backend:

否則,在您的標籤中設置項目(這通常是使用時的目前目錄名稱docker-compose):

labels:
...
 - "traefik.docker.network=your_project_name_here_web"

引用自:https://serverfault.com/questions/1080735