Docker Compose with one Terminating Container - docker

I'm having a docker compose setup of a database container, an application container and one container which pre-loads the database with necessary data.
I want to start all of the containers together with docker-compose up while the pre-loading container terminates after it has completed it work with exit 0.
But terminating this one container takes down the complete setup with the message:
composesetup_load_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Stopping composesetup_app_1...
Stopping composesetup_db_1...
Is there any way of having multiple containers with different life-time in one docker-compose setup? If yes, how?

My workaround for now is to keep the pre-loading container running by adding tail -f /dev/null to the end of the entrypoint script. This keeps the process running, while nothing actual happens.

Using -d option at docker-compose up -d will run the process in detached mode. This avoids the need to kill the service with Ctrl+C and therefore stop the containers.
Note: I am asumming you killed the process with Ctrl+C from the message "Gracefully stopping... (press Ctrl+C again to force)" you shared.

Related

Sending SIGINT to docker container from inside

I have have been trying to make it so that I am able to shutdown a docker container from inside. I have read that using tini is the best way to do this.
I have added init: true to my docker-compose.yml and I can see that docker-init is running as PID 1. However the only command that lets me shutdown the container from my shell script is using kill 1, but I want to gracefully shutdown my container so that it can do some cleanup.
I have tried using commands like kill -SIGINT 1 which results in the error kill: Illegal option -S
or kill -INT 1 and kill -2 1 which both seem to do nothing at all.
I can't seem to figure out the command that I can use. If there is an alternative to init that would also be an option.
The application inside the container doesn't need any special setup in order to shut down; it can just run its own shutdown sequence and exit, and when it does exit, the container will exit as well. If you're trying to do this from a debugging shell you launched with docker exec, you can just use docker stop to send SIGTERM and then SIGKILL. (...and reserve the docker exec shell for debugging; it should not be the primary way you interact with your container.)
If you need to send a container a non-default signal, docker kill has that option:
docker kill --signal SIGINT container_name
In terms of using kill(1) in a debugging shell, the man page for the underlying kill(2) function notes:
The only signals that can be sent to process ID 1, the init process, are those for which init has explicitly installed signal handlers. This is done to assure the system is not brought down accidentally.
It looks like tini collects and forwards a pretty broad range of signals, everything except SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGTRAP, SIGSYS, and the uncatchable signals (notably SIGKILL). Since it does register a signal handler, kill -INT 1 should forward that signal on to the actual container process. (Its pid is probably 2, so kill -INT 2 should also tell the process to stop.)

How to automatically stop and remove Docker container on Ctrl+C in terminal/gitbash/powershell/etc.?

For example I run
docker run --rm --name mycontainer -p 8080:8080 myrepo/myimage
then I see an output of my application, everything is OK. Then I press the Ctrl+C but the container is still running and I'm forced to explicitly stop and remove it:
docker rm -f <container_id>
Or even worse:
docker stop <container_id>
docker rm <container_id>
Is there any way to do it automatically? If not it's OK.
PS: What is the purpose of all that stopped containers still kept on the harddrive?!
What is the purpose of all that stopped containers still kept on the harddrive?!
Running containers include the process you are running along with the namespaced environment to run that process inside of (networking, pid, filesystem, etc).
A stopped container has the container specific read/write filesystem layer, any configuration you included to run the container (e.g. environment variables), and logs if you are using the json logging driver (default).
Removing a container deletes that RW filesystem layer, json logs, and the configuration, which also removes the container from the list of stopped containers. This is a permanent operation, so do not remove containers you may want to later inspect or restart.
I press the Ctrl+C but the container is still running and I'm forced to explicitly stop and remove it
First, make sure you are running a current version of docker. I believe somewhere around 1.13 they migrated the processing of the --rm option from the client to the server. Next, make sure your application handles the Ctrl+C command. In a shell script, this would be a handler for a SIGTERM. You also need run the container interactively so that the keyboard input is sent to the container, that is the -it flag. With all three of those done, you should see containers automatically cleaned up with:
docker run --rm -it --name mycontainer -p 8080:8080 myrepo/myimage
followed by a Ctrl+C. The -it will pass the SIGTERM to the container which should then stop the process, which stops the running container. And the --rm will result in the container being automatically removed.
If for some reason you cannot get your container to handle the SIGTERM, then you can send a SIGKILL with a docker kill command, which cannot be trapped and ignored by the application.
Note that if you run a docker stop on your container and see a 10 second delay before it is stopped, then your application is ignoring the SIGTERM. One common cause for this is a /bin/sh running as pid 1. A shell will ignore this signal when it's running as pid 1 by default, on the assumption that you are in signal user mode.
Per default, docker runs the image command as pid 1. pid 1 is handled special by the kernel as it normally is used for the system init process. For this reason, CTRL+C / SIGTERM does not work on pid 1.
Actual docker versions provide option --init to run a minimal init system (tini) as pid 1. Your image command runs as a child of tini. As no longer being pid 1, your image command will accept CTRL+C again.
Add --init to your sample command, and you can stop with CTRL+C
docker run --rm --init --name mycontainer -p 8080:8080 myrepo/myimage
Not needed in your case, just additional info: You can change the signal from docker stop with --stop-signal SIGNAL with SIGNAL being one of the many signals shown by kill -L, for example SIGHUP or SIGINT.

