phusion/baseimage-docker: an Ubuntu base image with a working PID 1
A minimal Ubuntu base image modified for Docker-friendliness
At a glance
- What is it?
- Baseimage-docker replaces the stock Ubuntu image's broken init behaviour with /sbin/my_init, a syslog daemon and a runit-style service directory. It suits images that need more than one long-running process; it is the wrong tool for a single static binary.
- Who is it for?
- Adopt phusion/baseimage-docker when your container must run several long-lived processes, needs a real init to reap zombies and forward SIGTERM, or needs syslog inside the container. Do not adopt it for a single static binary that can be the entrypoint itself; the added init, syslog-ng and runit layer buys you nothing there, and Ubuntu 26.04's Rust Coreutils track changes the shell tooling you get.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The PID 1 problem baseimage-docker exists to solve
The stock ubuntu image is not built for containers. The README states that Ubuntu's init system assumes real or virtualized hardware, and that a container wants a minimal system instead. Two concrete failures follow from that mismatch. First, PID 1 inherits orphaned child processes and must reap them; most Docker containers have no init process doing this, so zombie processes accumulate over the container's lifetime. Second, docker stop sends SIGTERM to PID 1, and the README says most init systems do not handle this correctly inside a container because they were built for hardware shutdowns. Processes then get SIGKILL instead of a chance to deinitialize, which the README says can cause file corruption.
Baseimage-docker ships /sbin/my_init, which the README describes as performing both tasks correctly. The audience is anyone whose Dockerfile starts from ubuntu and then has to work around these two behaviours by hand, plus anyone running several daemons in one container who does not want to write their own process supervisor. The README's own framing is that by the time you have configured the base system correctly yourself, you have reinvented baseimage-docker.
What is inside the image: my_init, syslog-ng and runit services
The image is Ubuntu plus four categories of change: Docker-friendliness modifications, administration tools, mechanisms for running multiple processes, and an APT fix. The APT change addresses a documented incompatibility with Docker (the README links to docker issue 1024).
syslog-ng is included because the README states a syslog daemon is necessary for many services, including the kernel itself, to log. That matters in containers where there is no host syslog socket to write to.
Service management is the part that shapes your Dockerfile. The README's table of contents lists a section on adding additional daemons and a section on running scripts during container startup, which implies two distinct extension points: long-running services that my_init supervises, and one-shot setup scripts that run once at boot. The README also documents environment variable handling in depth, including centrally defining your own variables, environment variable dumps, modifying variables, and a security subsection. That last one is worth reading before you bake secrets into the image, because the README treats environment variables as something with a security dimension rather than a plain convenience.
One caveat sits in the component table: Ubuntu 26.04 ships Rust Coreutils (uutils coreutils) instead of GNU Coreutils, and the README points to a dedicated section for details and alternatives. If your startup scripts parse the output of coreutils tools, that substitution is a real behavioural difference, not a cosmetic one.
Using phusion/baseimage-docker as a base image
The README points to two registries: the Docker registry (phusion/baseimage) and GHCR (ghcr.io/phusion/baseimage-docker). Pulling the image is the first step.
docker pull phusion/baseimageThe README's getting started section is the reference for the Dockerfile that follows, and it is where the FROM line and the init entrypoint are specified. The repository's Makefile shows the naming convention for builds you produce yourself: the default VERSION is noble-1.0.2, and NAME defaults to phusion/baseimage. To build from the image directory rather than pull:
make buildThat target runs docker build against the image directory with --no-cache and --rm, tagging the result with the version argument. Running the test suite is a separate target:
make testwhich invokes test/runner.sh with NAME and VERSION in the environment. For a login shell inside a running container, the README covers docker exec and, separately, SSH access with its own key handling. The Makefile also exposes an ssh target that locates the running container by image name and calls tools/docker-ssh with the container ID; if no matching container is running it prints "Container is not running." and exits 1.
Before you write services, read the README's startup-script and additional-daemon sections in full. The directory layout and naming rules for those scripts are the one thing you cannot guess, and getting them wrong produces a container that starts cleanly and runs nothing.
Where baseimage-docker is the wrong choice
The README pre-empts the obvious objection with a section titled "Wait, I thought Docker is about running a single process in a container?" and another asking whether baseimage-docker advocates fat containers or treating containers as VMs. Those sections exist because the project is routinely misread as an argument for putting an entire system in one container. It is not; it is a base for images that legitimately need more than one process, and the README's own wording is that the mechanisms let you run multiple processes without violating the Docker philosophy.
If your workload is one static binary, this image is overhead. You get an init process, syslog-ng and a service supervisor you will not use, on top of a full Ubuntu userland. A distroless or scratch-based image, or a minimal distribution image, gets you a smaller artifact and a shorter list of things that can break. The README's comparison is against Busybox and Alpine on the grounds that baseimage-docker is more powerful while consuming 8.3 MB RAM; that claim is about capability, and it does not make the image the right pick for every container.
A second limitation is the Ubuntu 26.04 track. Rust Coreutils replaces GNU Coreutils there, and the README directs readers to a dedicated section for details and alternatives. That is an admission that the substitution can affect existing images. If your startup scripts or health checks depend on GNU-specific flags or output formatting, the resolute track is a migration, not a drop-in.
A third is version drift between tracks. The Makefile defaults to noble-1.0.2 while the recent releases are resolute-1.0.7 through resolute-1.0.9. Nothing in the README says the two tracks move together, so pin the tag you actually tested rather than tracking latest.
How it differs from passenger-docker and from hand-rolled Ubuntu images
The README points readers who want a more complete base image, one aimed at Ruby, Python, Node.js and Meteor web apps, to passenger-docker. The difference is scope. Baseimage-docker gives you the base system plus the init and service machinery and leaves the language runtime to you. passenger-docker layers a specific application server and its runtime on top, so it makes decisions about how your app is launched that baseimage-docker deliberately does not. If you are deploying a Passenger-served web app, starting from baseimage-docker means rebuilding much of what passenger-docker already ships. If you are not, passenger-docker carries a runtime you would have to remove.
The other alternative is the one the README addresses head on: configuring the stock ubuntu image yourself. That is a legitimate approach, and the README concedes you can do it. The trade-off it names is effort and corner cases, plus build and redeploy time. Because Docker caches the base image after the first pull, subsequent deploys only download the layers you add on top; a hand-rolled base that you rebuild frequently loses that benefit unless you are careful with layer ordering. The honest reading is that baseimage-docker is a bet that the corner cases are numerous enough to be worth a dependency, and the README's argument for that bet is the list of corner cases it claims to have already handled.
Maintenance, licensing and upgrade cost
The repository is not archived, and the last push was on 2026-09-20. Recent releases are resolute-1.0.7 (2026-07-12), resolute-1.0.8 (2026-07-19) and resolute-1.0.9 (2026-07-26), a weekly cadence across July. The version string in the Makefile is noble-1.0.2, which is a different track from those resolute releases, so the repository is maintaining at least two Ubuntu lines at once. That is a maintenance cost you inherit: when you pin a tag, you are pinning one of those lines, and the base system underneath it moves on Ubuntu's schedule, not yours.
The licence is MIT. That is permissive and short, and it does not impose copyleft obligations on your own image layers. It also says nothing about the licences of what the image contains: Ubuntu packages, syslog-ng, runit and the rest carry their own terms, and MIT on the repository does not override them. If you redistribute images built on this base, check the package licences inside rather than assuming the repository licence covers everything. This is a description of the licence text, not legal advice.
Upgrade cost concentrates in two places: the Ubuntu release the tag tracks, and the Coreutils substitution on the 26.04 line. The README's section on upgrading the operating system inside the container is the starting point for the first. The second has no automated answer in the README; you test your scripts against uutils behaviour yourself.
Editorial conclusion
Adopt phusion/baseimage-docker when your container must run several long-lived processes, needs a real init to reap zombies and forward SIGTERM, or needs syslog inside the container. Do not adopt it for a single static binary that can be the entrypoint itself; the added init, syslog-ng and runit layer buys you nothing there, and Ubuntu 26.04's Rust Coreutils track changes the shell tooling you get. Before committing, verify which tag you are pulling (the Makefile defaults to noble-1.0.2, and the resolute-1.0.x releases are a separate track), check whether your services fit the runit directory layout, and confirm your Dockerfile does not rely on GNU Coreutils behaviour that the 26.04 track replaces.
Frequently asked questions
What is phusion/baseimage-docker?
It is a minimal Ubuntu base image modified for Docker-friendliness, intended to be used as the base for your own Docker images. It adds a correct init process at /sbin/my_init, syslog-ng, administration tools and mechanisms for running multiple processes.
Where do I pull phusion/baseimage-docker from?
The README says the image is available from the Docker registry as phusion/baseimage and from GHCR at ghcr.io/phusion/baseimage-docker.
Does phusion/baseimage-docker let me run more than one process in a container?
Yes. The README lists mechanisms for easily running multiple processes without violating the Docker philosophy, and has separate sections for adding additional daemons and for running scripts during container startup.
What changed in the Ubuntu 26.04 track of phusion/baseimage-docker?
Ubuntu 26.04 ships Rust Coreutils (uutils coreutils) instead of GNU Coreutils, and the README points to a dedicated section for details and alternatives. That substitution can affect scripts that depend on GNU Coreutils behaviour.
What licence does phusion/baseimage-docker use?
The repository is MIT licensed. That covers the repository; the Ubuntu packages and daemons inside the image carry their own licences.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/phusion-baseimage-docker)