feat: add seed credential env vars to k8s deployment #28

Merged
forgejo_admin merged 2 commits from 28-seed-credentials-k8s into main 2026-02-26 05:35:44 +00:00

Summary

  • Add PALDOCS_SEED_EMAIL and PALDOCS_SEED_PASSWORD env vars to k8s deployment
  • References existing pal-e-docs-secrets k8s secret (already created with all 3 keys)
  • Required for auth system (PR #27) to seed the first user on startup

Changes

  • k8s/deployment.yaml: Add two new env vars referencing pal-e-docs-secrets secret keys seed-email and seed-password. Remove stale TODO comment.

Test Plan

  • Pod starts without CreateContainerConfigError
  • Seed user is created on startup (check pod logs)
  • Can log in at /browse/login with seeded credentials
  • No regressions — existing health checks pass

Review Checklist

  • No secrets committed (credentials are in k8s secret, not in code)
  • No unnecessary file changes
  • Commit message is descriptive
  • issue-seed-credentials-k8s — the issue this PR addresses
  • plan-2026-02-25-private-notes-auth — Phase 1 deployment follow-up
## Summary - Add `PALDOCS_SEED_EMAIL` and `PALDOCS_SEED_PASSWORD` env vars to k8s deployment - References existing `pal-e-docs-secrets` k8s secret (already created with all 3 keys) - Required for auth system (PR #27) to seed the first user on startup ## Changes - `k8s/deployment.yaml`: Add two new env vars referencing `pal-e-docs-secrets` secret keys `seed-email` and `seed-password`. Remove stale TODO comment. ## Test Plan - [ ] Pod starts without `CreateContainerConfigError` - [ ] Seed user is created on startup (check pod logs) - [ ] Can log in at `/browse/login` with seeded credentials - [ ] No regressions — existing health checks pass ## Review Checklist - [ ] No secrets committed (credentials are in k8s secret, not in code) - [ ] No unnecessary file changes - [ ] Commit message is descriptive ## Related Notes - `issue-seed-credentials-k8s` — the issue this PR addresses - `plan-2026-02-25-private-notes-auth` — Phase 1 deployment follow-up
feat: add seed credential env vars to k8s deployment
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
a3937bc51f
Add PALDOCS_SEED_EMAIL and PALDOCS_SEED_PASSWORD env vars referencing
the pal-e-docs-secrets k8s secret, so the auth system seeds the first
user on startup. Remove stale TODO comment.

Ref: issue-seed-credentials-k8s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

QA Review: PASS ✓

All checks passed. This PR is clean and ready to merge.

Findings

Configuration & Secrets:

  • ✓ k8s secret pal-e-docs-secrets exists in pal-e-docs namespace with all 3 expected keys: secret-key, seed-email, seed-password
  • ✓ Secret key names in deployment match actual k8s secret keys exactly

Code Integration:

  • src/pal_e_docs/config.py defines seed_email and seed_password settings with PALDOCS_ prefix (matches env var names)
  • src/pal_e_docs/main.py implements _seed_user() function that consumes these settings on app startup
  • ✓ Seeding is conditional (checks if not settings.seed_email or not settings.seed_password: return)
  • ✓ Idempotent: checks if user already exists before creating (line 27-29 in main.py)

YAML & Deployment:

  • ✓ YAML syntax is valid
  • ✓ Indentation correct
  • ✓ Both new env vars use valueFrom.secretKeyRef pattern (no hardcoded secrets)
  • ✓ TODO comment appropriately removed (k8s secret now created)

No Issues Found

  • No hardcoded secrets
  • No unnecessary changes
  • Clear commit message
  • All credential references point to k8s secret, not code
## QA Review: PASS ✓ All checks passed. This PR is clean and ready to merge. ### Findings **Configuration & Secrets:** - ✓ k8s secret `pal-e-docs-secrets` exists in `pal-e-docs` namespace with all 3 expected keys: `secret-key`, `seed-email`, `seed-password` - ✓ Secret key names in deployment match actual k8s secret keys exactly **Code Integration:** - ✓ `src/pal_e_docs/config.py` defines `seed_email` and `seed_password` settings with `PALDOCS_` prefix (matches env var names) - ✓ `src/pal_e_docs/main.py` implements `_seed_user()` function that consumes these settings on app startup - ✓ Seeding is conditional (checks `if not settings.seed_email or not settings.seed_password: return`) - ✓ Idempotent: checks if user already exists before creating (line 27-29 in main.py) **YAML & Deployment:** - ✓ YAML syntax is valid - ✓ Indentation correct - ✓ Both new env vars use `valueFrom.secretKeyRef` pattern (no hardcoded secrets) - ✓ TODO comment appropriately removed (k8s secret now created) **No Issues Found** - No hardcoded secrets - No unnecessary changes - Clear commit message - All credential references point to k8s secret, not code
feat: add Litestream sidecar for continuous SQLite backup to MinIO
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
e0b5c03c55
Add init container (restore-if-not-exists) and sidecar container
(continuous replication) using litestream/litestream:0.3. Both mount
the shared /data PVC and a ConfigMap with litestream.yml config.
Credentials come from litestream-creds secret via envFrom.

Resolves: issue-litestream-sidecar (plan-2026-02-24-docs-foundation Phase 6)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forgejo_admin deleted branch 28-seed-credentials-k8s 2026-02-26 05:35:44 +00:00
Author
Owner

PR #28 Review -- Seed Credentials + Litestream Sidecar

Overall Assessment: APPROVED (post-merge review)

This is a clean, well-structured PR that adds two distinct but related features: seed credential env vars for the auth system, and Litestream continuous backup to MinIO. Both are implemented correctly following k8s best practices.


1. k8s/deployment.yaml -- Litestream Pattern

Init container (litestream-restore): Correct. The -if-db-not-exists flag is critical -- it ensures a fresh deployment restores from backup, but an existing PVC with a live database is left alone. The config path, data path, and volume mounts are all consistent.

Sidecar (litestream-replicate): Correct. Runs alongside the main container with shared /data volume. The replicate command will continuously stream WAL changes to MinIO.

Volume sharing: Both Litestream containers and the main app container all mount the data PVC at /data, and both Litestream containers mount the configmap at /etc/litestream. This is exactly right.

Resources: Reasonable and conservative. Init container gets 32Mi request / 64Mi limit, sidecar gets 32Mi / 64Mi, main app gets 32Mi / 128Mi. CPU requests are 10m across the board. No CPU limits set, which is the correct modern practice (CPU limits cause throttling).

Strategy and replicas: replicas: 1 with strategy: Recreate -- essential for SQLite/Litestream. No two pods should ever run concurrently against the same PVC. Already present from before this PR.

2. k8s/litestream-configmap.yaml -- Litestream Config

Env var substitution: Correct. Litestream natively supports ${ENV_VAR} substitution in its YAML config at runtime. The four env vars (LITESTREAM_BUCKET, LITESTREAM_ENDPOINT, LITESTREAM_ACCESS_KEY, LITESTREAM_SECRET_KEY) are injected via envFrom from the litestream-creds secret.

MinIO compatibility flags:

  • force-path-style: true -- required for MinIO (not a virtual-hosted-style S3).
  • skip-verify: true -- correct for internal cluster traffic to minio.minio.svc.cluster.local.

Replica path: pal-e-docs/ -- clean, identifies the service within the shared bucket.

DB path: /data/pal-e-docs.db -- matches PALDOCS_DATABASE_PATH env var in the main container.

3. k8s/kustomization.yaml

New resource litestream-configmap.yaml is listed. Correct.

4. Seed Credential Env Vars

PALDOCS_SEED_EMAIL and PALDOCS_SEED_PASSWORD both reference pal-e-docs-secrets with keys seed-email and seed-password. Verified against the app config.py which expects PALDOCS_ prefix settings seed_email and seed_password (both str | None). The env var names map correctly via pydantic-settings.

The stale TODO comment was correctly removed.

5. Minor Observations (non-blocking)

  1. Litestream image tag 0.3: Litestream is now at 0.5.x. The 0.3 tag still works and is battle-tested, so this is not a blocker, but worth noting for a future upgrade. The 0.3 tag is a major-version float which will pull the latest 0.3.x patch.

  2. No readOnly on configmap mount: The /etc/litestream mount could use readOnly: true since Litestream only reads the config. Not a blocker -- just a hardening nit.

  3. PR title mentions only seed credentials but the branch also contains the Litestream commit. The PR title should arguably reflect both changes. Minor -- the diff speaks for itself.


Verdict: Ship it. The Litestream pattern is textbook (init restore + sidecar replicate), volume sharing is correct, env var plumbing matches the app config, and the configmap properly uses Litestream native env substitution for MinIO credentials. No secrets in code.

## PR #28 Review -- Seed Credentials + Litestream Sidecar ### Overall Assessment: APPROVED (post-merge review) This is a clean, well-structured PR that adds two distinct but related features: seed credential env vars for the auth system, and Litestream continuous backup to MinIO. Both are implemented correctly following k8s best practices. --- ### 1. k8s/deployment.yaml -- Litestream Pattern **Init container (litestream-restore):** Correct. The `-if-db-not-exists` flag is critical -- it ensures a fresh deployment restores from backup, but an existing PVC with a live database is left alone. The config path, data path, and volume mounts are all consistent. **Sidecar (litestream-replicate):** Correct. Runs alongside the main container with shared `/data` volume. The `replicate` command will continuously stream WAL changes to MinIO. **Volume sharing:** Both Litestream containers and the main app container all mount the `data` PVC at `/data`, and both Litestream containers mount the configmap at `/etc/litestream`. This is exactly right. **Resources:** Reasonable and conservative. Init container gets 32Mi request / 64Mi limit, sidecar gets 32Mi / 64Mi, main app gets 32Mi / 128Mi. CPU requests are 10m across the board. No CPU limits set, which is the correct modern practice (CPU limits cause throttling). **Strategy and replicas:** `replicas: 1` with `strategy: Recreate` -- essential for SQLite/Litestream. No two pods should ever run concurrently against the same PVC. Already present from before this PR. ### 2. k8s/litestream-configmap.yaml -- Litestream Config **Env var substitution:** Correct. Litestream natively supports `${ENV_VAR}` substitution in its YAML config at runtime. The four env vars (`LITESTREAM_BUCKET`, `LITESTREAM_ENDPOINT`, `LITESTREAM_ACCESS_KEY`, `LITESTREAM_SECRET_KEY`) are injected via `envFrom` from the `litestream-creds` secret. **MinIO compatibility flags:** - `force-path-style: true` -- required for MinIO (not a virtual-hosted-style S3). - `skip-verify: true` -- correct for internal cluster traffic to `minio.minio.svc.cluster.local`. **Replica path:** `pal-e-docs/` -- clean, identifies the service within the shared bucket. **DB path:** `/data/pal-e-docs.db` -- matches `PALDOCS_DATABASE_PATH` env var in the main container. ### 3. k8s/kustomization.yaml New resource `litestream-configmap.yaml` is listed. Correct. ### 4. Seed Credential Env Vars `PALDOCS_SEED_EMAIL` and `PALDOCS_SEED_PASSWORD` both reference `pal-e-docs-secrets` with keys `seed-email` and `seed-password`. Verified against the app `config.py` which expects `PALDOCS_` prefix settings `seed_email` and `seed_password` (both `str | None`). The env var names map correctly via pydantic-settings. The stale TODO comment was correctly removed. ### 5. Minor Observations (non-blocking) 1. **Litestream image tag `0.3`:** Litestream is now at 0.5.x. The `0.3` tag still works and is battle-tested, so this is not a blocker, but worth noting for a future upgrade. The `0.3` tag is a major-version float which will pull the latest 0.3.x patch. 2. **No `readOnly` on configmap mount:** The `/etc/litestream` mount could use `readOnly: true` since Litestream only reads the config. Not a blocker -- just a hardening nit. 3. **PR title mentions only seed credentials** but the branch also contains the Litestream commit. The PR title should arguably reflect both changes. Minor -- the diff speaks for itself. --- **Verdict:** Ship it. The Litestream pattern is textbook (init restore + sidecar replicate), volume sharing is correct, env var plumbing matches the app config, and the configmap properly uses Litestream native env substitution for MinIO credentials. No secrets in code.
Sign in to join this conversation.
No description provided.