- Change header from 'Inspired Color Palette' to 'Complementary Style Suggestions' - Add note explaining wedding's actual color scheme is sage green (matching app) - Clarify earthly tones are optional suggestions to complement theme, not requirements - Update narrative to emphasize guests can choose their own colors - Update style tip to emphasize these are optional suggestions, not requirements - Addresses guest confusion about needing to match earthly tones
9.2 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
Connect to Supabase Network:
To enable direct communication with Supabase services via internal Docker networking, connect your app container to the Supabase network:
Option A: Via Coolify UI (Recommended)
- In your Coolify service settings, navigate to "Networks" or "Docker Networks"
- Add an external network with the name:
n4k8sswk0wocsg48cowookk8 - Ensure the network is marked as "external"
- Save the configuration
Option B: Via Docker Compose Override
- If Coolify supports docker-compose configuration, add this to your service's docker-compose section:
networks: - default - supabaseAnd define the network:
networks: supabase: external: true name: n4k8sswk0wocsg48cowookk8Note: The network ID
n4k8sswk0wocsg48cowookk8must exist before your container starts. If Supabase is deployed in Coolify, this network should already exist. -
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
- Solution: Ensure app container is connected to Supabase network (
n4k8sswk0wocsg48cowookk8) - Solution: Verify network exists:
docker network ls | grep n4k8sswk0wocsg48cowookk8
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