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.
Quick check
Section titled “Quick check”- 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, orpython: 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.
Image families
Section titled “Image families”| Image | Runs | What to know |
|---|---|---|
| Alpine and derivatives | Yes | A bare alpine entrypoint is a shell, so it needs keepalive |
| Debian / Ubuntu | Yes | Bare images exit immediately and need keepalive; service images are fine. /etc/hosts starts empty |
| nginx | Yes | Runs unchanged. Its declared stop signal is honoured, so shutdown drains gracefully |
| PostgreSQL | Yes, with care | See the note below about PGDATA |
| Redis | Yes | Attach a volume at /data for persistence. A very large save may not finish inside the stop grace period |
| Node / Python | Yes | Service images are fine; a bare node or python3 entrypoint is a REPL and exits |
| Go distroless | Yes, with limits | Runs, including a numeric user, but has no shell |
| Images with a health check | Yes | Probing, status, and automatic recovery all work |
| Images that fork children | Yes | Child processes are reaped and signals reach the group |
| Images that ignore SIGTERM | Yes | Escalates to a forced stop after the grace period |
Volume ownership
Section titled “Volume ownership”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.
Not supported
Section titled “Not supported”- Automatic anonymous volumes. A
VOLUMEdeclaration 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.
Stop behaviour
Section titled “Stop behaviour”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.