PDF-accessibility-saas/docker-compose.prod.yml
Vadym Samoilenko 5cbbcc6e5e
Some checks are pending
CI / Backend — lint + test (push) Waiting to run
CI / Frontend — lint + typecheck (push) Waiting to run
CI / Build + push Docker images (push) Blocked by required conditions
Phase 4–6: Next.js frontend, production deploy, CI/CD
Frontend (Next.js 15 + shadcn/ui + Tailwind, Supabase Auth):
- Landing page: hero, feature grid, social proof (EU Accessibility Act), CTA
- Pricing page: Free / Pro $29 / Business $149 with highlighted Pro tier
- Auth: magic link login + signup (Supabase OTP, no password)
- App layout: sidebar nav (Dashboard, History, Billing, Team)
- Dashboard: drag-and-drop PDF upload with quota error handling
- Jobs history: table with score badges and status indicators
- Billing: Stripe Checkout + Customer Portal integration
- Supabase SSR client/server helpers

Deploy:
- docker-compose.prod.yml: postgres, redis, minio, api, celery, nextjs, caddy
- Caddyfile: auto-SSL for pdfaccess.ai-impress.com
- Watchtower excluded (locally-built images)

CI/CD (Forgejo Actions):
- backend-lint-test: pytest with real postgres + redis
- frontend-lint: tsc typecheck
- build-and-push: docker build → push to registry.ai-impress.com
- SSH deploy to homelab on push to main

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:51:14 +01:00

99 lines
2.4 KiB
YAML

services:
postgres:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_DB: ${DB_NAME:-pdf_accessibility}
POSTGRES_USER: ${DB_USER:-pdf_accessibility}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-pdf_accessibility}"]
interval: 10s
timeout: 5s
retries: 5
labels:
- "com.centurylinklabs.watchtower.enable=false"
redis:
image: redis:7-alpine
restart: always
command: redis-server --appendonly yes
volumes:
- redis_data:/data
labels:
- "com.centurylinklabs.watchtower.enable=false"
minio:
image: minio/minio:latest
restart: always
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY}
volumes:
- minio_data:/data
labels:
- "com.centurylinklabs.watchtower.enable=false"
api:
image: registry.ai-impress.com/pdf-accessibility/api:latest
restart: always
env_file: .env
environment:
- DB_HOST=postgres
- REDIS_URL=redis://redis:6379/0
- STORAGE_ENDPOINT=http://minio:9000
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
labels:
- "com.centurylinklabs.watchtower.enable=false"
celery:
image: registry.ai-impress.com/pdf-accessibility/api:latest
command: uv run celery -A app.services.queue.celery_app worker --loglevel=info -c 2
restart: always
env_file: .env
environment:
- DB_HOST=postgres
- REDIS_URL=redis://redis:6379/0
- STORAGE_ENDPOINT=http://minio:9000
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
labels:
- "com.centurylinklabs.watchtower.enable=false"
nextjs:
image: registry.ai-impress.com/pdf-accessibility/frontend:latest
restart: always
env_file: frontend/.env.local
labels:
- "com.centurylinklabs.watchtower.enable=false"
caddy:
image: caddy:2-alpine
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- api
- nextjs
volumes:
postgres_data:
redis_data:
minio_data:
caddy_data:
caddy_config: