Skip to content

Container Startup Order

Hansehart edited this page Sep 13, 2026 · 1 revision

Stages

Every stage a container can pass through, in the order they fire:

Stage Configured in Runs on When
initializeCommand devcontainer.json host Before the container is created, and again on every start
container start ENTRYPOINT/CMD in Dockerfile
entrypoint:/command: in compose.yaml
a feature's entrypoint
container The container's entrypoint and command, on every start
health check compose.yaml container Repeatedly after start, until the container reports healthy
onCreateCommand devcontainer.json
a feature
container First creation only
updateContentCommand devcontainer.json
a feature
container After onCreateCommand, and whenever content is refreshed
postCreateCommand devcontainer.json
a feature
container After updateContentCommand, first creation only
postStartCommand devcontainer.json
a feature
container Every start
connect waitFor in devcontainer.json editor Once the stage it names has finished, updateContentCommand by default
postAttachCommand devcontainer.json
a feature
container Every time a tool attaches

The sections below list only the stages each container actually runs.

Dev container (cage)

Where you work.

Step Purpose User User determined by
initializeCommand Seed the editable config files and this host's proxy CA before any container starts host user -
container start Trust the proxy CA, route egress through the gateway, then keep the container alive root no USER in Dockerfile
postCreateCommand Initialise the tools the features layered on, each feature bringing its own ubuntu remoteUser in devcontainer.json
postStartCommand Verify non-allow-listed egress stays blocked ubuntu remoteUser in devcontainer.json
connect Attach the editor ubuntu remoteUser in devcontainer.json

Gateway container (gateway)

The egress firewall.

Step Purpose User User determined by
container start Build the firewall rules and start dnsmasq root no USER in Dockerfile
health check Signal ready once it resolves the first allow-listed host and reaches it on its first port root no USER in Dockerfile

Proxy container (proxy)

The name-level allowlist and secret injector.

Step Purpose User User determined by
container start Authorise each connection by its handshake name, then swap the markers for this host's real tokens host user O3S_UID/O3S_GID in compose.yaml

Clone this wiki locally