Stu Mason
Stu Mason

Ditching Forge for Coolify: The Full Migration

Stu Mason4 min read

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_URL to your new domain
  • DB_HOST to the Coolify postgres container hostname
  • Any other service-specific URLs

The Zero-Downtime Switch

Don't change your DNS until everything works.

  1. Set up the app in Coolify with a temporary domain or Coolify's built-in URL
  2. Deploy and test thoroughly
  3. Check queue processing works
  4. Check scheduled tasks work
  5. Check file uploads work
  6. 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.