From 8bed8fdcb2f7baf965cc63a77900fd0a68ec7d4b Mon Sep 17 00:00:00 2001 From: git Date: Tue, 7 Apr 2026 19:39:48 +1000 Subject: [PATCH] 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