Skip to content

Will my image run?

Updated

Most images that work under Docker work as an AppVM unchanged. This page is the check to run before you import one, and the explanation when something exits straight away.

  • Service images such as nginx, redis, postgres, or your own service: import and run. Remember to attach a volume for anything that must persist.
  • Base and runtime images such as alpine, debian, ubuntu, node, or python: these exit immediately. Their entrypoint is an interactive shell or REPL with nothing attached to it. Turn on keepalive if you want to stay inside and poke around, or use an image with a real entrypoint to run a service.
  • Non-root images run fine. To write to a data volume, the image must already contain that directory owned by the image’s user.
  • Distroless and other images with no shell: the workload runs. What you lose is everything that needs /bin/sh, which means no web terminal, no keepalive, no shell-form entrypoint, and no shell-form health check.
ImageRunsWhat to know
Alpine and derivativesYesA bare alpine entrypoint is a shell, so it needs keepalive
Debian / UbuntuYesBare images exit immediately and need keepalive; service images are fine. /etc/hosts starts empty
nginxYesRuns unchanged. Its declared stop signal is honoured, so shutdown drains gracefully
PostgreSQLYes, with careSee the note below about PGDATA
RedisYesAttach a volume at /data for persistence. A very large save may not finish inside the stop grace period
Node / PythonYesService images are fine; a bare node or python3 entrypoint is a REPL and exits
Go distrolessYes, with limitsRuns, including a numeric user, but has no shell
Images with a health checkYesProbing, status, and automatic recovery all work
Images that fork childrenYesChild processes are reaped and signals reach the group
Images that ignore SIGTERMYesEscalates to a forced stop after the grace period

A brand new volume takes its owner and mode from the directory the image ships at that mount point. If the image does not contain the directory, the mount point is created owned by root, and a non-root workload will not be able to write to its own volume.

Two ways out: use an image that ships the directory with the right owner, or use an image whose entrypoint starts as root and adjusts ownership itself, which is what the postgres and redis images do.

  • Automatic anonymous volumes. A VOLUME declaration does not create a volume for you. Persistent data needs an explicitly attached volume. The create form does warn when the image declares a path as persistent and you have not attached anything to it.
  • Non-amd64 images.
  • Health checks declared by OCI-format images. The format does not carry the field. You can add one yourself when you create the machine.
  • Interactive stdin and TTY entrypoints. Keepalive is an escape hatch for debugging, not a way to run an interactive program as a service.
  • Multiple containers in one machine, and in-guest namespaces or cgroups. The VM is the boundary, so there is nothing for them to add.

If the image declares a stop signal, that is what gets sent, so postgres gets its fast-shutdown signal and nginx gets its graceful-drain signal. The grace period defaults to 10 seconds and can be raised to 300 when you create the machine. After it expires the workload is killed and the machine is torn down.