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

The full shape

name: my-app                    # default: directory name
domain: app.example.com         # default: prompt on first deploy
port: 8080                      # default: auto-detect from Dockerfile EXPOSE
https: true                     # null=default, true=force HTTPS, false=HTTP-only
edge_https: true                # HTTP origin behind an HTTPS edge (Cloudflare Flexible SSL)
dockerfile: ./docker/Dockerfile # default: ./Dockerfile
command: php artisan octane:start   # override the image CMD

env:
  APP_ENV: production
env_file: .env.production
env_encrypted: .env.encrypted

release:
  - php artisan migrate --force

hooks:
  pre_build: [npm run build]
  post_deploy: [curl -X POST https://hooks.slack.com/...]

volumes:
  uploads: /app/storage/uploads

workers:
  queue:
    command: php artisan queue:work

sidecars:
  redis:
    image: redis:7-alpine

basic_auth:
  user: admin
  password: "${NEO_BASIC_AUTH_PASSWORD}"

scale: 1
restart: unless-stopped

health:
  cmd: "curl -f http://localhost:8080/health"

dev:
  env_file: .env

environments:
  staging:
    server: staging-box
    domain: staging.example.com

Where each field is covered

Environment-block override rules

Fields inside an environments: block either override the top-level value (domain, port, https, scale, restart, health) or fully replace it when present (env_file, env_encrypted, dockerfile, command, release, hooks, workers, sidecars) — there's no merging of lists or partial overrides for the replace-style fields.

dev: is deploy-invisible

Everything under dev: is read only by neo dev for local development and is completely ignored by neo deploy — it's safe to keep local-only settings there without worrying about them leaking into a production deploy.

Try it yourself — Neo is free, with every feature unlocked.

Get started free