From 787f34ae14e654e15cb49cb907d6641ed8b68e86 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 18:11:45 +0000 Subject: [PATCH] Add Coolify deployment guide and rename app to Well Apps - Add compose.coolify.yml: simplified compose without Traefik labels for Coolify's built-in reverse proxy and SSL management - Add docs/coolify-deployment.md: full setup guide covering Coolify install, GitHub App integration, env vars, backups, and monitoring - Rename project from "Full Stack FastAPI Project" to "Well Apps" across .env, page titles, footer, and index.html - Update footer social links to point to the-ai-buildr/well-apps - Update Docker image names to well-apps-backend/well-apps-frontend https://claude.ai/code/session_017P3qDGqPD5Hi2T7fFTwQ2p --- .env | 8 +- compose.coolify.yml | 100 +++++++ docs/coolify-deployment.md | 317 ++++++++++++++++++++++ frontend/index.html | 2 +- frontend/src/components/Common/Footer.tsx | 13 +- frontend/src/routes/_layout/admin.tsx | 2 +- frontend/src/routes/_layout/index.tsx | 2 +- frontend/src/routes/_layout/items.tsx | 2 +- frontend/src/routes/_layout/settings.tsx | 2 +- frontend/src/routes/login.tsx | 2 +- frontend/src/routes/recover-password.tsx | 2 +- frontend/src/routes/reset-password.tsx | 2 +- frontend/src/routes/signup.tsx | 2 +- 13 files changed, 433 insertions(+), 23 deletions(-) create mode 100644 compose.coolify.yml create mode 100644 docs/coolify-deployment.md diff --git a/.env b/.env index 1d44286e25..fbf7af3025 100644 --- a/.env +++ b/.env @@ -13,8 +13,8 @@ FRONTEND_HOST=http://localhost:5173 # Environment: local, staging, production ENVIRONMENT=local -PROJECT_NAME="Full Stack FastAPI Project" -STACK_NAME=full-stack-fastapi-project +PROJECT_NAME="Well Apps" +STACK_NAME=well-apps # Backend BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,https://localhost,https://localhost:5173,http://localhost.tiangolo.com" @@ -41,5 +41,5 @@ POSTGRES_PASSWORD=changethis SENTRY_DSN= # Configure these with your own Docker registry images -DOCKER_IMAGE_BACKEND=backend -DOCKER_IMAGE_FRONTEND=frontend +DOCKER_IMAGE_BACKEND=well-apps-backend +DOCKER_IMAGE_FRONTEND=well-apps-frontend diff --git a/compose.coolify.yml b/compose.coolify.yml new file mode 100644 index 0000000000..2674856238 --- /dev/null +++ b/compose.coolify.yml @@ -0,0 +1,100 @@ +services: + + db: + image: postgres:18 + restart: always + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + retries: 5 + start_period: 30s + timeout: 10s + volumes: + - well-apps-db-data:/var/lib/postgresql/data/pgdata + environment: + - PGDATA=/var/lib/postgresql/data/pgdata + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_DB=${POSTGRES_DB} + + prestart: + image: ${DOCKER_IMAGE_BACKEND:-well-apps-backend}:${TAG:-latest} + build: + context: . + dockerfile: backend/Dockerfile + depends_on: + db: + condition: service_healthy + restart: true + command: bash scripts/prestart.sh + environment: + - DOMAIN=${DOMAIN} + - FRONTEND_HOST=${FRONTEND_HOST} + - ENVIRONMENT=${ENVIRONMENT} + - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} + - SECRET_KEY=${SECRET_KEY} + - FIRST_SUPERUSER=${FIRST_SUPERUSER} + - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD} + - SMTP_HOST=${SMTP_HOST} + - SMTP_USER=${SMTP_USER} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL} + - POSTGRES_SERVER=db + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - SENTRY_DSN=${SENTRY_DSN} + + backend: + image: ${DOCKER_IMAGE_BACKEND:-well-apps-backend}:${TAG:-latest} + restart: always + depends_on: + db: + condition: service_healthy + restart: true + prestart: + condition: service_completed_successfully + environment: + - DOMAIN=${DOMAIN} + - FRONTEND_HOST=${FRONTEND_HOST} + - ENVIRONMENT=${ENVIRONMENT} + - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} + - SECRET_KEY=${SECRET_KEY} + - FIRST_SUPERUSER=${FIRST_SUPERUSER} + - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD} + - SMTP_HOST=${SMTP_HOST} + - SMTP_USER=${SMTP_USER} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL} + - POSTGRES_SERVER=db + - POSTGRES_PORT=${POSTGRES_PORT:-5432} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - SENTRY_DSN=${SENTRY_DSN} + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"] + interval: 10s + timeout: 5s + retries: 5 + build: + context: . + dockerfile: backend/Dockerfile + ports: + - "8000:8000" + + frontend: + image: ${DOCKER_IMAGE_FRONTEND:-well-apps-frontend}:${TAG:-latest} + restart: always + build: + context: . + dockerfile: frontend/Dockerfile + args: + - VITE_API_URL=https://api.${DOMAIN} + - NODE_ENV=production + ports: + - "80:80" + +volumes: + well-apps-db-data: diff --git a/docs/coolify-deployment.md b/docs/coolify-deployment.md new file mode 100644 index 0000000000..ba6c523427 --- /dev/null +++ b/docs/coolify-deployment.md @@ -0,0 +1,317 @@ +# Well Apps — Coolify Deployment Guide + +Deploy Well Apps to a VPS using [Coolify](https://coolify.io), an open-source self-hosted PaaS. + +## Architecture + +``` +Internet (HTTPS) + | +Coolify Traefik (auto-SSL via Let's Encrypt) + | + ├── dashboard.yourdomain.com → frontend (Nginx, port 80) + ├── api.yourdomain.com → backend (FastAPI, port 8000) + └── (internal only) → db (PostgreSQL 18) +``` + +Coolify manages Traefik, SSL certificates, and domain routing. The app uses +`compose.coolify.yml` — a simplified compose file without Traefik labels. + +--- + +## Prerequisites + +- A VPS with 2+ vCPUs, 4+ GB RAM, 40+ GB disk (Ubuntu 24.04 LTS recommended) +- A domain with DNS pointed to your VPS IP +- A wildcard DNS record: `*.yourdomain.com → VPS_IP` +- A GitHub account with access to `the-ai-buildr/well-apps` + +--- + +## 1. Install Coolify on Your VPS + +SSH into your server and run: + +```bash +curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash +``` + +After installation, access the Coolify dashboard at `http://YOUR_VPS_IP:8000`. + +Create your admin account and complete the initial setup wizard. + +--- + +## 2. Connect GitHub to Coolify + +### Create a GitHub App (recommended over deploy keys) + +1. In Coolify: **Settings → Git Sources → Add** +2. Select **GitHub App** +3. Follow the OAuth flow — Coolify will create a GitHub App in your account +4. Grant access to the `the-ai-buildr/well-apps` repository + +This gives Coolify push/webhook access for auto-deploy. + +--- + +## 3. Configure GitHub Repository Secrets + +Even though Coolify handles deployment, GitHub Actions still runs CI (tests, +linting). Set these secrets so CI continues to work. + +### Using the `gh` CLI + +```bash +# Authenticate (if not already) +gh auth login + +# Navigate to your repo +cd well-apps + +# --- CI secrets (repository-level) --- +gh secret set POSTGRES_PASSWORD --body "ci-test-password" +gh secret set POSTGRES_USER --body "postgres" +gh secret set POSTGRES_DB --body "app" +gh secret set SECRET_KEY --body "$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" +gh secret set FIRST_SUPERUSER --body "admin@wellbeing.app" +gh secret set FIRST_SUPERUSER_PASSWORD --body "$(python3 -c 'import secrets; print(secrets.token_urlsafe(16))')" + +# --- Staging environment secrets --- +gh secret set DOMAIN_STAGING --env staging --body "staging.yourdomain.com" +gh secret set STACK_NAME_STAGING --env staging --body "well-apps-staging" + +# --- Production environment secrets --- +gh secret set DOMAIN_PRODUCTION --env production --body "yourdomain.com" +gh secret set STACK_NAME_PRODUCTION --env production --body "well-apps-production" + +# --- Shared across environments --- +for env in staging production; do + gh secret set SECRET_KEY --env "$env" \ + --body "$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" + gh secret set FIRST_SUPERUSER --env "$env" --body "admin@wellbeing.app" + gh secret set FIRST_SUPERUSER_PASSWORD --env "$env" \ + --body "$(python3 -c 'import secrets; print(secrets.token_urlsafe(16))')" + gh secret set POSTGRES_PASSWORD --env "$env" \ + --body "$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" + gh secret set EMAILS_FROM_EMAIL --env "$env" --body "noreply@yourdomain.com" + gh secret set SMTP_HOST --env "$env" --body "" + gh secret set SMTP_USER --env "$env" --body "" + gh secret set SMTP_PASSWORD --env "$env" --body "" +done +``` + +### Create GitHub Environments + +```bash +# Create staging and production environments +gh api repos/:owner/:repo/environments/staging -X PUT +gh api repos/:owner/:repo/environments/production -X PUT +``` + +For production, add a **required reviewers** protection rule in the GitHub UI: +**Settings → Environments → production → Required reviewers**. + +--- + +## 4. Create the Coolify Project + +### 4a. Create the Project + +1. In Coolify dashboard: **Projects → Add** +2. Name: `Well Apps` +3. Create two environments: `staging` and `production` + +### 4b. Add the Application (per environment) + +For each environment (staging, production): + +1. **Add New Resource → Docker Compose** +2. **Git Repository**: select `the-ai-buildr/well-apps` +3. **Branch**: `master` (production) or `develop` (staging) +4. **Docker Compose File**: `compose.coolify.yml` +5. **Build Pack**: Docker Compose + +### 4c. Configure Domains + +In the resource settings, configure the service domains: + +| Service | Domain | +|---------|--------| +| `frontend` (port 80) | `dashboard.yourdomain.com` | +| `backend` (port 8000) | `api.yourdomain.com` | + +For staging, use: + +| Service | Domain | +|---------|--------| +| `frontend` (port 80) | `dashboard.staging.yourdomain.com` | +| `backend` (port 8000) | `api.staging.yourdomain.com` | + +Coolify will automatically provision Let's Encrypt SSL certificates. + +--- + +## 5. Set Environment Variables in Coolify + +In the Coolify resource settings, go to **Environment Variables** and add: + +### Required + +| Variable | Example Value | Notes | +|----------|---------------|-------| +| `DOMAIN` | `yourdomain.com` | Your root domain | +| `ENVIRONMENT` | `production` | `staging` or `production` | +| `FRONTEND_HOST` | `https://dashboard.yourdomain.com` | Full URL to the frontend | +| `SECRET_KEY` | *(generate)* | `python3 -c "import secrets; print(secrets.token_urlsafe(32))"` | +| `FIRST_SUPERUSER` | `admin@wellbeing.app` | Admin email | +| `FIRST_SUPERUSER_PASSWORD` | *(generate)* | Strong password | +| `POSTGRES_USER` | `postgres` | | +| `POSTGRES_PASSWORD` | *(generate)* | Strong password | +| `POSTGRES_DB` | `well_apps` | | +| `POSTGRES_PORT` | `5432` | | +| `BACKEND_CORS_ORIGINS` | `https://dashboard.yourdomain.com` | Comma-separated allowed origins | +| `PROJECT_NAME` | `Well Apps` | Shown in API docs and emails | + +### Optional + +| Variable | Example Value | Notes | +|----------|---------------|-------| +| `SMTP_HOST` | `smtp.mailgun.org` | For email sending | +| `SMTP_USER` | `postmaster@yourdomain.com` | | +| `SMTP_PASSWORD` | *(your smtp password)* | | +| `SMTP_PORT` | `587` | | +| `SMTP_TLS` | `True` | | +| `EMAILS_FROM_EMAIL` | `noreply@yourdomain.com` | | +| `SENTRY_DSN` | `https://...@sentry.io/...` | Error tracking | +| `DOCKER_IMAGE_BACKEND` | `well-apps-backend` | | +| `DOCKER_IMAGE_FRONTEND` | `well-apps-frontend` | | + +--- + +## 6. Deploy + +### First deploy + +Click **Deploy** in the Coolify dashboard. Coolify will: + +1. Clone the repo +2. Build the backend and frontend Docker images +3. Start PostgreSQL and wait for it to be healthy +4. Run the prestart migration script +5. Start the backend and frontend services +6. Configure Traefik routing and SSL + +### Auto-deploy on push + +In the resource settings, enable **Auto Deploy** and select the branch. +Coolify installs a GitHub webhook that triggers a build on every push. + +### Manual deploy via Coolify API + +```bash +# Get your Coolify API token from Settings → API Tokens +COOLIFY_TOKEN="your-api-token" +COOLIFY_URL="https://coolify.yourdomain.com" + +# Trigger a deployment +curl -X POST "$COOLIFY_URL/api/v1/deploy" \ + -H "Authorization: Bearer $COOLIFY_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"uuid": "your-resource-uuid"}' +``` + +--- + +## 7. Post-Deploy Verification + +```bash +# Health check +curl -f https://api.yourdomain.com/api/v1/utils/health-check/ + +# API docs +open https://api.yourdomain.com/docs + +# Frontend +open https://dashboard.yourdomain.com +``` + +--- + +## 8. Backups + +Configure automated PostgreSQL backups in Coolify: + +1. Go to your resource → **Backups** +2. Select the `db` service +3. Set schedule (e.g., daily at 2 AM) +4. Choose backup destination: + - **Local**: stored on the VPS (configure offsite sync separately) + - **S3-compatible**: direct upload to S3, Backblaze B2, R2, etc. + +### Manual backup + +```bash +# SSH into your VPS +docker exec well-apps-db-1 pg_dump -U postgres well_apps > backup_$(date +%Y%m%d).sql +``` + +--- + +## 9. Monitoring + +Coolify provides basic container monitoring (CPU, memory, disk). For +production, consider adding: + +- **Sentry** — set `SENTRY_DSN` env var for error tracking +- **Uptime Kuma** — deploy as a separate Coolify service for uptime monitoring +- **Dozzle** — deploy for centralized container log viewing + +--- + +## Compose Files Reference + +| File | Use | +|------|-----| +| `compose.coolify.yml` | Coolify deployment (no Traefik labels) | +| `compose.yml` | Self-hosted production with external Traefik | +| `compose.override.yml` | Local development (hot-reload, mailcatcher) | +| `compose.traefik.yml` | Standalone Traefik proxy (not needed with Coolify) | + +--- + +## Migrating from Self-Hosted Runner Deployment + +If you previously deployed using the GitHub Actions self-hosted runner +workflow (`deploy-staging.yml` / `deploy-production.yml`), those workflows +are no longer needed for Coolify deployments. Coolify handles builds and +deploys directly via its GitHub webhook integration. + +The CI workflows (`test-backend.yml`, `playwright.yml`, etc.) continue to +run as before — they validate code on push/PR and are independent of the +deployment method. + +--- + +## Troubleshooting + +**Build fails: "Variable not set"** +Check that all required environment variables are configured in the Coolify +resource settings. The `compose.coolify.yml` file uses `${VAR}` syntax +without the `?Variable not set` assertions, so missing vars will be empty +strings rather than hard errors — check Coolify logs for runtime issues. + +**Database connection refused** +The prestart service waits for the database health check. If it still fails, +check that `POSTGRES_SERVER=db` is set (Coolify's shared network lets +services reach each other by service name). + +**SSL certificate not provisioning** +Verify your DNS A record points to the VPS IP and the wildcard `*.domain` +is configured. Coolify's Traefik needs ports 80 and 443 open on the VPS +firewall. + +**Frontend shows "Network Error"** +Check `VITE_API_URL` build arg in `compose.coolify.yml` — it must match +your API domain (`https://api.yourdomain.com`). This is baked into the +frontend at build time, so a redeploy is needed after changing the domain. diff --git a/frontend/index.html b/frontend/index.html index 57621a268b..5f34892e9e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,7 +4,7 @@ - Full Stack FastAPI Project + Well Apps diff --git a/frontend/src/components/Common/Footer.tsx b/frontend/src/components/Common/Footer.tsx index 279e1e7628..94811fb367 100644 --- a/frontend/src/components/Common/Footer.tsx +++ b/frontend/src/components/Common/Footer.tsx @@ -1,18 +1,11 @@ -import { FaGithub, FaLinkedinIn } from "react-icons/fa" -import { FaXTwitter } from "react-icons/fa6" +import { FaGithub } from "react-icons/fa" const socialLinks = [ { icon: FaGithub, - href: "https://github.com/fastapi/fastapi", + href: "https://github.com/the-ai-buildr/well-apps", label: "GitHub", }, - { icon: FaXTwitter, href: "https://x.com/fastapi", label: "X" }, - { - icon: FaLinkedinIn, - href: "https://linkedin.com/company/fastapi", - label: "LinkedIn", - }, ] export function Footer() { @@ -22,7 +15,7 @@ export function Footer() {