routing
Custom domain
Set any domain or subdomain per project, or configure a default domain on the server to auto-assign subdomains. Configurable at registration or anytime after.
# default: auto-assigned subdomain
poof add myapp
✓ myapp → myapp.mydomain.com
# custom domain (no subdomain)
poof add otherapp --domain another-domain.xyz
# update anytime
poof configure myapp --domain myapp2.mydomain.com
routing
Domain redirects
Redirect any domain to another: www aliases, legacy domains, or migration paths. Caddy handles the 301 and TLS automatically.
poof redirect add www.mydomain.com mydomain.com
poof redirect add old-name.com mydomain.com
poof redirect list
1 www.mydomain.com → mydomain.com
routing
Multiple services, one repo
Register multiple projects from a single repository. Each folder gets its own project, domain, and CI workflow. Each workflow triggers only on changes to its folder.
poof add api --folder backend --port 3000
poof add web --folder frontend --port 8080
✓ api → api.mydomain.com
✓ web → web.mydomain.com
containerization
Static sites
Serve static files straight from your repo with Caddy — no container needed. Add --spa for single-page apps, --build if a Dockerfile produces the files.
# plain static site
poof add mysite --static
# SPA with client-side routing
poof add myapp --static --spa
# Angular/React built via Dockerfile → served as SPA
poof add myapp --static --spa --build
containerization
Environment variables
Inject secrets and config into containers. Keys are listed but values are never exposed. Deploy to apply changes.
poof env set myapp DATABASE_URL=postgres://...
poof env set myapp KEY=val1 SECRET=val2
poof env get myapp
DATABASE_URL,SECRET,KEY
containerization
Persistent volumes
Mount a path into your container. Let Poof! manage the host directory, or point to one you control. Changes apply on next deploy.
# managed (Poof! owns it)
poof volume add myapp /data
# explicit host path
poof volume add myapp /mnt/uploads:/app/uploads
poof deploy myapp
ops
Clone environments
Spin up a test or staging environment by cloning an existing project. The clone deploys from a branch matching the suffix. Optionally copy env vars in one go.
poof clone myapp test
✓ cloned "myapp" → "myapp-test" (branch: test)
domain: myapp-test.mydomain.com
# clone with env vars
poof clone myapp staging --env --all
ops
Rollback
Something broke after a deploy? Poof! keeps a deployment history and can restore the previous image in seconds.
poof rollback myapp
✓ rolled back to ghcr.io/org/myapp:prev
✦ https://myapp.mydomain.com is live
# or deploy a specific image
poof deploy myapp --image ghcr.io/org/myapp:v2
ops
Declarative config
Instead of running individual commands, you can define all projects in a poof.ini file and reconcile with one command. Great for reproducible infrastructure and staging environments.
# poof.ini
[api]
domain = api.mydomain.com
port = 3000
poof apply --dry-run
poof apply
ops
Logs, status & updates
Inspect running projects, tail logs, and keep both the CLI and the server up to date, all from your machine.
poof status myapp
poof logs myapp -n 50
poof list
poof update local
poof update server