How to deploy a Next.js app on Coolify

Deploy Next.js on self-hosted Coolify: install it, connect your repo, pick Nixpacks or the official standalone Dockerfile, set env vars and add an HTTPS domain.

Contents10 sections
By Toni LukeUpdated 6 min read

To deploy Next.js on Coolify, create an application from your Git repository, leave the Build Pack on Nixpacks, make sure Ports Exposes is 3000, add your environment variables, and enter your domain with https:// so Coolify's proxy gets a Let's Encrypt certificate. If Nixpacks gives you trouble, Coolify's own Next.js page says to switch to a Dockerfile copied from the official Next.js repository, built in standalone mode.

That's the whole recipe. The steps below fill in the details, with each one taken from Coolify's or Next.js's documentation. The latest Coolify release is v4.3.23, published 18 September 2026.

Prerequisites

  • A 64-bit Linux server (amd64 or arm64) you can reach over SSH, with at least 2 CPU cores, 2 GB of RAM and 10 GB free disk. That's Coolify's own minimum, and it covers Coolify itself, not your app. The docs warn that builds on the same server can use enough resources to make it unresponsive. A Next.js build is exactly that kind of load, so give it headroom. Best VPS for self-hosting covers server choices.
  • A domain where you can add an A record.
  • A Next.js project in a Git repository, with working build and start scripts in package.json.

Step 1: install Coolify

SSH in as root (or a sudo user) on a fresh server and run the documented installer:

bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

Expected result: a "Congratulations!" message with the dashboard link. Open http://<server-ip>:8000 and create the admin account straight away. Coolify's docs warn that "anyone who reaches the registration page first can become the instance admin and gain root access to your server."

Then back up /data/coolify/source/.env somewhere safe. It holds APP_KEY, which encrypts Coolify's database values, and you need it to restore from a backup.

On Ubuntu, use an LTS release. If Docker came from snap, remove it first. Both notes are from the install page.

Step 2: open the right ports

For the server running Coolify, the firewall page lists:

PortUsed for
22/tcpSSH
80/tcpHTTP, and certificate generation through the Coolify proxy
443/tcpHTTPS through the Coolify proxy
8000/tcpThe dashboard by IP
6001/tcp, 6002/tcpReal-time updates and the web terminal by IP

Once the dashboard itself runs on a domain through the proxy, you can close 8000, 6001 and 6002 to the public. The docs recommend your hosting provider's firewall where there is one.

Step 3: point DNS at the server

Create an A record, for example app.example.com, pointing to the server's IP. The domains page says to point the domain at the server and verify the record first, with inbound TCP ports 80 and 443 open.

Step 4: create the application

In Coolify, open a project, select + New, and choose your source.

  • Public repository: choose Public Repository, paste the HTTPS clone URL (not the SSH URL), and select Check Repository. Review the branch Coolify picks.
  • Private repository, or you want auto-deploy on push: set up a GitHub App first under Sources → + Add, using Automated Installation. Then install it on only the repositories it needs. The docs note that GitHub must be able to reach your Coolify URL for automatic deployments to work.

Coolify's public-repository page is explicit that a repo connected by URL "does not configure automatic deployments". You'd add a manual webhook instead. The GitHub App route is less fiddly.

Step 5: choose how to build

Option A: Nixpacks (the default)

Coolify's Next.js page covers two cases:

  • Server build (Node.js): set Build Pack to nixpacks. That's all.
  • Static export: set Build Pack to nixpacks, enable Is it a static site?, and set Output Directory to out. This only applies if your next.config uses output: 'export'. Next.js's static-export docs show the site landing in /out.

Check that Ports Exposes is 3000. That's the port Coolify's Next.js guide gives, and the port the official Next.js Docker example serves on.

To pin the Node.js major version, the Nixpacks versioning page says to keep one source of truth in the repo, such as "engines": { "node": "22" } in package.json. Nixpacks can also read .nvmrc. It picks the major version. The exact patch release depends on the Nix package archive the build uses.

Option B: the official standalone Dockerfile

Coolify's Next.js page: "If you are having problems with Nixpacks or want more control over the building stage, you can use a Dockerfile." Its steps are to set Ports Exposes to 3000, copy the Dockerfile from the official Next.js repository into your project root, and set Build Pack to Dockerfile.

The Next.js with-docker example has two requirements. First, add standalone output to your config:

