# Coolify Migration Guide This document outlines the changes made to prepare the Next.js wedding app for deployment on Coolify (self-hosted on Proxmox). ## ✅ Changes Completed ### 1. Next.js Configuration (`next.config.ts`) - ✅ Already configured with `output: "standalone"` for Docker deployment - ✅ No localhost-specific configurations found - ✅ Compatible with Coolify's build process ### 2. Environment Variables Strategy #### Updated Files: - **`src/lib/env.ts`**: Added support for dual Supabase URLs - `SUPABASE_URL`: Server-side internal Docker URL (optional, falls back to `NEXT_PUBLIC_SUPABASE_URL`) - `NEXT_PUBLIC_SUPABASE_URL`: Client-side external URL (required) - New `ENV.SUPABASE.SERVER_URL` property that uses internal URL in production #### Created Files: - **`.env.example`**: Complete production environment variable template with documentation ### 3. Supabase Client Configuration #### Updated Files: - **`src/lib/supabase.ts`**: - `createSupabaseClient()`: Always uses `NEXT_PUBLIC_SUPABASE_URL` for browser/client-side - `createSupabaseAdminClient()`: Uses `ENV.SUPABASE.SERVER_URL` (internal Docker URL in production) - **`src/lib/supabase-server.ts`**: - `createServerSupabaseClient()`: Uses `ENV.SUPABASE.SERVER_URL` for server components - `createRequestSupabaseClient()`: Uses `ENV.SUPABASE.SERVER_URL` for API routes ### 4. Database Connection (Prisma) - ✅ `prisma/schema.prisma`: Already compatible with both local and Docker network connections - ✅ `package.json`: Build scripts include `prisma generate` which runs during Docker build - ✅ `postinstall` script ensures Prisma client is generated after `npm install` ### 5. Docker Optimization - ✅ Created `.dockerignore` with proper exclusions - ✅ Verified `package.json` scripts work in Docker environment - ✅ Prisma client generation runs during build (`prisma generate` in build script) ### 6. Hardcoded URL Fixes - ✅ Fixed `src/app/api/admin/guests/route.ts`: Now uses `ENV.APP_URL` - ✅ Fixed `src/app/api/rsvp/submit/route.ts`: Now uses `ENV.APP_URL` (2 instances) - ✅ Fixed `src/lib/api-client.ts`: Now uses `ENV.APP_URL` for server-side ### 7. Git Configuration - ✅ Updated `.gitignore` to exclude `.env.production` ## 📋 Environment Variables Required in Coolify Set these environment variables in your Coolify service configuration: ### Required Variables ```bash # Application NODE_ENV=production NEXT_PUBLIC_APP_URL=https://themoyos.co.za # Supabase - Client-side (external via Cloudflare) NEXT_PUBLIC_SUPABASE_URL=https://supabase-api.themoyos.co.za NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key # Supabase - Server-side (internal Docker network) SUPABASE_URL=http://supabase-kong-CONTAINER_ID:8000 SUPABASE_SERVICE_ROLE_KEY=your_service_role_key # Database (internal Docker network) DATABASE_URL=postgresql://postgres:PASSWORD@supabase-db-CONTAINER_ID:5432/postgres # Security SESSION_SECRET=your_32_char_minimum_secret CSRF_SECRET=your_csrf_secret ADMIN_PASSWORD=your_secure_password ``` ### Optional Variables ```bash # Email (Resend) RESEND_API_KEY=your_resend_key FROM_EMAIL=noreply@themoyos.co.za # SMS (Twilio) TWILIO_ACCOUNT_SID=your_twilio_sid TWILIO_AUTH_TOKEN=your_twilio_token TWILIO_PHONE_NUMBER=+1234567890 # Feature Flags ENABLE_NOTIFICATIONS=true ENABLE_ANALYTICS=false # Error Tracking NEXT_PUBLIC_SENTRY_DSN=your_sentry_dsn # Analytics NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX # Weather API OPENWEATHER_API_KEY=your_openweather_key # Ollama AI (Wedding Concierge) # Use internal Docker network URL if Ollama is in same Coolify stack # Or external URL if Ollama is on a different service OLLAMA_URL=http://ollama-CONTAINER_ID:11434 # Or: OLLAMA_URL=https://ollama.yourdomain.com OLLAMA_MODEL=jarvis-concierge OLLAMA_TEMPERATURE=0.7 ``` ## 🔧 How Dual Supabase URLs Work ### Development (Local Mac) - Uses `NEXT_PUBLIC_SUPABASE_URL` for both client and server - `SUPABASE_URL` can be omitted (falls back to `NEXT_PUBLIC_SUPABASE_URL`) - Example: `http://localhost:54321` ### Production (Coolify) - **Client-side (Browser)**: Uses `NEXT_PUBLIC_SUPABASE_URL` → External URL via Cloudflare tunnel - Example: `https://supabase-api.themoyos.co.za` - **Server-side (API Routes, Server Components)**: Uses `SUPABASE_URL` → Internal Docker network URL - Example: `http://supabase-kong-CONTAINER_ID:8000` - Falls back to `NEXT_PUBLIC_SUPABASE_URL` if `SUPABASE_URL` is not set ### Benefits - **Performance**: Server-side calls use internal Docker network (faster, no external routing) - **Security**: Service role key only used server-side (never exposed to browser) - **Reliability**: Internal network calls don't depend on Cloudflare tunnel availability ## 🚀 Deployment Steps ### Before Deployment 1. **Get Container IDs from Coolify**: - Find your Supabase Kong container ID - Find your Supabase DB container ID - Update `SUPABASE_URL` and `DATABASE_URL` with actual container IDs 2. **Generate Secrets**: ```bash # Generate SESSION_SECRET openssl rand -base64 32 # Generate CSRF_SECRET openssl rand -base64 32 ``` 3. **Verify Local Build**: ```bash cd app npm run build ``` Ensure build succeeds without errors. ### In Coolify 1. **Create New Service**: - Source: Your Git repository - Build Command: `npm ci && npm run build` - Start Command: `npm start` - Port: `3000` 2. **Set Environment Variables**: - Copy all required variables from `.env.example` - Replace placeholders with actual values - **Important**: Set `SUPABASE_URL` with actual container ID 3. **Configure Networking**: - Ensure Next.js app can reach Supabase containers via Docker network - Verify container names match your `SUPABASE_URL` and `DATABASE_URL` 4. **Deploy**: - Coolify will run `npm ci`, `npm run build`, then `npm start` - Prisma client will be generated during build (`prisma generate` in build script) ## 🔍 Verification Checklist After deployment, verify: - [ ] Application starts without errors - [ ] API routes respond correctly - [ ] Supabase client-side calls work (check browser network tab) - [ ] Supabase server-side calls work (check API route logs) - [ ] Database connections work (Prisma queries succeed) - [ ] No hardcoded localhost URLs in production logs - [ ] Environment variables are loaded correctly ## 🐛 Troubleshooting ### Issue: "Supabase is not configured" - **Solution**: Ensure `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` are set ### Issue: Server-side Supabase calls fail - **Solution**: Check `SUPABASE_URL` is set correctly with container ID - **Solution**: Verify Docker network allows communication between containers ### Issue: Database connection fails - **Solution**: Verify `DATABASE_URL` uses correct container ID and password - **Solution**: Check Docker network connectivity ### Issue: Build fails with Prisma errors - **Solution**: Ensure `DATABASE_URL` is set during build (Prisma needs it for introspection) - **Solution**: Check `prisma generate` runs successfully in build script ## 📝 Notes - **Local Development**: Still works with `.env.local` using `localhost` URLs - **Backward Compatibility**: If `SUPABASE_URL` is not set, falls back to `NEXT_PUBLIC_SUPABASE_URL` - **Test Files**: Hardcoded `localhost:3000` in test files is intentional and fine - **Proxy/Geofence**: `src/proxy.ts` checks for localhost - this is intentional for development ## 🔄 Migration Summary | Component | Before | After | |-----------|--------|-------| | Client Supabase | `NEXT_PUBLIC_SUPABASE_URL` | `NEXT_PUBLIC_SUPABASE_URL` (unchanged) | | Server Supabase | `NEXT_PUBLIC_SUPABASE_URL` | `SUPABASE_URL` (internal Docker) or fallback | | Database | `DATABASE_URL` (localhost) | `DATABASE_URL` (Docker network) | | App URLs | Hardcoded localhost | `ENV.APP_URL` | | Build Output | Standard | Standalone (Docker-ready) | ## ✨ Next Steps 1. Test the build locally: `npm run build` 2. Set up environment variables in Coolify 3. Deploy to Coolify 4. Verify all functionality works 5. Monitor logs for any issues --- **Migration completed on**: $(date) **Next.js Version**: 16.1.1 **React Version**: 19.2.1 **Prisma Version**: 7.2.0