Tutorials

Hands-on guides for real Neo workflows — written by the people who built the features, grouped by what you're trying to do rather than by release number.

Getting Started

What neo init Actually Does (and Why That Restraint Is the Point)

neo init doesn't run an agent or a control plane — but it touches more than Docker and Caddy: swap, a managed SSH key, a bare-IP welcome page. Here's the complete, honest list, and how to undo every part of it.

8 min read
Security

Team Access Without Sharing Passwords: SSH Key Management

neo key add grants a teammate SSH access to a server without ever sharing a private key or a root password.

4 min read v0.5.0+
Domains & SSL

Free Wildcard HTTPS with neo caddy dns

Wildcard certificates need DNS-01 validation — neo caddy dns configures it once, and every subdomain after that gets HTTPS automatically.

5 min read v0.17.0
Domains & SSL

Reading neo caddy routes and Repairing Drift with neo caddy reload

Caddy applies changes instantly — there is no "reload" in the usual sense. These two commands exist for when the live proxy disagrees with your config.

5 min read v0.24.3
Domains & SSL

Cloudflare in Front of Neo: Flexible SSL and edge_https

Cloudflare's Flexible SSL mode talks HTTP to your origin — edge_https tells your app it was actually HTTPS, without a redirect loop.

5 min read
Operations

Why "0 Apps" Doesn't Mean What You Think

Server state and the actual server can disagree — neo list and neo status now say so explicitly instead of quietly undercounting.

5 min read v0.24.1+
Operations

Keeping Disk Usage Under Control: Image Pruning

Every deploy leaves the old image on disk — neo prune, and automatic cleanup after every deploy, keep a small VPS from filling up.

4 min read v0.10.0+
Operations

Joining a Server Someone Else Set Up with neo attach

neo attach adds an already-initialized server to your local config, without re-running neo init or touching what's already there.

3 min read v0.19.0
Operations

Backing Up and Restoring App Data with neo backup

Volume snapshots you can restore on the same server or a different one — for the data a redeploy alone can't protect against.

4 min read
Databases

Shared Database Services: One MySQL for Multiple Apps

neo service create runs one database instance that several apps link to, instead of a redundant bundled database per app.

5 min read
Comparisons

Neo vs Kamal vs Coolify vs Dokku: Choosing a Self-Hosted Deploy Tool

Four different answers to "how do I deploy Docker apps to my own server without a cloud platform" — and which shape fits which workflow.

7 min read
CI/CD

CI/CD: Deploying with Neo from GitHub Actions

Neo needs SSH access and a license key — that's the whole CI setup. No server-side webhook receiver, no agent to install.

6 min read
Security

HTTP Basic Auth That Actually Stays On

basic_auth: is enforced at the Caddy layer, persisted to state so it survives every future route rebuild — including the bug where it silently stopped applying.

6 min read v0.23.2+
Configuration

Understanding .neo.yml: The File That Actually Describes Your Deployment

It's the single most important file in a Neo project, and the most commonly misunderstood — here's the mental model, not just the field list.

7 min read
1 Neo 101

Why Neo? What Problem It Actually Solves

Lesson 1 of 10: what Neo actually is — a CLI that drives Docker and Caddy over SSH you already trust, nothing new to secure.

4 min read
2 Neo 101

Installing Neo and Activating Your License

Lesson 2 of 10: install the CLI and activate a free license — two commands, and there is no payment method to enter, ever.

3 min read
3 Neo 101

Turning a Bare VPS into a Neo Server

Lesson 3 of 10: one command checks the OS, installs Docker, and starts Caddy — your server is now ready for neo deploy.

3 min read
4 Neo 101

Your First Deploy: From Dockerfile to Live URL

Lesson 4 of 10: neo deploy builds, ships, health-checks, and switches traffic — the old version stays up the whole time.

3 min read
5 Neo 101

What .neo.yml Is, and Why You Want One

Lesson 5 of 10: the file that turns "whatever the last deploy happened to set" into something committed and reviewable.

3 min read
6 Neo 101

Pointing a Real Domain at Your App (With Free HTTPS)

Lesson 6 of 10: an A record and one command — Caddy issues and renews the certificate automatically, no certbot involved.

3 min read
7 Neo 101

Environment Variables and Secrets, the Right Way

Lesson 7 of 10: neo env set for quick changes, .neo.yml for defaults, and where real secrets belong instead of a committed .env.

3 min read
8 Neo 101

Redeploying, and Knowing What's Actually Live

Lesson 8 of 10: redeploying is the same command you already know — neo status and neo deploys show what is actually live.

3 min read
9 Neo 101

