From 7f70bd2acbdf6c20db353817e3893d4f14454372 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 14:51:15 +1000 Subject: [PATCH 1/8] modified: core/authelia/configuration.yml modified: core/test/docker-compose.yml modified: monitoring/node-red/Dockerfile modified: monitoring/node-red/docker-compose.yml modified: monitoring/prometheus/docker-compose.yml modified: monitoring/prometheus/prometheus.yml modified: update-containers.log --- core/authelia/configuration.yml | 7 +++++ core/test/docker-compose.yml | 2 +- monitoring/node-red/Dockerfile | 1 + monitoring/node-red/docker-compose.yml | 5 +++- monitoring/prometheus/docker-compose.yml | 38 ++++++++++++------------ monitoring/prometheus/prometheus.yml | 1 + update-containers.log | 26 ++++++++-------- 7 files changed, 46 insertions(+), 34 deletions(-) diff --git a/core/authelia/configuration.yml b/core/authelia/configuration.yml index b27674e..5c0c2cf 100644 --- a/core/authelia/configuration.yml +++ b/core/authelia/configuration.yml @@ -35,6 +35,13 @@ access_control: - "^/health" policy: bypass + - domain: node-red.lan.ddnsgeek.com + resources: + - "^/health" + - "^/uptime-kuma" + - "^/docker-update-lockouts/clear" + policy: bypass + - domain: prometheus.lan.ddnsgeek.com resources: - "^/-/healthy" diff --git a/core/test/docker-compose.yml b/core/test/docker-compose.yml index 23b7bfc..5696354 100644 --- a/core/test/docker-compose.yml +++ b/core/test/docker-compose.yml @@ -1,6 +1,6 @@ services: update-test: - image: nginx:1.27.4 + image: nginx:1.28.1 container_name: update-test profiles: ["test"] healthcheck: diff --git a/monitoring/node-red/Dockerfile b/monitoring/node-red/Dockerfile index 6bf9008..0730c1d 100644 --- a/monitoring/node-red/Dockerfile +++ b/monitoring/node-red/Dockerfile @@ -3,4 +3,5 @@ FROM nodered/node-red:latest USER root RUN apk add --no-cache docker-cli docker-cli-compose RUN addgroup -g 131 -S docker && addgroup node-red docker + USER node-red diff --git a/monitoring/node-red/docker-compose.yml b/monitoring/node-red/docker-compose.yml index 5f6343d..16f6daf 100644 --- a/monitoring/node-red/docker-compose.yml +++ b/monitoring/node-red/docker-compose.yml @@ -7,12 +7,15 @@ services: profiles: ["monitoring","all"] restart: unless-stopped privileged: true + environment: + - TZ=${TZ} # ports: # - "1880:1880" volumes: - ${PROJECT_ROOT}/monitoring/node-red/data:/data - /var/run/docker.sock:/var/run/docker.sock:rw - - ${PROJECT_ROOT}:/compose + - ${PROJECT_ROOT}:/compose/docker:ro + - /home/nixos/raspi:/compose/raspi:ro - ${PROJECT_ROOT}/default-environment.env:/usr/src/node-red/default-environment.env:ro - ${PROJECT_ROOT}/default-network.yml:/usr/src/node-red/default-network.yml:ro - ${PROJECT_ROOT}/core/docker-compose.yml:/usr/src/node-red/core/docker-compose.yml:ro diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index dbcfc88..11dfb51 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -162,30 +162,30 @@ services: # - ${PROJECT_ROOT}/monitoring/docker-exporter/data:/data:rw # - ${PROJECT_ROOT}/services-up.sh:/app/services-up.sh:ro environment: - LOG_LEVEL: DEBUG + LOG_LEVEL: INFO volumes: - ~/.docker/config.json:/root/.docker/config.json:ro - /var/run/docker.sock:/var/run/docker.sock - ${PROJECT_ROOT}/monitoring/docker-exporter/data:/data:rw - - ${PROJECT_ROOT}:/compose - - ${PROJECT_ROOT}/default-environment.env:/compose/default-environment.env:ro - - ${PROJECT_ROOT}/default-network.yml:/compose/default-network.yml:ro - - ${PROJECT_ROOT}/core/docker-compose.yml:/compose/core/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/prometheus/docker-compose.yml:/compose/monitoring/prometheus/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/gotify/docker-compose.yml:/compose/monitoring/gotify/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/grafana/docker-compose.yml:/compose/monitoring/grafana/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/portainer/docker-compose.yml:/compose/monitoring/portainer/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/uptime-kuma/docker-compose.yml:/compose/monitoring/uptime-kuma/docker-compose.yml:> - - ${PROJECT_ROOT}/apps/gitea/docker-compose.yml:/compose/apps/gitea/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/gramps/docker-compose.yml:/compose/apps/gramps/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/nextcloud/docker-compose.yml:/compose/apps/nextcloud/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/passbolt/docker-compose.yml:/compose/apps/passbolt/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/searxng/docker-compose.yml:/compose/apps/searxng/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/shift-recorder/docker-compose.yml:/compose/apps/shift-recorder/docker-compose.yml:ro - - ${PROJECT_ROOT}/apps/stockfill/docker-compose.yml:/compose/apps/stockfill/docker-compose.yml:ro - - ${PROJECT_ROOT}/monitoring/node-red/docker-compose.yml:/compose/monitoring/node-red/docker-compose.yml:ro - - ${PROJECT_ROOT}/core/test/docker-compose.yml:/compose/core/test/docker-compose.yml:ro + - ${PROJECT_ROOT}:/compose:ro +# - ${PROJECT_ROOT}/default-environment.env:/compose/default-environment.env:ro +# - ${PROJECT_ROOT}/default-network.yml:/compose/default-network.yml:ro +# - ${PROJECT_ROOT}/core/docker-compose.yml:/compose/core/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/prometheus/docker-compose.yml:/compose/monitoring/prometheus/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/gotify/docker-compose.yml:/compose/monitoring/gotify/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/grafana/docker-compose.yml:/compose/monitoring/grafana/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/portainer/docker-compose.yml:/compose/monitoring/portainer/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/uptime-kuma/docker-compose.yml:/compose/monitoring/uptime-kuma/docker-compose.yml:> +# - ${PROJECT_ROOT}/apps/gitea/docker-compose.yml:/compose/apps/gitea/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/gramps/docker-compose.yml:/compose/apps/gramps/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/nextcloud/docker-compose.yml:/compose/apps/nextcloud/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/passbolt/docker-compose.yml:/compose/apps/passbolt/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/searxng/docker-compose.yml:/compose/apps/searxng/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/shift-recorder/docker-compose.yml:/compose/apps/shift-recorder/docker-compose.yml:ro +# - ${PROJECT_ROOT}/apps/stockfill/docker-compose.yml:/compose/apps/stockfill/docker-compose.yml:ro +# - ${PROJECT_ROOT}/monitoring/node-red/docker-compose.yml:/compose/monitoring/node-red/docker-compose.yml:ro +# - ${PROJECT_ROOT}/core/test/docker-compose.yml:/compose/core/test/docker-compose.yml:ro # ports: diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index 283d254..00ff587 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -63,6 +63,7 @@ scrape_configs: static_configs: - targets: - telegraf:9273 + - raspberrypi.tail13f623.ts.net:9273 labels: role: docker diff --git a/update-containers.log b/update-containers.log index ebc4cb1..1c1982c 100644 --- a/update-containers.log +++ b/update-containers.log @@ -1,13 +1,13 @@ -07:29:20 INFO: === Update started: 2026-04-01 07:29:20 === -07:29:20 WARNING: Skipping traefik (directory does not exist) -07:29:20 WARNING: Skipping nextcloud (directory does not exist) -07:29:20 WARNING: Skipping passbolt (directory does not exist) -07:29:20 WARNING: Skipping searxng (directory does not exist) -07:29:20 WARNING: Skipping gitea (directory does not exist) -07:29:20 WARNING: Skipping gotify (directory does not exist) -07:29:20 WARNING: Skipping grafana (directory does not exist) -07:29:20 WARNING: Skipping gramps (directory does not exist) -07:29:20 WARNING: Skipping portainer (directory does not exist) -07:29:20 WARNING: Skipping prometheus (directory does not exist) -07:29:20 WARNING: Skipping uptime-kuma (directory does not exist) -07:29:20 INFO: Pruning unused containers, images, networks, and volumes... +12:23:36 INFO: === Update started: 2026-04-04 12:23:36 === +12:23:36 WARNING: Skipping traefik (directory does not exist) +12:23:36 WARNING: Skipping nextcloud (directory does not exist) +12:23:36 WARNING: Skipping passbolt (directory does not exist) +12:23:36 WARNING: Skipping searxng (directory does not exist) +12:23:36 WARNING: Skipping gitea (directory does not exist) +12:23:36 WARNING: Skipping gotify (directory does not exist) +12:23:36 WARNING: Skipping grafana (directory does not exist) +12:23:36 WARNING: Skipping gramps (directory does not exist) +12:23:36 WARNING: Skipping portainer (directory does not exist) +12:23:36 WARNING: Skipping prometheus (directory does not exist) +12:23:36 WARNING: Skipping uptime-kuma (directory does not exist) +12:23:36 INFO: Pruning unused containers, images, networks, and volumes... From 634abe4b39f05ca69abf3494cb150856b00a1b1b Mon Sep 17 00:00:00 2001 From: beatz174-bit Date: Tue, 7 Apr 2026 15:08:59 +1000 Subject: [PATCH 2/8] Move hard-coded env values into default-environment.env --- apps/gitea/docker-compose.yml | 8 +- apps/gramps/docker-compose.yml | 18 ++--- apps/nextcloud/docker-compose.yml | 58 +++++++------- apps/passbolt/docker-compose.yml | 20 ++--- core/docker-compose.yml | 4 +- default-environment.env | 81 ++++++++++++++++++++ monitoring/gotify/docker-compose.yml | 6 +- monitoring/gotify/docker-health-to-gotify.sh | 4 +- monitoring/grafana/docker-compose.yml | 2 +- monitoring/portainer/docker-compose.yml | 2 +- monitoring/prometheus/docker-compose.yml | 18 ++--- 11 files changed, 151 insertions(+), 70 deletions(-) diff --git a/apps/gitea/docker-compose.yml b/apps/gitea/docker-compose.yml index 55f6bc3..df09a2f 100644 --- a/apps/gitea/docker-compose.yml +++ b/apps/gitea/docker-compose.yml @@ -5,10 +5,10 @@ services: image: gitea/gitea:latest # change to 1-rootless once find out how to move data. restart: always environment: - - USER_UID=1000 - - USER_GID=1000 - - GITEA__database__DB_TYPE=sqlite3 - - GITEA__server__ROOT_URL=https://gitea.lan.ddnsgeek.com/ + - USER_UID=${GITEA_USER_UID} + - USER_GID=${GITEA_USER_GID} + - GITEA__database__DB_TYPE=${GITEA_DB_TYPE} + - GITEA__server__ROOT_URL=${GITEA_ROOT_URL} volumes: - ${PROJECT_ROOT}/apps/gitea/data:/data networks: diff --git a/apps/gramps/docker-compose.yml b/apps/gramps/docker-compose.yml index 80f01af..65b4bc1 100644 --- a/apps/gramps/docker-compose.yml +++ b/apps/gramps/docker-compose.yml @@ -5,9 +5,9 @@ services: container_name: gramps-db restart: always environment: - POSTGRES_USER: gramps - POSTGRES_PASSWORD: grampspassword - POSTGRES_DB: gramps + POSTGRES_USER: ${GRAMPS_POSTGRES_USER} + POSTGRES_PASSWORD: ${GRAMPS_POSTGRES_PASSWORD} + POSTGRES_DB: ${GRAMPS_POSTGRES_DB} volumes: - ${PROJECT_ROOT}/apps/gramps/db:/var/lib/postgresql networks: @@ -30,14 +30,14 @@ services: # ports: # - "5000:5000" # access via http://localhost:5000 environment: - DB_URI: postgresql://gramps:grampspassword@db:5432/gramps - GRAMPSWEB_LOGLEVEL: INFO + DB_URI: ${GRAMPS_DB_URI} + GRAMPSWEB_LOGLEVEL: ${GRAMPSWEB_LOGLEVEL} # default admin user created on first run: - INITIAL_ADMIN: admin - INITIAL_ADMIN_PASSWORD: admin + INITIAL_ADMIN: ${GRAMPS_INITIAL_ADMIN} + INITIAL_ADMIN_PASSWORD: ${GRAMPS_INITIAL_ADMIN_PASSWORD} # optional: storage paths inside container - GRAMPSWEB_MEDIAPATH: /app/media - GRAMPSWEB_TREE: "main" + GRAMPSWEB_MEDIAPATH: ${GRAMPSWEB_MEDIAPATH} + GRAMPSWEB_TREE: "${GRAMPSWEB_TREE}" volumes: - ${PROJECT_ROOT}/apps/gramps/data/users:/app/users - ${PROJECT_ROOT}/apps/gramps/data/media:/app/media diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index cd5b94f..fe7ffed 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -16,26 +16,26 @@ services: - nextcloud-db - nextcloud-redis environment: - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MYSQL_HOST=nextcloud_db:3306 - - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com - - OVERWRITEPROTOCOL=https - - OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} + - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} + - MYSQL_HOST=${NEXTCLOUD_MYSQL_HOST} + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} + - OVERWRITEPROTOCOL=${NEXTCLOUD_OVERWRITEPROTOCOL} + - OVERWRITECLIURL=${NEXTCLOUD_OVERWRITECLIURL} - - SMTP_HOST=smtp.gmail.com - - SMTP_SECURE=tls - - SMTP_PORT=587 - - SMTP_AUTHTYPE=login - - MAIL_FROM_ADDRESS=beatz174 - - MAIL_DOMAIN=gmail.com - - SMTP_NAME=beatz174@gmail.com - - SMTP_PASSWORD=kqdw fvml wlag ldgv + - SMTP_HOST=${NEXTCLOUD_SMTP_HOST} + - SMTP_SECURE=${NEXTCLOUD_SMTP_SECURE} + - SMTP_PORT=${NEXTCLOUD_SMTP_PORT} + - SMTP_AUTHTYPE=${NEXTCLOUD_SMTP_AUTHTYPE} + - MAIL_FROM_ADDRESS=${NEXTCLOUD_MAIL_FROM_ADDRESS} + - MAIL_DOMAIN=${NEXTCLOUD_MAIL_DOMAIN} + - SMTP_NAME=${NEXTCLOUD_SMTP_NAME} + - SMTP_PASSWORD=${NEXTCLOUD_SMTP_PASSWORD} - - REDIS_HOST=redis - - REDIS_HOST_PORT=6379 - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + - REDIS_HOST=${NEXTCLOUD_REDIS_HOST} + - REDIS_HOST_PORT=${NEXTCLOUD_REDIS_HOST_PORT} + - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} networks: - traefik - nextcloud @@ -81,19 +81,19 @@ services: volumes: - ${PROJECT_ROOT}/apps/nextcloud/database:/var/lib/mysql:rw environment: - - MYSQL_ROOT_PASSWORD=R1m@dmin - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MARIADB_AUTO_UPGRADE=1 - - NEXTCLOUD_ADMIN_USER=admin - - NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin + - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_MYSQL_ROOT_PASSWORD} + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} + - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} + - MARIADB_AUTO_UPGRADE=${NEXTCLOUD_MARIADB_AUTO_UPGRADE} + - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} networks: - nextcloud labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -u nextcloud --password=R1m@dmin --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -u ${NEXTCLOUD_MYSQL_USER} --password=${NEXTCLOUD_MYSQL_PASSWORD} --silent"] interval: 10s timeout: 5s retries: 12 @@ -103,11 +103,11 @@ services: nextcloud-redis: image: "redis" profiles: ["apps","all","nextcloud"] - command: ["redis-server", "--requirepass", "TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n", "--appendonly", "yes", "--save", "60", "1000"] + command: ["redis-server", "--requirepass", "${NEXTCLOUD_REDIS_HOST_PASSWORD}", "--appendonly", "yes", "--save", "60", "1000"] hostname: redis container_name: nextcloud-redis environment: - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} volumes: - ${PROJECT_ROOT}/apps/nextcloud/data/redis:/data:rw restart: always @@ -116,7 +116,7 @@ services: labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "redis-cli -a TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n PING | grep -q PONG"] + test: ["CMD-SHELL", "redis-cli -a ${NEXTCLOUD_REDIS_HOST_PASSWORD} PING | grep -q PONG"] interval: 10s timeout: 5s retries: 6 diff --git a/apps/passbolt/docker-compose.yml b/apps/passbolt/docker-compose.yml index f7c0e7a..a0bcc89 100644 --- a/apps/passbolt/docker-compose.yml +++ b/apps/passbolt/docker-compose.yml @@ -5,10 +5,10 @@ services: image: mariadb:12 restart: always environment: - MYSQL_RANDOM_ROOT_PASSWORD: "true" - MYSQL_DATABASE: "passbolt" - MYSQL_USER: "passbolt" - MYSQL_PASSWORD: "P4ssb0lt" + MYSQL_RANDOM_ROOT_PASSWORD: "${PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD}" + MYSQL_DATABASE: "${PASSBOLT_MYSQL_DATABASE}" + MYSQL_USER: "${PASSBOLT_MYSQL_USER}" + MYSQL_PASSWORD: "${PASSBOLT_MYSQL_PASSWORD}" volumes: - ${PROJECT_ROOT}/apps/passbolt/data/database:/var/lib/mysql networks: @@ -32,12 +32,12 @@ services: depends_on: - passbolt-db environment: - APP_FULL_BASE_URL: https://passbolt.lan.ddnsgeek.com - DATASOURCES_DEFAULT_HOST: "passbolt-db" - DATASOURCES_DEFAULT_USERNAME: "passbolt" - DATASOURCES_DEFAULT_PASSWORD: "P4ssb0lt" - DATASOURCES_DEFAULT_DATABASE: "passbolt" - PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "CBBB2B8F3E9FACA114537ACB8965B750F7363586" + APP_FULL_BASE_URL: ${PASSBOLT_APP_FULL_BASE_URL} + DATASOURCES_DEFAULT_HOST: "${PASSBOLT_DATASOURCES_DEFAULT_HOST}" + DATASOURCES_DEFAULT_USERNAME: "${PASSBOLT_DATASOURCES_DEFAULT_USERNAME}" + DATASOURCES_DEFAULT_PASSWORD: "${PASSBOLT_DATASOURCES_DEFAULT_PASSWORD}" + DATASOURCES_DEFAULT_DATABASE: "${PASSBOLT_DATASOURCES_DEFAULT_DATABASE}" + PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT}" volumes: - ${PROJECT_ROOT}/apps/passbolt/data/gpg:/etc/passbolt/gpg - ${PROJECT_ROOT}/apps/passbolt/data/jwt:/etc/passbolt/jwt diff --git a/core/docker-compose.yml b/core/docker-compose.yml index 63eaa40..145ae00 100644 --- a/core/docker-compose.yml +++ b/core/docker-compose.yml @@ -51,7 +51,7 @@ services: container_name: crowdsec restart: always environment: - - COLLECTIONS=crowdsecurity/traefik + - COLLECTIONS=${CROWDSEC_COLLECTIONS} volumes: - ${PROJECT_ROOT}/core/crowdsec/logs:/logs:ro - ${PROJECT_ROOT}/core/crowdsec/data:/var/lib/crowdsec/data @@ -73,7 +73,7 @@ services: container_name: error-pages read_only: true environment: - TEMPLATE_NAME: app-down + TEMPLATE_NAME: ${ERROR_PAGES_TEMPLATE_NAME} networks: # - reverse_proxy - traefik diff --git a/default-environment.env b/default-environment.env index 2219493..f1510cc 100644 --- a/default-environment.env +++ b/default-environment.env @@ -2,3 +2,84 @@ PROJECT_ROOT=/home/nixos/docker DOMAIN=lan.ddnsgeek.com TZ=Australia/Brisbane EMAIL=wayne.bennett@live.com + +# Core +CROWDSEC_COLLECTIONS=crowdsecurity/traefik +ERROR_PAGES_TEMPLATE_NAME=app-down + +# Gitea +GITEA_USER_UID=1000 +GITEA_USER_GID=1000 +GITEA_DB_TYPE=sqlite3 +GITEA_ROOT_URL=https://gitea.lan.ddnsgeek.com/ + +# Grafana +GRAFANA_ROOT_URL=https://grafana.lan.ddnsgeek.com/ + +# Nextcloud +NEXTCLOUD_MYSQL_ROOT_PASSWORD=R1m@dmin +NEXTCLOUD_MYSQL_PASSWORD=R1m@dmin +NEXTCLOUD_MYSQL_DATABASE=nextcloud +NEXTCLOUD_MYSQL_USER=nextcloud +NEXTCLOUD_MYSQL_HOST=nextcloud_db:3306 +NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com +NEXTCLOUD_OVERWRITEPROTOCOL=https +NEXTCLOUD_OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com +NEXTCLOUD_SMTP_HOST=smtp.gmail.com +NEXTCLOUD_SMTP_SECURE=tls +NEXTCLOUD_SMTP_PORT=587 +NEXTCLOUD_SMTP_AUTHTYPE=login +NEXTCLOUD_MAIL_FROM_ADDRESS=beatz174 +NEXTCLOUD_MAIL_DOMAIN=gmail.com +NEXTCLOUD_SMTP_NAME=beatz174@gmail.com +NEXTCLOUD_SMTP_PASSWORD=kqdw fvml wlag ldgv +NEXTCLOUD_REDIS_HOST=redis +NEXTCLOUD_REDIS_HOST_PORT=6379 +NEXTCLOUD_REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n +NEXTCLOUD_MARIADB_AUTO_UPGRADE=1 +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin + +# Passbolt +PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD=true +PASSBOLT_MYSQL_DATABASE=passbolt +PASSBOLT_MYSQL_USER=passbolt +PASSBOLT_MYSQL_PASSWORD=P4ssb0lt +PASSBOLT_APP_FULL_BASE_URL=https://passbolt.lan.ddnsgeek.com +PASSBOLT_DATASOURCES_DEFAULT_HOST=passbolt-db +PASSBOLT_DATASOURCES_DEFAULT_USERNAME=passbolt +PASSBOLT_DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt +PASSBOLT_DATASOURCES_DEFAULT_DATABASE=passbolt +PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=CBBB2B8F3E9FACA114537ACB8965B750F7363586 + +# Gramps +GRAMPS_POSTGRES_USER=gramps +GRAMPS_POSTGRES_PASSWORD=grampspassword +GRAMPS_POSTGRES_DB=gramps +GRAMPS_DB_URI=postgresql://gramps:grampspassword@db:5432/gramps +GRAMPSWEB_LOGLEVEL=INFO +GRAMPS_INITIAL_ADMIN=admin +GRAMPS_INITIAL_ADMIN_PASSWORD=admin +GRAMPSWEB_MEDIAPATH=/app/media +GRAMPSWEB_TREE=main + +# Prometheus stack +INFLUXDB_INIT_MODE=setup +INFLUXDB_INIT_USERNAME=admin +INFLUXDB_INIT_PASSWORD=adminpassword +INFLUXDB_INIT_ORG=pbs +INFLUXDB_INIT_BUCKET=telemetry +DOCKER_EXPORTER_LOG_LEVEL=INFO +PIHOLE_HOSTNAME=pihole.sweet.home +PIHOLE_PASSWORD= +PIHOLE_EXPORTER_PORT=9617 + +# Gotify +GOTIFY_DEFAULTUSER_NAME=admin +GOTIFY_DEFAULTUSER_PASS=R1m@dmin +GOTIFY_REGISTRATION=false +GOTIFY_URL=https://gotify.lan.ddnsgeek.com +GOTIFY_TOKEN=ADuOnDBG7C27hcf + +# Portainer +PORTAINER_GODEBUG=netdns=cgo diff --git a/monitoring/gotify/docker-compose.yml b/monitoring/gotify/docker-compose.yml index bad0989..e8927ed 100644 --- a/monitoring/gotify/docker-compose.yml +++ b/monitoring/gotify/docker-compose.yml @@ -10,9 +10,9 @@ services: environment: - TZ=${TZ} - - GOTIFY_DEFAULTUSER_NAME=admin - - GOTIFY_DEFAULTUSER_PASS=R1m@dmin - - GOTIFY_REGISTRATION=false + - GOTIFY_DEFAULTUSER_NAME=${GOTIFY_DEFAULTUSER_NAME} + - GOTIFY_DEFAULTUSER_PASS=${GOTIFY_DEFAULTUSER_PASS} + - GOTIFY_REGISTRATION=${GOTIFY_REGISTRATION} networks: # - traefik_reverse_proxy diff --git a/monitoring/gotify/docker-health-to-gotify.sh b/monitoring/gotify/docker-health-to-gotify.sh index fa52b9d..ec8bfdd 100755 --- a/monitoring/gotify/docker-health-to-gotify.sh +++ b/monitoring/gotify/docker-health-to-gotify.sh @@ -4,8 +4,8 @@ set -euo pipefail #: "${GOTIFY_URL:?Set GOTIFY_URL (e.g. https://gotify.lan.ddnsgeek.com)}" #: "${GOTIFY_TOKEN:?Set GOTIFY_TOKEN (AAM..CtNmUGoNIV)}" -GOTIFY_URL="https://gotify.lan.ddnsgeek.com" -GOTIFY_TOKEN="ADuOnDBG7C27hcf" +GOTIFY_URL="${GOTIFY_URL}" +GOTIFY_TOKEN="${GOTIFY_TOKEN}" STATE_DIR="./docker-health-alert" STATE_FILE="${STATE_DIR}/last_unhealthy.txt" diff --git a/monitoring/grafana/docker-compose.yml b/monitoring/grafana/docker-compose.yml index 1806f02..227b770 100644 --- a/monitoring/grafana/docker-compose.yml +++ b/monitoring/grafana/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: grafana restart: unless-stopped environment: - - GF_SERVER_ROOT_URL=https://grafana.lan.ddnsgeek.com/ + - GF_SERVER_ROOT_URL=${GRAFANA_ROOT_URL} volumes: - ${PROJECT_ROOT}/monitoring/grafana/data:/var/lib/grafana networks: diff --git a/monitoring/portainer/docker-compose.yml b/monitoring/portainer/docker-compose.yml index 57badde..6402119 100644 --- a/monitoring/portainer/docker-compose.yml +++ b/monitoring/portainer/docker-compose.yml @@ -24,7 +24,7 @@ services: - traefik.http.services.portainer.loadbalancer.server.port=9000 environment: - - GODEBUG=netdns=cgo + - GODEBUG=${PORTAINER_GODEBUG} # healthcheck: # test: ["CMD", "wget", "--spider", "-q", "https://portainer.lan.ddnsgeek.com/api/status"] # interval: 30s diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index 11dfb51..d54f917 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -104,11 +104,11 @@ services: volumes: - ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE: setup - DOCKER_INFLUXDB_INIT_USERNAME: admin - DOCKER_INFLUXDB_INIT_PASSWORD: adminpassword - DOCKER_INFLUXDB_INIT_ORG: pbs - DOCKER_INFLUXDB_INIT_BUCKET: telemetry + DOCKER_INFLUXDB_INIT_MODE: ${INFLUXDB_INIT_MODE} + DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME} + DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_INIT_PASSWORD} + DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG} + DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_INIT_BUCKET} networks: # - edge # - traefik_reverse_proxy @@ -162,7 +162,7 @@ services: # - ${PROJECT_ROOT}/monitoring/docker-exporter/data:/data:rw # - ${PROJECT_ROOT}/services-up.sh:/app/services-up.sh:ro environment: - LOG_LEVEL: INFO + LOG_LEVEL: ${DOCKER_EXPORTER_LOG_LEVEL} volumes: - ~/.docker/config.json:/root/.docker/config.json:ro @@ -206,9 +206,9 @@ services: image: ekofr/pihole-exporter:latest container_name: pihole-exporter environment: - PIHOLE_HOSTNAME: pihole.sweet.home - PIHOLE_PASSWORD: "" - PORT: 9617 + PIHOLE_HOSTNAME: ${PIHOLE_HOSTNAME} + PIHOLE_PASSWORD: "${PIHOLE_PASSWORD}" + PORT: ${PIHOLE_EXPORTER_PORT} ports: - "9617:9617" restart: unless-stopped From b7983b30d3ccd1c10888c4d98b73fd7a3e53242f Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 15:12:42 +1000 Subject: [PATCH 3/8] modified: apps/gitea/docker-compose.yml modified: apps/gramps/docker-compose.yml modified: apps/nextcloud/docker-compose.yml modified: apps/passbolt/docker-compose.yml modified: core/docker-compose.yml modified: default-environment.env modified: monitoring/prometheus/docker-compose.yml --- apps/gitea/docker-compose.yml | 8 +-- apps/gramps/docker-compose.yml | 18 +++--- apps/nextcloud/docker-compose.yml | 58 ++++++++--------- apps/passbolt/docker-compose.yml | 20 +++--- core/docker-compose.yml | 4 +- default-environment.env | 81 ++++++++++++++++++++++++ monitoring/prometheus/docker-compose.yml | 18 +++--- 7 files changed, 144 insertions(+), 63 deletions(-) diff --git a/apps/gitea/docker-compose.yml b/apps/gitea/docker-compose.yml index 55f6bc3..df09a2f 100644 --- a/apps/gitea/docker-compose.yml +++ b/apps/gitea/docker-compose.yml @@ -5,10 +5,10 @@ services: image: gitea/gitea:latest # change to 1-rootless once find out how to move data. restart: always environment: - - USER_UID=1000 - - USER_GID=1000 - - GITEA__database__DB_TYPE=sqlite3 - - GITEA__server__ROOT_URL=https://gitea.lan.ddnsgeek.com/ + - USER_UID=${GITEA_USER_UID} + - USER_GID=${GITEA_USER_GID} + - GITEA__database__DB_TYPE=${GITEA_DB_TYPE} + - GITEA__server__ROOT_URL=${GITEA_ROOT_URL} volumes: - ${PROJECT_ROOT}/apps/gitea/data:/data networks: diff --git a/apps/gramps/docker-compose.yml b/apps/gramps/docker-compose.yml index 80f01af..65b4bc1 100644 --- a/apps/gramps/docker-compose.yml +++ b/apps/gramps/docker-compose.yml @@ -5,9 +5,9 @@ services: container_name: gramps-db restart: always environment: - POSTGRES_USER: gramps - POSTGRES_PASSWORD: grampspassword - POSTGRES_DB: gramps + POSTGRES_USER: ${GRAMPS_POSTGRES_USER} + POSTGRES_PASSWORD: ${GRAMPS_POSTGRES_PASSWORD} + POSTGRES_DB: ${GRAMPS_POSTGRES_DB} volumes: - ${PROJECT_ROOT}/apps/gramps/db:/var/lib/postgresql networks: @@ -30,14 +30,14 @@ services: # ports: # - "5000:5000" # access via http://localhost:5000 environment: - DB_URI: postgresql://gramps:grampspassword@db:5432/gramps - GRAMPSWEB_LOGLEVEL: INFO + DB_URI: ${GRAMPS_DB_URI} + GRAMPSWEB_LOGLEVEL: ${GRAMPSWEB_LOGLEVEL} # default admin user created on first run: - INITIAL_ADMIN: admin - INITIAL_ADMIN_PASSWORD: admin + INITIAL_ADMIN: ${GRAMPS_INITIAL_ADMIN} + INITIAL_ADMIN_PASSWORD: ${GRAMPS_INITIAL_ADMIN_PASSWORD} # optional: storage paths inside container - GRAMPSWEB_MEDIAPATH: /app/media - GRAMPSWEB_TREE: "main" + GRAMPSWEB_MEDIAPATH: ${GRAMPSWEB_MEDIAPATH} + GRAMPSWEB_TREE: "${GRAMPSWEB_TREE}" volumes: - ${PROJECT_ROOT}/apps/gramps/data/users:/app/users - ${PROJECT_ROOT}/apps/gramps/data/media:/app/media diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index cd5b94f..fe7ffed 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -16,26 +16,26 @@ services: - nextcloud-db - nextcloud-redis environment: - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MYSQL_HOST=nextcloud_db:3306 - - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com - - OVERWRITEPROTOCOL=https - - OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} + - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} + - MYSQL_HOST=${NEXTCLOUD_MYSQL_HOST} + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} + - OVERWRITEPROTOCOL=${NEXTCLOUD_OVERWRITEPROTOCOL} + - OVERWRITECLIURL=${NEXTCLOUD_OVERWRITECLIURL} - - SMTP_HOST=smtp.gmail.com - - SMTP_SECURE=tls - - SMTP_PORT=587 - - SMTP_AUTHTYPE=login - - MAIL_FROM_ADDRESS=beatz174 - - MAIL_DOMAIN=gmail.com - - SMTP_NAME=beatz174@gmail.com - - SMTP_PASSWORD=kqdw fvml wlag ldgv + - SMTP_HOST=${NEXTCLOUD_SMTP_HOST} + - SMTP_SECURE=${NEXTCLOUD_SMTP_SECURE} + - SMTP_PORT=${NEXTCLOUD_SMTP_PORT} + - SMTP_AUTHTYPE=${NEXTCLOUD_SMTP_AUTHTYPE} + - MAIL_FROM_ADDRESS=${NEXTCLOUD_MAIL_FROM_ADDRESS} + - MAIL_DOMAIN=${NEXTCLOUD_MAIL_DOMAIN} + - SMTP_NAME=${NEXTCLOUD_SMTP_NAME} + - SMTP_PASSWORD=${NEXTCLOUD_SMTP_PASSWORD} - - REDIS_HOST=redis - - REDIS_HOST_PORT=6379 - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + - REDIS_HOST=${NEXTCLOUD_REDIS_HOST} + - REDIS_HOST_PORT=${NEXTCLOUD_REDIS_HOST_PORT} + - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} networks: - traefik - nextcloud @@ -81,19 +81,19 @@ services: volumes: - ${PROJECT_ROOT}/apps/nextcloud/database:/var/lib/mysql:rw environment: - - MYSQL_ROOT_PASSWORD=R1m@dmin - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MARIADB_AUTO_UPGRADE=1 - - NEXTCLOUD_ADMIN_USER=admin - - NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin + - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_MYSQL_ROOT_PASSWORD} + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} + - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} + - MARIADB_AUTO_UPGRADE=${NEXTCLOUD_MARIADB_AUTO_UPGRADE} + - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} networks: - nextcloud labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -u nextcloud --password=R1m@dmin --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -u ${NEXTCLOUD_MYSQL_USER} --password=${NEXTCLOUD_MYSQL_PASSWORD} --silent"] interval: 10s timeout: 5s retries: 12 @@ -103,11 +103,11 @@ services: nextcloud-redis: image: "redis" profiles: ["apps","all","nextcloud"] - command: ["redis-server", "--requirepass", "TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n", "--appendonly", "yes", "--save", "60", "1000"] + command: ["redis-server", "--requirepass", "${NEXTCLOUD_REDIS_HOST_PASSWORD}", "--appendonly", "yes", "--save", "60", "1000"] hostname: redis container_name: nextcloud-redis environment: - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} volumes: - ${PROJECT_ROOT}/apps/nextcloud/data/redis:/data:rw restart: always @@ -116,7 +116,7 @@ services: labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "redis-cli -a TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n PING | grep -q PONG"] + test: ["CMD-SHELL", "redis-cli -a ${NEXTCLOUD_REDIS_HOST_PASSWORD} PING | grep -q PONG"] interval: 10s timeout: 5s retries: 6 diff --git a/apps/passbolt/docker-compose.yml b/apps/passbolt/docker-compose.yml index f7c0e7a..a0bcc89 100644 --- a/apps/passbolt/docker-compose.yml +++ b/apps/passbolt/docker-compose.yml @@ -5,10 +5,10 @@ services: image: mariadb:12 restart: always environment: - MYSQL_RANDOM_ROOT_PASSWORD: "true" - MYSQL_DATABASE: "passbolt" - MYSQL_USER: "passbolt" - MYSQL_PASSWORD: "P4ssb0lt" + MYSQL_RANDOM_ROOT_PASSWORD: "${PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD}" + MYSQL_DATABASE: "${PASSBOLT_MYSQL_DATABASE}" + MYSQL_USER: "${PASSBOLT_MYSQL_USER}" + MYSQL_PASSWORD: "${PASSBOLT_MYSQL_PASSWORD}" volumes: - ${PROJECT_ROOT}/apps/passbolt/data/database:/var/lib/mysql networks: @@ -32,12 +32,12 @@ services: depends_on: - passbolt-db environment: - APP_FULL_BASE_URL: https://passbolt.lan.ddnsgeek.com - DATASOURCES_DEFAULT_HOST: "passbolt-db" - DATASOURCES_DEFAULT_USERNAME: "passbolt" - DATASOURCES_DEFAULT_PASSWORD: "P4ssb0lt" - DATASOURCES_DEFAULT_DATABASE: "passbolt" - PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "CBBB2B8F3E9FACA114537ACB8965B750F7363586" + APP_FULL_BASE_URL: ${PASSBOLT_APP_FULL_BASE_URL} + DATASOURCES_DEFAULT_HOST: "${PASSBOLT_DATASOURCES_DEFAULT_HOST}" + DATASOURCES_DEFAULT_USERNAME: "${PASSBOLT_DATASOURCES_DEFAULT_USERNAME}" + DATASOURCES_DEFAULT_PASSWORD: "${PASSBOLT_DATASOURCES_DEFAULT_PASSWORD}" + DATASOURCES_DEFAULT_DATABASE: "${PASSBOLT_DATASOURCES_DEFAULT_DATABASE}" + PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT}" volumes: - ${PROJECT_ROOT}/apps/passbolt/data/gpg:/etc/passbolt/gpg - ${PROJECT_ROOT}/apps/passbolt/data/jwt:/etc/passbolt/jwt diff --git a/core/docker-compose.yml b/core/docker-compose.yml index 63eaa40..145ae00 100644 --- a/core/docker-compose.yml +++ b/core/docker-compose.yml @@ -51,7 +51,7 @@ services: container_name: crowdsec restart: always environment: - - COLLECTIONS=crowdsecurity/traefik + - COLLECTIONS=${CROWDSEC_COLLECTIONS} volumes: - ${PROJECT_ROOT}/core/crowdsec/logs:/logs:ro - ${PROJECT_ROOT}/core/crowdsec/data:/var/lib/crowdsec/data @@ -73,7 +73,7 @@ services: container_name: error-pages read_only: true environment: - TEMPLATE_NAME: app-down + TEMPLATE_NAME: ${ERROR_PAGES_TEMPLATE_NAME} networks: # - reverse_proxy - traefik diff --git a/default-environment.env b/default-environment.env index 2219493..f1510cc 100644 --- a/default-environment.env +++ b/default-environment.env @@ -2,3 +2,84 @@ PROJECT_ROOT=/home/nixos/docker DOMAIN=lan.ddnsgeek.com TZ=Australia/Brisbane EMAIL=wayne.bennett@live.com + +# Core +CROWDSEC_COLLECTIONS=crowdsecurity/traefik +ERROR_PAGES_TEMPLATE_NAME=app-down + +# Gitea +GITEA_USER_UID=1000 +GITEA_USER_GID=1000 +GITEA_DB_TYPE=sqlite3 +GITEA_ROOT_URL=https://gitea.lan.ddnsgeek.com/ + +# Grafana +GRAFANA_ROOT_URL=https://grafana.lan.ddnsgeek.com/ + +# Nextcloud +NEXTCLOUD_MYSQL_ROOT_PASSWORD=R1m@dmin +NEXTCLOUD_MYSQL_PASSWORD=R1m@dmin +NEXTCLOUD_MYSQL_DATABASE=nextcloud +NEXTCLOUD_MYSQL_USER=nextcloud +NEXTCLOUD_MYSQL_HOST=nextcloud_db:3306 +NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com +NEXTCLOUD_OVERWRITEPROTOCOL=https +NEXTCLOUD_OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com +NEXTCLOUD_SMTP_HOST=smtp.gmail.com +NEXTCLOUD_SMTP_SECURE=tls +NEXTCLOUD_SMTP_PORT=587 +NEXTCLOUD_SMTP_AUTHTYPE=login +NEXTCLOUD_MAIL_FROM_ADDRESS=beatz174 +NEXTCLOUD_MAIL_DOMAIN=gmail.com +NEXTCLOUD_SMTP_NAME=beatz174@gmail.com +NEXTCLOUD_SMTP_PASSWORD=kqdw fvml wlag ldgv +NEXTCLOUD_REDIS_HOST=redis +NEXTCLOUD_REDIS_HOST_PORT=6379 +NEXTCLOUD_REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n +NEXTCLOUD_MARIADB_AUTO_UPGRADE=1 +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin + +# Passbolt +PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD=true +PASSBOLT_MYSQL_DATABASE=passbolt +PASSBOLT_MYSQL_USER=passbolt +PASSBOLT_MYSQL_PASSWORD=P4ssb0lt +PASSBOLT_APP_FULL_BASE_URL=https://passbolt.lan.ddnsgeek.com +PASSBOLT_DATASOURCES_DEFAULT_HOST=passbolt-db +PASSBOLT_DATASOURCES_DEFAULT_USERNAME=passbolt +PASSBOLT_DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt +PASSBOLT_DATASOURCES_DEFAULT_DATABASE=passbolt +PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=CBBB2B8F3E9FACA114537ACB8965B750F7363586 + +# Gramps +GRAMPS_POSTGRES_USER=gramps +GRAMPS_POSTGRES_PASSWORD=grampspassword +GRAMPS_POSTGRES_DB=gramps +GRAMPS_DB_URI=postgresql://gramps:grampspassword@db:5432/gramps +GRAMPSWEB_LOGLEVEL=INFO +GRAMPS_INITIAL_ADMIN=admin +GRAMPS_INITIAL_ADMIN_PASSWORD=admin +GRAMPSWEB_MEDIAPATH=/app/media +GRAMPSWEB_TREE=main + +# Prometheus stack +INFLUXDB_INIT_MODE=setup +INFLUXDB_INIT_USERNAME=admin +INFLUXDB_INIT_PASSWORD=adminpassword +INFLUXDB_INIT_ORG=pbs +INFLUXDB_INIT_BUCKET=telemetry +DOCKER_EXPORTER_LOG_LEVEL=INFO +PIHOLE_HOSTNAME=pihole.sweet.home +PIHOLE_PASSWORD= +PIHOLE_EXPORTER_PORT=9617 + +# Gotify +GOTIFY_DEFAULTUSER_NAME=admin +GOTIFY_DEFAULTUSER_PASS=R1m@dmin +GOTIFY_REGISTRATION=false +GOTIFY_URL=https://gotify.lan.ddnsgeek.com +GOTIFY_TOKEN=ADuOnDBG7C27hcf + +# Portainer +PORTAINER_GODEBUG=netdns=cgo diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index 11dfb51..d54f917 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -104,11 +104,11 @@ services: volumes: - ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE: setup - DOCKER_INFLUXDB_INIT_USERNAME: admin - DOCKER_INFLUXDB_INIT_PASSWORD: adminpassword - DOCKER_INFLUXDB_INIT_ORG: pbs - DOCKER_INFLUXDB_INIT_BUCKET: telemetry + DOCKER_INFLUXDB_INIT_MODE: ${INFLUXDB_INIT_MODE} + DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME} + DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_INIT_PASSWORD} + DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG} + DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_INIT_BUCKET} networks: # - edge # - traefik_reverse_proxy @@ -162,7 +162,7 @@ services: # - ${PROJECT_ROOT}/monitoring/docker-exporter/data:/data:rw # - ${PROJECT_ROOT}/services-up.sh:/app/services-up.sh:ro environment: - LOG_LEVEL: INFO + LOG_LEVEL: ${DOCKER_EXPORTER_LOG_LEVEL} volumes: - ~/.docker/config.json:/root/.docker/config.json:ro @@ -206,9 +206,9 @@ services: image: ekofr/pihole-exporter:latest container_name: pihole-exporter environment: - PIHOLE_HOSTNAME: pihole.sweet.home - PIHOLE_PASSWORD: "" - PORT: 9617 + PIHOLE_HOSTNAME: ${PIHOLE_HOSTNAME} + PIHOLE_PASSWORD: "${PIHOLE_PASSWORD}" + PORT: ${PIHOLE_EXPORTER_PORT} ports: - "9617:9617" restart: unless-stopped From 8d0ecf0adf9996595d72a98e9166c5dbd1c00988 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 15:34:41 +1000 Subject: [PATCH 4/8] modified: default-environment.env modified: monitoring/gotify/docker-health-to-gotify.sh --- default-environment.env | 4 ++-- monitoring/gotify/docker-health-to-gotify.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/default-environment.env b/default-environment.env index f1510cc..e4f10ca 100644 --- a/default-environment.env +++ b/default-environment.env @@ -78,8 +78,8 @@ PIHOLE_EXPORTER_PORT=9617 GOTIFY_DEFAULTUSER_NAME=admin GOTIFY_DEFAULTUSER_PASS=R1m@dmin GOTIFY_REGISTRATION=false -GOTIFY_URL=https://gotify.lan.ddnsgeek.com -GOTIFY_TOKEN=ADuOnDBG7C27hcf +#GOTIFY_URL=https://gotify.lan.ddnsgeek.com +#GOTIFY_TOKEN=ADuOnDBG7C27hcf # Portainer PORTAINER_GODEBUG=netdns=cgo diff --git a/monitoring/gotify/docker-health-to-gotify.sh b/monitoring/gotify/docker-health-to-gotify.sh index ec8bfdd..fa52b9d 100755 --- a/monitoring/gotify/docker-health-to-gotify.sh +++ b/monitoring/gotify/docker-health-to-gotify.sh @@ -4,8 +4,8 @@ set -euo pipefail #: "${GOTIFY_URL:?Set GOTIFY_URL (e.g. https://gotify.lan.ddnsgeek.com)}" #: "${GOTIFY_TOKEN:?Set GOTIFY_TOKEN (AAM..CtNmUGoNIV)}" -GOTIFY_URL="${GOTIFY_URL}" -GOTIFY_TOKEN="${GOTIFY_TOKEN}" +GOTIFY_URL="https://gotify.lan.ddnsgeek.com" +GOTIFY_TOKEN="ADuOnDBG7C27hcf" STATE_DIR="./docker-health-alert" STATE_FILE="${STATE_DIR}/last_unhealthy.txt" From 3c2d28c763a1ce337a27ccc7c4f475c222d5b2a0 Mon Sep 17 00:00:00 2001 From: beatz174-bit Date: Tue, 7 Apr 2026 16:12:50 +1000 Subject: [PATCH 5/8] Harden compose secrets and add required provisioning docs --- .env.example | 9 +++ .gitignore | 4 +- DEPLOYMENT.md | 49 ++++++++++++++++ SECURITY_SECRETS_INVENTORY.md | 31 ++++++++++ apps/gramps/docker-compose.yml | 34 +++++------ apps/nextcloud/docker-compose.yml | 74 ++++++++++++++---------- apps/passbolt/docker-compose.yml | 36 ++++++------ core/authelia/configuration.yml | 9 +-- core/docker-compose.yml | 5 ++ core/traefik/dynamic.yml | 2 +- monitoring/gotify/docker-compose.yml | 15 ++--- monitoring/prometheus/docker-compose.yml | 28 ++++++--- monitoring/prometheus/prometheus.yml | 4 +- secrets/.env.secrets.example | 35 +++++++++++ 14 files changed, 242 insertions(+), 93 deletions(-) create mode 100644 .env.example create mode 100644 DEPLOYMENT.md create mode 100644 SECURITY_SECRETS_INVENTORY.md create mode 100644 secrets/.env.secrets.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9232eaf --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# Copy this file to default-environment.env (non-secret defaults) and update values. +PROJECT_ROOT=/path/to/docker +DOMAIN=example.com +TZ=Etc/UTC +EMAIL=admin@example.com + +# Required secret file path used by compose services. +# Create this file from secrets/.env.secrets.example and keep it out of git. +SECRETS_ENV_FILE=${PROJECT_ROOT}/secrets/stack-secrets.env diff --git a/.gitignore b/.gitignore index d1efebd..4cf1b7d 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ apps/searxng/* venv/ core/authelia/users_database.yml monitoring/influxdb/* - +secrets/* +!secrets/.env.secrets.example +!.env.example diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..7f2e1e0 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,49 @@ +# Deployment prerequisites (required) + +Before running `docker compose up`, you **must** provision runtime secrets. + +## 1) Create non-committed secret files + +```bash +cp secrets/.env.secrets.example secrets/stack-secrets.env +chmod 600 secrets/stack-secrets.env +``` + +Create these Docker secret files (all ignored by git): + +- `secrets/nextcloud_db_root_password.txt` +- `secrets/nextcloud_db_password.txt` +- `secrets/nextcloud_admin_password.txt` +- `secrets/nextcloud_smtp_password.txt` +- `secrets/nextcloud_redis_password.txt` +- `secrets/passbolt_db_password.txt` +- `secrets/gramps_db_password.txt` +- `secrets/influxdb_init_password.txt` +- `secrets/prometheus_kuma_basic_auth_password.txt` + +Recommended permissions: + +```bash +chmod 600 secrets/*.txt +``` + +## 2) Rotate previously committed credentials + +These values were previously hardcoded and must be rotated in upstream systems immediately: + +- Database credentials (Nextcloud, Passbolt, Gramps, InfluxDB). +- Nextcloud SMTP app password. +- Authelia reset JWT secret, session secret, storage encryption key. +- Traefik CrowdSec LAPI key. +- Gotify admin password. +- Prometheus Uptime Kuma basic-auth password. + +## 3) Start stack + +After secrets are provisioned: + +```bash +docker compose -f core/docker-compose.yml up -d +docker compose -f monitoring/prometheus/docker-compose.yml up -d +docker compose -f apps/nextcloud/docker-compose.yml up -d +``` diff --git a/SECURITY_SECRETS_INVENTORY.md b/SECURITY_SECRETS_INVENTORY.md new file mode 100644 index 0000000..3f06a34 --- /dev/null +++ b/SECURITY_SECRETS_INVENTORY.md @@ -0,0 +1,31 @@ +# Credential Inventory (apps/, core/, monitoring/) + +## apps/ +- `apps/nextcloud/docker-compose.yml` + - `MYSQL_PASSWORD` (nextcloud-webapp) -> `MYSQL_PASSWORD_FILE` + Docker secret. + - `SMTP_PASSWORD` -> `SMTP_PASSWORD_FILE` + Docker secret. + - `REDIS_HOST_PASSWORD` -> `REDIS_HOST_PASSWORD_FILE` + Docker secret. + - `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD`, `NEXTCLOUD_ADMIN_PASSWORD` (nextcloud-db) -> `_FILE` variants + Docker secrets. + - Redis `--requirepass` inline value -> read from Docker secret at runtime. +- `apps/passbolt/docker-compose.yml` + - `MYSQL_PASSWORD`, `DATASOURCES_DEFAULT_PASSWORD` -> `_FILE` variants + Docker secret. +- `apps/gramps/docker-compose.yml` + - `POSTGRES_PASSWORD` -> `POSTGRES_PASSWORD_FILE` + Docker secret. + - `DB_URI` password + `INITIAL_ADMIN_PASSWORD` -> env references from non-committed secrets env file. + +## core/ +- `core/authelia/configuration.yml` + - `identity_validation.reset_password.jwt_secret` -> `${AUTHELIA_JWT_SECRET}`. + - `session.secret` -> `${AUTHELIA_SESSION_SECRET}`. + - `storage.encryption_key` -> `${AUTHELIA_STORAGE_ENCRYPTION_KEY}`. +- `core/traefik/dynamic.yml` + - `crowdsecLapiKey` -> `${CROWDSEC_LAPI_KEY}`. + +## monitoring/ +- `monitoring/gotify/docker-compose.yml` + - `GOTIFY_DEFAULTUSER_PASS` -> `${GOTIFY_DEFAULTUSER_PASS}` from non-committed secrets env file. +- `monitoring/prometheus/docker-compose.yml` + - `DOCKER_INFLUXDB_INIT_PASSWORD` -> `DOCKER_INFLUXDB_INIT_PASSWORD_FILE` + Docker secret. + - `PIHOLE_PASSWORD` -> `${PIHOLE_PASSWORD}` from non-committed secrets env file. +- `monitoring/prometheus/prometheus.yml` + - Uptime Kuma basic_auth `password` -> `password_file` mounted from non-committed secret file. diff --git a/apps/gramps/docker-compose.yml b/apps/gramps/docker-compose.yml index 80f01af..e5a5200 100644 --- a/apps/gramps/docker-compose.yml +++ b/apps/gramps/docker-compose.yml @@ -4,22 +4,25 @@ services: image: postgres:13 container_name: gramps-db restart: always + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - POSTGRES_USER: gramps - POSTGRES_PASSWORD: grampspassword - POSTGRES_DB: gramps + POSTGRES_USER: ${GRAMPS_DB_USER} + POSTGRES_PASSWORD_FILE: /run/secrets/gramps_db_password + POSTGRES_DB: ${GRAMPS_DB_NAME} + secrets: + - gramps_db_password volumes: - ${PROJECT_ROOT}/apps/gramps/db:/var/lib/postgresql networks: - gramps healthcheck: - test: ["CMD-SHELL", "pg_isready -h db -p 5432 -U gramps -d gramps"] + test: ["CMD-SHELL", "pg_isready -h gramps-db -p 5432 -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 10s timeout: 5s retries: 12 start_period: 30s - grampsweb: profiles: ["apps","all","gramps"] image: ghcr.io/gramps-project/grampsweb:latest @@ -27,15 +30,13 @@ services: depends_on: - gramps-db restart: always -# ports: -# - "5000:5000" # access via http://localhost:5000 + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - DB_URI: postgresql://gramps:grampspassword@db:5432/gramps + DB_URI: postgresql://${GRAMPS_DB_USER}:${GRAMPS_DB_PASSWORD}@gramps-db:5432/${GRAMPS_DB_NAME} GRAMPSWEB_LOGLEVEL: INFO - # default admin user created on first run: - INITIAL_ADMIN: admin - INITIAL_ADMIN_PASSWORD: admin - # optional: storage paths inside container + INITIAL_ADMIN: ${GRAMPS_INITIAL_ADMIN} + INITIAL_ADMIN_PASSWORD: ${GRAMPS_INITIAL_ADMIN_PASSWORD} GRAMPSWEB_MEDIAPATH: /app/media GRAMPSWEB_TREE: "main" volumes: @@ -62,10 +63,9 @@ services: retries: 6 start_period: 60s - - networks: -# traefik_reverse_proxy: -# external: true gramps: -# driver: bridge + +secrets: + gramps_db_password: + file: ${PROJECT_ROOT}/secrets/gramps_db_password.txt diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index cd5b94f..b9203ea 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -1,12 +1,13 @@ services: nextcloud-webapp: -# image: nextcloud:production profiles: ["apps","all","nextcloud"] build: context: ${PROJECT_ROOT}/apps/nextcloud container_name: nextcloud-webapp restart: always hostname: nextcloud.lan.ddnsgeek.com + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/apps/nextcloud/data:/var/www/html/data:rw - ${PROJECT_ROOT}/apps/nextcloud/config:/var/www/html/config:rw @@ -16,26 +17,28 @@ services: - nextcloud-db - nextcloud-redis environment: - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud + - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_USER=${NEXTCLOUD_DB_USER} - MYSQL_HOST=nextcloud_db:3306 - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com - OVERWRITEPROTOCOL=https - OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com - - SMTP_HOST=smtp.gmail.com - SMTP_SECURE=tls - SMTP_PORT=587 - SMTP_AUTHTYPE=login - - MAIL_FROM_ADDRESS=beatz174 - - MAIL_DOMAIN=gmail.com - - SMTP_NAME=beatz174@gmail.com - - SMTP_PASSWORD=kqdw fvml wlag ldgv - + - MAIL_FROM_ADDRESS=${NEXTCLOUD_SMTP_FROM_ADDRESS} + - MAIL_DOMAIN=${NEXTCLOUD_SMTP_DOMAIN} + - SMTP_NAME=${NEXTCLOUD_SMTP_NAME} + - SMTP_PASSWORD_FILE=/run/secrets/nextcloud_smtp_password - REDIS_HOST=redis - REDIS_HOST_PORT=6379 - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + - REDIS_HOST_PASSWORD_FILE=/run/secrets/nextcloud_redis_password + secrets: + - nextcloud_db_password + - nextcloud_smtp_password + - nextcloud_redis_password networks: - traefik - nextcloud @@ -54,7 +57,6 @@ services: - "traefik.http.middlewares.nextcloud-webfinger.redirectregex.regex=https://(.*)/.well-known/webfinger" - "traefik.http.middlewares.nextcloud-webfinger.redirectregex.replacement=https://$${1}/nextcloud/index.php/.well-known/webfinger" - "traefik.docker.network=core_traefik" - healthcheck: test: - CMD-SHELL @@ -68,9 +70,6 @@ services: retries: 6 start_period: 180s - - - nextcloud-db: image: mariadb:11.4 restart: always @@ -78,36 +77,41 @@ services: container_name: nextcloud-db hostname: nextcloud_db command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/apps/nextcloud/database:/var/lib/mysql:rw environment: - - MYSQL_ROOT_PASSWORD=R1m@dmin - - MYSQL_PASSWORD=R1m@dmin - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/nextcloud_db_root_password + - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_USER=${NEXTCLOUD_DB_USER} - MARIADB_AUTO_UPGRADE=1 - - NEXTCLOUD_ADMIN_USER=admin - - NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin + - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/nextcloud_admin_password + secrets: + - nextcloud_db_root_password + - nextcloud_db_password + - nextcloud_admin_password networks: - nextcloud labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -u nextcloud --password=R1m@dmin --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -u $$MYSQL_USER --password=$$(cat /run/secrets/nextcloud_db_password) --silent"] interval: 10s timeout: 5s retries: 12 start_period: 60s - nextcloud-redis: image: "redis" profiles: ["apps","all","nextcloud"] - command: ["redis-server", "--requirepass", "TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n", "--appendonly", "yes", "--save", "60", "1000"] + command: ["sh", "-c", "redis-server --requirepass \"$$(cat /run/secrets/nextcloud_redis_password)\" --appendonly yes --save 60 1000"] hostname: redis container_name: nextcloud-redis - environment: - - REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n + secrets: + - nextcloud_redis_password volumes: - ${PROJECT_ROOT}/apps/nextcloud/data/redis:/data:rw restart: always @@ -116,15 +120,23 @@ services: labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "redis-cli -a TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n PING | grep -q PONG"] + test: ["CMD-SHELL", "redis-cli -a \"$$(cat /run/secrets/nextcloud_redis_password)\" PING | grep -q PONG"] interval: 10s timeout: 5s retries: 6 start_period: 10s - networks: -# traefik_reverse_proxy: -# external: true nextcloud: -# driver: bridge + +secrets: + nextcloud_db_root_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_db_root_password.txt + nextcloud_db_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_db_password.txt + nextcloud_admin_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_admin_password.txt + nextcloud_smtp_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_smtp_password.txt + nextcloud_redis_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_redis_password.txt diff --git a/apps/passbolt/docker-compose.yml b/apps/passbolt/docker-compose.yml index f7c0e7a..e92cea2 100644 --- a/apps/passbolt/docker-compose.yml +++ b/apps/passbolt/docker-compose.yml @@ -4,17 +4,21 @@ services: container_name: passbolt-db image: mariadb:12 restart: always + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: MYSQL_RANDOM_ROOT_PASSWORD: "true" - MYSQL_DATABASE: "passbolt" - MYSQL_USER: "passbolt" - MYSQL_PASSWORD: "P4ssb0lt" + MYSQL_DATABASE: ${PASSBOLT_DB_NAME} + MYSQL_USER: ${PASSBOLT_DB_USER} + MYSQL_PASSWORD_FILE: /run/secrets/passbolt_db_password + secrets: + - passbolt_db_password volumes: - ${PROJECT_ROOT}/apps/passbolt/data/database:/var/lib/mysql networks: - passbolt healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u\"$$MARIADB_USER\" -p\"$$MARIADB_PASSWORD\" --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u\"$$MYSQL_USER\" -p\"$$(cat /run/secrets/passbolt_db_password)\" --silent"] interval: 10s timeout: 5s retries: 12 @@ -22,22 +26,24 @@ services: labels: - "io.portainer.accesscontrol.public" - passbolt-webapp: image: passbolt/passbolt:latest-ce profiles: ["apps","all","passbolt"] container_name: passbolt-webapp - #Alternatively you can use rootless: restart: always depends_on: - passbolt-db + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: APP_FULL_BASE_URL: https://passbolt.lan.ddnsgeek.com DATASOURCES_DEFAULT_HOST: "passbolt-db" - DATASOURCES_DEFAULT_USERNAME: "passbolt" - DATASOURCES_DEFAULT_PASSWORD: "P4ssb0lt" - DATASOURCES_DEFAULT_DATABASE: "passbolt" + DATASOURCES_DEFAULT_USERNAME: ${PASSBOLT_DB_USER} + DATASOURCES_DEFAULT_PASSWORD_FILE: /run/secrets/passbolt_db_password + DATASOURCES_DEFAULT_DATABASE: ${PASSBOLT_DB_NAME} PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "CBBB2B8F3E9FACA114537ACB8965B750F7363586" + secrets: + - passbolt_db_password volumes: - ${PROJECT_ROOT}/apps/passbolt/data/gpg:/etc/passbolt/gpg - ${PROJECT_ROOT}/apps/passbolt/data/jwt:/etc/passbolt/jwt @@ -60,20 +66,16 @@ services: - "traefik.http.routers.passbolt.tls.certresolver=myresolver" - "io.portainer.accesscontrol.public" - "traefik.docker.network=core_traefik" - healthcheck: test: ["CMD-SHELL", "curl -fsS http://localhost/healthcheck/status | grep -qx OK"] -# su -s /bin/sh -c "/usr/share/php/passbolt/bin/cake passbolt healthcheck" www-data -# | grep -q "No error found" interval: 30s timeout: 10s retries: 6 start_period: 120s - networks: -# traefik_reverse_proxy: -# external: true -# internal: -# driver: bridge passbolt: + +secrets: + passbolt_db_password: + file: ${PROJECT_ROOT}/secrets/passbolt_db_password.txt diff --git a/core/authelia/configuration.yml b/core/authelia/configuration.yml index b27674e..8981896 100644 --- a/core/authelia/configuration.yml +++ b/core/authelia/configuration.yml @@ -3,16 +3,16 @@ server.address: tcp://0.0.0.0:9091 log: level: info -identity_validation.reset_password.jwt_secret: T72Xcxa4d7xpQRypFDZpunlZt0IjqspojmBlxBr69gnkRjzR144YgjZsgFYZK0gS +identity_validation.reset_password.jwt_secret: ${AUTHELIA_JWT_SECRET} session: - secret: BYksO7YUAJ8gXx9Endgpe46RgB10nkeKpD1qcQPt0GuYGQm2pS2zjJtNOrCEqpav + secret: ${AUTHELIA_SESSION_SECRET} cookies: - domain: lan.ddnsgeek.com authelia_url: https://auth.lan.ddnsgeek.com storage: - encryption_key: N7mkWziClgDhLgZDRkRwU6jEHmGF6ciOt53pzoFcZ0meEV1AZCC5bWZd24jeu19y + encryption_key: ${AUTHELIA_STORAGE_ENCRYPTION_KEY} local: path: /config/data/db.sqlite3 @@ -23,8 +23,6 @@ authentication_backend: access_control: default_policy: deny rules: -# - domain: "*.lan.ddnsgeek.com" -# policy: two_factor - domain: alertmanager.lan.ddnsgeek.com resources: - "^/api/.*" @@ -45,7 +43,6 @@ access_control: - "^/metrics" policy: bypass - - domain: "*.lan.ddnsgeek.com" policy: two_factor diff --git a/core/docker-compose.yml b/core/docker-compose.yml index 63eaa40..79c07e8 100644 --- a/core/docker-compose.yml +++ b/core/docker-compose.yml @@ -17,6 +17,8 @@ services: build: context: ${PROJECT_ROOT}/core + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -52,6 +54,7 @@ services: restart: always environment: - COLLECTIONS=crowdsecurity/traefik + - CROWDSEC_LAPI_KEY=${CROWDSEC_LAPI_KEY} volumes: - ${PROJECT_ROOT}/core/crowdsec/logs:/logs:ro - ${PROJECT_ROOT}/core/crowdsec/data:/var/lib/crowdsec/data @@ -99,6 +102,8 @@ services: restart: always build: context: ${PROJECT_ROOT}/core/authelia + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/core/authelia:/config networks: diff --git a/core/traefik/dynamic.yml b/core/traefik/dynamic.yml index 47f950e..e95e11f 100644 --- a/core/traefik/dynamic.yml +++ b/core/traefik/dynamic.yml @@ -4,7 +4,7 @@ http: plugin: crowdsec-bouncer: crowdsecMode: live - crowdsecLapiKey: HeneLa2mazFVzl5+DQRKOdchBuJxKdjrHsHBE/03Acs + crowdsecLapiKey: ${CROWDSEC_LAPI_KEY} crowdsecLapiHost: crowdsec:8080 crowdsecLapiScheme: http diff --git a/monitoring/gotify/docker-compose.yml b/monitoring/gotify/docker-compose.yml index bad0989..bc19268 100644 --- a/monitoring/gotify/docker-compose.yml +++ b/monitoring/gotify/docker-compose.yml @@ -4,20 +4,17 @@ services: image: gotify/server:latest container_name: gotify restart: always - + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/gotify/data:/app/data - environment: - TZ=${TZ} - - GOTIFY_DEFAULTUSER_NAME=admin - - GOTIFY_DEFAULTUSER_PASS=R1m@dmin + - GOTIFY_DEFAULTUSER_NAME=${GOTIFY_DEFAULTUSER_NAME} + - GOTIFY_DEFAULTUSER_PASS=${GOTIFY_DEFAULTUSER_PASS} - GOTIFY_REGISTRATION=false - networks: -# - traefik_reverse_proxy - traefik - labels: - "traefik.enable=true" - "traefik.docker.network=core_traefik" @@ -26,7 +23,3 @@ services: - "traefik.http.routers.gotify.entrypoints=websecure" - "traefik.http.routers.gotify.tls.certresolver=myresolver" - "traefik.http.services.gotify.loadbalancer.server.port=80" - -#networks: -# traefik_reverse_proxy: -# external: true diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index dbcfc88..de8840a 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -4,6 +4,8 @@ services: prometheus: profiles: ["monitoring","all","prometheus"] image: prom/prometheus:latest + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env container_name: prometheus depends_on: # - alertmanager @@ -22,6 +24,7 @@ services: - ${PROJECT_ROOT}/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ${PROJECT_ROOT}/monitoring/prometheus/data:/prometheus - ${PROJECT_ROOT}/monitoring/prometheus/rules:/etc/prometheus/rules:ro + - ${PROJECT_ROOT}/secrets/prometheus_kuma_basic_auth_password.txt:/run/secrets/prometheus_kuma_basic_auth_password:ro restart: unless-stopped labels: @@ -53,7 +56,7 @@ services: # volumes: # - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro # restart: unless-stopped -# networks: +# secrets: # - edge # - traefik_reverse_proxy # healthcheck: @@ -101,14 +104,18 @@ services: image: influxdb:2.7 container_name: influxdb restart: unless-stopped + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2 environment: DOCKER_INFLUXDB_INIT_MODE: setup - DOCKER_INFLUXDB_INIT_USERNAME: admin - DOCKER_INFLUXDB_INIT_PASSWORD: adminpassword - DOCKER_INFLUXDB_INIT_ORG: pbs - DOCKER_INFLUXDB_INIT_BUCKET: telemetry + DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME} + DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb_init_password + DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG} + DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_INIT_BUCKET} + secrets: + - influxdb_init_password networks: # - edge # - traefik_reverse_proxy @@ -205,9 +212,11 @@ services: profiles: ["monitoring","all","prometheus-exporters"] image: ekofr/pihole-exporter:latest container_name: pihole-exporter + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - PIHOLE_HOSTNAME: pihole.sweet.home - PIHOLE_PASSWORD: "" + PIHOLE_HOSTNAME: ${PIHOLE_HOSTNAME} + PIHOLE_PASSWORD: ${PIHOLE_PASSWORD} PORT: 9617 ports: - "9617:9617" @@ -228,3 +237,8 @@ services: # external: true + + +secrets: + influxdb_init_password: + file: ${PROJECT_ROOT}/secrets/influxdb_init_password.txt diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index 283d254..5126509 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -95,8 +95,8 @@ scrape_configs: scrape_interval: 30s basic_auth: - username: wayne.bennett@live.com - password: '4vjCco?[%{=+,t`):C' + username: ${PROMETHEUS_KUMA_BASIC_AUTH_USERNAME} + password_file: /run/secrets/prometheus_kuma_basic_auth_password static_configs: - targets: diff --git a/secrets/.env.secrets.example b/secrets/.env.secrets.example new file mode 100644 index 0000000..087ce04 --- /dev/null +++ b/secrets/.env.secrets.example @@ -0,0 +1,35 @@ +# Copy to secrets/stack-secrets.env and set real values. +# Do NOT commit secrets/stack-secrets.env. + +NEXTCLOUD_DB_NAME=nextcloud +NEXTCLOUD_DB_USER=nextcloud +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_SMTP_FROM_ADDRESS=mailuser +NEXTCLOUD_SMTP_DOMAIN=example.com +NEXTCLOUD_SMTP_NAME=mailuser@example.com + +PASSBOLT_DB_NAME=passbolt +PASSBOLT_DB_USER=passbolt + +GRAMPS_DB_NAME=gramps +GRAMPS_DB_USER=gramps +GRAMPS_DB_PASSWORD=CHANGE_ME +GRAMPS_INITIAL_ADMIN=admin +GRAMPS_INITIAL_ADMIN_PASSWORD=CHANGE_ME + +GOTIFY_DEFAULTUSER_NAME=admin +GOTIFY_DEFAULTUSER_PASS=CHANGE_ME + +INFLUXDB_INIT_USERNAME=admin +INFLUXDB_INIT_ORG=homelab +INFLUXDB_INIT_BUCKET=telemetry + +PIHOLE_HOSTNAME=pihole.example.com +PIHOLE_PASSWORD=CHANGE_ME + +PROMETHEUS_KUMA_BASIC_AUTH_USERNAME=monitoring@example.com + +AUTHELIA_JWT_SECRET=CHANGE_ME +AUTHELIA_SESSION_SECRET=CHANGE_ME +AUTHELIA_STORAGE_ENCRYPTION_KEY=CHANGE_ME +CROWDSEC_LAPI_KEY=CHANGE_ME From 3b1e0efa1928f8db5dd8ab6b6926bd6a12b1c6f0 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 19:38:51 +1000 Subject: [PATCH 6/8] modified: .gitignore modified: apps/gramps/docker-compose.yml modified: apps/nextcloud/docker-compose.yml modified: apps/passbolt/docker-compose.yml modified: core/docker-compose.yml modified: monitoring/gotify/docker-compose.yml modified: monitoring/prometheus/docker-compose.yml modified: monitoring/prometheus/prometheus.yml .env.example DEPLOYMENT.md SECURITY_SECRETS_INVENTORY.md secrets/ --- .gitignore | 4 +- apps/gramps/docker-compose.yml | 26 +++---- apps/nextcloud/docker-compose.yml | 92 +++++++++++++----------- apps/passbolt/docker-compose.yml | 44 ++++++------ core/docker-compose.yml | 7 +- monitoring/gotify/docker-compose.yml | 10 +-- monitoring/prometheus/docker-compose.yml | 24 +++++-- monitoring/prometheus/prometheus.yml | 4 +- 8 files changed, 121 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index d1efebd..4cf1b7d 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ apps/searxng/* venv/ core/authelia/users_database.yml monitoring/influxdb/* - +secrets/* +!secrets/.env.secrets.example +!.env.example diff --git a/apps/gramps/docker-compose.yml b/apps/gramps/docker-compose.yml index 65b4bc1..54c69f7 100644 --- a/apps/gramps/docker-compose.yml +++ b/apps/gramps/docker-compose.yml @@ -4,22 +4,25 @@ services: image: postgres:13 container_name: gramps-db restart: always + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - POSTGRES_USER: ${GRAMPS_POSTGRES_USER} - POSTGRES_PASSWORD: ${GRAMPS_POSTGRES_PASSWORD} - POSTGRES_DB: ${GRAMPS_POSTGRES_DB} + POSTGRES_USER: ${GRAMPS_DB_USER} + POSTGRES_PASSWORD_FILE: /run/secrets/gramps_db_password + POSTGRES_DB: ${GRAMPS_DB_NAME} + secrets: + - gramps_db_password volumes: - ${PROJECT_ROOT}/apps/gramps/db:/var/lib/postgresql networks: - gramps healthcheck: - test: ["CMD-SHELL", "pg_isready -h db -p 5432 -U gramps -d gramps"] + test: ["CMD-SHELL", "pg_isready -h gramps-db -p 5432 -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 10s timeout: 5s retries: 12 start_period: 30s - grampsweb: profiles: ["apps","all","gramps"] image: ghcr.io/gramps-project/grampsweb:latest @@ -27,8 +30,8 @@ services: depends_on: - gramps-db restart: always -# ports: -# - "5000:5000" # access via http://localhost:5000 + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: DB_URI: ${GRAMPS_DB_URI} GRAMPSWEB_LOGLEVEL: ${GRAMPSWEB_LOGLEVEL} @@ -62,10 +65,9 @@ services: retries: 6 start_period: 60s - - networks: -# traefik_reverse_proxy: -# external: true gramps: -# driver: bridge + +secrets: + gramps_db_password: + file: ${PROJECT_ROOT}/secrets/gramps_db_password.txt diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index fe7ffed..b9203ea 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -1,12 +1,13 @@ services: nextcloud-webapp: -# image: nextcloud:production profiles: ["apps","all","nextcloud"] build: context: ${PROJECT_ROOT}/apps/nextcloud container_name: nextcloud-webapp restart: always hostname: nextcloud.lan.ddnsgeek.com + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/apps/nextcloud/data:/var/www/html/data:rw - ${PROJECT_ROOT}/apps/nextcloud/config:/var/www/html/config:rw @@ -16,26 +17,28 @@ services: - nextcloud-db - nextcloud-redis environment: - - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} - - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} - - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} - - MYSQL_HOST=${NEXTCLOUD_MYSQL_HOST} - - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} - - OVERWRITEPROTOCOL=${NEXTCLOUD_OVERWRITEPROTOCOL} - - OVERWRITECLIURL=${NEXTCLOUD_OVERWRITECLIURL} - - - SMTP_HOST=${NEXTCLOUD_SMTP_HOST} - - SMTP_SECURE=${NEXTCLOUD_SMTP_SECURE} - - SMTP_PORT=${NEXTCLOUD_SMTP_PORT} - - SMTP_AUTHTYPE=${NEXTCLOUD_SMTP_AUTHTYPE} - - MAIL_FROM_ADDRESS=${NEXTCLOUD_MAIL_FROM_ADDRESS} - - MAIL_DOMAIN=${NEXTCLOUD_MAIL_DOMAIN} + - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_USER=${NEXTCLOUD_DB_USER} + - MYSQL_HOST=nextcloud_db:3306 + - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com + - OVERWRITEPROTOCOL=https + - OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com + - SMTP_HOST=smtp.gmail.com + - SMTP_SECURE=tls + - SMTP_PORT=587 + - SMTP_AUTHTYPE=login + - MAIL_FROM_ADDRESS=${NEXTCLOUD_SMTP_FROM_ADDRESS} + - MAIL_DOMAIN=${NEXTCLOUD_SMTP_DOMAIN} - SMTP_NAME=${NEXTCLOUD_SMTP_NAME} - - SMTP_PASSWORD=${NEXTCLOUD_SMTP_PASSWORD} - - - REDIS_HOST=${NEXTCLOUD_REDIS_HOST} - - REDIS_HOST_PORT=${NEXTCLOUD_REDIS_HOST_PORT} - - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} + - SMTP_PASSWORD_FILE=/run/secrets/nextcloud_smtp_password + - REDIS_HOST=redis + - REDIS_HOST_PORT=6379 + - REDIS_HOST_PASSWORD_FILE=/run/secrets/nextcloud_redis_password + secrets: + - nextcloud_db_password + - nextcloud_smtp_password + - nextcloud_redis_password networks: - traefik - nextcloud @@ -54,7 +57,6 @@ services: - "traefik.http.middlewares.nextcloud-webfinger.redirectregex.regex=https://(.*)/.well-known/webfinger" - "traefik.http.middlewares.nextcloud-webfinger.redirectregex.replacement=https://$${1}/nextcloud/index.php/.well-known/webfinger" - "traefik.docker.network=core_traefik" - healthcheck: test: - CMD-SHELL @@ -68,9 +70,6 @@ services: retries: 6 start_period: 180s - - - nextcloud-db: image: mariadb:11.4 restart: always @@ -78,36 +77,41 @@ services: container_name: nextcloud-db hostname: nextcloud_db command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/apps/nextcloud/database:/var/lib/mysql:rw environment: - - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_MYSQL_ROOT_PASSWORD} - - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} - - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} - - MYSQL_USER=${NEXTCLOUD_MYSQL_USER} - - MARIADB_AUTO_UPGRADE=${NEXTCLOUD_MARIADB_AUTO_UPGRADE} + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/nextcloud_db_root_password + - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password + - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_USER=${NEXTCLOUD_DB_USER} + - MARIADB_AUTO_UPGRADE=1 - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} + - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/nextcloud_admin_password + secrets: + - nextcloud_db_root_password + - nextcloud_db_password + - nextcloud_admin_password networks: - nextcloud labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -u ${NEXTCLOUD_MYSQL_USER} --password=${NEXTCLOUD_MYSQL_PASSWORD} --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -u $$MYSQL_USER --password=$$(cat /run/secrets/nextcloud_db_password) --silent"] interval: 10s timeout: 5s retries: 12 start_period: 60s - nextcloud-redis: image: "redis" profiles: ["apps","all","nextcloud"] - command: ["redis-server", "--requirepass", "${NEXTCLOUD_REDIS_HOST_PASSWORD}", "--appendonly", "yes", "--save", "60", "1000"] + command: ["sh", "-c", "redis-server --requirepass \"$$(cat /run/secrets/nextcloud_redis_password)\" --appendonly yes --save 60 1000"] hostname: redis container_name: nextcloud-redis - environment: - - REDIS_HOST_PASSWORD=${NEXTCLOUD_REDIS_HOST_PASSWORD} + secrets: + - nextcloud_redis_password volumes: - ${PROJECT_ROOT}/apps/nextcloud/data/redis:/data:rw restart: always @@ -116,15 +120,23 @@ services: labels: - "io.portainer.accesscontrol.public" healthcheck: - test: ["CMD-SHELL", "redis-cli -a ${NEXTCLOUD_REDIS_HOST_PASSWORD} PING | grep -q PONG"] + test: ["CMD-SHELL", "redis-cli -a \"$$(cat /run/secrets/nextcloud_redis_password)\" PING | grep -q PONG"] interval: 10s timeout: 5s retries: 6 start_period: 10s - networks: -# traefik_reverse_proxy: -# external: true nextcloud: -# driver: bridge + +secrets: + nextcloud_db_root_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_db_root_password.txt + nextcloud_db_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_db_password.txt + nextcloud_admin_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_admin_password.txt + nextcloud_smtp_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_smtp_password.txt + nextcloud_redis_password: + file: ${PROJECT_ROOT}/secrets/nextcloud_redis_password.txt diff --git a/apps/passbolt/docker-compose.yml b/apps/passbolt/docker-compose.yml index a0bcc89..e92cea2 100644 --- a/apps/passbolt/docker-compose.yml +++ b/apps/passbolt/docker-compose.yml @@ -4,17 +4,21 @@ services: container_name: passbolt-db image: mariadb:12 restart: always + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - MYSQL_RANDOM_ROOT_PASSWORD: "${PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD}" - MYSQL_DATABASE: "${PASSBOLT_MYSQL_DATABASE}" - MYSQL_USER: "${PASSBOLT_MYSQL_USER}" - MYSQL_PASSWORD: "${PASSBOLT_MYSQL_PASSWORD}" + MYSQL_RANDOM_ROOT_PASSWORD: "true" + MYSQL_DATABASE: ${PASSBOLT_DB_NAME} + MYSQL_USER: ${PASSBOLT_DB_USER} + MYSQL_PASSWORD_FILE: /run/secrets/passbolt_db_password + secrets: + - passbolt_db_password volumes: - ${PROJECT_ROOT}/apps/passbolt/data/database:/var/lib/mysql networks: - passbolt healthcheck: - test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u\"$$MARIADB_USER\" -p\"$$MARIADB_PASSWORD\" --silent"] + test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u\"$$MYSQL_USER\" -p\"$$(cat /run/secrets/passbolt_db_password)\" --silent"] interval: 10s timeout: 5s retries: 12 @@ -22,22 +26,24 @@ services: labels: - "io.portainer.accesscontrol.public" - passbolt-webapp: image: passbolt/passbolt:latest-ce profiles: ["apps","all","passbolt"] container_name: passbolt-webapp - #Alternatively you can use rootless: restart: always depends_on: - passbolt-db + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - APP_FULL_BASE_URL: ${PASSBOLT_APP_FULL_BASE_URL} - DATASOURCES_DEFAULT_HOST: "${PASSBOLT_DATASOURCES_DEFAULT_HOST}" - DATASOURCES_DEFAULT_USERNAME: "${PASSBOLT_DATASOURCES_DEFAULT_USERNAME}" - DATASOURCES_DEFAULT_PASSWORD: "${PASSBOLT_DATASOURCES_DEFAULT_PASSWORD}" - DATASOURCES_DEFAULT_DATABASE: "${PASSBOLT_DATASOURCES_DEFAULT_DATABASE}" - PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT}" + APP_FULL_BASE_URL: https://passbolt.lan.ddnsgeek.com + DATASOURCES_DEFAULT_HOST: "passbolt-db" + DATASOURCES_DEFAULT_USERNAME: ${PASSBOLT_DB_USER} + DATASOURCES_DEFAULT_PASSWORD_FILE: /run/secrets/passbolt_db_password + DATASOURCES_DEFAULT_DATABASE: ${PASSBOLT_DB_NAME} + PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "CBBB2B8F3E9FACA114537ACB8965B750F7363586" + secrets: + - passbolt_db_password volumes: - ${PROJECT_ROOT}/apps/passbolt/data/gpg:/etc/passbolt/gpg - ${PROJECT_ROOT}/apps/passbolt/data/jwt:/etc/passbolt/jwt @@ -60,20 +66,16 @@ services: - "traefik.http.routers.passbolt.tls.certresolver=myresolver" - "io.portainer.accesscontrol.public" - "traefik.docker.network=core_traefik" - healthcheck: test: ["CMD-SHELL", "curl -fsS http://localhost/healthcheck/status | grep -qx OK"] -# su -s /bin/sh -c "/usr/share/php/passbolt/bin/cake passbolt healthcheck" www-data -# | grep -q "No error found" interval: 30s timeout: 10s retries: 6 start_period: 120s - networks: -# traefik_reverse_proxy: -# external: true -# internal: -# driver: bridge passbolt: + +secrets: + passbolt_db_password: + file: ${PROJECT_ROOT}/secrets/passbolt_db_password.txt diff --git a/core/docker-compose.yml b/core/docker-compose.yml index 145ae00..fad817e 100644 --- a/core/docker-compose.yml +++ b/core/docker-compose.yml @@ -17,6 +17,8 @@ services: build: context: ${PROJECT_ROOT}/core + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -51,7 +53,8 @@ services: container_name: crowdsec restart: always environment: - - COLLECTIONS=${CROWDSEC_COLLECTIONS} + - COLLECTIONS=crowdsecurity/traefik + - CROWDSEC_LAPI_KEY=${CROWDSEC_LAPI_KEY} volumes: - ${PROJECT_ROOT}/core/crowdsec/logs:/logs:ro - ${PROJECT_ROOT}/core/crowdsec/data:/var/lib/crowdsec/data @@ -99,6 +102,8 @@ services: restart: always build: context: ${PROJECT_ROOT}/core/authelia + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/core/authelia:/config networks: diff --git a/monitoring/gotify/docker-compose.yml b/monitoring/gotify/docker-compose.yml index e8927ed..ebaee66 100644 --- a/monitoring/gotify/docker-compose.yml +++ b/monitoring/gotify/docker-compose.yml @@ -4,10 +4,10 @@ services: image: gotify/server:latest container_name: gotify restart: always - + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/gotify/data:/app/data - environment: - TZ=${TZ} - GOTIFY_DEFAULTUSER_NAME=${GOTIFY_DEFAULTUSER_NAME} @@ -15,9 +15,7 @@ services: - GOTIFY_REGISTRATION=${GOTIFY_REGISTRATION} networks: -# - traefik_reverse_proxy - traefik - labels: - "traefik.enable=true" - "traefik.docker.network=core_traefik" @@ -26,7 +24,3 @@ services: - "traefik.http.routers.gotify.entrypoints=websecure" - "traefik.http.routers.gotify.tls.certresolver=myresolver" - "traefik.http.services.gotify.loadbalancer.server.port=80" - -#networks: -# traefik_reverse_proxy: -# external: true diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index d54f917..f95401e 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -4,6 +4,8 @@ services: prometheus: profiles: ["monitoring","all","prometheus"] image: prom/prometheus:latest + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env container_name: prometheus depends_on: # - alertmanager @@ -22,6 +24,7 @@ services: - ${PROJECT_ROOT}/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ${PROJECT_ROOT}/monitoring/prometheus/data:/prometheus - ${PROJECT_ROOT}/monitoring/prometheus/rules:/etc/prometheus/rules:ro + - ${PROJECT_ROOT}/secrets/prometheus_kuma_basic_auth_password.txt:/run/secrets/prometheus_kuma_basic_auth_password:ro restart: unless-stopped labels: @@ -53,7 +56,7 @@ services: # volumes: # - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro # restart: unless-stopped -# networks: +# secrets: # - edge # - traefik_reverse_proxy # healthcheck: @@ -101,14 +104,18 @@ services: image: influxdb:2.7 container_name: influxdb restart: unless-stopped + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE: ${INFLUXDB_INIT_MODE} + DOCKER_INFLUXDB_INIT_MODE: setup DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME} - DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_INIT_PASSWORD} + DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb_init_password DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG} DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_INIT_BUCKET} + secrets: + - influxdb_init_password networks: # - edge # - traefik_reverse_proxy @@ -205,10 +212,12 @@ services: profiles: ["monitoring","all","prometheus-exporters"] image: ekofr/pihole-exporter:latest container_name: pihole-exporter + env_file: + - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: PIHOLE_HOSTNAME: ${PIHOLE_HOSTNAME} - PIHOLE_PASSWORD: "${PIHOLE_PASSWORD}" - PORT: ${PIHOLE_EXPORTER_PORT} + PIHOLE_PASSWORD: ${PIHOLE_PASSWORD} + PORT: 9617 ports: - "9617:9617" restart: unless-stopped @@ -228,3 +237,8 @@ services: # external: true + + +secrets: + influxdb_init_password: + file: ${PROJECT_ROOT}/secrets/influxdb_init_password.txt diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index 00ff587..d4db4d4 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -96,8 +96,8 @@ scrape_configs: scrape_interval: 30s basic_auth: - username: wayne.bennett@live.com - password: '4vjCco?[%{=+,t`):C' + username: ${PROMETHEUS_KUMA_BASIC_AUTH_USERNAME} + password_file: /run/secrets/prometheus_kuma_basic_auth_password static_configs: - targets: From 8bed8fdcb2f7baf965cc63a77900fd0a68ec7d4b Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 19:39:48 +1000 Subject: [PATCH 7/8] new file: .env.example new file: DEPLOYMENT.md new file: SECURITY_SECRETS_INVENTORY.md new file: secrets/.env.secrets.example --- .env.example | 9 +++++++ DEPLOYMENT.md | 49 +++++++++++++++++++++++++++++++++++ SECURITY_SECRETS_INVENTORY.md | 31 ++++++++++++++++++++++ secrets/.env.secrets.example | 35 +++++++++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 .env.example create mode 100644 DEPLOYMENT.md create mode 100644 SECURITY_SECRETS_INVENTORY.md create mode 100644 secrets/.env.secrets.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9232eaf --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# Copy this file to default-environment.env (non-secret defaults) and update values. +PROJECT_ROOT=/path/to/docker +DOMAIN=example.com +TZ=Etc/UTC +EMAIL=admin@example.com + +# Required secret file path used by compose services. +# Create this file from secrets/.env.secrets.example and keep it out of git. +SECRETS_ENV_FILE=${PROJECT_ROOT}/secrets/stack-secrets.env diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..7f2e1e0 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,49 @@ +# Deployment prerequisites (required) + +Before running `docker compose up`, you **must** provision runtime secrets. + +## 1) Create non-committed secret files + +```bash +cp secrets/.env.secrets.example secrets/stack-secrets.env +chmod 600 secrets/stack-secrets.env +``` + +Create these Docker secret files (all ignored by git): + +- `secrets/nextcloud_db_root_password.txt` +- `secrets/nextcloud_db_password.txt` +- `secrets/nextcloud_admin_password.txt` +- `secrets/nextcloud_smtp_password.txt` +- `secrets/nextcloud_redis_password.txt` +- `secrets/passbolt_db_password.txt` +- `secrets/gramps_db_password.txt` +- `secrets/influxdb_init_password.txt` +- `secrets/prometheus_kuma_basic_auth_password.txt` + +Recommended permissions: + +```bash +chmod 600 secrets/*.txt +``` + +## 2) Rotate previously committed credentials + +These values were previously hardcoded and must be rotated in upstream systems immediately: + +- Database credentials (Nextcloud, Passbolt, Gramps, InfluxDB). +- Nextcloud SMTP app password. +- Authelia reset JWT secret, session secret, storage encryption key. +- Traefik CrowdSec LAPI key. +- Gotify admin password. +- Prometheus Uptime Kuma basic-auth password. + +## 3) Start stack + +After secrets are provisioned: + +```bash +docker compose -f core/docker-compose.yml up -d +docker compose -f monitoring/prometheus/docker-compose.yml up -d +docker compose -f apps/nextcloud/docker-compose.yml up -d +``` diff --git a/SECURITY_SECRETS_INVENTORY.md b/SECURITY_SECRETS_INVENTORY.md new file mode 100644 index 0000000..3f06a34 --- /dev/null +++ b/SECURITY_SECRETS_INVENTORY.md @@ -0,0 +1,31 @@ +# Credential Inventory (apps/, core/, monitoring/) + +## apps/ +- `apps/nextcloud/docker-compose.yml` + - `MYSQL_PASSWORD` (nextcloud-webapp) -> `MYSQL_PASSWORD_FILE` + Docker secret. + - `SMTP_PASSWORD` -> `SMTP_PASSWORD_FILE` + Docker secret. + - `REDIS_HOST_PASSWORD` -> `REDIS_HOST_PASSWORD_FILE` + Docker secret. + - `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD`, `NEXTCLOUD_ADMIN_PASSWORD` (nextcloud-db) -> `_FILE` variants + Docker secrets. + - Redis `--requirepass` inline value -> read from Docker secret at runtime. +- `apps/passbolt/docker-compose.yml` + - `MYSQL_PASSWORD`, `DATASOURCES_DEFAULT_PASSWORD` -> `_FILE` variants + Docker secret. +- `apps/gramps/docker-compose.yml` + - `POSTGRES_PASSWORD` -> `POSTGRES_PASSWORD_FILE` + Docker secret. + - `DB_URI` password + `INITIAL_ADMIN_PASSWORD` -> env references from non-committed secrets env file. + +## core/ +- `core/authelia/configuration.yml` + - `identity_validation.reset_password.jwt_secret` -> `${AUTHELIA_JWT_SECRET}`. + - `session.secret` -> `${AUTHELIA_SESSION_SECRET}`. + - `storage.encryption_key` -> `${AUTHELIA_STORAGE_ENCRYPTION_KEY}`. +- `core/traefik/dynamic.yml` + - `crowdsecLapiKey` -> `${CROWDSEC_LAPI_KEY}`. + +## monitoring/ +- `monitoring/gotify/docker-compose.yml` + - `GOTIFY_DEFAULTUSER_PASS` -> `${GOTIFY_DEFAULTUSER_PASS}` from non-committed secrets env file. +- `monitoring/prometheus/docker-compose.yml` + - `DOCKER_INFLUXDB_INIT_PASSWORD` -> `DOCKER_INFLUXDB_INIT_PASSWORD_FILE` + Docker secret. + - `PIHOLE_PASSWORD` -> `${PIHOLE_PASSWORD}` from non-committed secrets env file. +- `monitoring/prometheus/prometheus.yml` + - Uptime Kuma basic_auth `password` -> `password_file` mounted from non-committed secret file. diff --git a/secrets/.env.secrets.example b/secrets/.env.secrets.example new file mode 100644 index 0000000..087ce04 --- /dev/null +++ b/secrets/.env.secrets.example @@ -0,0 +1,35 @@ +# Copy to secrets/stack-secrets.env and set real values. +# Do NOT commit secrets/stack-secrets.env. + +NEXTCLOUD_DB_NAME=nextcloud +NEXTCLOUD_DB_USER=nextcloud +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_SMTP_FROM_ADDRESS=mailuser +NEXTCLOUD_SMTP_DOMAIN=example.com +NEXTCLOUD_SMTP_NAME=mailuser@example.com + +PASSBOLT_DB_NAME=passbolt +PASSBOLT_DB_USER=passbolt + +GRAMPS_DB_NAME=gramps +GRAMPS_DB_USER=gramps +GRAMPS_DB_PASSWORD=CHANGE_ME +GRAMPS_INITIAL_ADMIN=admin +GRAMPS_INITIAL_ADMIN_PASSWORD=CHANGE_ME + +GOTIFY_DEFAULTUSER_NAME=admin +GOTIFY_DEFAULTUSER_PASS=CHANGE_ME + +INFLUXDB_INIT_USERNAME=admin +INFLUXDB_INIT_ORG=homelab +INFLUXDB_INIT_BUCKET=telemetry + +PIHOLE_HOSTNAME=pihole.example.com +PIHOLE_PASSWORD=CHANGE_ME + +PROMETHEUS_KUMA_BASIC_AUTH_USERNAME=monitoring@example.com + +AUTHELIA_JWT_SECRET=CHANGE_ME +AUTHELIA_SESSION_SECRET=CHANGE_ME +AUTHELIA_STORAGE_ENCRYPTION_KEY=CHANGE_ME +CROWDSEC_LAPI_KEY=CHANGE_ME From f221b12f8d8e7761a8814ed28eb70ed959f1d054 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 21:57:22 +1000 Subject: [PATCH 8/8] modified: apps/gramps/docker-compose.yml modified: apps/nextcloud/docker-compose.yml modified: apps/passbolt/docker-compose.yml modified: core/authelia/configuration.yml modified: core/docker-compose.yml modified: default-environment.env modified: monitoring/gotify/docker-compose.yml modified: monitoring/prometheus/docker-compose.yml modified: monitoring/prometheus/prometheus.yml modified: services-up.sh --- apps/gramps/docker-compose.yml | 4 +-- apps/nextcloud/docker-compose.yml | 38 ++++++++++++------------ apps/passbolt/docker-compose.yml | 16 +++++----- core/authelia/configuration.yml | 6 ++-- core/docker-compose.yml | 14 +++++---- default-environment.env | 33 +++----------------- monitoring/gotify/docker-compose.yml | 4 +-- monitoring/prometheus/docker-compose.yml | 18 +++++------ monitoring/prometheus/prometheus.yml | 4 +-- services-up.sh | 3 +- 10 files changed, 60 insertions(+), 80 deletions(-) diff --git a/apps/gramps/docker-compose.yml b/apps/gramps/docker-compose.yml index 54c69f7..8064fac 100644 --- a/apps/gramps/docker-compose.yml +++ b/apps/gramps/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: gramps-db restart: always env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env + - ${SECRETS_ENV_FILE} environment: POSTGRES_USER: ${GRAMPS_DB_USER} POSTGRES_PASSWORD_FILE: /run/secrets/gramps_db_password @@ -31,7 +31,7 @@ services: - gramps-db restart: always env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env + - ${SECRETS_ENV_FILE} environment: DB_URI: ${GRAMPS_DB_URI} GRAMPSWEB_LOGLEVEL: ${GRAMPSWEB_LOGLEVEL} diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index b9203ea..5c98a83 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -5,9 +5,9 @@ services: context: ${PROJECT_ROOT}/apps/nextcloud container_name: nextcloud-webapp restart: always - hostname: nextcloud.lan.ddnsgeek.com - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env + hostname: ${NEXTCLOUD_TRUSTED_DOMAINS} +# env_file: +# - ${SECRETS_ENV_FILE} volumes: - ${PROJECT_ROOT}/apps/nextcloud/data:/var/www/html/data:rw - ${PROJECT_ROOT}/apps/nextcloud/config:/var/www/html/config:rw @@ -18,22 +18,22 @@ services: - nextcloud-redis environment: - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password - - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} - MYSQL_USER=${NEXTCLOUD_DB_USER} - - MYSQL_HOST=nextcloud_db:3306 - - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com - - OVERWRITEPROTOCOL=https - - OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com - - SMTP_HOST=smtp.gmail.com - - SMTP_SECURE=tls - - SMTP_PORT=587 - - SMTP_AUTHTYPE=login + - MYSQL_HOST=${NEXTCLOUD_MYSQL_HOST} + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} + - OVERWRITEPROTOCOL=${NEXTCLOUD_OVERWRITEPROTOCOL} + - OVERWRITECLIURL=${NEXTCLOUD_OVERWRITECLIURL} + - SMTP_HOST=${NEXTCLOUD_SMTP_HOST} + - SMTP_SECURE=${NEXTCLOUD_SMTP_SECURE} + - SMTP_PORT=${NEXTCLOUD_SMTP_PORT} + - SMTP_AUTHTYPE=${NEXTCLOUD_SMTP_AUTHTYPE} - MAIL_FROM_ADDRESS=${NEXTCLOUD_SMTP_FROM_ADDRESS} - MAIL_DOMAIN=${NEXTCLOUD_SMTP_DOMAIN} - SMTP_NAME=${NEXTCLOUD_SMTP_NAME} - SMTP_PASSWORD_FILE=/run/secrets/nextcloud_smtp_password - - REDIS_HOST=redis - - REDIS_HOST_PORT=6379 + - REDIS_HOST=${NEXTCLOUD_REDIS_HOST} + - REDIS_HOST_PORT=${NEXTCLOUD_REDIS_HOST_PORT} - REDIS_HOST_PASSWORD_FILE=/run/secrets/nextcloud_redis_password secrets: - nextcloud_db_password @@ -43,7 +43,7 @@ services: - traefik - nextcloud labels: - - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.lan.ddnsgeek.com`)" + - "traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_TRUSTED_DOMAINS}`)" - "traefik.enable=true" - "traefik.http.routers.nextcloud.entrypoints=websecure" - "traefik.http.routers.nextcloud.tls.certresolver=myresolver" @@ -77,16 +77,16 @@ services: container_name: nextcloud-db hostname: nextcloud_db command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/apps/nextcloud/database:/var/lib/mysql:rw environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/nextcloud_db_root_password - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_password - - MYSQL_DATABASE=${NEXTCLOUD_DB_NAME} + - MYSQL_DATABASE=${NEXTCLOUD_MYSQL_DATABASE} - MYSQL_USER=${NEXTCLOUD_DB_USER} - - MARIADB_AUTO_UPGRADE=1 + - MARIADB_AUTO_UPGRADE=${NEXTCLOUD_MARIADB_AUTO_UPGRADE} - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/nextcloud_admin_password secrets: diff --git a/apps/passbolt/docker-compose.yml b/apps/passbolt/docker-compose.yml index e92cea2..a42c38a 100644 --- a/apps/passbolt/docker-compose.yml +++ b/apps/passbolt/docker-compose.yml @@ -4,10 +4,10 @@ services: container_name: passbolt-db image: mariadb:12 restart: always - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - MYSQL_RANDOM_ROOT_PASSWORD: "true" + MYSQL_RANDOM_ROOT_PASSWORD: ${PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD} MYSQL_DATABASE: ${PASSBOLT_DB_NAME} MYSQL_USER: ${PASSBOLT_DB_USER} MYSQL_PASSWORD_FILE: /run/secrets/passbolt_db_password @@ -33,15 +33,15 @@ services: restart: always depends_on: - passbolt-db - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: - APP_FULL_BASE_URL: https://passbolt.lan.ddnsgeek.com - DATASOURCES_DEFAULT_HOST: "passbolt-db" + APP_FULL_BASE_URL: ${PASSBOLT_APP_FULL_BASE_URL} + DATASOURCES_DEFAULT_HOST: ${PASSBOLT_DATASOURCES_DEFAULT_HOST} DATASOURCES_DEFAULT_USERNAME: ${PASSBOLT_DB_USER} DATASOURCES_DEFAULT_PASSWORD_FILE: /run/secrets/passbolt_db_password DATASOURCES_DEFAULT_DATABASE: ${PASSBOLT_DB_NAME} - PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "CBBB2B8F3E9FACA114537ACB8965B750F7363586" + PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: ${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT} secrets: - passbolt_db_password volumes: diff --git a/core/authelia/configuration.yml b/core/authelia/configuration.yml index 6212d20..57b30fd 100644 --- a/core/authelia/configuration.yml +++ b/core/authelia/configuration.yml @@ -3,16 +3,16 @@ server.address: tcp://0.0.0.0:9091 log: level: info -identity_validation.reset_password.jwt_secret: ${AUTHELIA_JWT_SECRET} +identity_validation.reset_password.jwt_secret: T72Xcxa4d7xpQRypFDZpunlZt0IjqspojmBlxBr69gnkRjzR144YgjZsgFYZK0gS session: - secret: ${AUTHELIA_SESSION_SECRET} + secret: BYksO7YUAJ8gXx9Endgpe46RgB10nkeKpD1qcQPt0GuYGQm2pS2zjJtNOrCEqpav cookies: - domain: lan.ddnsgeek.com authelia_url: https://auth.lan.ddnsgeek.com storage: - encryption_key: ${AUTHELIA_STORAGE_ENCRYPTION_KEY} + encryption_key: N7mkWziClgDhLgZDRkRwU6jEHmGF6ciOt53pzoFcZ0meEV1AZCC5bWZd24jeu19y local: path: /config/data/db.sqlite3 diff --git a/core/docker-compose.yml b/core/docker-compose.yml index fad817e..087ac58 100644 --- a/core/docker-compose.yml +++ b/core/docker-compose.yml @@ -17,8 +17,8 @@ services: build: context: ${PROJECT_ROOT}/core - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env + # env_file: + # - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -54,7 +54,7 @@ services: restart: always environment: - COLLECTIONS=crowdsecurity/traefik - - CROWDSEC_LAPI_KEY=${CROWDSEC_LAPI_KEY} +# - CROWDSEC_LAPI_KEY=${CROWDSEC_LAPI_KEY} volumes: - ${PROJECT_ROOT}/core/crowdsec/logs:/logs:ro - ${PROJECT_ROOT}/core/crowdsec/data:/var/lib/crowdsec/data @@ -102,8 +102,12 @@ services: restart: always build: context: ${PROJECT_ROOT}/core/authelia - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env +# environment: +# - AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET:${AUTHELIA_JWT_SECRET} +# - AUTHELIA_SESSION_SECRET:${AUTHELIA_SESSION_SECRET} +# - AUTHELIA_STORAGE_ENCRYPTION_KEY:${AUTHELIA_STORAGE_ENCRYPTION_KEY} volumes: - ${PROJECT_ROOT}/core/authelia:/config networks: diff --git a/default-environment.env b/default-environment.env index e4f10ca..f92003d 100644 --- a/default-environment.env +++ b/default-environment.env @@ -2,6 +2,7 @@ PROJECT_ROOT=/home/nixos/docker DOMAIN=lan.ddnsgeek.com TZ=Australia/Brisbane EMAIL=wayne.bennett@live.com +SECRETS_ENV_FILE=${PROJECT_ROOT}/secrets/stack-secrets.env # Core CROWDSEC_COLLECTIONS=crowdsecurity/traefik @@ -17,69 +18,43 @@ GITEA_ROOT_URL=https://gitea.lan.ddnsgeek.com/ GRAFANA_ROOT_URL=https://grafana.lan.ddnsgeek.com/ # Nextcloud -NEXTCLOUD_MYSQL_ROOT_PASSWORD=R1m@dmin -NEXTCLOUD_MYSQL_PASSWORD=R1m@dmin NEXTCLOUD_MYSQL_DATABASE=nextcloud -NEXTCLOUD_MYSQL_USER=nextcloud NEXTCLOUD_MYSQL_HOST=nextcloud_db:3306 NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.lan.ddnsgeek.com NEXTCLOUD_OVERWRITEPROTOCOL=https -NEXTCLOUD_OVERWRITECLIURL=https://nextcloud.lan.ddnsgeek.com +NEXTCLOUD_OVERWRITECLIURL=https://${NEXTCLOUD_TRUSTED_DOMAINS} NEXTCLOUD_SMTP_HOST=smtp.gmail.com NEXTCLOUD_SMTP_SECURE=tls NEXTCLOUD_SMTP_PORT=587 NEXTCLOUD_SMTP_AUTHTYPE=login -NEXTCLOUD_MAIL_FROM_ADDRESS=beatz174 -NEXTCLOUD_MAIL_DOMAIN=gmail.com -NEXTCLOUD_SMTP_NAME=beatz174@gmail.com -NEXTCLOUD_SMTP_PASSWORD=kqdw fvml wlag ldgv NEXTCLOUD_REDIS_HOST=redis NEXTCLOUD_REDIS_HOST_PORT=6379 -NEXTCLOUD_REDIS_HOST_PASSWORD=TzBF8wcJNmVd9p2CTmBejPS9dpye6kWQeH3DmrQS9TPfTRriSHFN5VqH4CgzcuVZYWH2GBb7QU5GuEpNDGYdKjM6hjmLyjSgCFMiPms3Hv9n NEXTCLOUD_MARIADB_AUTO_UPGRADE=1 -NEXTCLOUD_ADMIN_USER=admin -NEXTCLOUD_ADMIN_PASSWORD=R1m@dmin # Passbolt PASSBOLT_MYSQL_RANDOM_ROOT_PASSWORD=true PASSBOLT_MYSQL_DATABASE=passbolt PASSBOLT_MYSQL_USER=passbolt -PASSBOLT_MYSQL_PASSWORD=P4ssb0lt PASSBOLT_APP_FULL_BASE_URL=https://passbolt.lan.ddnsgeek.com PASSBOLT_DATASOURCES_DEFAULT_HOST=passbolt-db -PASSBOLT_DATASOURCES_DEFAULT_USERNAME=passbolt -PASSBOLT_DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt -PASSBOLT_DATASOURCES_DEFAULT_DATABASE=passbolt -PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=CBBB2B8F3E9FACA114537ACB8965B750F7363586 # Gramps -GRAMPS_POSTGRES_USER=gramps -GRAMPS_POSTGRES_PASSWORD=grampspassword -GRAMPS_POSTGRES_DB=gramps -GRAMPS_DB_URI=postgresql://gramps:grampspassword@db:5432/gramps GRAMPSWEB_LOGLEVEL=INFO -GRAMPS_INITIAL_ADMIN=admin -GRAMPS_INITIAL_ADMIN_PASSWORD=admin GRAMPSWEB_MEDIAPATH=/app/media GRAMPSWEB_TREE=main # Prometheus stack INFLUXDB_INIT_MODE=setup -INFLUXDB_INIT_USERNAME=admin -INFLUXDB_INIT_PASSWORD=adminpassword INFLUXDB_INIT_ORG=pbs INFLUXDB_INIT_BUCKET=telemetry + DOCKER_EXPORTER_LOG_LEVEL=INFO + PIHOLE_HOSTNAME=pihole.sweet.home -PIHOLE_PASSWORD= PIHOLE_EXPORTER_PORT=9617 # Gotify -GOTIFY_DEFAULTUSER_NAME=admin -GOTIFY_DEFAULTUSER_PASS=R1m@dmin GOTIFY_REGISTRATION=false -#GOTIFY_URL=https://gotify.lan.ddnsgeek.com -#GOTIFY_TOKEN=ADuOnDBG7C27hcf # Portainer PORTAINER_GODEBUG=netdns=cgo diff --git a/monitoring/gotify/docker-compose.yml b/monitoring/gotify/docker-compose.yml index ebaee66..1ff0517 100644 --- a/monitoring/gotify/docker-compose.yml +++ b/monitoring/gotify/docker-compose.yml @@ -4,8 +4,8 @@ services: image: gotify/server:latest container_name: gotify restart: always - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/gotify/data:/app/data environment: diff --git a/monitoring/prometheus/docker-compose.yml b/monitoring/prometheus/docker-compose.yml index f95401e..a4b1a1f 100644 --- a/monitoring/prometheus/docker-compose.yml +++ b/monitoring/prometheus/docker-compose.yml @@ -4,8 +4,8 @@ services: prometheus: profiles: ["monitoring","all","prometheus"] image: prom/prometheus:latest - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env container_name: prometheus depends_on: # - alertmanager @@ -104,12 +104,12 @@ services: image: influxdb:2.7 container_name: influxdb restart: unless-stopped - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env volumes: - ${PROJECT_ROOT}/monitoring/influxdb:/var/lib/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_MODE: ${INFLUXDB_INIT_MODE} DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_INIT_USERNAME} DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb_init_password DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_INIT_ORG} @@ -212,14 +212,14 @@ services: profiles: ["monitoring","all","prometheus-exporters"] image: ekofr/pihole-exporter:latest container_name: pihole-exporter - env_file: - - ${PROJECT_ROOT}/secrets/stack-secrets.env +# env_file: +# - ${PROJECT_ROOT}/secrets/stack-secrets.env environment: PIHOLE_HOSTNAME: ${PIHOLE_HOSTNAME} PIHOLE_PASSWORD: ${PIHOLE_PASSWORD} - PORT: 9617 + PORT: ${PIHOLE_EXPORTER_PORT} ports: - - "9617:9617" + - "${PIHOLE_EXPORTER_PORT}:${PIHOLE_EXPORTER_PORT}" restart: unless-stopped networks: # - edge diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index d4db4d4..c769360 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -96,9 +96,9 @@ scrape_configs: scrape_interval: 30s basic_auth: - username: ${PROMETHEUS_KUMA_BASIC_AUTH_USERNAME} + username: wayne.bennett@live.com password_file: /run/secrets/prometheus_kuma_basic_auth_password - +# password: '4vjCco?[%{=+,t`):C' static_configs: - targets: - monitor-kuma:3001 diff --git a/services-up.sh b/services-up.sh index dd9b591..789acb7 100755 --- a/services-up.sh +++ b/services-up.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash ENV="default-environment.env" +SECRETS="secrets/stack-secrets.env" PROJECT="core" FILES=( -f default-network.yml @@ -21,4 +22,4 @@ FILES=( -f core/test/docker-compose.yml ) -docker compose -p $PROJECT --env-file $ENV "${FILES[@]}" $1 $2 $3 $4 $5 $6 $7 $8 $9 +docker compose -p $PROJECT --env-file $ENV --env-file $SECRETS "${FILES[@]}" $1 $2 $3 $4 $5 $6 $7 $8 $9