js
// next.config.js
module.exports = {
  output: "standalone",
};

Second, copy its Dockerfile and .dockerignore into your repo root. The final stage of that Dockerfile is what makes it work behind a proxy:

dockerfile
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
...
COPY --from=builder --chown=node:node /app/.next/standalone ./
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
USER node
EXPOSE 3000
CMD ["node", "server.js"]

That's an excerpt. Copy the full file from the repository rather than this snippet. It installs dependencies from whichever lockfile you have (npm, Yarn or pnpm) and runs as the non-root node user. Its header also tells you to bump NODE_VERSION to the current LTS over time.

Step 6: set environment variables

Open Configuration → Environment Variables. Each variable has two independent switches, Build Variable and Runtime Variable, and both are on by default.

The Next.js rule that catches people: anything prefixed NEXT_PUBLIC_ is inlined into the JavaScript bundle at build time. Next.js's docs say that after the build, "your app will no longer respond to changes to these environment variables." So:

  • NEXT_PUBLIC_* values need Build Variable on, and changing one means a new deployment, not a restart.
  • Server-only secrets (database URLs, API keys) can have Build Variable off. Coolify's docs recommend that for any secret the app only reads after the container starts, and warn that ordinary Docker build arguments "can appear in image metadata."

Coolify's rule of thumb: redeploy when build-time values change, and restart when only runtime values change. It also injects PORT (the first exposed port) and HOST=0.0.0.0 if you haven't set them.

Step 7: add the domain and deploy

In the application's General settings, enter the full URL in Domains, including the scheme:

https://app.example.com

Coolify's domains page says to use https:// for automatic TLS. Then select Deploy and watch the deployment log.

Expected result, per the domains page: the hostname resolves to your server, the URL loads your app, and the browser shows a valid certificate. If you changed DNS recently, you may have to wait out the old record's TTL.

Troubleshooting

These are all from Coolify's troubleshooting docs.

  • Bad Gateway on the domain, but the app works on IP:port. Coolify says this is usually the port or the bind address. Check that Ports Exposes matches what the app listens on (3000), remove any host port mapping, and make sure the app listens on 0.0.0.0, not just localhost. The official Dockerfile sets HOSTNAME="0.0.0.0" for exactly this reason. A failing health check can cause it too.
  • The browser warns about an insecure certificate. Coolify is serving its self-signed fallback because Let's Encrypt failed. Check that port 80 is open. If Cloudflare proxies the domain, either stop proxying or use a DNS challenge. If you have an AAAA record, make sure IPv6 reaches the server too, or remove the record. A 429 in the proxy logs means Let's Encrypt has rate-limited you, and a 403 usually means a WAF is blocking it.
  • A NEXT_PUBLIC_ value is stale. It was baked in at build time. Change it with Build Variable on, then redeploy.
  • The server locks up during builds. That's the resource warning from the install docs. Add RAM or move builds elsewhere.

What to do next

Sources (14)Show
  1. Coolify Docs: NextJS (Nixpacks server/static builds, Dockerfile, Ports Exposes 3000) · accessed 2026-09-29
  2. Coolify Docs: Start with Self-hosted (requirements, install script, admin account, .env backup) · accessed 2026-09-29
  3. Coolify Docs: Firewall (ports 8000, 6001, 6002, 22, 80, 443) · accessed 2026-09-29
  4. Coolify Docs: Public repositories · accessed 2026-09-29
  5. Coolify Docs: Set Up a GitHub App · accessed 2026-09-29
  6. Coolify Docs: Environment Variables (build vs runtime, predefined PORT and HOST) · accessed 2026-09-29
  7. Coolify Docs: Domains · accessed 2026-09-29
  8. Coolify Docs: Node.js versioning in Nixpacks · accessed 2026-09-29
  9. Coolify Docs: Bad Gateway error · accessed 2026-09-29
  10. Coolify Docs: Let's Encrypt not generating SSL certificates · accessed 2026-09-29
  11. Next.js with-docker example (Dockerfile, next.config output: standalone) · accessed 2026-09-29
  12. Next.js Docs: Environment variables (NEXT_PUBLIC_ values inlined at build time) · accessed 2026-09-29
  13. Next.js Docs: Static exports (output: 'export', out directory) · accessed 2026-09-29
  14. GitHub releases API: coollabsio/coolify (v4.3.23, 2026-09-18), as recorded in the Coolify profile · accessed 2026-09-29