Currently I have a dockerfile that runs two executables using an ampersand:
FROM <Linux base image>
CMD ["bin/sh", "-c", "/service1 & /service2"]
As I am looking to migrate this dockerfile to distroless, I will no longer be able to run this ampersand command, since my new minimal image will no longer have a shell to recognize it. Thus I am looking for alternate ways to ensure I can run both services from the same image.
As an alternative, I am experimenting with doing something like this:
FROM <minimal base image>
RUN /service1
CMD ["/service2"]
Is there any issue with executing /service1 using the RUN command? Is this even possible, given /service1 will be a process running on the container?
Note: I am aware it is not usually recommended to run two services from the same container, but this is to help me better understand RUN and CMD commands. I have read through Dockerfile reference but it is still unclear to me. I have also tested this out locally and the container fails to run, although I do not see logs to confirm this is the reason.
CodePudding user response:
The RUN
instruction is executed at container build time and the result of the command is saved to the image that is built as a new layer.
See the reference here RUN
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
I would recommend writing a single initialization script that starts your services for you. Since you cannot rely on any distro specific tooling you would need to execute the script with something that you installed earlier in your docker file.
CodePudding user response:
You cannot start background services with a RUN
command. They are not persisted in the image, and are stopped as soon as the RUN
command completes.
What you can do, though, is override the CMD
when you run the container. Rather than trying to run two processes in a single container, it's a better practice to run two separate containers with one process each.
docker run -d your-image /service1
docker run -d your-image /service2
version: '3.8'
services:
service1:
build: .
command: /service1
service2:
build: .
command: /service2
Since this setup doesn't require a shell or any other sort of automation in a container, it will also work just fine with a FROM scratch
or another kind of "distroless" image.
Fundamentally a container runs one process (which could launch subprocesses) and when that process completes the container exits. If you want to run two processes in the same container then either one needs to launch the other, or you need some common parent process that can manage the two. That requires you to introduce at least a shell in most cases, which gets away from the spirit of these extremely minimal images.