From 62a216fccf74082ea073844627533644e34e3e72 Mon Sep 17 00:00:00 2001 From: Chandler Copeland Date: Fri, 3 Apr 2026 16:50:31 -0600 Subject: [PATCH] fix(17): add DEPLOYMENT.md task to 17-02 per checker feedback --- .../phases/17-docker-deployment/17-02-PLAN.md | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/.planning/phases/17-docker-deployment/17-02-PLAN.md b/.planning/phases/17-docker-deployment/17-02-PLAN.md index 26eb048..984bc72 100644 --- a/.planning/phases/17-docker-deployment/17-02-PLAN.md +++ b/.planning/phases/17-docker-deployment/17-02-PLAN.md @@ -10,6 +10,7 @@ files_modified: - teressa-copeland-homes/.dockerignore - teressa-copeland-homes/.env.production.example - teressa-copeland-homes/.gitignore + - teressa-copeland-homes/DEPLOYMENT.md autonomous: true requirements: [DEPLOY-01, DEPLOY-02, DEPLOY-03, DEPLOY-04, DEPLOY-05] must_haves: @@ -19,6 +20,7 @@ must_haves: - "Uploaded PDFs persist across container restarts via named volume" - "Dockerfile uses node:20-slim with --platform linux/amd64 on all 3 FROM lines" - "seeds/forms directory is available inside the container for form library imports" + - "DEPLOYMENT.md documents the full deploy workflow including migration step" artifacts: - path: "teressa-copeland-homes/Dockerfile" provides: "Three-stage Docker build" @@ -32,6 +34,9 @@ must_haves: - path: "teressa-copeland-homes/.env.production.example" provides: "Env var template for production" contains: "DATABASE_URL" + - path: "teressa-copeland-homes/DEPLOYMENT.md" + provides: "Deployment instructions with migration step" + contains: "drizzle-kit migrate" key_links: - from: "teressa-copeland-homes/docker-compose.yml" to: ".env.production" @@ -48,11 +53,11 @@ must_haves: --- -Create all Docker deployment files: Dockerfile (three-stage, node:20-slim, linux/amd64), docker-compose.yml (env_file secrets, named uploads volume, SMTP DNS fix), .dockerignore, .env.production.example, and update .gitignore. +Create all Docker deployment files: Dockerfile (three-stage, node:20-slim, linux/amd64), docker-compose.yml (env_file secrets, named uploads volume, SMTP DNS fix), .dockerignore, .env.production.example, update .gitignore, and create DEPLOYMENT.md documenting the migration step. Purpose: This is the deployment infrastructure that makes the app run reliably on the production home server. Secrets are injected at runtime, uploads persist across restarts, and SMTP DNS is fixed. -Output: Dockerfile, docker-compose.yml, .dockerignore, .env.production.example, updated .gitignore +Output: Dockerfile, docker-compose.yml, .dockerignore, .env.production.example, updated .gitignore, DEPLOYMENT.md @@ -308,6 +313,45 @@ APP_BASE_URL (already renamed from NEXT_PUBLIC_BASE_URL in Phase 15): docker-compose.yml with env_file secrets, DNS fix, named volume, and restart policy; .gitignore updated + + Task 3: Create DEPLOYMENT.md with migration and startup instructions + teressa-copeland-homes/DEPLOYMENT.md + + Create `teressa-copeland-homes/DEPLOYMENT.md` documenting the production deployment workflow (per D-02, CONTEXT.md domain item 9). + + The file should contain these sections in order: + + **Prerequisites** — Git, Docker, Docker Compose installed on server. + + **Step 1: Configure environment** — Copy `.env.production.example` to `.env.production` and fill in real values for all 11 vars (DATABASE_URL, SIGNING_JWT_SECRET, AUTH_SECRET, AGENT_EMAIL, AGENT_PASSWORD, CONTACT_EMAIL_USER, CONTACT_EMAIL_PASS, CONTACT_SMTP_HOST, CONTACT_SMTP_PORT, OPENAI_API_KEY, APP_BASE_URL). + + **Step 2: Run database migration** — From the project directory (not inside the container), run: + ``` + DATABASE_URL= npx drizzle-kit migrate + ``` + This must complete before starting the container. Migrations are NOT run inside Docker (per D-02). + + **Step 3: Build and start** — Run: + ``` + docker compose up -d --build + ``` + + **Step 4: Verify** — Run: + ``` + curl http://localhost:3000/api/health + ``` + Expected response: `{"ok":true,"db":"connected"}` + + **Updating** — To deploy a new version: `git pull`, re-run migration if schema changed, then `docker compose up -d --build`. + + Keep the file concise — no more than ~50 lines. No badges, no table of contents, no verbose prose. + + + cd /Users/ccopeland/temp/red/teressa-copeland-homes && test -f DEPLOYMENT.md && grep -q "env.production.example" DEPLOYMENT.md && grep -q "drizzle-kit migrate" DEPLOYMENT.md && grep -q "docker compose up" DEPLOYMENT.md && grep -q "api/health" DEPLOYMENT.md && echo "PASS" + + DEPLOYMENT.md exists at teressa-copeland-homes/DEPLOYMENT.md covering env setup, migration from host, docker compose startup, and health check verification + + @@ -325,6 +369,11 @@ Verify no secrets in Dockerfile: ```bash ! grep -iE "(password|secret|key=)" Dockerfile ``` + +Verify DEPLOYMENT.md covers all required steps: +```bash +grep -q "drizzle-kit migrate" DEPLOYMENT.md && grep -q "docker compose up" DEPLOYMENT.md && grep -q "env.production" DEPLOYMENT.md && echo "DEPLOYMENT.md complete" +``` @@ -336,6 +385,7 @@ Verify no secrets in Dockerfile: - .env.production.example has all 11 required vars, no dead vars - .dockerignore excludes node_modules, .next, .env*, uploads/ - .gitignore covers .env.production and uploads/ +- DEPLOYMENT.md documents: env setup, migration from host, docker compose up, health check