fly.io /init override documentation

fly.io seems to inject and run its own /init file when running containers, but Fly.io developer documentation · Fly Docs don’t have a page documenting this behavior and why it is needed.

Does fly modify the image before running?

Does it rename old /init or make it accessible in some other way?

Why fly needs its own /init?

Can it use some other /init like s6-overlay ?

Is it possible to turn off the /init override?

If not, then why? What would happen without /init override?

Anything else I missed?

Fly injects a lightweight /init process at runtime when your machine starts, it doesn’t modify your image in the registry. This init is a critical part of the Fly runtime as it takes on the responsibilities that a container process on its own can’t handle, like reaping orphaned child processes, forwarding signals from the VM host to your app, setting up networking and mounts, and coordinating clean shutdowns so volumes and workloads aren’t left in a bad state.

Because so much of the Fly platform depends on this layer, it isn’t something you can disable or swap out with alternatives like s6-overlay. You’re free to run your own process manager inside the container if you want, but it will always run under Fly’s init rather than replacing it. The design is in place to allow consistent behavior across all Fly apps, without this supervision, machines could fail to restart, hang on shutdown, or lose data integrity.

So basically, in short: /init is a small but essential piece of Fly’s runtime that guarantees your image runs safely and predictably inside Firecracker VMs, while leaving your actual image untouched.

Hope this helps clarify things!

Related: Should we use an `init` process in our Dockerfiles?

1 Like

Fly injects a lightweight /init process at runtime

So if I run /init explicitly afterwards, I will invoke old process that is in the image, right?

By “container process” do you mean outside process? Like podman/docker - the one that launches container? And that process can not control things inside the container, like forward signals there?

Unfortunately, I am not free to run my own process manager. It doesn’t work in case of s6-overlay, because in order for the process manager to reap zombies, it needs to be run as PID 1, and I get fatal: can only run as pid 1 , which is the case with all LinuxServer.io · GitHub images (https://github.com/just-containers/s6-overlay/issues/630).

It doesn’t work like this. I have to touch the original image to add magic unshare hack to get PID of the container shipped /init process from s6-overlay back to 1 (magic hack, because I don’t understand most of its parameters yet). It would be nice if Fly /init could do this automatically or through some fly.toml flag.

EDIT: clarified that unshare hack is needed to run s6-overlayprocess manager as PID 1

I’ve seen these pages. Unfortunately, the bits of fragmented information lost in an ocean of probably important context are no substitute for the real documentation. Before reading the forum I tried Qwen3-MAX with web search to solve this problem and it started hallucinating, giving me non-existing parameters and half baked scripts.

What problem are you trying to solve? It seems that all of your questions in the first post have been answered, but I wonder if this is an XY Problem. If readers have an understanding of why you want to run your own init, they may be able to advise you better.

For this specific thread the problem is the lack of documetation on fly.io /initprocess. Why it exists, why it is internally injected, why it named /init instead of /fly-injected-init, and why it steals PID 1, which in turn conflicts with in-container processes managers like s6-overlay.

Some of there questions were answered (correct me if I wrong), but not all:

Q: Does fly modify the image before running /init?
A: No. It injects the /init process dynamically when machine starts.
Q: How?

Q: Does it rename old /init or make it accessible in some other way?
A: If an image ships with own /init, if you run /init, the image version is invoked. There is no way to run injected fly.io /initexplicitly - it always starts first no matter what.

Q: Why fly needs to inject/init?
A: Because fly.io platform uses FirecrackerVM, and it does allow outside “container process” reap orphaned child processes, forward signals from the VM host to app, setup networking and mounts, and coordinate clean shutdowns so volumes and workloads aren’t left in a bad state.
Q: Isn’t it a security risk to give control over infrastructure to processes inside container?
Q: Does FirecrackerVM provide a way to create “container manager” tool that operates outside container?
Q: Why can not this “container manager” handle specified fly.io tasks outside of container?

Q: Can container use some other /init like s6-overlay ?
A: fly.io/init and s6-overlay /init are both zombie reapers that need to be run with PID 1, because zombies fall under PID 1 ownership. People share some magic hacks with unshare, but it is not officially supported.

Q: Is it possible to turn off the /init override?
A: No.

Q: Can fly.io injected/initbe named /fly-injected-initto avoid name shadowing?

Q: Why fly.io /init can not get back PID 1 to the first container process automatically?

Q: Can fly.io /init return PID 1 to the first container process through an option in fly.toml, to avoid modyfing original container image and maintaining its updates?

Missing from that description: fly.io has two init processes for you to chose from.

The default init that fly.io provides runs your dockerfile’s ENTRYPOINT and CMD as a pid other than 1.

The Pilot init process is the one you get if you specify you want to use containers. Container processes are run as pid 1.

GitHub - fly-apps/rate-limiter-demo: Rate Limiter fly machine with containers demo contains several demos on how to run with containers depending on whether you want to use that machine API or fly launch/deploy or docker compose.

1 Like

I think you misunderstood my question, Anatoli. Forget PID1 for the moment, that’s the “how” of solving a problem. What business or software problem do you have?

For example, in one of my links above, I mentioned that I am in the habit of adding my own PID1 in order to forward Unix signals correctly, e.g. if the entrypoint is a shell script. I was told, quite correctly, that the Fly init does that for me, and thus my wanting to grab PID1 is unnecessary in Fly.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.