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.
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.
neo key add grants a teammate SSH access to a server without ever sharing a private key or a root password.
Wildcard certificates need DNS-01 validation — neo caddy dns configures it once, and every subdomain after that gets HTTPS automatically.
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.
Cloudflare's Flexible SSL mode talks HTTP to your origin — edge_https tells your app it was actually HTTPS, without a redirect loop.
Server state and the actual server can disagree — neo list and neo status now say so explicitly instead of quietly undercounting.
Every deploy leaves the old image on disk — neo prune, and automatic cleanup after every deploy, keep a small VPS from filling up.
neo attach adds an already-initialized server to your local config, without re-running neo init or touching what's already there.
Volume snapshots you can restore on the same server or a different one — for the data a redeploy alone can't protect against.
neo service create runs one database instance that several apps link to, instead of a redundant bundled database per app.
Four different answers to "how do I deploy Docker apps to my own server without a cloud platform" — and which shape fits which workflow.
Neo needs SSH access and a license key — that's the whole CI setup. No server-side webhook receiver, no agent to install.
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.
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.
Lesson 1 of 10: what Neo actually is — a CLI that drives Docker and Caddy over SSH you already trust, nothing new to secure.
Lesson 2 of 10: install the CLI and activate a free license — two commands, and there is no payment method to enter, ever.
Lesson 3 of 10: one command checks the OS, installs Docker, and starts Caddy — your server is now ready for neo deploy.
Lesson 4 of 10: neo deploy builds, ships, health-checks, and switches traffic — the old version stays up the whole time.
Lesson 5 of 10: the file that turns "whatever the last deploy happened to set" into something committed and reviewable.
Lesson 6 of 10: an A record and one command — Caddy issues and renews the certificate automatically, no certbot involved.
Lesson 7 of 10: neo env set for quick changes, .neo.yml for defaults, and where real secrets belong instead of a committed .env.
Lesson 8 of 10: redeploying is the same command you already know — neo status and neo deploys show what is actually live.
Lesson 9 of 10: workers, sidecars, volumes, release commands, and multi-environment configs — the rest of .neo.yml, briefly.
Lesson 10 of 10: no exam, no certificate — just a curated map of what is left, grouped by what you will actually hit next.
A complete .neo.yml for Laravel: encrypted secrets, migrations on deploy, and a queue worker — no PaaS, no control plane.
neo install scaffolds a ready-to-deploy project for ten common self-hosted apps — it never touches your server directly.
Running neo with no arguments launches a full TUI for servers, apps, deploys and logs — here is what lives where.
Neo requires a free license key but has no paid tier — what activation actually checks, and what works offline.
release: runs commands inside the new container before traffic switches — a failed migration rolls back instead of going live broken.
command: lets an environment run Octane with different worker counts — but set it to a one-off task and the container exits immediately.
dockerfile: now resolves per environment, and --all refuses to run when environments disagree on which image to build.
servers: fans an environment out to several machines at once — and why a misconfigured group must refuse to guess which one you meant.
scale: runs N containers of the same app, load-balanced by Caddy, with the same blue-green rollout guarantees as a single container.
neo deploy --all builds once and ships to every environment concurrently — --parallel controls how many servers get hit at once.
The old container keeps serving until the new one proves itself healthy — the mechanics of every neo deploy, redeploy or not.
neo status <app> and neo deploys answer "which commit is running?" — a question image timestamps alone never could.
From a bare Dockerfile to a live HTTPS domain in one command — what neo init and neo deploy actually do.
A minimal Dockerfile and .neo.yml for a Node API — port detection, env vars, and a PM2-free process model.
Next.js's standalone output mode produces exactly the small, self-contained image Neo deploys well.
workers: runs a second process from the same image with its own container, restart policy, and health check.
sidecars: run their own image on the app's network — for services the app needs but that aren't shared across other apps.
neo config generate migrates a compose project automatically — deterministically now, and it tells you exactly what it could not carry over.
neo sync now writes into the right environment block, in place, without touching your comments or formatting.
Every environment needs a server: — Neo checks before building an image, not after the build has already run.
Anything not declared as a volume lives inside the container and disappears on the next deploy — three ways to declare one.
Every top-level field, what it does, and which tutorial covers it in depth — the one page to bookmark.
env_encrypted: lets you commit .env.encrypted to git — Laravel's own format, decrypted by Neo in memory at deploy.
No tutorials in this category yet.