Leveling Up .neo.yml: Workers, Volumes, and Multiple Environments

Lesson 9 of 10: workers, sidecars, volumes, release commands, and multi-environment configs — the rest of .neo.yml, briefly.

4 min read
10 Neo 101

You've Finished Neo 101 — Here's the Rest of the Library

Lesson 10 of 10: no exam, no certificate — just a curated map of what is left, grouped by what you will actually hit next.

3 min read
Deployment

Deploying a Laravel App to a VPS with Neo

A complete .neo.yml for Laravel: encrypted secrets, migrations on deploy, and a queue worker — no PaaS, no control plane.

7 min read
Getting Started

From Zero to Ghost, WordPress, or n8n in One Command

neo install scaffolds a ready-to-deploy project for ten common self-hosted apps — it never touches your server directly.

5 min read v0.22.0
Getting Started

The Interactive Dashboard: Managing Servers Without Memorizing Commands

Running neo with no arguments launches a full TUI for servers, apps, deploys and logs — here is what lives where.

4 min read v0.16.0+
Getting Started

Free Forever: Licensing and Activation with neo activate

Neo requires a free license key but has no paid tier — what activation actually checks, and what works offline.

4 min read v0.20.0+
Deployment

Running Database Migrations Safely on Every Deploy

release: runs commands inside the new container before traffic switches — a failed migration rolls back instead of going live broken.

6 min read v0.25.0
Deployment

Overriding the App Container Command (and When Not To)

command: lets an environment run Octane with different worker counts — but set it to a one-off task and the container exits immediately.

5 min read v0.25.1
Deployment

One Dockerfile Per Environment

dockerfile: now resolves per environment, and --all refuses to run when environments disagree on which image to build.

4 min read v0.24.5
Deployment

Multi-Server Deployments: Environments and Server Groups

servers: fans an environment out to several machines at once — and why a misconfigured group must refuse to guess which one you meant.

6 min read v0.4.0+
Deployment

Horizontal Scaling: Running Multiple Replicas Behind Caddy

scale: runs N containers of the same app, load-balanced by Caddy, with the same blue-green rollout guarantees as a single container.

4 min read v0.3.0+
Deployment

Deploying Faster with --parallel and --all

neo deploy --all builds once and ships to every environment concurrently — --parallel controls how many servers get hit at once.

4 min read v0.11.0+
Deployment

Zero-Downtime Deploys Explained: How Neo's Blue-Green Switch Works

The old container keeps serving until the new one proves itself healthy — the mechanics of every neo deploy, redeploy or not.

5 min read
Deployment

Tracking Exactly What's Deployed: Git Commits and Deploy History

neo status <app> and neo deploys answer "which commit is running?" — a question image timestamps alone never could.

6 min read v0.26.0
Getting Started

Deploying Your First App with Neo

From a bare Dockerfile to a live HTTPS domain in one command — what neo init and neo deploy actually do.

6 min read
Deployment

Deploying a Node.js / Express App with Neo

A minimal Dockerfile and .neo.yml for a Node API — port detection, env vars, and a PM2-free process model.

5 min read
Deployment

Deploying a Next.js App with Neo

Next.js's standalone output mode produces exactly the small, self-contained image Neo deploys well.

5 min read
Deployment

Setting Up Background Workers and Queues in .neo.yml

workers: runs a second process from the same image with its own container, restart policy, and health check.

5 min read
Deployment

Sidecar Containers: Running Redis, Meilisearch, or a Custom Service Alongside Your App

sidecars: run their own image on the app's network — for services the app needs but that aren't shared across other apps.

5 min read
Configuration

Generating .neo.yml from docker-compose.yml

neo config generate migrates a compose project automatically — deterministically now, and it tells you exactly what it could not carry over.

6 min read v0.25.2+
Configuration

Fixing 'neo sync Broke My .neo.yml'

neo sync now writes into the right environment block, in place, without touching your comments or formatting.

5 min read v0.24.4
Configuration

Catching .neo.yml Mistakes Before They Reach the Server

Every environment needs a server: — Neo checks before building an image, not after the build has already run.

4 min read v0.6.0+
Configuration

Persistent Volumes: Don't Lose Data on Redeploy

Anything not declared as a volume lives inside the container and disappears on the next deploy — three ways to declare one.

5 min read
Configuration

A Complete .neo.yml Reference Walkthrough

Every top-level field, what it does, and which tutorial covers it in depth — the one page to bookmark.

6 min read
Security

How to Commit Secrets Safely with Encrypted Environment Files

env_encrypted: lets you commit .env.encrypted to git — Laravel's own format, decrypted by Neo in memory at deploy.

6 min read v0.24.0