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?