Coolify is a self-hosted deployment control panel. It runs on your VPS and deploys Next.js from Git or Docker, with a database, reverse proxy and TLS. You trade managed convenience for lower fixed cost and more operational responsibility.
Key takeaways
- Best for: teams that want a predictable VPS bill and are comfortable managing backups, updates and monitoring.
- Not ideal for: teams without someone who can own server security and recovery.
- Pin the Node version and keep production secrets out of the repository.
- Test auth, forms, images and redirects on a preview URL before promoting.
- Choose the region close to your database and users, and move long jobs to a worker.
What Coolify expects from a Next.js app
A Next.js deployment has four parts: a build, a runtime, environment-specific configuration and persistent services. The build turns your routes into server and client output. The runtime serves dynamic requests and static assets. Environment values connect the app to its database and third-party APIs. Persistent services — database, object storage, queues — must live outside the app container.
| Layer | What to check before deploying |
|---|---|
| Build | Node version, install command, monorepo root, build output |
| Runtime | Serverless, container or static; timeout and memory limits |
| Configuration | Production and preview environment variables; secrets |
| Data | Managed database, connection pooling, backups and migrations |
| Files | Object storage for uploads; no reliance on the local filesystem |
| Observability | Logs, errors, uptime checks and a spending limit |
Step-by-step deployment
- Provision a VPS. Choose a provider and size the server for the build, the app and the database. Start with separate volumes for data.
- Install Coolify. Follow the current install guide, secure the dashboard and enable automatic updates with a rollback plan.
- Add the application. Connect the repository or a Dockerfile, set the build pack and the start command.
- Add PostgreSQL. Create a database in Coolify, back it up and connect over the internal network.
- Configure the domain and TLS. Point DNS to the server and let Coolify issue certificates.
- Set backups and alerts. Back up the database and uploads off the server; add uptime and disk alerts.
Environment variables and secrets
- Store secrets in Coolify's environment settings, not in the repository.
- Use a separate database service or volume; do not bake data into the app container.
- Keep the server's SSH access and firewall rules tight.
What usually breaks in production
| Symptom | Likely cause | Fix |
|---|---|---|
| Build passes locally, fails on the host | Different Node version or missing lockfile | Pin the runtime and commit the lockfile |
| Auth callback loops | Wrong callback URL or cookie domain | Set the production URL and secure cookie settings |
| Images 404 or unoptimised | Image loader or static export mismatch | Configure the loader or use a CDN |
| Database connection errors | Wrong region, pooling or TLS settings | Use the internal URL, a pooler and the required TLS mode |
| Uploads disappear | Ephemeral filesystem | Move uploads to object storage |
| Long request times out | Work is running in the request path | Move it to a queue or background worker |
Limits and cost on Coolify
The software is open source; the main cost is the VPS, backups and your time. A small app can run cheaply, but the operational cost is real.
Do not skip the preview
A preview deployment is not a production test if it uses a different database and a different auth callback. Test the real user journey with production-like data before you promote.
When to choose something else
Choose a managed platform if nobody on the team can own the server when the trade-offs above do not fit. The right platform is the one your team can operate safely at 2am, not the one with the best demo.
Pre-launch checklist
- The production domain, HTTPS and canonical URL are correct.
- Auth callbacks, cookies and email links use the production origin.
- Database migrations have run, and a restore has been tested.
- Every environment variable exists in production, not just preview.
- A test order, form or sign-up completes end to end.
- Robots, sitemap, analytics and consent behave as expected.
- The error page, 404 and a hard refresh on a deep route all work.
Rollback and recovery
| Failure | Immediate action | What to verify |
|---|---|---|
| Bad application release | Promote the previous build | The database change is backward compatible |
| Broken migration | Stop writes and restore from a verified backup | Data loss window and reconciliation |
| Auth outage | Roll back the auth configuration | Sessions and callback URLs |
| Payment errors | Disable the failing method | Pending orders and webhook retries |
| Traffic spike | Scale or enable a queue | Database connections and rate limits |
| Region incident | Fail over or restore elsewhere | DNS, data replication and RPO |
Observability after launch
| Signal | What to watch | Why |
|---|---|---|
| Errors | New error groups and affected routes | Catch regressions before support does |
| Latency | p95 and p99 by route | Find slow queries and cold starts |
| Database | Connections, slow queries and storage | The most common bottleneck |
| Jobs | Queue depth and failed retries | Silent backlog |
| Vitals | LCP, INP and CLS by device | Real-user experience |
| Cost | Spend and egress | Avoid a surprise invoice |
Frequently asked questions
Not necessarily. Check the runtime features you use: Server Actions, dynamic routes, image optimisation, middleware, WebSockets, background jobs and native dependencies. Teams without someone who can own server security and recovery.
Use a monorepo when the app shares code or types with other packages and the platform supports a root directory. Use a separate repository when the deployment is simpler and the app has no shared build pipeline. The important thing is to pin the root, install command and lockfile.
Run migrations as a separate deployment step with a lock, not on every app boot. Back up first, test against a staging database and have a rollback plan. If the platform has no release phase, run the migration from CI before promoting the app.
Error rate, p95 response time, database connections, background-job failures, Core Web Vitals and the main conversion event. Add an uptime check from outside the platform and a billing alert.
Sources and further reading
- Next.js deployment guide (nextjs.org)
- Next.js self-hosting guide (nextjs.org)
- Coolify documentation (coolify.io)
Related reading
Need a deployment review?
Send the stack, the hosting plan and the launch date. I will flag the runtime limits, data risks and missing checks before you go live.
How to cite this guide: Nur Hossain Repon, “Deploy a Next.js app to Coolify: step-by-step guide”, Nhrepon Portfolio, reviewed October 2026, https://nhrepon.com/posts/deploy-a-next-js-app-to-coolify-step-by-step-guide.





Comments
No comments yet.