From 5c963c6dbb935cdf8c051fe6816460517b8f7b98 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Wed, 24 Sep 2025 15:58:12 +0200 Subject: [PATCH 1/8] [WIP] Upgrade Traefik from v1.7.10 to v3.3.7 with enhanced tls/header security --- services/dockerhub/docker-compose.yml | 13 +++- services/home/docker-compose.yml | 10 ++- services/pygeoapi_cite/docker-compose.yml | 10 ++- services/pygeoapi_covid-19/docker-compose.yml | 12 ++-- services/pygeoapi_master/docker-compose.yml | 10 ++- services/pygeoapi_stable/docker-compose.yml | 10 ++- services/traefik/config/default.nusa.toml | 33 ++++++--- .../traefik/config/dynamic/middlewares.yml | 17 +++++ services/traefik/config/dynamic/tls.yml | 14 ++++ services/traefik/config/traefik.PYGEOAPI.toml | 72 ++++++++++--------- services/traefik/config/traefik.default.toml | 33 ++++++--- services/traefik/docker-compose.yml | 35 +++++++-- services/traefik/start.sh | 3 + 13 files changed, 194 insertions(+), 78 deletions(-) create mode 100644 services/traefik/config/dynamic/middlewares.yml create mode 100644 services/traefik/config/dynamic/tls.yml diff --git a/services/dockerhub/docker-compose.yml b/services/dockerhub/docker-compose.yml index 94a1eb4..332d1e2 100644 --- a/services/dockerhub/docker-compose.yml +++ b/services/dockerhub/docker-compose.yml @@ -16,9 +16,14 @@ services: labels: - "traefik.enable=true" - - "traefik.frontend.rule=Host:demo.pygeoapi.io;PathPrefixStrip:/dhubhook" - - "traefik.backend=dockerhub" - - "traefik.frontend.priority=100" + - "traefik.http.routers.dockerhub.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/dhubhook`)" + - "traefik.http.routers.dockerhub.entrypoints=http,https" + - "traefik.http.routers.dockerhub.tls.certresolver=le" + - "traefik.http.routers.dockerhub.tls.options=tls_default@file" + - "traefik.http.routers.dockerhub.priority=100" + - "traefik.http.routers.dockerhub.middlewares=dhubhook-stripprefix,secure-headers@file" + - "traefik.http.middlewares.dhubhook-stripprefix.stripprefix.prefixes=/dhubhook" + - "traefik.http.services.dockerhub.loadbalancer.server.port=3000" - "traefik.docker.network=pygeoapi-network" volumes: @@ -31,6 +36,8 @@ services: - ./../pygeoapi_covid-19:/srv/pygeoapi_covid-19 + env_file: dockerhub.env + networks: default: name: pygeoapi-network diff --git a/services/home/docker-compose.yml b/services/home/docker-compose.yml index 4db0b59..d40ee0a 100644 --- a/services/home/docker-compose.yml +++ b/services/home/docker-compose.yml @@ -9,10 +9,14 @@ services: container_name: home labels: - - "traefik.backend=home_app" - "traefik.enable=true" - - "traefik.frontend.priority=5" - - "traefik.frontend.rule=Host:demo.pygeoapi.io; PathPrefixStrip:/" + - "traefik.http.routers.home.rule=Host(`demo.pygeoapi.io`) && Path(`/`)" + - "traefik.http.routers.home.entrypoints=http,https" + - "traefik.http.routers.home.tls.certresolver=le" + - "traefik.http.routers.home.tls.options=tls_default@file" + - "traefik.http.routers.home.priority=5" + - "traefik.http.routers.home.middlewares=secure-headers@file" + - "traefik.http.services.home.loadbalancer.server.port=5000" - "traefik.docker.network=pygeoapi-network" networks: diff --git a/services/pygeoapi_cite/docker-compose.yml b/services/pygeoapi_cite/docker-compose.yml index a5fac69..16fef0c 100644 --- a/services/pygeoapi_cite/docker-compose.yml +++ b/services/pygeoapi_cite/docker-compose.yml @@ -21,9 +21,13 @@ services: labels: - "traefik.enable=true" - - "traefik.frontend.rule=Host:demo.pygeoapi.io,localhost;PathPrefix:/cite" - - "traefik.backend=pygeoapi_cite" - - "traefik.frontend.priority=100" + - "traefik.http.routers.pygeoapi_cite.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/cite`)" + - "traefik.http.routers.pygeoapi_cite.entrypoints=http,https" + - "traefik.http.routers.pygeoapi_cite.tls.certresolver=le" + - "traefik.http.routers.pygeoapi_cite.tls.options=tls_default@file" + - "traefik.http.routers.pygeoapi_cite.priority=100" + - "traefik.http.routers.pygeoapi_cite.middlewares=secure-headers@file" + - "traefik.http.services.pygeoapi_cite.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" networks: diff --git a/services/pygeoapi_covid-19/docker-compose.yml b/services/pygeoapi_covid-19/docker-compose.yml index f30f5ac..0f2ddc8 100644 --- a/services/pygeoapi_covid-19/docker-compose.yml +++ b/services/pygeoapi_covid-19/docker-compose.yml @@ -1,6 +1,6 @@ services: - pygeoapi_cite: + pygeoapi_covid19: image: geopython/pygeoapi_covid-19:latest build: ./pygeoapi @@ -20,9 +20,13 @@ services: labels: - "traefik.enable=true" - - "traefik.frontend.rule=Host:demo.pygeoapi.io,localhost;PathPrefix:/covid-19" - - "traefik.backend=pygeoapi_covid-19" - - "traefik.frontend.priority=100" + - "traefik.http.routers.pygeoapi_covid19.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/covid-19`)" + - "traefik.http.routers.pygeoapi_covid19.entrypoints=http,https" + - "traefik.http.routers.pygeoapi_covid19.tls.certresolver=le" + - "traefik.http.routers.pygeoapi_covid19.tls.options=tls_default@file" + - "traefik.http.routers.pygeoapi_covid19.priority=100" + - "traefik.http.routers.pygeoapi_covid19.middlewares=secure-headers@file" + - "traefik.http.services.pygeoapi_covid19.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" networks: diff --git a/services/pygeoapi_master/docker-compose.yml b/services/pygeoapi_master/docker-compose.yml index bee9f6c..ab9498e 100644 --- a/services/pygeoapi_master/docker-compose.yml +++ b/services/pygeoapi_master/docker-compose.yml @@ -19,9 +19,13 @@ services: labels: - "traefik.enable=true" - - "traefik.frontend.rule=Host:demo.pygeoapi.io,localhost;PathPrefix:/master" - - "traefik.backend=pygeoapi_master" - - "traefik.frontend.priority=100" + - "traefik.http.routers.pygeoapi_master.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/master`)" + - "traefik.http.routers.pygeoapi_master.entrypoints=http,https" + - "traefik.http.routers.pygeoapi_master.tls.certresolver=le" + - "traefik.http.routers.pygeoapi_master.tls.options=tls_default@file" + - "traefik.http.routers.pygeoapi_master.priority=100" + - "traefik.http.routers.pygeoapi_master.middlewares=secure-headers@file" + - "traefik.http.services.pygeoapi_master.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" networks: diff --git a/services/pygeoapi_stable/docker-compose.yml b/services/pygeoapi_stable/docker-compose.yml index d1d81e7..fd8dc82 100644 --- a/services/pygeoapi_stable/docker-compose.yml +++ b/services/pygeoapi_stable/docker-compose.yml @@ -23,9 +23,13 @@ services: labels: - "traefik.enable=true" - - "traefik.frontend.rule=Host:demo.pygeoapi.io,localhost;PathPrefix:/stable" - - "traefik.backend=pygeoapi_stable" - - "traefik.frontend.priority=100" + - "traefik.http.routers.pygeoapi_stable.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/stable`)" + - "traefik.http.routers.pygeoapi_stable.entrypoints=http,https" + - "traefik.http.routers.pygeoapi_stable.tls.certresolver=le" + - "traefik.http.routers.pygeoapi_stable.tls.options=tls_default@file" + - "traefik.http.routers.pygeoapi_stable.priority=100" + - "traefik.http.routers.pygeoapi_stable.middlewares=secure-headers@file" + - "traefik.http.services.pygeoapi_stable.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" networks: diff --git a/services/traefik/config/default.nusa.toml b/services/traefik/config/default.nusa.toml index 5bac1e0..18a7b07 100644 --- a/services/traefik/config/default.nusa.toml +++ b/services/traefik/config/default.nusa.toml @@ -1,18 +1,31 @@ -# defaultEntryPoints must be at the top because it should not be in any table below -# Initial from: -# https://github.com/containerize-my-server/reverse-proxy/blob/master/traefik.toml -defaultEntryPoints = ["http"] +# Traefik v3.x configuration - Nusa +# Updated for v3.5.2 compatibility [entryPoints] [entryPoints.http] - address = ":80" + address = ":80" -[retry] +[providers] + [providers.docker] + endpoint = "unix:///var/run/docker.sock" + exposedByDefault = false + network = "pygeoapi-network" + watch = true -[docker] -endpoint = "unix:///var/run/docker.sock" -watch = true -exposedbydefault = false + [providers.file] + directory = "/etc/traefik/dynamic" + watch = true + +[log] + level = "INFO" + filePath = "/var/log/traefik/traefik.log" [accessLog] filePath = "/var/log/traefik/access.log" + +[api] + dashboard = false + +[global] + checkNewVersion = false + sendAnonymousUsage = false diff --git a/services/traefik/config/dynamic/middlewares.yml b/services/traefik/config/dynamic/middlewares.yml new file mode 100644 index 0000000..3f82192 --- /dev/null +++ b/services/traefik/config/dynamic/middlewares.yml @@ -0,0 +1,17 @@ +http: + middlewares: + secure-headers: + headers: + stsIncludeSubdomains: true + stsPreload: true + stsSeconds: 63072000 + contentTypeNosniff: true + accessControlAllowMethods: + - GET + - POST + - PUT + accessControlAllowOriginList: '*' + accessControlMaxAge: 100 + addVaryheader: true + accessControlAllowHeaders: Authorization + hostsproxyheaders: X-Forwarded-Host \ No newline at end of file diff --git a/services/traefik/config/dynamic/tls.yml b/services/traefik/config/dynamic/tls.yml new file mode 100644 index 0000000..d930ee2 --- /dev/null +++ b/services/traefik/config/dynamic/tls.yml @@ -0,0 +1,14 @@ +tls: + options: + tls_default: + minVersion: VersionTLS12 + sniStrict: true + cipherSuites: + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + tlsv13only: + minVersion: VersionTLS13 \ No newline at end of file diff --git a/services/traefik/config/traefik.PYGEOAPI.toml b/services/traefik/config/traefik.PYGEOAPI.toml index 318c2a8..44860dd 100644 --- a/services/traefik/config/traefik.PYGEOAPI.toml +++ b/services/traefik/config/traefik.PYGEOAPI.toml @@ -1,41 +1,47 @@ -# defaultEntryPoints must be at the top because it should not be in any table below -# Initial from: -# https://github.com/containerize-my-server/reverse-proxy/blob/master/traefik.toml -defaultEntryPoints = ["http", "https"] +# Traefik v3.x configuration +# Updated for v3.5.2 compatibility - -# Entrypoints, http and https [entryPoints] - -# http should be redirected to https [entryPoints.http] - address = ":80" - [entryPoints.http.redirect] - entryPoint = "https" + address = ":80" + [entryPoints.http.http] + [entryPoints.http.http.redirections] + [entryPoints.http.http.redirections.entryPoint] + to = "https" + scheme = "https" [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "just@justobjects.nl" -storage = "/acme.json" -entryPoint = "https" -onHostRule = false -onDemand = false - -[acme.tlsChallenge] #enables the TLS ALPN Challenge - -[[acme.domains]] - main = "demo.pygeoapi.io" - -[retry] - -[docker] -endpoint = "unix:///var/run/docker.sock" -domain = "pygeoapi.io" -watch = true -exposedbydefault = false + address = ":443" + +[certificatesResolvers] + [certificatesResolvers.le] + [certificatesResolvers.le.acme] + email = "just@justobjects.nl" + storage = "/certificates/acme.json" + keyType = "EC256" + [certificatesResolvers.le.acme.tlsChallenge] + +[providers] + [providers.docker] + endpoint = "unix:///var/run/docker.sock" + exposedByDefault = false + network = "pygeoapi-network" + watch = true + + [providers.file] + directory = "/etc/traefik/dynamic" + watch = true + +[log] + level = "INFO" + filePath = "/var/log/traefik/traefik.log" [accessLog] filePath = "/var/log/traefik/access.log" + +[api] + dashboard = false + +[global] + checkNewVersion = false + sendAnonymousUsage = false diff --git a/services/traefik/config/traefik.default.toml b/services/traefik/config/traefik.default.toml index 5bac1e0..42d9916 100644 --- a/services/traefik/config/traefik.default.toml +++ b/services/traefik/config/traefik.default.toml @@ -1,18 +1,31 @@ -# defaultEntryPoints must be at the top because it should not be in any table below -# Initial from: -# https://github.com/containerize-my-server/reverse-proxy/blob/master/traefik.toml -defaultEntryPoints = ["http"] +# Traefik v3.x configuration - Default/Development +# Updated for v3.5.2 compatibility [entryPoints] [entryPoints.http] - address = ":80" + address = ":80" -[retry] +[providers] + [providers.docker] + endpoint = "unix:///var/run/docker.sock" + exposedByDefault = false + network = "pygeoapi-network" + watch = true -[docker] -endpoint = "unix:///var/run/docker.sock" -watch = true -exposedbydefault = false + [providers.file] + directory = "/etc/traefik/dynamic" + watch = true + +[log] + level = "INFO" + filePath = "/var/log/traefik/traefik.log" [accessLog] filePath = "/var/log/traefik/access.log" + +[api] + dashboard = false + +[global] + checkNewVersion = false + sendAnonymousUsage = false diff --git a/services/traefik/docker-compose.yml b/services/traefik/docker-compose.yml index 8a37668..b2325a2 100644 --- a/services/traefik/docker-compose.yml +++ b/services/traefik/docker-compose.yml @@ -1,12 +1,29 @@ services: proxy: - image: traefik:1.7.10-alpine + image: traefik:v3.3.7 container_name: traefik restart: unless-stopped - command: --docker --logLevel=INFO + command: + - --entrypoints.http.address=:80 + - --entrypoints.https.address=:443 + - --providers.docker + - --providers.docker.watch=true + - --providers.docker.exposedbydefault=false + - --providers.docker.network=pygeoapi-network + - --providers.file + - --providers.file.directory=/etc/traefik/dynamic + - --accesslog + - --accesslog.filePath=/var/log/traefik/access.log + - --log + - --log.level=INFO + - --log.filePath=/var/log/traefik/traefik.log + - --certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL} + - --certificatesresolvers.le.acme.storage=/certificates/acme.json + - --certificatesresolvers.le.acme.tlschallenge=true + - --api.dashboard=false ports: - "${HTTP_PORT}:80" @@ -14,12 +31,18 @@ services: # - "8080:8080" labels: - - "traefik.enable=false" + - "traefik.enable=true" + - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.https_redirect.redirectscheme.permanent=true" + - "traefik.http.routers.traefik_http.rule=Host(`${HOSTNAME}`)" + - "traefik.http.routers.traefik_http.entrypoints=http" + - "traefik.http.routers.traefik_http.middlewares=https_redirect@docker" volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./config/traefik.${HOSTNAME}.toml:/traefik.toml - - ./config/acme.json:/acme.json + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./config/traefik.${HOSTNAME}.toml:/etc/traefik/traefik.toml:ro + - ./config/dynamic:/etc/traefik/dynamic:ro + - ./config/acme.json:/certificates/acme.json - traefik_logs:/var/log/traefik volumes: diff --git a/services/traefik/start.sh b/services/traefik/start.sh index f1af8ee..fa28825 100755 --- a/services/traefik/start.sh +++ b/services/traefik/start.sh @@ -9,6 +9,9 @@ export HOSTNAME export HTTP_PORT=80 [[ ${HOSTNAME} != PYGEOAPI ]] && HTTP_PORT=8000 +# Set Let's Encrypt email - customize as needed +export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-"just@justobjects.nl"} + export ACME_FILE="config/acme.json" [[ -f ${ACME_FILE} ]] \ From 7e9b8d040eff71e31c742af80c88aa84979d9b8d Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Wed, 24 Sep 2025 16:38:07 +0200 Subject: [PATCH 2/8] [WIP] Toml file converted into yaml --- services/traefik/config/default.nusa.toml | 31 ----------- services/traefik/config/default.nusa.yml | 36 +++++++++++++ services/traefik/config/traefik.PYGEOAPI.toml | 47 ---------------- services/traefik/config/traefik.PYGEOAPI.yml | 53 +++++++++++++++++++ services/traefik/config/traefik.default.toml | 31 ----------- services/traefik/config/traefik.default.yml | 36 +++++++++++++ services/traefik/docker-compose.yml | 2 +- 7 files changed, 126 insertions(+), 110 deletions(-) delete mode 100644 services/traefik/config/default.nusa.toml create mode 100644 services/traefik/config/default.nusa.yml delete mode 100644 services/traefik/config/traefik.PYGEOAPI.toml create mode 100644 services/traefik/config/traefik.PYGEOAPI.yml delete mode 100644 services/traefik/config/traefik.default.toml create mode 100644 services/traefik/config/traefik.default.yml diff --git a/services/traefik/config/default.nusa.toml b/services/traefik/config/default.nusa.toml deleted file mode 100644 index 18a7b07..0000000 --- a/services/traefik/config/default.nusa.toml +++ /dev/null @@ -1,31 +0,0 @@ -# Traefik v3.x configuration - Nusa -# Updated for v3.5.2 compatibility - -[entryPoints] - [entryPoints.http] - address = ":80" - -[providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" - exposedByDefault = false - network = "pygeoapi-network" - watch = true - - [providers.file] - directory = "/etc/traefik/dynamic" - watch = true - -[log] - level = "INFO" - filePath = "/var/log/traefik/traefik.log" - -[accessLog] - filePath = "/var/log/traefik/access.log" - -[api] - dashboard = false - -[global] - checkNewVersion = false - sendAnonymousUsage = false diff --git a/services/traefik/config/default.nusa.yml b/services/traefik/config/default.nusa.yml new file mode 100644 index 0000000..3c5a8d1 --- /dev/null +++ b/services/traefik/config/default.nusa.yml @@ -0,0 +1,36 @@ +# Traefik v3.x configuration - Nusa +# Updated for v3.3.7 compatibility + +# Entry points +entryPoints: + http: + address: ":80" + +# Providers +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + network: "pygeoapi-network" + watch: true + + file: + directory: "/etc/traefik/dynamic" + watch: true + +# Logging +log: + level: "INFO" + filePath: "/var/log/traefik/traefik.log" + +accessLog: + filePath: "/var/log/traefik/access.log" + +# API and dashboard +api: + dashboard: false + +# Global configuration +global: + checkNewVersion: false + sendAnonymousUsage: false \ No newline at end of file diff --git a/services/traefik/config/traefik.PYGEOAPI.toml b/services/traefik/config/traefik.PYGEOAPI.toml deleted file mode 100644 index 44860dd..0000000 --- a/services/traefik/config/traefik.PYGEOAPI.toml +++ /dev/null @@ -1,47 +0,0 @@ -# Traefik v3.x configuration -# Updated for v3.5.2 compatibility - -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http.http] - [entryPoints.http.http.redirections] - [entryPoints.http.http.redirections.entryPoint] - to = "https" - scheme = "https" - - [entryPoints.https] - address = ":443" - -[certificatesResolvers] - [certificatesResolvers.le] - [certificatesResolvers.le.acme] - email = "just@justobjects.nl" - storage = "/certificates/acme.json" - keyType = "EC256" - [certificatesResolvers.le.acme.tlsChallenge] - -[providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" - exposedByDefault = false - network = "pygeoapi-network" - watch = true - - [providers.file] - directory = "/etc/traefik/dynamic" - watch = true - -[log] - level = "INFO" - filePath = "/var/log/traefik/traefik.log" - -[accessLog] - filePath = "/var/log/traefik/access.log" - -[api] - dashboard = false - -[global] - checkNewVersion = false - sendAnonymousUsage = false diff --git a/services/traefik/config/traefik.PYGEOAPI.yml b/services/traefik/config/traefik.PYGEOAPI.yml new file mode 100644 index 0000000..037c269 --- /dev/null +++ b/services/traefik/config/traefik.PYGEOAPI.yml @@ -0,0 +1,53 @@ +# Traefik v3.x configuration +# Updated for v3.3.7 compatibility + +# Entry points +entryPoints: + http: + address: ":80" + http: + redirections: + entryPoint: + to: "https" + scheme: "https" + + https: + address: ":443" + +# Certificate resolvers (Let's Encrypt) +certificatesResolvers: + le: + acme: + email: "just@justobjects.nl" + storage: "/certificates/acme.json" + keyType: "EC256" + tlsChallenge: {} + +# Providers +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + network: "pygeoapi-network" + watch: true + + file: + directory: "/etc/traefik/dynamic" + watch: true + +# Logging +log: + level: "INFO" + filePath: "/var/log/traefik/traefik.log" + +accessLog: + filePath: "/var/log/traefik/access.log" + +# API and dashboard +api: + dashboard: false + +# Global configuration +global: + checkNewVersion: false + sendAnonymousUsage: false \ No newline at end of file diff --git a/services/traefik/config/traefik.default.toml b/services/traefik/config/traefik.default.toml deleted file mode 100644 index 42d9916..0000000 --- a/services/traefik/config/traefik.default.toml +++ /dev/null @@ -1,31 +0,0 @@ -# Traefik v3.x configuration - Default/Development -# Updated for v3.5.2 compatibility - -[entryPoints] - [entryPoints.http] - address = ":80" - -[providers] - [providers.docker] - endpoint = "unix:///var/run/docker.sock" - exposedByDefault = false - network = "pygeoapi-network" - watch = true - - [providers.file] - directory = "/etc/traefik/dynamic" - watch = true - -[log] - level = "INFO" - filePath = "/var/log/traefik/traefik.log" - -[accessLog] - filePath = "/var/log/traefik/access.log" - -[api] - dashboard = false - -[global] - checkNewVersion = false - sendAnonymousUsage = false diff --git a/services/traefik/config/traefik.default.yml b/services/traefik/config/traefik.default.yml new file mode 100644 index 0000000..2fe7ed6 --- /dev/null +++ b/services/traefik/config/traefik.default.yml @@ -0,0 +1,36 @@ +# Traefik v3.x configuration - Default/Development +# Updated for v3.3.7 compatibility + +# Entry points +entryPoints: + http: + address: ":80" + +# Providers +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + network: "pygeoapi-network" + watch: true + + file: + directory: "/etc/traefik/dynamic" + watch: true + +# Logging +log: + level: "INFO" + filePath: "/var/log/traefik/traefik.log" + +accessLog: + filePath: "/var/log/traefik/access.log" + +# API and dashboard +api: + dashboard: false + +# Global configuration +global: + checkNewVersion: false + sendAnonymousUsage: false \ No newline at end of file diff --git a/services/traefik/docker-compose.yml b/services/traefik/docker-compose.yml index b2325a2..fd2c2e7 100644 --- a/services/traefik/docker-compose.yml +++ b/services/traefik/docker-compose.yml @@ -40,7 +40,7 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - - ./config/traefik.${HOSTNAME}.toml:/etc/traefik/traefik.toml:ro + - ./config/traefik.${HOSTNAME}.yml:/etc/traefik/traefik.yml:ro - ./config/dynamic:/etc/traefik/dynamic:ro - ./config/acme.json:/certificates/acme.json - traefik_logs:/var/log/traefik From d87fe840c4b9d791de137642e6e95903f66e72c0 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Wed, 24 Sep 2025 16:41:52 +0200 Subject: [PATCH 3/8] README.md update --- README.md | 11 +++++++++-- services/traefik/config/README.md | 23 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f41632e..96db750 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The demo server runs the following apps/services: * [pygeoapi_stable](services/pygeoapi_stable) - (last stable version of) `pygeoapi` service with test data * [pygeoapi_cite](services/pygeoapi_cite) - (latest GitHub `master` version of) `pygeoapi` service with CITE configuration * [pygeoapi_covid-19](services/pygeoapi_covid-19) - (latest GitHub `master` version of) `pygeoapi` service with Covid-19 configuration -* [traefik](services/traefik) - edge/proxy server routing incoming HTTP(S) and managing SSL-certificates (via Let's Encrypt) +* [traefik](services/traefik) - Traefik v3.3.7 edge/proxy server with HTTP(S) routing, SSL certificate management (Let's Encrypt), security headers, and TLS optimization * [dockerhub listener](services/dockerhub) - listens to webhooks from DockerHub to redeploy [home](services/home) and [pygeoapi_master](services/pygeoapi_master) ## Auto Update @@ -41,7 +41,6 @@ to the `master` of the [pygeoapi GitHub repo](https://github.com/geopython/pygeo ## Common setup with Ansible ``` - # get code git clone https://github.com/geopython/demo.pygeoapi.io @@ -103,3 +102,11 @@ sudo service pygeoapi status ``` +## New Traefik v3.3.7 Files + +This setup uses **Traefik v3.3.7** with enhanced security and modern configuration: + +### Key Files +- `services/traefik/config/traefik.PYGEOAPI.yml` - Production configuration +- `services/traefik/config/dynamic/tls.yml` - TLS security options +- `services/traefik/config/dynamic/middlewares.yml` - HTTP security headers \ No newline at end of file diff --git a/services/traefik/config/README.md b/services/traefik/config/README.md index 7d578b6..f2828de 100644 --- a/services/traefik/config/README.md +++ b/services/traefik/config/README.md @@ -1,5 +1,20 @@ -# Traefik Config +# Traefik v3.3.7 Configuration -In this dir acme.json should be created with LetsEncrypt certs automagically. -The config files are named after the host's hostname to allow -non-HTTPS for local testing. `PYGEOAPI` is the production host. +This directory contains the Traefik v3.x configuration files and dynamic configurations. + +## Configuration Files + +The main configuration files are named after the host's hostname: +- `traefik.PYGEOAPI.yml` - Production config with HTTPS and Let's Encrypt +- `traefik.default.yml` - Development/default config (HTTP only) +- `default.nusa.yml` - Nusa-specific configuration + +## Dynamic Configuration + +The `dynamic/` directory contains: +- `tls.yml` - TLS security options with strong cipher suites (TLS 1.2+ minimum) +- `middlewares.yml` - HTTP security headers and CORS configuration + +## Certificates + +- `acme.json` - Let's Encrypt certificates (created automatically, permissions 600) \ No newline at end of file From 5a5adc7020f4c55739ebdac0a82b728d8757152f Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Wed, 24 Sep 2025 16:50:39 +0200 Subject: [PATCH 4/8] Correct traefik version: 3.5.2 --- README.md | 6 +++--- services/traefik/config/README.md | 2 +- services/traefik/config/default.nusa.yml | 2 +- services/traefik/config/traefik.PYGEOAPI.yml | 2 +- services/traefik/config/traefik.default.yml | 2 +- services/traefik/docker-compose.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 96db750..95caf00 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The demo server runs the following apps/services: * [pygeoapi_stable](services/pygeoapi_stable) - (last stable version of) `pygeoapi` service with test data * [pygeoapi_cite](services/pygeoapi_cite) - (latest GitHub `master` version of) `pygeoapi` service with CITE configuration * [pygeoapi_covid-19](services/pygeoapi_covid-19) - (latest GitHub `master` version of) `pygeoapi` service with Covid-19 configuration -* [traefik](services/traefik) - Traefik v3.3.7 edge/proxy server with HTTP(S) routing, SSL certificate management (Let's Encrypt), security headers, and TLS optimization +* [traefik](services/traefik) - Traefik v3.5.2 edge/proxy server with HTTP(S) routing, SSL certificate management (Let's Encrypt), security headers, and TLS optimization * [dockerhub listener](services/dockerhub) - listens to webhooks from DockerHub to redeploy [home](services/home) and [pygeoapi_master](services/pygeoapi_master) ## Auto Update @@ -102,9 +102,9 @@ sudo service pygeoapi status ``` -## New Traefik v3.3.7 Files +## New Traefik v3.5.2 Files -This setup uses **Traefik v3.3.7** with enhanced security and modern configuration: +This setup uses **Traefik v3.5.2** with enhanced security and modern configuration: ### Key Files - `services/traefik/config/traefik.PYGEOAPI.yml` - Production configuration diff --git a/services/traefik/config/README.md b/services/traefik/config/README.md index f2828de..51a580a 100644 --- a/services/traefik/config/README.md +++ b/services/traefik/config/README.md @@ -1,4 +1,4 @@ -# Traefik v3.3.7 Configuration +# Traefik v3.5.2 Configuration This directory contains the Traefik v3.x configuration files and dynamic configurations. diff --git a/services/traefik/config/default.nusa.yml b/services/traefik/config/default.nusa.yml index 3c5a8d1..d1504e8 100644 --- a/services/traefik/config/default.nusa.yml +++ b/services/traefik/config/default.nusa.yml @@ -1,5 +1,5 @@ # Traefik v3.x configuration - Nusa -# Updated for v3.3.7 compatibility +# Updated for v3.5.2 compatibility # Entry points entryPoints: diff --git a/services/traefik/config/traefik.PYGEOAPI.yml b/services/traefik/config/traefik.PYGEOAPI.yml index 037c269..a990e74 100644 --- a/services/traefik/config/traefik.PYGEOAPI.yml +++ b/services/traefik/config/traefik.PYGEOAPI.yml @@ -1,5 +1,5 @@ # Traefik v3.x configuration -# Updated for v3.3.7 compatibility +# Updated for v3.5.2 compatibility # Entry points entryPoints: diff --git a/services/traefik/config/traefik.default.yml b/services/traefik/config/traefik.default.yml index 2fe7ed6..09192e7 100644 --- a/services/traefik/config/traefik.default.yml +++ b/services/traefik/config/traefik.default.yml @@ -1,5 +1,5 @@ # Traefik v3.x configuration - Default/Development -# Updated for v3.3.7 compatibility +# Updated for v3.5.2 compatibility # Entry points entryPoints: diff --git a/services/traefik/docker-compose.yml b/services/traefik/docker-compose.yml index fd2c2e7..955a09f 100644 --- a/services/traefik/docker-compose.yml +++ b/services/traefik/docker-compose.yml @@ -1,6 +1,6 @@ services: proxy: - image: traefik:v3.3.7 + image: traefik:v3.5.2 container_name: traefik From 51ea62494857ade9bb821e2a8f662011f4b76b86 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Fri, 10 Oct 2025 10:33:35 +0200 Subject: [PATCH 5/8] [WIP] Removed traefik.PYGEOAPI.yml and traefik.default.yml. Docker named volume acme_certificates. Localhost uses HTTP only demo.pygeoapi.io#62 --- services/home/docker-compose.yml | 8 ++- services/pygeoapi_cite/docker-compose.yml | 10 +++- services/pygeoapi_covid-19/docker-compose.yml | 10 +++- services/pygeoapi_master/docker-compose.yml | 10 +++- services/pygeoapi_stable/docker-compose.yml | 10 +++- services/traefik/config/traefik.PYGEOAPI.yml | 53 ------------------- services/traefik/config/traefik.default.yml | 36 ------------- services/traefik/docker-compose.yml | 4 +- 8 files changed, 41 insertions(+), 100 deletions(-) delete mode 100644 services/traefik/config/traefik.PYGEOAPI.yml delete mode 100644 services/traefik/config/traefik.default.yml diff --git a/services/home/docker-compose.yml b/services/home/docker-compose.yml index d40ee0a..aff4925 100644 --- a/services/home/docker-compose.yml +++ b/services/home/docker-compose.yml @@ -10,12 +10,18 @@ services: labels: - "traefik.enable=true" + # Production router (HTTPS with Let's Encrypt) - "traefik.http.routers.home.rule=Host(`demo.pygeoapi.io`) && Path(`/`)" - - "traefik.http.routers.home.entrypoints=http,https" + - "traefik.http.routers.home.entrypoints=https" - "traefik.http.routers.home.tls.certresolver=le" - "traefik.http.routers.home.tls.options=tls_default@file" - "traefik.http.routers.home.priority=5" - "traefik.http.routers.home.middlewares=secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.home_local.rule=Host(`localhost`) && Path(`/`)" + - "traefik.http.routers.home_local.entrypoints=http" + - "traefik.http.routers.home_local.priority=5" + # Common service definition - "traefik.http.services.home.loadbalancer.server.port=5000" - "traefik.docker.network=pygeoapi-network" diff --git a/services/pygeoapi_cite/docker-compose.yml b/services/pygeoapi_cite/docker-compose.yml index 16fef0c..d5b0516 100644 --- a/services/pygeoapi_cite/docker-compose.yml +++ b/services/pygeoapi_cite/docker-compose.yml @@ -21,12 +21,18 @@ services: labels: - "traefik.enable=true" - - "traefik.http.routers.pygeoapi_cite.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/cite`)" - - "traefik.http.routers.pygeoapi_cite.entrypoints=http,https" + # Production router (HTTPS with Let's Encrypt) + - "traefik.http.routers.pygeoapi_cite.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/cite`)" + - "traefik.http.routers.pygeoapi_cite.entrypoints=https" - "traefik.http.routers.pygeoapi_cite.tls.certresolver=le" - "traefik.http.routers.pygeoapi_cite.tls.options=tls_default@file" - "traefik.http.routers.pygeoapi_cite.priority=100" - "traefik.http.routers.pygeoapi_cite.middlewares=secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.pygeoapi_cite_local.rule=Host(`localhost`) && PathPrefix(`/cite`)" + - "traefik.http.routers.pygeoapi_cite_local.entrypoints=http" + - "traefik.http.routers.pygeoapi_cite_local.priority=100" + # Common service definition - "traefik.http.services.pygeoapi_cite.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" diff --git a/services/pygeoapi_covid-19/docker-compose.yml b/services/pygeoapi_covid-19/docker-compose.yml index 0f2ddc8..e0de864 100644 --- a/services/pygeoapi_covid-19/docker-compose.yml +++ b/services/pygeoapi_covid-19/docker-compose.yml @@ -20,12 +20,18 @@ services: labels: - "traefik.enable=true" - - "traefik.http.routers.pygeoapi_covid19.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/covid-19`)" - - "traefik.http.routers.pygeoapi_covid19.entrypoints=http,https" + # Production router (HTTPS with Let's Encrypt) + - "traefik.http.routers.pygeoapi_covid19.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/covid-19`)" + - "traefik.http.routers.pygeoapi_covid19.entrypoints=https" - "traefik.http.routers.pygeoapi_covid19.tls.certresolver=le" - "traefik.http.routers.pygeoapi_covid19.tls.options=tls_default@file" - "traefik.http.routers.pygeoapi_covid19.priority=100" - "traefik.http.routers.pygeoapi_covid19.middlewares=secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.pygeoapi_covid19_local.rule=Host(`localhost`) && PathPrefix(`/covid-19`)" + - "traefik.http.routers.pygeoapi_covid19_local.entrypoints=http" + - "traefik.http.routers.pygeoapi_covid19_local.priority=100" + # Common service definition - "traefik.http.services.pygeoapi_covid19.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" diff --git a/services/pygeoapi_master/docker-compose.yml b/services/pygeoapi_master/docker-compose.yml index ab9498e..9218841 100644 --- a/services/pygeoapi_master/docker-compose.yml +++ b/services/pygeoapi_master/docker-compose.yml @@ -19,12 +19,18 @@ services: labels: - "traefik.enable=true" - - "traefik.http.routers.pygeoapi_master.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/master`)" - - "traefik.http.routers.pygeoapi_master.entrypoints=http,https" + # Production router (HTTPS with Let's Encrypt) + - "traefik.http.routers.pygeoapi_master.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/master`)" + - "traefik.http.routers.pygeoapi_master.entrypoints=https" - "traefik.http.routers.pygeoapi_master.tls.certresolver=le" - "traefik.http.routers.pygeoapi_master.tls.options=tls_default@file" - "traefik.http.routers.pygeoapi_master.priority=100" - "traefik.http.routers.pygeoapi_master.middlewares=secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.pygeoapi_master_local.rule=Host(`localhost`) && PathPrefix(`/master`)" + - "traefik.http.routers.pygeoapi_master_local.entrypoints=http" + - "traefik.http.routers.pygeoapi_master_local.priority=100" + # Common service definition - "traefik.http.services.pygeoapi_master.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" diff --git a/services/pygeoapi_stable/docker-compose.yml b/services/pygeoapi_stable/docker-compose.yml index fd8dc82..2e91663 100644 --- a/services/pygeoapi_stable/docker-compose.yml +++ b/services/pygeoapi_stable/docker-compose.yml @@ -23,12 +23,18 @@ services: labels: - "traefik.enable=true" - - "traefik.http.routers.pygeoapi_stable.rule=(Host(`demo.pygeoapi.io`) || Host(`localhost`)) && PathPrefix(`/stable`)" - - "traefik.http.routers.pygeoapi_stable.entrypoints=http,https" + # Production router (HTTPS with Let's Encrypt) + - "traefik.http.routers.pygeoapi_stable.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/stable`)" + - "traefik.http.routers.pygeoapi_stable.entrypoints=https" - "traefik.http.routers.pygeoapi_stable.tls.certresolver=le" - "traefik.http.routers.pygeoapi_stable.tls.options=tls_default@file" - "traefik.http.routers.pygeoapi_stable.priority=100" - "traefik.http.routers.pygeoapi_stable.middlewares=secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.pygeoapi_stable_local.rule=Host(`localhost`) && PathPrefix(`/stable`)" + - "traefik.http.routers.pygeoapi_stable_local.entrypoints=http" + - "traefik.http.routers.pygeoapi_stable_local.priority=100" + # Common service definition - "traefik.http.services.pygeoapi_stable.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" diff --git a/services/traefik/config/traefik.PYGEOAPI.yml b/services/traefik/config/traefik.PYGEOAPI.yml deleted file mode 100644 index a990e74..0000000 --- a/services/traefik/config/traefik.PYGEOAPI.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Traefik v3.x configuration -# Updated for v3.5.2 compatibility - -# Entry points -entryPoints: - http: - address: ":80" - http: - redirections: - entryPoint: - to: "https" - scheme: "https" - - https: - address: ":443" - -# Certificate resolvers (Let's Encrypt) -certificatesResolvers: - le: - acme: - email: "just@justobjects.nl" - storage: "/certificates/acme.json" - keyType: "EC256" - tlsChallenge: {} - -# Providers -providers: - docker: - endpoint: "unix:///var/run/docker.sock" - exposedByDefault: false - network: "pygeoapi-network" - watch: true - - file: - directory: "/etc/traefik/dynamic" - watch: true - -# Logging -log: - level: "INFO" - filePath: "/var/log/traefik/traefik.log" - -accessLog: - filePath: "/var/log/traefik/access.log" - -# API and dashboard -api: - dashboard: false - -# Global configuration -global: - checkNewVersion: false - sendAnonymousUsage: false \ No newline at end of file diff --git a/services/traefik/config/traefik.default.yml b/services/traefik/config/traefik.default.yml deleted file mode 100644 index 09192e7..0000000 --- a/services/traefik/config/traefik.default.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Traefik v3.x configuration - Default/Development -# Updated for v3.5.2 compatibility - -# Entry points -entryPoints: - http: - address: ":80" - -# Providers -providers: - docker: - endpoint: "unix:///var/run/docker.sock" - exposedByDefault: false - network: "pygeoapi-network" - watch: true - - file: - directory: "/etc/traefik/dynamic" - watch: true - -# Logging -log: - level: "INFO" - filePath: "/var/log/traefik/traefik.log" - -accessLog: - filePath: "/var/log/traefik/access.log" - -# API and dashboard -api: - dashboard: false - -# Global configuration -global: - checkNewVersion: false - sendAnonymousUsage: false \ No newline at end of file diff --git a/services/traefik/docker-compose.yml b/services/traefik/docker-compose.yml index 955a09f..92d0630 100644 --- a/services/traefik/docker-compose.yml +++ b/services/traefik/docker-compose.yml @@ -40,12 +40,12 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - - ./config/traefik.${HOSTNAME}.yml:/etc/traefik/traefik.yml:ro - ./config/dynamic:/etc/traefik/dynamic:ro - - ./config/acme.json:/certificates/acme.json + - acme_certificates:/certificates - traefik_logs:/var/log/traefik volumes: + acme_certificates: traefik_logs: networks: From 738641fdbccba390d1b9c769440a3707bf5bc668 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Sat, 11 Oct 2025 12:10:55 +0200 Subject: [PATCH 6/8] [WIP] localhost/https split on dockerhub and branch var. --- README.md | 18 +++++++++++------- ansible/bootstrap.yml | 2 +- ansible/deploy.yml | 2 +- ansible/hosts/pygeoapi.terraops.net | 5 +++++ services/dockerhub/docker-compose.yml | 9 ++++++++- 5 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 ansible/hosts/pygeoapi.terraops.net diff --git a/README.md b/README.md index 95caf00..42267d3 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,9 @@ These are not in this repo for obvious reasons... You need to create/populate th Have a remote Ubuntu VM installed with root access via pub/private key. ``` - # Installs entire system cd ansible -ansible-playbook -vv bootstrap.yml -i hosts/demo.pygeoapi.io - +ansible-playbook -vv bootstrap.yml -i hosts/demo.pygeoapi.io --become ``` @@ -102,11 +100,17 @@ sudo service pygeoapi status ``` -## New Traefik v3.5.2 Files +## Traefik v3.5.2 Configuration This setup uses **Traefik v3.5.2** with enhanced security and modern configuration: +### Configuration Approach +- **Static configuration**: Defined via command-line flags in `services/traefik/docker-compose.yml` +- **Dynamic configuration**: File-based configs for TLS and middleware settings +- **Certificates**: Stored in Docker volume `acme_certificates` (managed automatically by Let's Encrypt) +- **Routing**: Separate routers for production (HTTPS) and localhost (HTTP only) + ### Key Files -- `services/traefik/config/traefik.PYGEOAPI.yml` - Production configuration -- `services/traefik/config/dynamic/tls.yml` - TLS security options -- `services/traefik/config/dynamic/middlewares.yml` - HTTP security headers \ No newline at end of file +- `services/traefik/docker-compose.yml` - Main Traefik configuration via command flags +- `services/traefik/config/dynamic/tls.yml` - TLS security options (minimum TLS 1.2, cipher suites) +- `services/traefik/config/dynamic/middlewares.yml` - HTTP security headers (HSTS, CORS, etc.) \ No newline at end of file diff --git a/ansible/bootstrap.yml b/ansible/bootstrap.yml index b035c73..1a4ef84 100644 --- a/ansible/bootstrap.yml +++ b/ansible/bootstrap.yml @@ -37,7 +37,7 @@ tasks: - name: "Clone or Update Git Repo" - git: "repo={{ my_github_repo }} dest={{ my_git_home }} version=master clone=yes force=yes accept_hostkey=True" + git: "repo={{ my_github_repo }} dest={{ my_git_home }} version={{ my_git_branch | default('master') }} clone=yes force=yes accept_hostkey=True" - name: "Setup dirs and ownerships" shell: "mkdir -p {{ logs_dir }}; chown -R {{ my_admin_user }}:{{ my_admin_user }} {{ var_dir }} {{ my_git_home }}" diff --git a/ansible/deploy.yml b/ansible/deploy.yml index 3ccbcfe..c2c1be8 100644 --- a/ansible/deploy.yml +++ b/ansible/deploy.yml @@ -11,7 +11,7 @@ pre_tasks: - name: "Clone or Update Git Repo" - git: "repo={{ my_github_repo }} dest={{ my_git_home }} version=master clone=yes force=yes accept_hostkey=True" + git: "repo={{ my_github_repo }} dest={{ my_git_home }} version={{ my_git_branch | default('master') }} clone=yes force=yes accept_hostkey=True" tags: update - name: copy DockerHub env file diff --git a/ansible/hosts/pygeoapi.terraops.net b/ansible/hosts/pygeoapi.terraops.net new file mode 100644 index 0000000..864acf2 --- /dev/null +++ b/ansible/hosts/pygeoapi.terraops.net @@ -0,0 +1,5 @@ +[pygeoapi_terraops] +pygeoapi.terraops.net ansible_port=22 ansible_user=mende012 ansible_host=pygeoapi.terraops.net + +[pygeoapi_terraops:vars] +ansible_python_interpreter=/usr/bin/python3 diff --git a/services/dockerhub/docker-compose.yml b/services/dockerhub/docker-compose.yml index 332d1e2..4ade1d5 100644 --- a/services/dockerhub/docker-compose.yml +++ b/services/dockerhub/docker-compose.yml @@ -16,12 +16,19 @@ services: labels: - "traefik.enable=true" + # Production router (HTTPS with Let's Encrypt) - "traefik.http.routers.dockerhub.rule=Host(`demo.pygeoapi.io`) && PathPrefix(`/dhubhook`)" - - "traefik.http.routers.dockerhub.entrypoints=http,https" + - "traefik.http.routers.dockerhub.entrypoints=https" - "traefik.http.routers.dockerhub.tls.certresolver=le" - "traefik.http.routers.dockerhub.tls.options=tls_default@file" - "traefik.http.routers.dockerhub.priority=100" - "traefik.http.routers.dockerhub.middlewares=dhubhook-stripprefix,secure-headers@file" + # Localhost router (HTTP only) + - "traefik.http.routers.dockerhub_local.rule=Host(`localhost`) && PathPrefix(`/dhubhook`)" + - "traefik.http.routers.dockerhub_local.entrypoints=http" + - "traefik.http.routers.dockerhub_local.priority=100" + - "traefik.http.routers.dockerhub_local.middlewares=dhubhook-stripprefix" + # Common middleware and service - "traefik.http.middlewares.dhubhook-stripprefix.stripprefix.prefixes=/dhubhook" - "traefik.http.services.dockerhub.loadbalancer.server.port=3000" - "traefik.docker.network=pygeoapi-network" From ab35386f39f6ee88517bab101b4e4ddb78836713 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Sat, 11 Oct 2025 18:53:27 +0200 Subject: [PATCH 7/8] [WIP] Removal of create/chmod acme.json file --- services/traefik/start.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/services/traefik/start.sh b/services/traefik/start.sh index fa28825..8c8d392 100755 --- a/services/traefik/start.sh +++ b/services/traefik/start.sh @@ -4,7 +4,7 @@ # Stop and remove possibly old containers ./stop.sh -# Finally run. optionally create protected acme.json +# Set environment variables export HOSTNAME export HTTP_PORT=80 [[ ${HOSTNAME} != PYGEOAPI ]] && HTTP_PORT=8000 @@ -12,11 +12,7 @@ export HTTP_PORT=80 # Set Let's Encrypt email - customize as needed export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-"just@justobjects.nl"} -export ACME_FILE="config/acme.json" +# Note: acme.json is now stored in Docker volume 'acme_certificates' +# No need to create/chmod acme.json file anymore -[[ -f ${ACME_FILE} ]] \ - || echo "${ACME_FILE} does not exist! creating..." \ - && touch ${ACME_FILE} - -chmod 600 ${ACME_FILE} docker compose up -d From 27d8c1df06983fb45f4875ac98e2d43b07370101 Mon Sep 17 00:00:00 2001 From: "Jorge S. Mendes de Jesus" Date: Mon, 13 Oct 2025 12:04:54 +0200 Subject: [PATCH 8/8] [WIP] Fix traefik start.sh port logic (production=80, dev=8000) --- services/dockerhub/docker-compose.yml | 9 --------- services/home/docker-compose.yml | 3 --- services/pygeoapi_cite/docker-compose.yml | 10 ---------- services/pygeoapi_covid-19/docker-compose.yml | 7 ------- services/pygeoapi_master/docker-compose.yml | 8 -------- services/pygeoapi_stable/docker-compose.yml | 8 -------- services/traefik/docker-compose.yml | 6 ------ 7 files changed, 51 deletions(-) diff --git a/services/dockerhub/docker-compose.yml b/services/dockerhub/docker-compose.yml index 4ade1d5..5715048 100644 --- a/services/dockerhub/docker-compose.yml +++ b/services/dockerhub/docker-compose.yml @@ -3,17 +3,12 @@ services: # See https://github.com/maccyber/micro-dockerhub-hook dockerhub: image: maccyber/micro-dockerhub-hook - container_name: dockerhub - expose: - "3000" - # ports: # - "3000:3000" - env_file: dockerhub.env - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) @@ -32,7 +27,6 @@ services: - "traefik.http.middlewares.dhubhook-stripprefix.stripprefix.prefixes=/dhubhook" - "traefik.http.services.dockerhub.loadbalancer.server.port=3000" - "traefik.docker.network=pygeoapi-network" - volumes: - /var/run/docker.sock:/var/run/docker.sock - ./scripts:/src/scripts @@ -42,9 +36,6 @@ services: - ./../pygeoapi_cite:/srv/pygeoapi_cite - ./../pygeoapi_covid-19:/srv/pygeoapi_covid-19 - - env_file: dockerhub.env - networks: default: name: pygeoapi-network diff --git a/services/home/docker-compose.yml b/services/home/docker-compose.yml index aff4925..d4a882e 100644 --- a/services/home/docker-compose.yml +++ b/services/home/docker-compose.yml @@ -3,11 +3,8 @@ services: home: image: geopython/demo.pygeoapi.io:latest - restart: unless-stopped - container_name: home - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) diff --git a/services/pygeoapi_cite/docker-compose.yml b/services/pygeoapi_cite/docker-compose.yml index d5b0516..a2c2645 100644 --- a/services/pygeoapi_cite/docker-compose.yml +++ b/services/pygeoapi_cite/docker-compose.yml @@ -1,24 +1,15 @@ services: - pygeoapi_cite: - image: geopython/pygeoapi_cite:latest - build: ./pygeoapi - container_name: pygeoapi_cite - restart: unless-stopped - expose: - "80" - # ports: # - "5000:80" - environment: - SCRIPT_NAME=/cite - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) @@ -35,7 +26,6 @@ services: # Common service definition - "traefik.http.services.pygeoapi_cite.loadbalancer.server.port=80" - "traefik.docker.network=pygeoapi-network" - networks: default: name: pygeoapi-network diff --git a/services/pygeoapi_covid-19/docker-compose.yml b/services/pygeoapi_covid-19/docker-compose.yml index e0de864..c8cff69 100644 --- a/services/pygeoapi_covid-19/docker-compose.yml +++ b/services/pygeoapi_covid-19/docker-compose.yml @@ -2,22 +2,15 @@ services: pygeoapi_covid19: image: geopython/pygeoapi_covid-19:latest - build: ./pygeoapi - container_name: pygeoapi_covid-19 - restart: unless-stopped - expose: - "80" - # ports: # - "5000:80" - environment: - SCRIPT_NAME=/covid-19 - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) diff --git a/services/pygeoapi_master/docker-compose.yml b/services/pygeoapi_master/docker-compose.yml index 9218841..7008d63 100644 --- a/services/pygeoapi_master/docker-compose.yml +++ b/services/pygeoapi_master/docker-compose.yml @@ -1,22 +1,14 @@ services: - pygeoapi_master: - image: geopython/pygeoapi_master:latest - container_name: pygeoapi_master - restart: unless-stopped - expose: - "80" - # ports: # - "5000:80" - environment: - SCRIPT_NAME=/master - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) diff --git a/services/pygeoapi_stable/docker-compose.yml b/services/pygeoapi_stable/docker-compose.yml index 2e91663..c658933 100644 --- a/services/pygeoapi_stable/docker-compose.yml +++ b/services/pygeoapi_stable/docker-compose.yml @@ -1,26 +1,18 @@ services: pygeoapi_stable: - image: geopython/pygeoapi:0.20.0 - container_name: pygeoapi_stable - restart: unless-stopped - expose: - "80" - # ports: # - "5000:80" - volumes: - ./local.config.yml:/pygeoapi/local.config.yml - ./data:/pygeoapi/data - environment: - SCRIPT_NAME=/stable - labels: - "traefik.enable=true" # Production router (HTTPS with Let's Encrypt) diff --git a/services/traefik/docker-compose.yml b/services/traefik/docker-compose.yml index 92d0630..06a318a 100644 --- a/services/traefik/docker-compose.yml +++ b/services/traefik/docker-compose.yml @@ -1,11 +1,8 @@ services: proxy: image: traefik:v3.5.2 - container_name: traefik - restart: unless-stopped - command: - --entrypoints.http.address=:80 - --entrypoints.https.address=:443 @@ -24,12 +21,10 @@ services: - --certificatesresolvers.le.acme.storage=/certificates/acme.json - --certificatesresolvers.le.acme.tlschallenge=true - --api.dashboard=false - ports: - "${HTTP_PORT}:80" - "443:443" # - "8080:8080" - labels: - "traefik.enable=true" - "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https" @@ -37,7 +32,6 @@ services: - "traefik.http.routers.traefik_http.rule=Host(`${HOSTNAME}`)" - "traefik.http.routers.traefik_http.entrypoints=http" - "traefik.http.routers.traefik_http.middlewares=https_redirect@docker" - volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./config/dynamic:/etc/traefik/dynamic:ro