From 66bc3e95865c6975d62843f2a8175c634c37aa5c Mon Sep 17 00:00:00 2001 From: Wuesteon Date: Mon, 8 Dec 2025 22:43:53 +0100 Subject: [PATCH] docs: add staging deployment issues troubleshooting guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents common issues encountered during staging deployments: - Runtime env injection for SvelteKit (import.meta.env vs window) - CORS configuration for cross-app API calls - CD workflow version tag handling - Database creation for new backends - Better Auth user ID format (text vs uuid) Includes quick debugging commands and port reference. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/STAGING_DEPLOYMENT_ISSUES.md | 267 ++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 docs/STAGING_DEPLOYMENT_ISSUES.md diff --git a/docs/STAGING_DEPLOYMENT_ISSUES.md b/docs/STAGING_DEPLOYMENT_ISSUES.md new file mode 100644 index 000000000..2a72310d6 --- /dev/null +++ b/docs/STAGING_DEPLOYMENT_ISSUES.md @@ -0,0 +1,267 @@ +# Staging Deployment Issues & Solutions + +This document captures common issues encountered during staging deployments and their solutions. Reference this when debugging deployment problems. + +## Table of Contents + +1. [Runtime Environment Variables (SvelteKit)](#1-runtime-environment-variables-sveltekit) +2. [CORS Configuration](#2-cors-configuration) +3. [CD Workflow Version Tags](#3-cd-workflow-version-tags) +4. [Database Setup](#4-database-setup) +5. [User ID Format (Better Auth)](#5-user-id-format-better-auth) + +--- + +## 1. Runtime Environment Variables (SvelteKit) + +### Problem + +SvelteKit apps use `import.meta.env.PUBLIC_*` which gets **baked in at build time**. When running in Docker, the container uses whatever values were present during the GitHub Actions build, not the runtime environment variables. + +**Symptoms:** +- Web apps calling `localhost:3001` instead of staging server IP +- API calls going to wrong URLs despite correct Docker env vars + +### Solution + +Use **runtime env injection** via `hooks.server.ts`: + +```typescript +// src/hooks.server.ts +import type { Handle } from '@sveltejs/kit'; + +const PUBLIC_MANA_CORE_AUTH_URL_CLIENT = + process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || ''; +const PUBLIC_BACKEND_URL_CLIENT = + process.env.PUBLIC_BACKEND_URL_CLIENT || ''; + +export const handle: Handle = async ({ event, resolve }) => { + return resolve(event, { + transformPageChunk: ({ html }) => { + const envScript = ``; + return html.replace('', `${envScript}`); + }, + }); +}; +``` + +Then in client code, read from `window` instead of `import.meta.env`: + +```typescript +import { browser } from '$app/environment'; + +function getApiUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as any).__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + } + return 'http://localhost:3000'; // fallback for local dev +} +``` + +### Docker Compose Pattern + +Use two environment variables: +- `PUBLIC_*_URL` - Internal Docker network URL (container-to-container) +- `PUBLIC_*_URL_CLIENT` - External URL for browser access + +```yaml +environment: + PUBLIC_BACKEND_URL: http://backend-container:3000 # Server-side + PUBLIC_BACKEND_URL_CLIENT: http://46.224.108.214:3000 # Browser-side +``` + +--- + +## 2. CORS Configuration + +### Problem + +Backends only allow CORS from their own web apps, blocking requests from other origins like manacore-web dashboard. + +**Symptoms:** +- `Access to fetch blocked by CORS policy` +- `No 'Access-Control-Allow-Origin' header` + +### Solution + +Add all necessary origins to `CORS_ORIGINS` in docker-compose.staging.yml: + +```yaml +todo-backend: + environment: + # Include both the app's own web AND manacore-web dashboard + CORS_ORIGINS: http://46.224.108.214:5188,http://46.224.108.214:5173,http://localhost:5188,http://localhost:5173 +``` + +### Checklist for New Backends + +When deploying a new backend that will be called from manacore-web dashboard: +1. Add `http://46.224.108.214:5173` to CORS_ORIGINS +2. Add `http://localhost:5173` for local development +3. Restart the container after config changes + +### Testing CORS + +```bash +curl -I -X OPTIONS http://46.224.108.214:3018/api/v1/endpoint \ + -H "Origin: http://46.224.108.214:5173" \ + -H "Access-Control-Request-Method: GET" + +# Should see: +# Access-Control-Allow-Origin: http://46.224.108.214:5173 +``` + +--- + +## 3. CD Workflow Version Tags + +### Problem + +docker-compose uses variables like `${TODO_WEB_VERSION:-latest}`, but the CD workflow wasn't updating the `.env` file on the staging server, causing containers to always use `latest` instead of the tagged version. + +**Symptoms:** +- Deployed new version but container still running old code +- `docker ps` shows wrong image tag + +### Solution + +The CD workflow (`.github/workflows/cd-staging-tagged.yml`) now: +1. Computes the version variable name (e.g., `TODO_WEB_VERSION`) +2. Updates the `.env` file on staging server +3. docker-compose reads from `.env` + +### Verifying Deployment + +```bash +# Check running container version +docker ps --format '{{.Names}}: {{.Image}}' | grep todo + +# Check .env file +cat ~/manacore-staging/.env | grep VERSION +``` + +--- + +## 4. Database Setup + +### Problem + +New backends fail with `database "X" does not exist` because the PostgreSQL databases weren't created. + +**Symptoms:** +- 500 Internal Server Error +- Logs show: `PostgresError: database "todo" does not exist` + +### Solution + +Create databases manually on first deployment: + +```bash +# SSH to staging +ssh deploy@46.224.108.214 + +# Create databases +docker exec manacore-postgres-staging psql -U postgres -c 'CREATE DATABASE todo;' +docker exec manacore-postgres-staging psql -U postgres -c 'CREATE DATABASE calendar;' +docker exec manacore-postgres-staging psql -U postgres -c 'CREATE DATABASE clock;' + +# Restart backends (they auto-migrate schemas on startup) +cd ~/manacore-staging +docker compose restart todo-backend calendar-backend clock-backend +``` + +### Checklist for New Apps + +When deploying a new app with a database: +1. Create the database: `CREATE DATABASE appname;` +2. The backend will auto-migrate the schema on startup +3. Verify tables exist: `\dt` in psql + +--- + +## 5. User ID Format (Better Auth) + +### Problem + +Backend database schemas use `uuid` type for `user_id`, but Better Auth generates non-UUID user IDs like `otUe1YrfENPdHnrF3g1vSBfpkQfambCZ`. + +**Symptoms:** +- 500 Internal Server Error on authenticated requests +- Logs show: `invalid input syntax for type uuid: "otUe1YrfENPdHnrF3g1vSBfpkQfambCZ"` + +### Solution + +Change `user_id` columns from `uuid` to `text`: + +```sql +-- For each table with user_id +ALTER TABLE tasks ALTER COLUMN user_id TYPE text; +ALTER TABLE projects ALTER COLUMN user_id TYPE text; +-- etc. +``` + +### Prevention + +When creating new backend schemas, **always use `text` type for user_id**: + +```typescript +// Drizzle schema - CORRECT +export const tasks = pgTable('tasks', { + id: uuid('id').defaultRandom().primaryKey(), + userId: text('user_id').notNull(), // Use text, not uuid + // ... +}); + +// WRONG - Don't do this +export const tasks = pgTable('tasks', { + userId: uuid('user_id').notNull(), // Will fail with Better Auth +}); +``` + +--- + +## Quick Debugging Commands + +```bash +# Check container logs +docker logs --tail 50 + +# Check container is running correct version +docker ps --format '{{.Names}}: {{.Image}}' + +# Test CORS +curl -I -X OPTIONS -H "Origin: " + +# Check database exists +docker exec manacore-postgres-staging psql -U postgres -c '\l' + +# Check tables in database +docker exec manacore-postgres-staging psql -U postgres -d -c '\dt' + +# Restart a service +cd ~/manacore-staging && docker compose restart + +# Force recreate with new config +cd ~/manacore-staging && docker compose up -d --no-deps --force-recreate +``` + +--- + +## Port Reference + +| Service | Port | +|---------|------| +| mana-core-auth | 3001 | +| chat-backend | 3002 | +| calendar-backend | 3016 | +| clock-backend | 3017 | +| todo-backend | 3018 | +| chat-web | 3000 | +| manacore-web | 5173 | +| calendar-web | 5186 | +| clock-web | 5187 | +| todo-web | 5188 |