From Localhost to Production with Coolify
A practical walkthrough of moving apps from local development to a VPS with Coolify, including setup, domains, SSL, databases, backups, and the little mistakes to avoid.
For a long time, deploying side projects felt like choosing between two moods.
Either use a polished platform like Vercel or Netlify and enjoy the simple workflow, or rent a VPS and accept that you are now responsible for servers, reverse proxies, SSL, logs, and random late-night errors.
Coolify sits in the middle. You still own the server, but you get a dashboard and a git-based deployment flow that feels closer to modern hosting.
I started looking at it because I wanted more control for small apps, experiments, and client demos. Not everything needs a full managed platform. Sometimes a decent VPS and a clean deployment panel is enough.
What Coolify is
Coolify is an open-source self-hosting platform. You install it on your server, connect your Git provider, and deploy apps, databases, and services from a web UI.
Think of it like a self-hosted alternative to Heroku, Railway, or Vercel for many common use cases.
It can handle:
- Next.js apps
- Vite/React apps
- Node.js servers
- Dockerfile based apps
- PostgreSQL
- Redis
- MySQL
- Static sites
- Services like Uptime Kuma and more
The best part is that you are not paying per project. You pay for the VPS, then decide how to use the resources.
When self-hosting makes sense
Self-hosting is not always the right answer.
If you need global edge functions, instant scaling, enterprise support, or you do not want to think about servers at all, managed platforms are still great.
Coolify makes sense when:
- You run several small projects
- You want predictable monthly cost
- You need databases near your app
- You want to host internal tools
- You are comfortable debugging basic server issues
- You want more ownership over infra
For me, the sweet spot is personal projects, low-to-medium traffic apps, staging environments, and client demos where a full managed setup feels too expensive.
Picking a VPS
You do not need a monster server to begin.
For a few small apps, a VPS with 2 vCPU and 4GB RAM is a comfortable start. You can get away with 1 vCPU and 2GB RAM for very small projects, but builds may feel slow and databases can make things tight.
Providers people commonly use:
- Hetzner
- DigitalOcean
- Vultr
- Linode
- AWS Lightsail
Pick Ubuntu LTS unless you have a strong reason not to. Keep it boring. Production servers are not the place to be too clever.
Installing Coolify
On a fresh Ubuntu server, installation is usually one command from the official Coolify install flow:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bashAfter installation, Coolify gives you a URL and you finish setup in the browser.
Before deploying apps, I like doing these basics:
- Add SSH keys
- Update system packages
- Point a domain or subdomain to the server
- Check firewall rules
- Confirm Coolify can reach GitHub/GitLab
- Set up an admin account with a strong password
This is not exciting work, but it prevents confusion later.
Connecting your domain
DNS is where beginners get stuck alot.
The basic idea is simple: point an A record to your VPS IP.
For example:
app.example.com -> 123.123.123.123Once DNS resolves, Coolify can route traffic to the right app and issue SSL certificates. If you use Cloudflare, decide whether you want proxy mode on or DNS-only while setting things up. For first setup, DNS-only is often easier because it removes one layer of mystery.
After SSL works, you can enable the proxy if you need it.
Deploying a Next.js app
The deployment flow is mostly:
- Create a new resource in Coolify.
- Connect your GitHub repository.
- Pick the branch.
- Let Coolify detect the app or choose a build pack.
- Add environment variables.
- Set the domain.
- Deploy.
For most Next.js projects, Nixpacks works fine. If your project has unusual requirements, a Dockerfile gives you more control.
The main thing to check is package manager detection. If your repo uses pnpm, make sure the lockfile exists and the build command matches the project.
For example:
pnpm install --frozen-lockfile
pnpm build
pnpm startYour exact commands depend on the app, but do not assume the platform guessed everything correctly. Read the build logs.
Environment variables
Localhost hides env problems.
In production, one missing NEXT_PUBLIC_ variable or database URL can break the app. Keep a clean .env.example in your repo and copy values carefully into Coolify.
I usually group env vars like this:
- App URL and public config
- Database connection strings
- Auth secrets
- Storage keys
- Email provider keys
- Analytics keys
Never commit real secrets. Obvious, but still worth saying because it happens.
Databases and services
Coolify can create services like PostgreSQL and Redis from the dashboard. This is very convenient for small apps.
For a personal project, putting the app and database on the same VPS can be fine. For serious production work, think harder about backups, resource limits, and whether the database should live separately.
At minimum:
- Set strong passwords
- Do not expose database ports publicly unless needed
- Create automatic backups
- Test restoring a backup once
- Monitor disk usage
Backups are not real until you have restored one. I learnt this the uncomfortable way on a small project where the backup existed, but the restore process was not tested and took way longer than expected.
Logs and debugging
When something fails, Coolify logs are the first place to look.
Common problems:
- Wrong build command
- Missing env variable
- App binding to the wrong port
- Node version mismatch
- DNS not propagated yet
- SSL challenge blocked by proxy settings
- Not enough memory during build
Do not randomly change five things at once. Change one thing, redeploy, read logs, repeat. Server debugging becomes painful when you lose track of what you changed.
Monitoring
You do not need enterprise monitoring for a side project, but you need some signal.
At minimum, set up:
- Uptime checks
- Disk usage alerts
- CPU/RAM monitoring
- Error logging for the app
Uptime Kuma is a nice simple option and can also be hosted through Coolify. For app errors, use whatever fits your stack. The point is to know when the app is down before a client messages you.
Security basics
Self-hosting means you own more responsibility.
Do these basics:
- Use SSH keys, not password login
- Keep the server updated
- Use strong Coolify admin credentials
- Enable firewall rules
- Keep only needed ports open
- Rotate secrets if they leak
- Avoid running random install scripts without understanding the source
Also remember that every extra service is another thing to maintain. Do not install ten dashboards just because they are available.
Cost expectations
The cost saving is real, but it depends on how you use it.
A single VPS can host several small apps, but you are paying with your time. If an app is important and clients depend on it, ask whether saving a few dollars is worth being responsible for every production issue.
For learning, indie projects, and controlled workloads, Coolify is excellent. For mission-critical apps with unpredictable traffic, managed infra may still be the better choice.
My practical setup
If I was setting up a small production app today, I would start like this:
- One Ubuntu VPS with 2 vCPU and 4GB RAM.
- Coolify installed cleanly.
- Domain connected through Cloudflare.
- App deployed from GitHub.
- PostgreSQL service if the project needs it.
- Automatic backups to S3-compatible storage.
- Uptime Kuma monitoring.
- A simple deployment checklist in the repo.
That setup is not fancy, but it is understandable. And understandable infra is easier to fix at 1 AM.
Conclusion
Coolify makes self-hosting feel approachable again. You still need to understand servers a bit, but you do not have to manually wire every reverse proxy and SSL certificate yourself.
The main mindset shift is this: deploying is not the finish line. Production includes logs, backups, monitoring, updates, and boring checklists.
If you respect that, Coolify can be a really good way to move projects from localhost to something real without giving up control.