From a64aab79b987867addf799be243e5e6c83b88654 Mon Sep 17 00:00:00 2001 From: Jacob Nelson Date: Sun, 17 May 2026 20:34:05 -0500 Subject: [PATCH] Add Firefly III compose stack with k8s migration scaffold PostgreSQL 16, Redis 7, Firefly III core + data importer, cron container. Health checks on all services. .env.example documents all variables. k8s/ directory scaffolded for future migration. Co-Authored-By: Claude Sonnet 4.6 --- .env.example | 48 ++++++++++++++++++++++++++ .gitignore | 2 ++ docker-compose.yml | 85 ++++++++++++++++++++++++++++++++++++++++++++++ k8s/README.md | 36 ++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 docker-compose.yml create mode 100644 k8s/README.md diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3560c6c --- /dev/null +++ b/.env.example @@ -0,0 +1,48 @@ +# ------------------------------------------------------- +# Firefly III — environment configuration +# Copy to .env and fill in values before starting. +# ------------------------------------------------------- + +# --- App --- +APP_ENV=production +APP_DEBUG=false +APP_KEY=base64:REPLACE_WITH_GENERATED_KEY +APP_URL=https://firefly.jbnel.dev +TRUSTED_PROXIES=** + +# --- Database (PostgreSQL) --- +DB_CONNECTION=pgsql +DB_HOST=db +DB_PORT=5432 +DB_DATABASE=firefly +DB_USERNAME=firefly +DB_PASSWORD=REPLACE_WITH_STRONG_PASSWORD + +# Required by the postgres container +POSTGRES_DB=firefly +POSTGRES_USER=firefly +POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD + +# --- Redis --- +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD=REPLACE_WITH_STRONG_PASSWORD + +# --- Cache / Sessions --- +CACHE_DRIVER=redis +SESSION_DRIVER=redis + +# --- Mail (optional) --- +MAIL_MAILER=log +MAIL_HOST= +MAIL_PORT= +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION= +MAIL_FROM=firefly@jbnel.dev + +# --- Data Importer --- +# Set after Firefly III is running and you've created a Personal Access Token +FIREFLY_III_URL=http://app:8080 +VANITY_URL=https://import.jbnel.dev +FIREFLY_III_ACCESS_TOKEN=REPLACE_AFTER_FIRST_RUN diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2334d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +*.log diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7d71b73 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,85 @@ +services: + + app: + image: fireflyiii/core:latest + restart: unless-stopped + env_file: .env + volumes: + - firefly_upload:/var/www/html/storage/upload + networks: + - firefly + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + cron: + image: fireflyiii/core:latest + restart: unless-stopped + env_file: .env + command: sh -c "sleep 60 && php /var/www/html/artisan firefly-iii:cron" + entrypoint: /bin/sh + networks: + - firefly + depends_on: + - app + + importer: + image: fireflyiii/data-importer:latest + restart: unless-stopped + env_file: .env + networks: + - firefly + depends_on: + app: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + db: + image: postgres:16-alpine + restart: unless-stopped + env_file: .env + volumes: + - firefly_db:/var/lib/postgresql/data + networks: + - firefly + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD} + volumes: + - firefly_redis:/data + networks: + - firefly + healthcheck: + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + firefly_upload: + firefly_db: + firefly_redis: + +networks: + firefly: + driver: bridge diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 0000000..ab11a5b --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,36 @@ +# Kubernetes Manifests + +Placeholder for k8s migration. Planned structure: + +``` +k8s/ +├── namespace.yaml +├── secrets/ +│ └── firefly-secrets.yaml # APP_KEY, DB_PASSWORD, REDIS_PASSWORD +├── configmaps/ +│ └── firefly-config.yaml # APP_URL, DB_HOST, CACHE_DRIVER, etc. +├── postgres/ +│ ├── pvc.yaml +│ ├── deployment.yaml +│ └── service.yaml +├── redis/ +│ ├── pvc.yaml +│ ├── deployment.yaml +│ └── service.yaml +├── firefly/ +│ ├── pvc.yaml # upload storage +│ ├── deployment.yaml +│ ├── service.yaml +│ └── ingress.yaml +└── importer/ + ├── deployment.yaml + ├── service.yaml + └── ingress.yaml +``` + +## Migration notes + +- `docker-compose.yml` env vars split into Secrets (passwords, APP_KEY) and ConfigMaps (URLs, driver settings) +- Named volumes → PersistentVolumeClaims +- Health checks → liveness/readiness probes (already defined in compose) +- The `firefly` bridge network → k8s Services with DNS names matching compose service names