just-containers / s6-overlay

s6 overlay for containers (includes execline, s6-linux-utils & a custom init)
Other
3.69k stars 208 forks source link

How to run services only when `CMD` is not set (or is set to a known value)? #587

Closed akx closed 1 month ago

akx commented 1 month ago

As the title says – I'd need to run multiple services and initialization scripts within the container only when the image is being used to serve the main app (which happens via, let's say, CMD /run-app).

If the same image is used for an auxiliary command (let's say docker run -it myimage /do-housekeeping), the other services should not run before /do-housekeeping does.

Doing docker run -it --entrypoint= myimage /do-housekeeping would be an option, but it's a bit verbose.

skarnet commented 1 month ago

That's... the point of s6-overlay? To run services when you launch the container.

(People who want to do housekeeping on an existing container usually do it via docker exec, since docker run always starts with a pristine image.)

Not using the s6-overlay entrypoint when you don't want to run s6-overlay sounds like... the right approach, even if verbose. ;-)

akx commented 1 month ago

Fair :-)

Let's call /do-housekeeping /install or /upgrade instead – i.e. something you'd use the image for once, and chances are that the main /run-app will fail in an ugly way if it hasn't been run?

skarnet commented 1 month ago

Call it whatever you want - the bottom line is, if you don't want the whole set of services started, don't use s6-overlay as your entry point.

akx commented 1 month ago

Thanks, gotcha :) I ended up with an entrypoint like

#!/bin/sh
# Defer to `/init` if no arguments are passed, otherwise execute the arguments.
# This allows for the container to be run with a custom command, e.g. `docker run -it my-image /bin/bash`,
# or when run without arguments, to run the main s6-overlay managed process.
if [ $# -eq 0 ]; then
  exec /init
else
  exec "$@"
fi

This seems to work and I can't immediately think of a great big downside (other than the custom command not being run under any init, but that'd be the case for a container without --init too).