Create .env.example and DEPLOYMENT.md for production onboarding #139

Open
opened 2026-03-28 08:53:06 +01:00 by marcel · 1 comment
Owner

Why

There is no .env.example at the repo root and no deployment documentation. This means:

  • A new operator (or future-you after 6 months) has no way to know which environment variables are required, what format they take, or what values are safe vs. secret.
  • The actual .env file contains real credentials and must never be committed — but without a documented template, someone will eventually commit it.
  • There is no runbook for "how do I get this running on a fresh VPS" — every deployment step lives only in someone's head.

What to do

1. Create .env.example

A complete template of every variable the stack needs, with placeholder values and inline comments explaining what each variable does and where to get it.

Required sections:

  • PostgreSQL credentials
  • MinIO / S3 credentials (dev vs. production values)
  • Backend port + base URL
  • Mail configuration (Mailpit for dev, real SMTP for prod)
  • SvelteKit ORIGIN
  • Any secrets (session secret, admin credentials)

All secret values must be replaced with descriptive placeholders like <your-strong-password>, never dummy values like password123 that someone might accidentally use in production.

2. Create DEPLOYMENT.md

A step-by-step production deployment guide. It should cover:

Prerequisites

  • VPS requirements (min specs, Ubuntu 24.04 LTS recommended)
  • Domain name with A record pointing to the VPS IP
  • Docker + Docker Compose installed
  • rclone installed and configured for Hetzner Object Storage (see backup scripts)

