From 7645dd739e881baddd37b18d1e6ad2f70a5d1eab Mon Sep 17 00:00:00 2001 From: Teck Meng Date: Fri, 31 May 2024 21:42:36 +0800 Subject: [PATCH] Refactor traefik.yml to update routing rules for chat and bot subdomains --- compose/traefik/traefik.yml | 2 +- emqx-docker | 1 - swarm/emqx.yml | 50 +++++++ swarm/services.yml | 253 ++++++++++++++++++++++++++++++++++++ swarm/traefik.yml | 11 ++ 5 files changed, 315 insertions(+), 2 deletions(-) delete mode 160000 emqx-docker create mode 100644 swarm/emqx.yml create mode 100644 swarm/services.yml diff --git a/compose/traefik/traefik.yml b/compose/traefik/traefik.yml index 370e829..f54a2fe 100644 --- a/compose/traefik/traefik.yml +++ b/compose/traefik/traefik.yml @@ -179,7 +179,7 @@ http: # https://doc.traefik.io/traefik/middlewares/http/headers/#hostsproxyheaders # https://docs.djangoproject.com/en/dev/ref/csrf/#ajax headers: - hostsProxyHeaders: ["X-CSRFToken"] + hostsProxyHeaders: ["X-CSRF-Token"] sslheader: # https://docs.traefik.io/master/middlewares/headers/ headers: diff --git a/emqx-docker b/emqx-docker deleted file mode 160000 index 554e4b1..0000000 --- a/emqx-docker +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 554e4b18725da24a974f37d810675126f30c1e1d diff --git a/swarm/emqx.yml b/swarm/emqx.yml new file mode 100644 index 0000000..d88fadb --- /dev/null +++ b/swarm/emqx.yml @@ -0,0 +1,50 @@ +services: + emqx1: + image: emqx:latest + healthcheck: + test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"] + interval: 60s + timeout: 25s + retries: 5 + networks: + - traefik-public + ports: + - "1883:1883" + # - 8083:8083 + # - 8084:8084 + # - 8883:8883 + # - 18083:18083 + volumes: + - emqx-data1:/opt/emqx/data + deploy: + mode: replicated + replicas: 1 + labels: + - "traefik.enable=true" + - "traefik.http.routers.emqx1.entrypoints=web-secure" + - "traefik.http.routers.emqx1.rule=Host(`mqtt.${DOMAINNAME}`)" + - "traefik.http.routers.emqx1.tls.certresolver=letsencrypt" + - "traefik.http.routers.emqx1.service=emqx-dashboard" + - "traefik.http.services.emqx-dashboard.loadbalancer.server.port=18083" + + mqttx-web: + image: emqx/mqttx-web:latest + restart: unless-stopped + networks: + - traefik-public + deploy: + labels: + - "traefik.enable=true" + - "traefik.http.routers.mqttx-web.entrypoints=web-secure" + - "traefik.http.routers.mqttx-web.rule=Host(`mqttx.${DOMAINNAME}`)" + - "traefik.http.routers.mqttx-web.tls.certresolver=letsencrypt" + - "traefik.http.routers.mqttx-web.service=mqttx-web-service" + - "traefik.http.services.mqttx-web-service.loadbalancer.server.port=80" + +networks: + traefik-public: + external: true + +volumes: + emqx-data1: + driver: local diff --git a/swarm/services.yml b/swarm/services.yml new file mode 100644 index 0000000..0346254 --- /dev/null +++ b/swarm/services.yml @@ -0,0 +1,253 @@ +volumes: + minio_data: {} + neo4j_data: {} + neo4j_logs: {} + postgres_data: {} + +services: + api_server: + image: furyhawk/listen:latest + restart: always + depends_on: + - postgres + environment: + DATABASE__HOSTNAME: ${DATABASE__HOSTNAME} + DATABASE__USERNAME: ${POSTGRES_USER} + DATABASE__PASSWORD: ${POSTGRES_PASSWORD} + DATABASE__PORT: ${DATABASE__PORT} + DATABASE__DB: ${DATABASE__DB} + SECURITY__JWT_SECRET_KEY: ${SECURITY__JWT_SECRET_KEY} + SECURITY__BACKEND_CORS_ORIGINS: ${SECURITY__BACKEND_CORS_ORIGINS} + SECURITY__ALLOWED_HOSTS: ${SECURITY__ALLOWED_HOSTS} + DOMAINNAME: ${DOMAINNAME} + ports: + - "8000:8000" + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.api_server.entrypoints=web-secure" + - "traefik.http.routers.api_server.rule=Host(`api.${DOMAINNAME}`)" + - "traefik.http.routers.api_server.middlewares=csrf@file, rate-limit@file" + - "traefik.http.routers.api_server.tls.certresolver=letsencrypt" + - "traefik.http.routers.api_server.service=api_server_service" + - "traefik.http.services.api_server_service.loadbalancer.server.port=8000" + + postgres: + image: postgres + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATA: "/var/lib/postgresql/data" + LANG: en_US.utf8 + TZ: Asia/Singapore + # DOMAINNAME: ${DOMAINNAME} + command: ["postgres", "-c", "log_connections=on"] + volumes: + - postgres_data:/var/lib/postgresql/data + # - ./config/postgresql.conf:/etc/postgresql.conf + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 30s + timeout: 10s + retries: 10 + # ports: + # - "5432:5432" + expose: + - 5432 + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.tcp.routers.postgres.entrypoints=postgres-socket" + - "traefik.tcp.routers.postgres.rule=HostSNI(`*`)" + - "traefik.tcp.routers.postgres.service=postgres_service" + - "traefik.tcp.services.postgres_service.loadbalancer.server.port=5432" + # - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10" + # - "traefik.tcp.routers.postgres.rule=HostSNIRegexp(`^.+\\.furyhawk\\.lol$`)" + # - "traefik.tcp.routers.postgres.tls=true" + # - "traefik.tcp.routers.postgres.tls.certresolver=letsencrypt" + # - "traefik.tcp.routers.postgres.middlewares=test-inflightconn" + # - "traefik.http.routers.postgres.entrypoints=web-secure" + # - "traefik.http.routers.postgres.rule=Host(`db.${DOMAINNAME}`)" + # - "traefik.http.routers.postgres.middlewares=rate-limit@file, csrf@file" + # - "traefik.http.routers.postgres.tls.certresolver=letsencrypt" + # - "traefik.http.routers.postgres.service=postgres_service" + # - "traefik.http.services.postgres_service.loadbalancer.server.port=5432" + + osrm-backend: + environment: + # OSRM manager setup + - OSRM_ALGORITHM=mld + - OSRM_THREADS=2 + - OSRM_PORT=${OSRM_PORT:-5000} + - OSRM_PROFILE=/opt/car.lua + - OSRM_MAP_NAME=${OSRM_MAP_NAME} + - OSRM_GEOFABRIK_PATH=${OSRM_GEOFABRIK_PATH} + # Notify OSRM Manager to restart without stopping container + - OSRM_NOTIFY_FILEPATH=/data/osrm_notify.txt + - DOMAINNAME=${DOMAINNAME} + image: furyhawk/osrm-backend:${OSRM_VERSION:-latest} + restart: unless-stopped + expose: + - ${OSRM_PORT:-5000} + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.osrm-backend.entrypoints=web-secure" + - "traefik.http.routers.osrm-backend.rule=Host(`osrm.${DOMAINNAME}`)" + - "traefik.http.routers.osrm-backend.middlewares=csrf@file" + - "traefik.http.routers.osrm-backend.tls.certresolver=letsencrypt" + - "traefik.http.routers.osrm-backend.service=osrm_backend_service" + - "traefik.http.services.osrm_backend_service.loadbalancer.server.port=${OSRM_PORT:-5000}" + + minio-common: + image: minio/minio:latest + environment: + MINIO_ROOT_USER: "${MINIO_ROOT_USER:-minioadmin}" + MINIO_ROOT_PASSWORD: "${MINIO_ROOT_PASSWORD:-minioadmin}" + MINIO_OPTS: "--console-address :9001" + MINIO_SERVER_URL: https://minio.${DOMAINNAME} + DOMAINNAME: ${DOMAINNAME} + # user: "1000:1000" + restart: unless-stopped + command: server /data --address :9000 --console-address :9001 + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 60s + timeout: 5s + retries: 5 + volumes: + - minio_data:/data + expose: + - 9000 + - 9001 + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.minio-router.entrypoints=web-secure" + - "traefik.http.routers.minio-router.rule=Host(`drive.${DOMAINNAME}`) || Host(`storage.${DOMAINNAME}`)" + - "traefik.http.routers.minio-router.middlewares=csrf@file" + - "traefik.http.routers.minio-router.tls.certresolver=letsencrypt" + - "traefik.http.routers.minio-router.service=minio_common_service" + - "traefik.http.services.minio_common_service.loadbalancer.server.port=9001" + - "traefik.http.routers.minio-api-router.entrypoints=web-secure" + - "traefik.http.routers.minio-api-router.rule=Host(`minio.${DOMAINNAME}`) || Host(`s3.${DOMAINNAME}`)" + - "traefik.http.routers.minio-api-router.middlewares=csrf@file" + - "traefik.http.routers.minio-api-router.tls.certresolver=letsencrypt" + - "traefik.http.routers.minio-api-router.service=minio_api_service" + - "traefik.http.services.minio_api_service.loadbalancer.server.port=9000" + + neo4j_server: + # Docker image to be used + image: ${NEO4J_DOCKER_IMAGE:-neo4j:latest} + restart: unless-stopped + # Environment variables + environment: + NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:-12345678} + NEO4J_dbms.default_listen_address: "0.0.0.0" + NEO4J_dbms.default_advertised_address: "neo4j.${DOMAINNAME}" + NEO4J_dbms.connector.bolt.advertised_address: ":443" + NEO4J_PLUGINS: '["apoc"]' + NEO4J_dbms_security_procedures_unrestricted: "apoc.*" + NEO4J_dbms_security_procedures_allowlist: "apoc.*" + NEO4J_server_memory_pagecache_size: 512M + NEO4J_server_memory_heap_max__size: 2G + DOMAINNAME: ${DOMAINNAME} + user: "1000:1000" + depends_on: + - traefik + volumes: + - neo4j_data:/data + - neo4j_logs:/logs + # Expose ports + expose: + - 7474 + - 7687 + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.neo4j-router.entrypoints=web-secure" + - "traefik.http.routers.neo4j-router.rule=Host(`neo4j.${DOMAINNAME}`) && PathPrefix(`/neo4j`)||PathPrefix(`/browser`)" + - "traefik.http.routers.neo4j-router.middlewares=csrf@file, neo4j_strip@file" + - "traefik.http.routers.neo4j-router.tls.certresolver=letsencrypt" + - "traefik.http.routers.neo4j-router.service=neo4j_browser" + - "traefik.http.services.neo4j_browser.loadbalancer.server.port=7474" + - "traefik.http.routers.neo4j-bolt-router.entrypoints=web-secure" + - "traefik.http.routers.neo4j-bolt-router.rule=Host(`neo4j.${DOMAINNAME}`)" + - "traefik.http.routers.neo4j-bolt-router.middlewares=csrf@file" + - "traefik.http.routers.neo4j-bolt-router.tls.certresolver=letsencrypt" + - "traefik.http.routers.neo4j-bolt-router.service=neo4j_bolt" + - "traefik.http.services.neo4j_bolt.loadbalancer.server.port=7687" + - "traefik.tcp.routers.neo4j-bolt-router.entrypoints=bolt-socket" + - "traefik.tcp.routers.neo4j-bolt-router.rule=HostSNIRegexp(`^.+\\.furyhawk\\.lol$`)" + - "traefik.tcp.routers.neo4j-bolt-router.tls=true" + - "traefik.tcp.routers.neo4j-bolt-router.tls.certresolver=letsencrypt" + - "traefik.tcp.routers.neo4j-bolt-router.service=neo4j_bolt" + - "traefik.tcp.services.neo4j_bolt.loadbalancer.server.port=7687" + + syncthing: + image: syncthing/syncthing + environment: + - PUID=1000 + - PGID=1000 + - DOMAINNAME=${DOMAINNAME} + restart: unless-stopped + volumes: + - ~/st-sync:/var/syncthing + ports: + - "8384:8384" # Web UI + - "22000:22000/tcp" # TCP file transfers + - "22000:22000/udp" # QUIC file transfers + - "21027:21027/udp" # Receive local discovery broadcasts + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.syncthing.entrypoints=web-secure" + - "traefik.http.routers.syncthing.rule=Host(`sync.${DOMAINNAME}`)" + - "traefik.http.routers.syncthing.middlewares=csrf@file" + - "traefik.http.routers.syncthing.tls.certresolver=letsencrypt" + - "traefik.http.routers.syncthing.service=syncthing_service" + - "traefik.http.services.syncthing_service.loadbalancer.server.port=8384" + + dozzle: + image: amir20/dozzle:latest + restart: always + environment: + - DOMAINNAME=${DOMAINNAME} + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + expose: + - 8080 + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.dozzle.entrypoints=web-secure" + - "traefik.http.routers.dozzle.rule=Host(`log.${DOMAINNAME}`)" + - "traefik.http.routers.dozzle.middlewares=auth@file, csrf@file" + - "traefik.http.routers.dozzle.tls.certresolver=letsencrypt" + - "traefik.http.routers.dozzle.service=dozzle_service" + - "traefik.http.services.dozzle_service.loadbalancer.server.port=8080" + + # WhoAmI - For Testing and Troubleshooting + whoami: + image: traefik/whoami + security_opt: + - no-new-privileges:true + restart: unless-stopped + networks: + - net + labels: + - "traefik.enable=true" + - "traefik.http.routers.whoami-rtr.entrypoints=web-secure" + - "traefik.http.routers.whoami-rtr.rule=Host(`whoami.$DOMAINNAME`)" + - "traefik.http.routers.whoami-rtr.middlewares=csrf@file" + - "traefik.http.routers.whoami-rtr.tls.certresolver=letsencrypt" + - "traefik.http.routers.whoami-rtr.service=whoami-svc" + - "traefik.http.services.whoami-svc.loadbalancer.server.port=80" diff --git a/swarm/traefik.yml b/swarm/traefik.yml index 180a87b..7419d61 100644 --- a/swarm/traefik.yml +++ b/swarm/traefik.yml @@ -10,6 +10,11 @@ services: - target: 443 published: 443 mode: host + # - "7687:7687" + # - "8083:8083" + # - "8084:8084" + # - "8883:8883" + # - "5432:5432" deploy: placement: constraints: @@ -28,6 +33,7 @@ services: # admin-auth middleware with HTTP Basic auth # Using the environment variables USERNAME and HASHED_PASSWORD - traefik.http.middlewares.admin-auth.basicauth.users=${USERNAME?Variable not set}:${HASHED_PASSWORD?Variable not set} + - traefik.http.middlewares.csrf.headers.hostsProxyHeaders=["X-CSRFToken"] # traefik-https the actual router using HTTPS - traefik.http.routers.traefik-public-https.rule=Host(`dashboard.${DOMAIN?Variable not set}`) - traefik.http.routers.traefik-public-https.entrypoints=https @@ -64,6 +70,11 @@ services: - --entrypoints.http.http.redirections.entrypoint.permanent=true # Create an entrypoint "postgres-socket" listening on port 5432 - --entrypoints.postgres-socket.address=:5432 + # Others entrypoints can be created, like a TCP entrypoint + # - --entrypoints.mqtt.address=:1883 + - --entrypoints.web-socket.address=:8083 + - --entrypoints.web-socket-secure.address=:8084 + - --entrypoints.bolt-socket.address=:7687 # Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL - --certificatesresolvers.le.acme.email=${EMAIL?Variable not set} # Store the Let's Encrypt certificates in the mounted volume