v0.5.0 · homelab-ready · MIT

Your homelab can ship like the cloud.

A no-downtime, multi-tenant Next.js deployment manager for your own hardware. Blue-green deploys, preview branches, and managed Postgres, Redis and MinIO, proxied to the world through Cloudflare tunnels. No cloud bill required.

manager.yourdomain.dev
Applications
3 running
b
blog-app
blog.yourdomain.dev
live
s
shop-storefront
shop.yourdomain.dev
building
d
docs-site
docs.yourdomain.dev
live
deploy #1284 · 0ms downtime
i5-6500 · 16GB · home network
$0/mo
in recurring cloud bills
0ms
downtime on every deploy
One box
every side project, one machine
MIT
open source, yours forever
The blue/green swap

Watch a deploy happen, without a blink.

Push to main. Port-Au-Next builds the new version, health-checks it, and only then tells nginx to route traffic over. The old version serves the whole time.

blog-app · production
All traffic on the blue slot · healthy
git push
build image
health check
nginx router
Blue slot
Live
blog-app:v1.4.0
Green slot
Idle
blog-app:v1.5.0
0ms downtimeThe old slot keeps serving until the new one passes its health check, then nginx swaps the route and drains the old container.
Built for the homelab

Runs on whatever you've got.

No datacenter, no static IP, no credit card on file. You need a machine that runs Docker and a Cloudflare account. The closet PC is the whole point.

No ports. No static IP.

Cloudflare tunnels reach your apps through an outbound connection, so nothing on your home network is ever exposed. It works behind CGNAT, with no router config and no port forwarding.

A second career for old hardware.

That 2016 desktop, a mini-PC, a spare laptop, a NUC. If it runs Docker, it can run your whole fleet. Give the hardware you already own something useful to do.

Sips power, not budget.

A few watts in the closet instead of an invoice that renews every month whether you ship or not. Your projects, your electricity, your rules.

Renting the cloud
$20 to $100+ / mo

per app, every month, forever. Plus bandwidth, plus build minutes, plus the next price hike.

Owning the box
Hardware you already own

plus a few watts. The tenth app costs exactly what the ninth did: nothing.

Outgrow the closet? Nothing to relearn.

The same platform points at a VPS, a dedicated server, or a rack the day you need more. Start on the closet PC, move when it matters, keep every workflow.

Everything in the box

A real deployment platform, on your own metal.

The DX you'd expect from a managed cloud, without the vendor lock-in, the surprise bills, or handing over your data.

Blue/Green deployments

Every push spins up a fresh container. Traffic only switches once it's verified healthy. True zero downtime, even on a closet PC.

Multi-tenancy

Every side project on one box. Host as many Next.js apps as your hardware can handle, each isolated with its own database and env.

Preview branches

Ship any feature branch to its own subdomain with an isolated database and per-branch environment variables.

Domain management

Map any domain or subdomain to a specific app and branch. Cloudflare tunnels keep it reachable without open ports.

GitHub Actions integration

Push to a configured branch and it deploys automatically. Or trigger a deploy via the REST API from anywhere.

Health checks & rollback

Switches only happen when the new container is verified. Failed deploys roll traffic back to the last good version.

Environment isolation

Set env vars per app, per branch, or per preview. Run dev, staging and prod from one Port-Au-Next instance.

HTTP scheduling

port-schedule gives every app cron-like jobs that call your public routes. No crontab inside containers.

Secure by default

Authenticated admin UI, isolated Docker network, read-only SSH keys, and restricted Docker socket access.

The deployment workflow

Six steps, fully automated.

From a git push to live traffic, Port-Au-Next runs the whole pipeline so you never babysit a deploy on the closet box.

01
Preparation

Triggered by the UI or a GitHub webhook.

02
Building

Latest code built into a new Docker image.

03
Launching

New container starts, assigned a version.

04
Health check

Verified healthy before any traffic moves.

05
Switching

Nginx routes traffic to the new container.

06
Cleanup

Previous container gracefully terminated.

Shared infrastructure

Batteries included. Wired in automatically.

Every app gets credentials injected at deploy time, no manual config. Connect to managed services the moment your container boots.

PostgreSQL

A dedicated database and user per app, with isolated credentials. Optional Prisma support with managed migrations.

Redis

Shared cache for sessions, a Next.js cache handler, and anything else you need fast key-value storage for.

imgproxy

On-the-fly image optimization and resizing, ready to plug in as a custom Next.js image loader.

MinIO

S3-compatible object storage for uploads and assets, with per-app policies and credentials.

Nginx + Cloudflare

Reverse proxy that routes every domain and preview branch, exposed safely through Cloudflare tunnels.

port-schedule

A first-party HTTP cron scheduler. Per-app jobs fire signed webhooks at your public routes on a schedule.

