Documentation

NextDeploy Documentation

Star on GitHub1

NextDeploy is a self-hosted deployment engine for Next.js. It builds a complete picture of your app at build time — routes, integrations, secrets, assets — and uses that intelligence to deploy correctly to your own VPS or AWS, without a platform in the middle.

No monthly platform bill. No vendor lock-in. Your infrastructure, your AWS account, your server.

⚠️

Early Access — v0.1.x

Works well for personal and small-team projects. APIs may change between minor versions. Back up secrets and read changelogs before upgrading. Use nextdeploy update to get the latest binary.


How it actually works

Most deployment tools are transport layers — they move your build from A to B. NextDeploy is different. Every nextdeploy build produces a metadata.json that statically analyses your Next.js output before a single file is uploaded:

Route classification

Separates static, SSR, ISR, API, and middleware routes by parsing Next.js manifests. No config needed.

Integration detection

Detects Stripe, Cloudinary, Google Analytics, YouTube, and other external origins from the build output — not source code.

ISR awareness

Identifies ISR routes and revalidation intervals. Foundation for selective CDN invalidation instead of nuking the whole cache.

Secret cross-referencing

Knows which integrations your app uses. Can warn before deploy if Stripe is detected but STRIPE_KEY is missing.

Git provenance

Records commit hash and dirty state at build time. Every deploy is traceable. Warns if you're shipping uncommitted changes.

Security Sandboxing

Configures DynamicUser, ProtectSystem=strict, and PrivateTmp for process isolation. Minimal attack surface.

WAF & HMAC

Integrated Coraza WAF (OWASP CRS) and HMAC-SHA256 request signing between CLI and daemon.

Build fingerprint

Knows your package manager, entrypoint, output mode, Next.js version, and full asset inventory. Deploys exactly what your app needs.

This intelligence layer is what separates NextDeploy from a glorified deploy script. The metadata drives pre-deploy validation, targeted cache invalidation, deployment provenance, and — on the roadmap — per-route CloudFront behavior configuration that eliminates unnecessary Lambda invocations entirely.


What it handles today

  • VPS deployments — atomic port-swap, zero-downtime, Caddy reverse proxy, Fail2Ban, HSTS
  • Advanced isolation — DynamicUser, ProtectSystem=strict, PrivateTmp, and NoNewPrivileges
  • AWS serverless — Lambda + S3 + CloudFront + ACM, fully provisioned on first deploy
  • Build intelligence — static analysis of every Next.js build, route classification, integration detection
  • Lambda bridge adapter — translates Lambda events to HTTP for the Next.js standalone server
  • Secret management — encrypted locally, pushed to AWS Secrets Manager, injected via Lambda Extension at cold-start
  • Audit logging — structured JSON logs of every command and system change for traceability
  • Rollbacks — VPS ring buffer keeps last 5 releases, serverless restores from S3 deployment history
  • Deployment provenance — git commit, dirty state, Next.js version, and build timestamp on every deploy
  • Self-updating CLI — single static binary, no runtime dependencies, updates via GitHub Releases

Current limitations worth knowing

  • Lambda size limit: 250MB unzipped. Apps with heavy native binaries (sharp, Prisma) may exceed this.
  • No edge runtime: Next.js middleware runs at the edge. Everything currently routes to a single Lambda origin.
  • Single region: One Lambda per deploy. Multi-region requires manual configuration.
  • No ISR cache layer yet: ISR routes are detected and classified but selective revalidation isn't wired up yet — it's on the roadmap.
  • AWS only (for now): Cloudflare, GCP, and Azure providers are planned. The provider interface is already built for it.

Installation

CLI (your machine)

A single static binary. No Node, no runtime dependencies.

curl -sSf https://nextdeploy.org/install.sh | sh

Daemon (VPS only)

Runs as a systemd service on your server. Handles health checks, atomic swaps, release management, and secret injection via a Unix socket control plane. Not needed for serverless.

curl -sSf https://nextdeploy.org/daemon.sh | sh

VPS Deployment

Deploy to any Linux server you own or rent.

1. Initialize

nextdeploy init

Creates nextdeploy.yml in your project root with sensible defaults.

2. Configure

version: "1.0"
target_type: vps

app:
  name: my-next-app
  domain: app.example.com
  port: 3000
  environment: production

servers:
  - name: prod
    host: 1.2.3.4
    port: 22
    username: deploy
    ssh_key: ~/.ssh/id_rsa

3. Prepare the server (once)

Runs an Ansible playbook that installs Node, Bun, Caddy, Fail2Ban, and the NextDeploy daemon. Configures systemd with advanced isolation (DynamicUser=yes, ProtectSystem=strict), Unix socket permissions, and Caddy HTTPS automatically.

nextdeploy prepare

4. Deploy

nextdeploy ship

ship runs the full pipeline in one step — analyses your Next.js output, produces the metadata and artifact, uploads via SFTP, and signals the daemon for an atomic port-swap that's health checked before traffic cuts over. Incremental: skips the rebuild step when nothing has changed.

