Deploy Next.js on Hetzner for $5
This guide walks you through deploying a production-ready Next.js app on a $5/month Hetzner VPS using Better-PaaS. By the end, you will have:
- A live Next.js app running in a Docker container
- Automatic HTTPS on your custom domain
- A Postgres database attached to your app
- A flat, predictable hosting bill
What you need
- A Hetzner account (or any VPS that runs Ubuntu/Debian)
- A Next.js app in a Git repository
- A domain name you can point at your server
- About 15 minutes
Hetzner pricing
Hetzner's CX21 plan (2 vCPU / 4 GB RAM) is roughly €4.51/month at the time of writing and is plenty for a small Next.js app plus a Postgres database. Prices vary by region and currency.
Step 1 — Create a Hetzner server
- Log in to the Hetzner Cloud Console.
- Create a new project (or use an existing one).
- Click Add Server.
- Choose a location close to your users.
- Select Ubuntu 24.04 or Debian 12 as the operating system.
- Pick the CX21 type (2 vCPU, 4 GB RAM).
- Add your SSH key so you can log in.
- Create the server.
Once the server is running, copy its public IPv4 address.
Step 2 — Open the firewall
Better-PaaS needs the following ports open:
| Port | Purpose |
|---|---|
| 22 | SSH access |
| 80 | HTTP and Let's Encrypt validation |
| 443 | HTTPS traffic |
| 3000 | Default dashboard port |
| 8080 | Default API port |
In the Hetzner console, go to Firewalls, create a firewall with those inbound TCP rules, and apply it to your server.
Step 3 — Install Better-PaaS
SSH into your server and run the installer:
ssh root@YOUR_SERVER_IP
curl -fsSL https://raw.githubusercontent.com/sumon-ohid/better-paas/main/install.sh | bashThe installer installs Docker, Caddy, Go, Node.js, pnpm, and Nixpacks, then builds the Better-PaaS dashboard and API. This takes a few minutes.
When it finishes, it prints an admin token. Copy it somewhere safe.
Save the admin token
The installer prints the admin bearer token only once. You can also read it
later from backend/data/admin_token.txt on the server.
Step 4 — Log in to the dashboard
Open your browser and visit:
http://YOUR_SERVER_IP:3000Paste the admin token and sign in. You should see the Better-PaaS dashboard.
Step 5 — Prepare your Next.js app
Better-PaaS uses Nixpacks to detect and build Next.js apps automatically. Make sure your repository has these:
package.jsonwith abuildscript- A
startscript that starts the production server - A lockfile (
package-lock.json,pnpm-lock.yaml, oryarn.lock) - Your app listens on the
PORTenvironment variable
A typical package.json looks like this:
{
"scripts": {
"build": "next build",
"start": "next start"
}
}PORT variable
Next.js reads PORT automatically with next start. If you hard-code a port,
override it in the deploy wizard or update your start command to
next start -p $PORT.
Step 6 — Deploy the app
- In the Better-PaaS dashboard, click Deploy a service.
- Choose Git and paste your repository URL, e.g.
https://github.com/yourname/my-nextjs-app. - Select the
mainbranch. - Nixpacks detects Next.js automatically. Leave the build and start commands blank unless you need to override them.
- Click Deploy.
Better-PaaS clones the repo, builds a Docker image, starts the container, and runs a health check. The first deploy may take 60–120 seconds.
When it is healthy, the dashboard shows the container status as Running.
Step 7 — Add a Postgres database
- Go to the Databases section and click Create database.
- Choose Postgres.
- Give it a name, e.g.
myapp-db. - Better-PaaS creates the container and injects a
DATABASE_URLenvironment variable into any app you attach it to. - Open your app settings, go to Environment variables, and attach the database. The connection string is added automatically.
Step 8 — Add your domain and HTTPS
- In your domain registrar or DNS provider, create an
Arecord pointing your domain (e.g.app.yourdomain.com) to your Hetzner server IP. - In Better-PaaS, open your app and go to Domains.
- Click Add domain and enter
app.yourdomain.com. - Better-PaaS tells Caddy to request a free Let's Encrypt certificate.
After DNS propagates (usually within minutes), your app is live on
https://app.yourdomain.com.
DNS can take time
If HTTPS does not work immediately, check that DNS has propagated with
dig app.yourdomain.com or an online DNS checker.
Step 9 — Enable auto-deploy on git push
- Open your app in the dashboard and go to Settings.
- Copy the webhook URL.
- In your GitHub repo, go to Settings → Webhooks → Add webhook.
- Paste the URL and choose Just the push event.
- Add the webhook.
Now every push to main redeploys your app automatically.
See auto-deploy on git push for more details.
Cost breakdown
| Item | Cost |
|---|---|
| Hetzner CX21 VPS | ~$5.35/month |
| Better-PaaS control plane | $0 (open source) |
| Let's Encrypt certificate | $0 |
| Bandwidth | Included in VPS limits |
| Total | ~$5.35/month |
This single server can host multiple apps and databases. A second side project adds almost no cost.