0

We just started moving our app to containers so I am very new to container world. In our container image we only have the base linux image with some rpms installed and some scripts copied to the container. We were thinking that we will not have any command/entrypoint in the image itself. When the container comes up, our deployment job will then run a script inside the container to bring up the services (jetty/hbase/..). i.e. container bringup and services bringup are 2 different steps in the deployment job. This was working until I was bringing up the container using the docker run/podman run command. Now, we thought of moving to the docker-compose way. However when I say "docker-compose up" it complaints that "Error: No command specified on command line or as CMD or ENTRYPOINT in this image". i.e. while starting a container using the run command it's ok to not have any CMD or ENTRYPOINT, but while starting a container using docker-compose it's mandatory to provide one, why is that so ?

In order to get past that error, we tried putting some simple CMD in the compose file like, say, /bin/bash. However, with this approach, the container exits immediately. I found many stackoverflow links explaining why this is happening, eg: Why docker container exits immediately. If I put CMD as tail -f /dev/null in the compose file only then the container stays up.

Can you please help clarify what is the right thing to do. As mentioned, our requirement is that we want to bringup container without any services, and then bringup the services separately. Hence we don't have any use case for CMD/ENTRYPOINT.

anuragz
  • 63
  • 9
  • 1
    Why do you want to separate the start of the container from the start of the contained service? This sounds like an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Turing85 Dec 31 '21 at 18:24
  • You might want to look into the init system and workarounds like dumb-init https://github.com/Yelp/dumb-init . I think there is no default init system so that lightweight containers can be a thing, but I'm not too sure – Gavin Haynes Dec 31 '21 at 18:38
  • Also in general you don't need to "start" the container before running a command in the container, since you have nothing to run while it is idle. – Gavin Haynes Dec 31 '21 at 18:47
  • A container runs a single process; the Dockerfile `CMD` says what it is. You don't usually "start services" in a container. What is the single process the container is meant to run? Do you need multiple containers running each of your components (this would be an extremely normal setup)? – David Maze Dec 31 '21 at 21:07
  • Thanks for the answers so far. Our app essentially contains Jetty and Hbase. We are planning to run both of them in the same container. Can you please clarify this behavior: When I run the image like this: docker run -d bash --> My image dosn't have any CMD or ENTRYPOINT, so "bash" becomes the cmd here. In this case, my container comes up and stays up. However, if I put the same thing in compose file CMD: ["bash"] and say docker-compose up, then the container exits immediately. My question is how to make sure that container stays up while using the docker-compose. – anuragz Jan 03 '22 at 07:28

1 Answers1

0

Container( Image)s should be the thing that you deploy not a thing that you deploy code into; it is considered good practice to have immutable infrastructure (containers, VMs etc.).

Your build process should probably (!?) generate container images. A container image is (sha-256) hashed to uniquely identify it.

Whenever your sources change, you should consider generating a new container image. It is a good idea to label container images so that you can tie a specific image (not image name but tagged version) to a specific build so that you can always determine which e.g. commit resulted in which image version.

Corollary: it is considered bad practice to change container images.

One reason for preferring immutable infrastructure is that you will have reproducible deployments. If you have issues in a container version, you know you didn't change it and you know what build produced it and you know what source was used ...

There are other best practices for containers including that they should contain no state etc. It's old but seems comprehensive 10 thinks to avoid in containers and there are many analogs to The Twelve-Factor App

(Too!?) Often containers use CMD to start their process but, in my experience, it is better to use ENTRYPOINT. Both can be overridden but CMD is trivially overwritten while ENTRYPOINT requires a specific --entrypoint flag. In essence, if you use CMD, your users must remember to also run your process if they want to use command-line args. Whereas, ENTRYPOINT containers act more like running a regular-old binary.

DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • If you want to treat a container as though it is a host machine you run services in you probably want to search for "system containers" and "lxc" and "lxd" for linux. This can be a sensible approach if packaging your setup as "application containers" as DazWilkin describes is tricky based on your current setup. – Richard Huxton Jan 20 '22 at 10:12