For CI pipelines that want a separate build stage, run nextdeploy build first — it produces the same artifact ship would have built. Add --force to either command to bypass the incremental cache.

Rollback

The daemon keeps your last 5 releases. Revert instantly:

nextdeploy rollback

Serverless Deployment (AWS)

No servers, no daemon — Lambda + S3 + CloudFront, provisioned automatically.

ℹ️

What gets provisioned on first deploy

  • • S3 bucket with correct MIME types and cache headers per asset type
  • • Lambda function + IAM execution role
  • • Lambda Function URL with CloudFront OAC — Lambda is never publicly exposed
  • • ACM certificate for your custom domain
  • • CloudFront distribution wired to both S3 and Lambda
  • • AWS Secrets Manager namespace for your app

Prerequisite: AWS credentials in ~/.aws/credentials with the permissions listed in the AWS Deployer Permissions section.

1. Configure

version: "1.0"
target_type: serverless

app:
  name: my-next-app
  domain: app.example.com

serverless:
  provider: aws
  region: us-east-1      # ACM certificates must be us-east-1 for CloudFront

Tutorial: Automated AWS Serverless Deployment

Coming Soon

2. Add output: 'standalone'

// next.config.mjs
const nextConfig = {
  output: 'standalone',
}
export default nextConfig

Why standalone?

Default Next.js builds include the full node_modules — often 500MB+, over Lambda's 250MB unzipped limit. Standalone mode traces your actual imports and produces a self-contained server.js. NextDeploy then injects a bridge adapter that translates Lambda invocation events into HTTP requests the Next.js server understands.

3. Deploy

nextdeploy ship

One command runs the full pipeline. ship builds your app (only when something changed), then:

1

Validate build

Reads metadata.json — route types, integrations, ISR config, git state. Validates before uploading anything.

2

Push secrets

Syncs secrets to AWS Secrets Manager. They never touch the artifact or Lambda env vars directly.

3

Upload static assets

Syncs public/ and _next/static/ to S3 with correct MIME types and cache headers per asset type.

4

Deploy Lambda

Injects bridge adapter, zips .next/standalone/, updates Lambda via UpdateFunctionCode with retry logic for IAM propagation.

5

SSL + DNS guide

ACM cert requested. Detailed DNS guide generated in report. Re-run ship after DNS propagates.

6

Bust CDN cache

