Deploy to Coolify
Coolify is a self-hostable PaaS that makes deploying Docker applications easy. This guide covers deploying acodeaday to Coolify.
Prerequisites
- A Coolify instance (self-hosted or cloud)
- A VPS with at least 2 CPU cores and 4GB RAM
- A domain name (optional but recommended)
- Supabase account for auth and database
Deployment Methods
Method 1: Docker Compose (Recommended)
Deploy using the production compose file with pre-built images.
Step 1: Create a New Project
- In Coolify, go to Projects → New Project
- Name it
acodeaday
Step 2: Add Docker Compose Resource
- Click + New → Docker Compose
- Choose Empty Docker Compose
- Paste the contents of
docker-compose.prod.ymlfrom the repo
Step 3: Configure Environment Variables
In the Coolify UI, add these environment variables:
Required:
DATABASE_URL=postgresql+asyncpg://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
SUPABASE_URL=https://[your-project].supabase.co
SUPABASE_KEY=[your-anon-key]
SUPABASE_SERVICE_ROLE_KEY=[your-service-role-key]
VITE_SUPABASE_URL=https://[your-project].supabase.co
VITE_SUPABASE_KEY=[your-anon-key]Service Role Key
The SUPABASE_SERVICE_ROLE_KEY enables auto-confirmation of the default user's email. Without it, you'll need to manually confirm the user in Supabase Dashboard → Authentication → Users.
For path-based routing (recommended):
VITE_API_URL=/apiOptional (for AI chat):
GOOGLE_API_KEY=...
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...Step 4: Configure Domain Routing
Recommended: Path-based routing (single domain)
Configure Coolify/Caddy to route:
yourdomain.com/→ frontend container (port 3000)yourdomain.com/api/→ backend container (port 8000)
With this setup, set VITE_API_URL=/api (relative URL).
Alternative: Separate domains
app.yourdomain.com→ frontendapi.yourdomain.com→ backend
Set VITE_API_URL=https://api.yourdomain.com
Step 5: Enable Privileged Mode for Judge0
Judge0 requires privileged mode. In Coolify:
- Go to the Judge0 server container settings
- Enable Privileged Mode
- Do the same for Judge0 workers
WARNING
Privileged mode is required for Judge0's sandboxed code execution. Without it, code submissions will fail.
Step 6: Deploy
Click Deploy and wait for all services to start. The backend will automatically:
- Run database migrations
- Seed the problem database
Method 2: GitHub Repository
Let Coolify build from source.
Step 1: Connect GitHub
- In Coolify, go to Sources → Add GitHub App
- Authorize Coolify to access your repo
Step 2: Create Services
Add each service separately:
Frontend:
- + New → Public Repository or Private Repository
- Enter:
https://github.com/engineeringwithtemi/acodeaday - Set Build Pack: Docker
- Set Dockerfile Location:
frontend/Dockerfile - Set Docker Context:
frontend
Backend:
- Same process, but:
- Dockerfile Location:
backend/Dockerfile - Docker Context:
backend
- Dockerfile Location:
Judge0 Stack:
- Add as Docker Compose
- Include only Judge0 services from
docker-compose.yml
Step 3: Configure Networking
Ensure all services are on the same Docker network so they can communicate.
Step 4: Set Environment Variables
Same as Method 1.
Health Checks
The services include health checks:
Backend:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
start_period: 60s
retries: 3Frontend:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 30s
timeout: 10s
start_period: 30s
retries: 3Coolify will use these to determine when services are ready.
Troubleshooting
Judge0 fails to start
Problem: Judge0 requires privileged mode.
Solution: Enable privileged mode in Coolify container settings.
Frontend can't reach backend
Problem: VITE_API_URL is incorrect.
Solution:
- Path-based routing: Set
VITE_API_URL=/api - Separate domains: Set
VITE_API_URL=https://api.yourdomain.com
Database connection timeout
Problem: Supabase connection pooler timeout or connection errors.
Solution: You must use the Transaction pooler URL (port 6543), not direct connection (port 5432):
# ✅ Correct - Transaction pooler (port 6543)
postgresql+asyncpg://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
# ❌ Wrong - Direct connection (port 5432)
postgresql+asyncpg://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:5432/postgresTo get the correct connection string:
- Supabase Dashboard → Settings → Database
- Under Connection string, select URI
- Choose Transaction pooler (port 6543)
- Replace
postgresql://withpostgresql+asyncpg://
Migrations not running
Problem: Database tables don't exist.
Solution: The backend runs migrations automatically on startup. Check container logs:
docker logs acodeaday-backendIf migrations failed, you can run them manually:
docker exec acodeaday-backend alembic upgrade head
docker exec acodeaday-backend python scripts/seed_problems.py seedBrowser showing old API URLs after config change
Problem: After changing VITE_API_URL or other environment variables, the browser still makes requests to the old URL.
Cause: Browser caches the compiled JavaScript files. Even though the container replaces environment variables at startup, browsers may serve cached versions.
Solution:
- Hard refresh the page:
Ctrl+Shift+R(Windows/Linux) orCmd+Shift+R(Mac) - If that doesn't work, clear browser cache:
- Chrome: Settings → Privacy → Clear browsing data → Cached images and files
- Or open DevTools (F12) → Network tab → Check "Disable cache" → Refresh
- Log out and log back in - This forces a fresh page load
- Try incognito/private mode to verify the fix works with a clean cache
For Production
After changing environment variables in Coolify:
- Redeploy the frontend service
- Ask users to hard refresh if they experience issues
SSL/HTTPS issues
Problem: Mixed content errors.
Solution: Ensure all URLs use HTTPS:
VITE_API_URL=https://api.yourdomain.com(not http)VITE_SUPABASE_URL=https://[project].supabase.co
Updates
To update to a new version:
- Pull latest images:
docker compose pull - Restart services:
docker compose up -d
Or in Coolify, click Redeploy.
Next Steps
- Self-Hosting Overview - Other deployment options
- Environment Variables - Complete reference
- Adding Problems - Customize problem set