Umami

Opt-in privacy-focused analytics with a per-app dashboard login. Enable in settings, add the snippet, redeploy.

# injected into every app container, automatically
POSTGRES_USER=app_specific_user
POSTGRES_HOST=postgres
REDIS_URL=redis://redis:6379
IMGPROXY_HOST=cdn.yourdomain.dev
PORT_SCHEDULE_URL=http://port-schedule:8080
NEXT_PUBLIC_UMAMI_HOST=analytics.yourdomain.dev # when analytics enabled
The management UI

One dashboard for the whole fleet.

Add apps, watch deployments roll out, tail logs, and manage env vars, all from an authenticated web console.

manager.yourdomain.dev/deployments
Recent deployments
New app
AppBranchVersionSlotStatus
blog-appmainv1.5.0greenlive
shop-storefrontmainv2.1.3buildingbuilding
shop-storefrontfeat/checkoutpreviewpreviewpreview
docs-sitemainv0.9.1greenlive
Quick start

Running in three commands.

Point it at a VPS, a cloud box, or that old PC humming in your closet. If it runs Docker, it runs Port-Au-Next.

Docker & Docker Compose
Git
An SSH key for GitHub (for auto-deploys)
1Clone the repo
$ git clone https://github.com/cfpg/port-au-next.git
$ cd port-au-next
2Configure your .env
# copy the example and fill in your values
DEPLOYMENT_MANAGER_HOST=manager.yourdomain.dev
POSTGRES_USER=portaunext
POSTGRES_PASSWORD=changeme123
BETTER_AUTH_SECRET=changeme567
IMGPROXY_HOST=cdn.yourdomain.com
MINIO_HOST=storage.yourdomain.com
PORT_SCHEDULE_MASTER_API_KEY=a_long_random_secret
PORT_SCHEDULE_HOST=schedule.yourdomain.com
UMAMI_HOST=analytics.yourdomain.com
UMAMI_APP_SECRET=openssl_rand_hex_32
3Launch the stack
$ docker compose up --build -d
✓ deployment manager ready → http://localhost:80
Questions

Good to know before you self-host.

Do I need a cloud account or any paid service?

No. Port-Au-Next runs entirely on infrastructure you own — a VPS, a cloud box, or hardware at home. Cloudflare tunnels are optional but recommended to expose apps safely without opening ports. It's MIT licensed and free forever.

Will it run on a Raspberry Pi or an old laptop?

If it runs Docker and Docker Compose, it runs Port-Au-Next. A spare laptop, a mini-PC, an old desktop, even a Raspberry Pi for lighter workloads. More apps and heavier builds simply want more RAM, so a machine with 8GB or more is a comfortable starting point.

Do I need to open ports or have a static IP?

No. Cloudflare tunnels open an outbound connection from your machine, so your apps are reachable without port forwarding, a static IP, or exposing your home network. It works fine behind CGNAT, which is exactly the situation most home connections are in.

Is it okay to leave running 24/7?

That's the idea. A closet machine sips power compared to a recurring cloud invoice, and blue-green deploys mean you can update apps any time without taking anything down. When you outgrow the box, point the same setup at a VPS or a rack and keep every workflow.

How does the zero-downtime deploy actually work?

It's a true blue/green strategy. A new container is built and started alongside the running one. Only after it passes a health check does nginx switch traffic over, then the old container is gracefully drained. If the new version is unhealthy, traffic never moves.

Can I run more than one app on a single server?

Yes — that's the whole point. Port-Au-Next is multi-tenant. Each app runs in its own isolated container with its own database, credentials, and environment variables, and you map domains and subdomains to each one independently.

What are preview branches?

Deploy any feature branch to its own subdomain (e.g. feature-x.preview.yourdomain.dev) with an isolated database and branch-specific env vars. Point previews at dev services, test in a production-like environment, then clean them up automatically when the branch merges.

Does it auto-deploy from GitHub?

Yes. Push to a configured branch and Port-Au-Next deploys it via GitHub Actions integration. You can also trigger deployments programmatically through the REST API, or kick them off manually from the dashboard.

What is port-schedule?

A first-party HTTP scheduler. Instead of a crontab inside your container, each app registers cron-like jobs via an API, and port-schedule fires signed webhook requests to your app's public routes on schedule. Perfect for nightly syncs, cleanups, and recurring tasks in a stateless deploy model.

What is Umami analytics?

A shared, privacy-focused analytics instance. Opt in per app from the dashboard to get an isolated website, tracking env vars on production deploy, and your own Umami login. You add the Next.js snippet yourself; cookie and consent banners stay your responsibility.

Take back your deploys.

Self-hosting your Next.js apps shouldn't feel scary. Clone the repo and have a zero-downtime platform running on your own hardware tonight.