Context
I am running alpine linux in a Balena container composition. This is not your typical docker usecase. Instead, Balena deploys docker container compositions to embedded software as an easy way to deploy complex applications on small, idiosyncratic devices.
In that context, there is a lot of freedom. Docker is used more as an application module, and the balena OS is designed to handle this.
So, an atypical use case for docker containers is to run systemctl/systemd services in a container; but this represents a very typical use case for a Balena deployment when porting a normal, PC-centric application to the Balena world.
For the purposes of this question, I am unable to change code, and running services is an absolute requirement. Is is exactly what needs to be done, and the question is: what is the best way to do it on alpine? (I’ve already got it working on debian w/ systemctl
)
With that in mind…
I can get services running over openrc
, alpine’s analog to systemctl|systemd
in debian. However, in order to do it, I am enabling softlevel
mode in the docker container:
touch /run/openrc/softlevel
Rather than "booting" from openrc
. However, openrc
itself comes with a bright yellow warning line obtained from within the running docker container:
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/blkio/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/cpu/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/cpuacct/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/cpuset/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/devices/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/freezer/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/hugetlb/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/memory/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/misc/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/net_cls/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/net_prio/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/perf_event/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/pids/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/rdma/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 108: can't create /sys/fs/cgroup/systemd/tasks: Read-only file system
* You are attempting to run an openrc service on a
* system which openrc did not boot.
* You may be inside a chroot or you may have used
* another initialization system to boot this system.
* In this situation, you will get unpredictable results!
* If you really want to do this, issue the following command:
* touch /run/openrc/softlevel
Is this fine, or is there a better approach to getting openrc
running in docker? Does it even matter? Or will it just work?
Why I am not sure…
Ideally, I’ll keep the CMD|ENTRYPOINT
arguments to the docker container clean so it is as usable as possible, with openrc
working as is, if possible.
ENTRYPOINT specifies the command to run when the container starts.
If the Dockerfile has both ENTRYPOINT and CMD instructions, the CMD
arguments are passed as arguments to the ENTRYPOINT command. You can
override the ENTRYPOINT command by specifying a new command when you
run the container.
This explains that, even if I get the docker container set up correctly, it will not behave as intended if the CMD/ENTRYPOINT docker commands contain some openrc
startup invective. That means downstream usage of this container with ENTRYPOINT overloads in scripts, or by myself some time from now will break unless I know to include the correct openrc
abra-cadabra.
Instead, maybe softlevel
mode is exactly what I want to enable if I am running in the balenaOS
with openrc
, and ENTRYPOINT will often be overridden.
But I have no reason other than testing and seeing if it works to believe that is the case.
What would be the best way to run services with openrc
in a docker container given the context?
2
Answers
Did the following:
And it didn't really matter if I ran
/sbin/init
; as usual,CMD
andENTRYPOINT
did not behave well together.Instead, I had to make sure I ran
rc-status -s
before starting any services. This appeared to make everything better.A container doesn’t really "boot". You simply choose what process starts when the container starts — maybe that’s a process manager, like openrc, but more generally it’s a specific service.
If we’re designing a container to work with openrc, we could start with something like this:
A container that runs a couple of services under the control of openrc might look like this:
If we build an image from that Dockerfile and run it…
…we’ll see output like this:
No errors, I didn’t have to enable "softlevel" mode, and our services start up as expected. But maybe someone only wants to run a single service without using openrc! In that case, they can override
CMD
on the command line:That works, too.
In general, images based on our openrc image should be designed with the fact that openrc is an option in mind (they should install rc files for any provided services, etc), but they can have any
ENTRYPOINT
script they want as long as it respectsCMD
and ultimately starts/sbin/init
.At the same time, they can support single-service instances as well.