First deployment

  1. Clone the repo onto the VPS
  2. Copy .env.example to .env and fill in all values
  3. Create the Gitea secret E2E_ADMIN_PASSWORD (refs #128)
  4. docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
  5. Verify health: curl https://your-domain/api/actuator/health

Updating the application

  1. Pull latest images (or rebuild from source)
  2. docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --no-deps backend frontend
  3. Verify health

Database migrations
Flyway runs automatically on backend startup. If a migration fails, the backend will refuse to start — check logs with docker logs archive-backend.

Backup setup
Reference the steps from #139 (backup scripts issue).

Secrets rotation
How to rotate the database password, S3 credentials, and session secret without downtime.

Disaster recovery
How to restore the database from a backup file.

Acceptance criteria

  • .env.example exists at the repo root and contains every variable that appears in docker-compose.yml and docker-compose.prod.yml.
  • No real credentials in .env.example — only placeholders.
  • .env is listed in .gitignore (verify it already is).
  • DEPLOYMENT.md covers first deployment, updates, and backup setup end-to-end.
  • A developer unfamiliar with the project can follow DEPLOYMENT.md and get a working production instance without asking questions.
## Why There is no `.env.example` at the repo root and no deployment documentation. This means: - A new operator (or future-you after 6 months) has no way to know which environment variables are required, what format they take, or what values are safe vs. secret. - The actual `.env` file contains real credentials and must never be committed — but without a documented template, someone will eventually commit it. - There is no runbook for "how do I get this running on a fresh VPS" — every deployment step lives only in someone's head. ## What to do ### 1. Create `.env.example` A complete template of every variable the stack needs, with placeholder values and inline comments explaining what each variable does and where to get it. Required sections: - PostgreSQL credentials - MinIO / S3 credentials (dev vs. production values) - Backend port + base URL - Mail configuration (Mailpit for dev, real SMTP for prod) - SvelteKit `ORIGIN` - Any secrets (session secret, admin credentials) All secret values must be replaced with descriptive placeholders like `<your-strong-password>`, never dummy values like `password123` that someone might accidentally use in production. ### 2. Create `DEPLOYMENT.md` A step-by-step production deployment guide. It should cover: **Prerequisites** - VPS requirements (min specs, Ubuntu 24.04 LTS recommended) - Domain name with A record pointing to the VPS IP - Docker + Docker Compose installed - `rclone` installed and configured for Hetzner Object Storage (see backup scripts) **First deployment** 1. Clone the repo onto the VPS 2. Copy `.env.example` to `.env` and fill in all values 3. Create the Gitea secret `E2E_ADMIN_PASSWORD` (refs #128) 4. `docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d` 5. Verify health: `curl https://your-domain/api/actuator/health` **Updating the application** 1. Pull latest images (or rebuild from source) 2. `docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --no-deps backend frontend` 3. Verify health **Database migrations** Flyway runs automatically on backend startup. If a migration fails, the backend will refuse to start — check logs with `docker logs archive-backend`. **Backup setup** Reference the steps from #139 (backup scripts issue). **Secrets rotation** How to rotate the database password, S3 credentials, and session secret without downtime. **Disaster recovery** How to restore the database from a backup file. ## Acceptance criteria - `.env.example` exists at the repo root and contains every variable that appears in `docker-compose.yml` and `docker-compose.prod.yml`. - No real credentials in `.env.example` — only placeholders. - `.env` is listed in `.gitignore` (verify it already is). - `DEPLOYMENT.md` covers first deployment, updates, and backup setup end-to-end. - A developer unfamiliar with the project can follow `DEPLOYMENT.md` and get a working production instance without asking questions.
marcel added the devopsphase-6: deployment-docs labels 2026-03-28 10:46:45 +01:00
Author
Owner

Audit-derived scope addition (2026-05-07)

Audit found the following prod-essential docs missing from docs/:

  • README.md — present
  • CONTRIBUTING.md, COLLABORATING.md, CODESTYLE.md — present
  • ARCHITECTURE.md — present
  • 6 ADRs in docs/adr/ — well-formatted (Nygard)
  • docs/RUNBOOK.mdmissing (start/stop, common operations, restore procedure, log locations)
  • docs/INCIDENT_RESPONSE.mdmissing (escalation, recovery steps, on-call hand-off)

Suggested AC additions to this issue

  • docs/RUNBOOK.md covering at minimum:
    • How to start/stop the stack (prod compose)
    • Where logs live + how to tail them
    • How to restore from backup (referencing #138 — restore-test step)
    • How to rotate the admin password
    • How to add a new user / group
    • Common errors and what to check
  • docs/INCIDENT_RESPONSE.md covering:
    • Triage flow (is it user-facing? is data at risk?)
    • Communication template (status page / email to family)
    • Rollback procedure (restoring previous Docker image tag)
    • Post-mortem template
  • .env.example — already covered in this issue's title; ensure it documents every env var consumed by the stack (run grep -RE '\$\{[A-Z_]+}' docker-compose*.yml to enumerate).

Tracked in audit doc as F-26 (Low) — but operationally important for the same reason backups are: a solo-maintained system needs runbooks for the moment the maintainer is unavailable.

## Audit-derived scope addition (2026-05-07) Audit found the following prod-essential docs **missing** from `docs/`: - ✅ `README.md` — present - ✅ `CONTRIBUTING.md`, `COLLABORATING.md`, `CODESTYLE.md` — present - ✅ `ARCHITECTURE.md` — present - ✅ 6 ADRs in `docs/adr/` — well-formatted (Nygard) - ❌ `docs/RUNBOOK.md` — **missing** (start/stop, common operations, restore procedure, log locations) - ❌ `docs/INCIDENT_RESPONSE.md` — **missing** (escalation, recovery steps, on-call hand-off) ### Suggested AC additions to this issue - [ ] `docs/RUNBOOK.md` covering at minimum: - How to start/stop the stack (prod compose) - Where logs live + how to tail them - How to restore from backup (referencing #138 — restore-test step) - How to rotate the admin password - How to add a new user / group - Common errors and what to check - [ ] `docs/INCIDENT_RESPONSE.md` covering: - Triage flow (is it user-facing? is data at risk?) - Communication template (status page / email to family) - Rollback procedure (restoring previous Docker image tag) - Post-mortem template - [ ] `.env.example` — already covered in this issue's title; ensure it documents every env var consumed by the stack (run `grep -RE '\$\{[A-Z_]+}' docker-compose*.yml` to enumerate). Tracked in audit doc as **F-26** (Low) — but operationally important for the same reason backups are: a solo-maintained system needs runbooks for the moment the maintainer is unavailable.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#139