CloudFront /* invalidation triggered. Selective per-route invalidation using ISR metadata is on the roadmap.


Secret Management

Encrypted locally. Never in build artifacts. Never hardcoded in Lambda env vars.

Commands from the CLI are now cryptographically signed using HMAC-SHA256 to ensure daemon control plane integrity.

nextdeploy secrets set DATABASE_URL "postgres://user:pass@host/db"
nextdeploy secrets load
nextdeploy secrets list
nextdeploy secrets delete OLD_KEY

How secrets are stored

  • VPSEncrypted on-disk at /opt/nextdeploy/secrets/ with 0600 permissions. Decrypted and injected as environment variables at startup. Key is derived per-machine.
  • AWSPushed to AWS Secrets Manager under nextdeploy/apps/<name>/production. Lambda fetches them at cold-start via the AWS Secrets Extension — available as plain process.env. Only the ARN is set in Lambda, not the values.

DNS Configuration

How to point your domain to your new infrastructure correctly.

The "Loud" DNS Guide

NextDeploy generates a dns.md file in your project root and a visual DNS Setup Guide in your deployment report. It explicitly tells you which records to add to your registrar.

VPS Target

Point your domain directly to your server IP.

  • A Record: @ Server IP
  • CNAME: www @

Caddy handles SSL automatically via Let's Encrypt once DNS propagates.

Serverless Target

Requires two steps: verify ownership and route traffic.

  • 1. SSL Validation (ACM)Add the unique CNAME records provided in your report to prove ownership to AWS.
  • 2. Traffic RoutingPoint your domain to the CloudFront distribution:
    @ xxxx.cloudfront.net

Security & Isolation

Hardened by default for both VPS and Serverless deployments.

HMAC-SHA256 Command Signing

All CLI-to-Daemon commands require a cryptographic signature. A shared secret is generated during 'nextdeploy prepare', ensuring only authorized clients can control your apps.

Coraza WAF Integration

Caddy includes an embedded Web Application Firewall using the OWASP Core Rule Set. It blocks SQLi, XSS, and common exploit attempts at the edge.

Advanced Systemd Sandboxing

Apps run with DynamicUser=yes, ProtectSystem=strict, and PrivateTmp=yes. The process is sandboxed with minimal kernel attack surface and no filesystem access outside its data dir.

Structured Audit Logging

Every deployment, secret change, and system command is recorded in JSON format at /var/log/nextdeployd/audit.log for full environment traceability.

Mutual TLS (mTLS)

Daemon communication supports an optional TCP+mTLS listener. For network-attached management, both client and server must present valid certificates.

Atomic Permissions

Unix sockets are restricted to the 'nextdeploy' group with 0660 permissions, ensuring local privilege separation between users and the deployment plane.


Deep Dive: NextCore Metadata

The "Brain" that makes NextDeploy provider-agnostic.

During nextdeploy build, the NextCore engine performs a deep inspection of your Next.js build output. It doesn't just copy files; it understands the intent of every route and asset.

Metadata Analysis Loop

Manifest Scanning
Parses .next/routes-manifest.json to map every route (Static, Dynamic, ISR, Middleware).
Integration Detection
Detects Stripe, Cloudinary, etc., by scanning chunks for external origin calls.
Secret Cross-Ref
Matches detected integrations against your stored secrets to warn of missing config.
Git Provenance
Records commit hash, branch, and dirty state to ensure deployment traceability.

The resulting metadata.json serves as the source of truth for all providers:

VPS (nextdeployd)

  • • Maps the entrypoint to a Systemd Sandbox
  • • Allocates and persists Dynamic Ports
  • • Translates Domain metadata to Caddyfile Directives

AWS Serverless

  • • Splits assets between S3 (Static) and Lambda (Dynamic)
  • • Configures CloudFront Behaviors per route type
  • • Maps secrets to AWS Secrets Manager

CLI Reference

nextdeploy initScaffold nextdeploy.yml in your project
nextdeploy shipBuild (incrementally) and deploy in one step — the typical command. Targets VPS or serverless based on nextdeploy.yml.
nextdeploy ship --forceForce a full rebuild before deploying (skips the incremental cache).
nextdeploy buildRun only the build stage — analyse Next.js output, classify routes, detect integrations, produce metadata.json and app.tar.gz. Useful for CI when you want build and deploy on separate runners.
nextdeploy build --forceForce a clean rebuild from scratch.
nextdeploy prepareProvision a VPS — Caddy, daemon, Fail2Ban, Node, Bun, systemd (VPS only)
nextdeploy rollbackRevert to the previous release (VPS ring buffer or S3 history)
nextdeploy statusShow health, active release, route summary, and resource usage
nextdeploy logsTail live application logs from the server
nextdeploy secrets loadLoad secrets from a .env file to your server securely
nextdeploy secrets set KEY VALUEEncrypt and store — routed to daemon store or AWS Secrets Manager automatically
nextdeploy secrets listList secret names (values always hidden)
nextdeploy secrets delete KEYRemove a secret permanently
nextdeploy updateSelf-update the CLI binary from GitHub Releases

Configuration reference

version: "1.0"
target_type: vps

app:
  name: my-next-app         # Used for process naming and secret namespacing
  domain: app.example.com   # Caddy configures HTTPS automatically
  port: 3000
  environment: production

servers:
  - name: prod
    host: 1.2.3.4
    port: 22
    username: deploy
    ssh_key: ~/.ssh/id_rsa

secrets:
  provider: local           # "local" | "doppler" coming soon

logging:
  enabled: true

Architecture

VPS

Local Machinenextdeploy CLISFTPProduction VPSDaemonCaddyNext.jsFail2BanSupervisesConfiguresHTTPS Proxy

Serverless

Localnextdeploy CLIDeployAWS CloudLambda+ Bridge AdapterS3CloudFrontSecrets Managercold-start fetch

Under the hood

CLI

  • • Next.js manifest parsing + route classification
  • • Static integration detection from build output
  • • HMAC-SHA256 request signing & verification
  • • Build metadata generation per deploy
  • • Encrypted local secret storage
  • • SFTP (VPS) or AWS SDK (serverless)
  • • Self-update via GitHub Releases

Daemon (VPS)

  • • Systemd with socket & process isolation
  • • DynamicUser & ProtectSystem sandboxing
  • • Unix socket & TCP/mTLS control plane
  • • Health check + port arbitration & persistence
  • • Atomic hot-swap with instant rollback
  • • Release buffer (last 5 builds)
  • • Secret hot-reload without restart

Serverless engine

  • • Lambda bridge adapter (event → HTTP)
  • • CloudFront OAC + Lambda URL auth
  • • S3 deployment history for rollback
  • • Lambda version publishing per deploy
  • • Idempotent AWS resource provisioning
  • • Provider interface (GCP, Cloudflare planned)

Roadmap

The build metadata layer already collects the data needed for most of these. Several are one function away from the information that enables them.

✅ AWS — Lambda + S3 + CloudFront + ACM + Secrets ManagerLive — v0.1.60
✅ Build intelligence — route classification, integration detection, ISR awareness, git provenanceLive — v0.1.60
✅ VPS — atomic swap, Caddy, Fail2Ban, daemon, ring buffer rollbackLive — v0.1.60
✅ Pre-deploy validation — secret cross-referencing, git dirty warnings, Lambda size checksLive — v0.1.110
🔜 Selective CDN invalidation — invalidate only changed routes using ISR metadata diffPlanned
🔜 Smart CloudFront routing — static routes → S3, Lambda only for SSR/API routesPlanned
🔜 Deployment dashboard — route map, build trends, history, provenance per deployPlanned
🔜 Cloudflare Workers + R2 + CDN providerPlanned
🔜 GCP Cloud Run + GCS providerPlanned
🔜 Doppler / 1Password secret provider integrationPlanned