Skip to main content

Isolation

By default each worker is a host subprocess with the same UID as Caddy. Use isolation docker when a compromised app should not see the full host filesystem or ambient environment.

Quick config

python {
module_wsgi "main:app"
working_dir "/apps/site"
workers 2
isolation docker {
image "python:3.13-slim"
}
}

Omit isolation or set isolation none for the default process model.

CLI: --isolation docker --isolation-image python:3.13-slim (plus optional --isolation-network, --isolation-docker-host, --isolation-memory, --isolation-cpus, --isolation-read-only).

Requires a working Docker engine (docker on PATH, access to the socket or DOCKER_HOST). Linux only.

What changes

Boundaryisolation noneisolation docker
Host filesystemFull Caddy UID accessBind-mounted working_dir, venv, worker script
Host envInherits Caddy envenv_file + env_var + internal CADDYSNAKE_*
Other workersSame UIDSeparate containers
Shared cacheIn-processReachable via host.docker.internalstill not a tenant boundary
NetworkHost networkBridge; Caddy dials the container IP

workers N → N processes or N containers. Round-robin is unchanged.

When to use it

  • Untrusted or multi-tenant code on one handler
  • Preview environments where a branch should not read host files outside its release dir

When not enough: mutually hostile tenants that share the in-process cache, or need separate secrets stores — use key prefixes, external Redis, or separate Caddy handlers/hosts. For a shared-VM preview pattern, see branch previews.

Full option list: configuration reference.