8.1 KiB
8.1 KiB
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 URLsSUPABASE_URL: Server-side internal Docker URL (optional, falls back toNEXT_PUBLIC_SUPABASE_URL)NEXT_PUBLIC_SUPABASE_URL: Client-side external URL (required)- New
ENV.SUPABASE.SERVER_URLproperty 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 usesNEXT_PUBLIC_SUPABASE_URLfor browser/client-sidecreateSupabaseAdminClient(): UsesENV.SUPABASE.SERVER_URL(internal Docker URL in production)
-
src/lib/supabase-server.ts:createServerSupabaseClient(): UsesENV.SUPABASE.SERVER_URLfor server componentscreateRequestSupabaseClient(): UsesENV.SUPABASE.SERVER_URLfor API routes
4. Database Connection (Prisma)
- ✅
prisma/schema.prisma: Already compatible with both local and Docker network connections - ✅
package.json: Build scripts includeprisma generatewhich runs during Docker build - ✅
postinstallscript ensures Prisma client is generated afternpm install
5. Docker Optimization
- ✅ Created
.dockerignorewith proper exclusions - ✅ Verified
package.jsonscripts work in Docker environment - ✅ Prisma client generation runs during build (
prisma generatein build script)
6. Hardcoded URL Fixes
- ✅ Fixed
src/app/api/admin/guests/route.ts: Now usesENV.APP_URL - ✅ Fixed
src/app/api/rsvp/submit/route.ts: Now usesENV.APP_URL(2 instances) - ✅ Fixed
src/lib/api-client.ts: Now usesENV.APP_URLfor server-side
7. Git Configuration
- ✅ Updated
.gitignoreto exclude.env.production
📋 Environment Variables Required in Coolify
Set these environment variables in your Coolify service configuration:
Required Variables
# 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
# 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_URLfor both client and server SUPABASE_URLcan be omitted (falls back toNEXT_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
- Example:
-
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_URLifSUPABASE_URLis not set
- Example:
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
-
Get Container IDs from Coolify:
- Find your Supabase Kong container ID
- Find your Supabase DB container ID
- Update
SUPABASE_URLandDATABASE_URLwith actual container IDs
-
Generate Secrets:
# Generate SESSION_SECRET openssl rand -base64 32 # Generate CSRF_SECRET openssl rand -base64 32 -
Verify Local Build:
cd app npm run buildEnsure build succeeds without errors.
In Coolify
-
Create New Service:
- Source: Your Git repository
- Build Command:
npm ci && npm run build - Start Command:
npm start - Port:
3000
-
Set Environment Variables:
- Copy all required variables from
.env.example - Replace placeholders with actual values
- Important: Set
SUPABASE_URLwith actual container ID
- Copy all required variables from
-
Configure Networking:
- Ensure Next.js app can reach Supabase containers via Docker network
- Verify container names match your
SUPABASE_URLandDATABASE_URL
-
Deploy:
- Coolify will run
npm ci,npm run build, thennpm start - Prisma client will be generated during build (
prisma generatein build script)
- Coolify will run
🔍 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_URLandNEXT_PUBLIC_SUPABASE_ANON_KEYare set
Issue: Server-side Supabase calls fail
- Solution: Check
SUPABASE_URLis set correctly with container ID - Solution: Verify Docker network allows communication between containers
Issue: Database connection fails
- Solution: Verify
DATABASE_URLuses correct container ID and password - Solution: Check Docker network connectivity
Issue: Build fails with Prisma errors
- Solution: Ensure
DATABASE_URLis set during build (Prisma needs it for introspection) - Solution: Check
prisma generateruns successfully in build script
📝 Notes
- Local Development: Still works with
.env.localusinglocalhostURLs - Backward Compatibility: If
SUPABASE_URLis not set, falls back toNEXT_PUBLIC_SUPABASE_URL - Test Files: Hardcoded
localhost:3000in test files is intentional and fine - Proxy/Geofence:
src/proxy.tschecks 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
- Test the build locally:
npm run build - Set up environment variables in Coolify
- Deploy to Coolify
- Verify all functionality works
- 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