Ditching Forge for Coolify: The Full Migration
Migrating a production Laravel app from Forge to Coolify - database dumps, storage files, Nixpacks configs, and all the shit that can go wrong.
Ditching Forge for Coolify: The Full Migration
I'd been on Laravel Forge for years. It's great. Set up a server, deploy Laravel apps, job done. But at $19/month for the base plan (and you need the higher tiers for multiple servers), I started wondering if I could self-host something equivalent.
Enter Coolify. Open source, you run it yourself, does most of what Forge does. Zero-downtime deployments, SSL certs, environment variables, the lot. The catch? You have to set it up yourself, and the documentation assumes you know what you're doing.
Here's everything I learned migrating a production Laravel app from Forge to Coolify.
Before You Start
You need:
- SSH access to your Forge server (to pull the database)
- A Coolify instance already running
- Your repo access sorted (GitHub deploy key or whatever)
- Access to your DNS
Set up SSH aliases to make your life easier:
# ~/.ssh/config
Host forge
HostName your_forge_ip
User forge
IdentityFile ~/.ssh/id_rsa
Host coolify
HostName your_coolify_ip
User root
IdentityFile ~/.ssh/id_rsa
Now you can just ssh forge or ssh coolify. Small thing, big time saver.
The Database
This is the scary bit. You're moving production data.
Dump it from Forge:
ssh forge
pg_dump --data-only -U forge your_database > backup.sql
Pull it to your machine:
scp forge:/home/forge/backup.sql ./
Push it to Coolify:
scp backup.sql coolify:/tmp/
Import it:
# Find your postgres container
docker ps | grep postgres
# Copy the backup in
docker cp /tmp/backup.sql container_id:/tmp/
# Shell into the container and import
docker exec -it container_id bash
psql -U postgres postgres < /tmp/backup.sql
Storage Files
If you've got user uploads or anything in Laravel's storage folder, you need to move those too:
# From Forge
scp -r forge:/home/forge/your-site/storage/app ./storage-backup
# To Coolify (find your app's storage path in Coolify settings)
scp -r storage-backup/* coolify:/data/coolify/applications/xxx/app/storage/app/
Then fix permissions inside the container:
docker exec -it your_container bash
chmod -R 775 /app/storage
chown -R www-data:www-data /app/storage
The storage symlink might need recreating too:
php artisan storage:link --force
The Nixpacks Config
Coolify uses Nixpacks to build Laravel apps. You need a nixpacks.toml in your repo root:
[phases.setup]
nixPkgs = ["php82", "php82Extensions.redis", "python311Packages.supervisor"]
[phases.build]
cmds = [
"mkdir -p /var/log",
"mkdir -p /app/storage/framework/{views,cache,sessions}",
"chmod -R 775 /app/storage",
"chown -R www-data:www-data /app"
]
[start]
cmd = "php artisan serve --host=0.0.0.0 --port=8080"
This is a simplified version. If you need queue workers, Horizon, Reverb, etc., you'll need supervisor configs too.
Environment Variables
Copy your .env from Forge and paste it into Coolify's environment variables section. Update:
APP_URLto your new domainDB_HOSTto the Coolify postgres container hostname- Any other service-specific URLs
The Zero-Downtime Switch
Don't change your DNS until everything works.
- Set up the app in Coolify with a temporary domain or Coolify's built-in URL
- Deploy and test thoroughly
- Check queue processing works
- Check scheduled tasks work
- Check file uploads work
- THEN switch DNS
This way if something's broken, your users are still hitting the Forge server while you fix it.
What Coolify Handles Automatically
- SSL certificates (via Let's Encrypt)
- Reverse proxy config
- Container networking
- Zero-downtime deployments (blue-green style)
- Health checks
What You Have to Do Yourself
- Worker processes (supervisor config)
- PHP extensions (nixpacks.toml)
- File permissions (always fucking file permissions)
- Cron/scheduled tasks
- Any custom nginx config
Was It Worth It?
For me, yes. I'm now paying ~€20/month for a Coolify setup that runs 8 apps, compared to $39/month for Forge's Pro plan. The setup took a weekend, but I learned a lot and have more control over the infrastructure.
The main downside: when things break, there's no support team to email. You're googling error messages and reading Docker logs. If that sounds exhausting, stay on Forge. If it sounds fun, welcome to Coolify.
Get the Friday email
What I shipped this week, what I learned, one useful thing.
No spam. Unsubscribe anytime. Privacy policy.