commit e90d4292d5418e479f87e8ff681eea8cbfc6794e Author: bea Date: Sat Mar 21 23:34:52 2026 +0100 Initial commit: docker compose for frame stack diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..307fc8c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +backend.env +.env +data/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f1c82f --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# frame-deploy + +Docker Compose setup for the full Frame stack: + +- **frame-backend** — Go REST API (auth, users, posts) +- **frame-cms** — React/Nginx admin frontend +- **postgres** — PostgreSQL 18 + +--- + +## Quick Start + +### 1. Clone this repo + +```bash +git clone https://git.beatrice.wtf/panic.haus/frame-deploy +cd frame-deploy +``` + +### 2. Configure the backend + +```bash +cp backend.env.example backend.env +``` + +Edit `backend.env` and at minimum set: + +| Variable | What to change | +|---|---| +| `DATABASE_URL` | Leave as-is (points to the `postgres` service) | +| `JWT_SECRET` | **Change this in production** | +| `CORS_ALLOWED_ORIGINS` | URL where frame-cms will be served | +| `FRONTEND_BASE_URL` | Same URL (used in email links) | +| `SMTP_*` | Optional — needed for email verification | + +### 3. Pull images and start + +```bash +docker compose pull +docker compose up -d +``` + +Services will be available at: + +- **CMS:** http://localhost:3000 +- **API:** http://localhost:8080 + +Ports can be overridden via environment variables before `docker compose up`: + +```bash +BACKEND_PORT=9090 CMS_PORT=4000 docker compose up -d +``` + +### 4. Create an admin user (first time only) + +If SMTP is not configured, email verification won't work — you'll need to manually verify the user in the DB: + +```bash +docker compose exec postgres psql -U postgres -d appdb \ + -c "UPDATE users SET email_verified = true WHERE email = 'your@email.com';" +``` + +--- + +## Data persistence + +Postgres data is stored in `./data/postgres/` (relative to this directory). +This folder is gitignored — back it up separately. + +--- + +## Updating + +```bash +docker compose pull +docker compose up -d +``` + +--- + +## Stopping + +```bash +docker compose down # stop, keep data +docker compose down -v # stop + remove volumes (destructive) +``` diff --git a/backend.env.example b/backend.env.example new file mode 100644 index 0000000..e4b76af --- /dev/null +++ b/backend.env.example @@ -0,0 +1,20 @@ +# Database +DATABASE_URL=postgres://postgres:postgres@postgres:5432/appdb?sslmode=disable +DB_AUTO_MIGRATE=true + +# Auth +JWT_SECRET=change_me_in_production + +# CORS — must include the URL where frame-cms is served +CORS_ALLOWED_ORIGINS=http://localhost:3000 + +# Frontend base URL used in email links +FRONTEND_BASE_URL=http://localhost:3000 + +# SMTP (optional — without this, email verification won't work) +# SMTP_HOST=smtp.example.com +# SMTP_PORT=587 +# SMTP_USERNAME=user@example.com +# SMTP_PASSWORD=secret +# SMTP_FROM=noreply@example.com +# SMTP_MODE=tls diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0e46e67 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +services: + postgres: + image: postgres:18-alpine + restart: unless-stopped + environment: + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_DB: ${POSTGRES_DB:-appdb} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] + interval: 5s + timeout: 5s + retries: 5 + volumes: + - ./data/postgres:/var/lib/postgresql/data + + frame-backend: + image: docker.panic.haus/frame-backend:latest + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + env_file: + - backend.env + ports: + - "${BACKEND_PORT:-8080}:8080" + + frame-cms: + image: docker.panic.haus/frame-cms:latest + restart: unless-stopped + depends_on: + - frame-backend + ports: + - "${CMS_PORT:-3000}:80" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost/"] + interval: 30s + timeout: 5s + retries: 3