Docker container shows running even after exit command

I am new to docker, hence may be missing a simple piece. Here is my scenario. I started a container with command 'docker run -it ubuntu:14.04'. Then with Ctrl+P+Q, I exited such that the container keeps running. I verified with docker ps, and saw the container running. Then I again entered the container with 'docker exec -it bash. This took me inside the container again. Now on typing 'exit' command, I come out of the container, but the container is still in running mode. Normally with exit command, the container stops. Any idea why this is happening?
The container's running status is tied to the initial process that it was created for/with.
If you do docker run then this will create a new container with some inital process. When that process terminates, the whole container is stopped. If that initial process was bash, and you exit it, then this terminates the container itself.
docker exec starts a new process inside of the running container. When that process terminates, the container still keeps running.
Typing exit into an interactive bash shell will just exit that shell. It will not affect other processes running inside the same container (just like closing one terminal window in your host OS does not affect any other processes).
With the exit command in your case, the container stops only the /bin/bash/ executable. Probably some other application like NGINX or Apache is running inside the container and does not let it shut down.

Sending sigstop and sigcont to docker containers

I am attempting to send SIGSTOP, and then later, SIGKILL to a container. This line leads me to believe that it will behave as I expect: https://github.com/docker/docker/issues/5948#issuecomment-43684471
However, it is going ahead and actually removing the containers. The commands are:
docker kill -s STOP container
docker kill -s CONT container
(Equivalent through the dockerode API I am using, but I just went to command line when that wasn't working). Is there some missing options I'm missing?
I think you're actually looking for the commands docker pause and docker unpause. Using the STOP signal is likely to be error-prone and dependent on how the process handles the signal.
I guess what's happening in this case is that Docker thinks the process has terminated and stops the container (it shouldn't be removed however, you can restart it with docker start).

RUnit does not stop docker-compose's containers

I would like to have a RUnit service to supervise a set of containers launched by docker-compose tool, here's my the runit script:
In /etc/sv/app/run
#!/bin/bash
exec 2>&1
APP_HOME=/home/myapp
source $APP_HOME/env.sh
exec docker-compose -f $APP_HOME/docker-compose.yml up
Here's what I have then:
sv start app - launches the docker-compose thing just fine
sv stop app - stops docker-compose process itself but for unknown reason it leaves the containers running
Is there any chance to have the stop command to stop containers as well? I thought that is what docker-compose should do when it gets stopped by RUnit.
I'm not familiar with docker (yet) but I have familiarity with runit.
When you issue sv stop app you are actually telling runsvdir to signal the runsv for your docker launch to tear down the process. If you need something to signal the container to shut down, it won't happen because runsv will haul off and kill any child processes that are attached. You may wish to read up on ./finish scripts, which are tasked with cleaning up things.

Resources