I have a very simple dockerfile:
FROM alpine:3.14 AS build
LABEL version = "1.0"
LABEL description = "Our first Docker file!"
and a very simple docker-compose.yml file:
version: "3.9"
# Define services
services:
container1:
container_name: first_container
build:
context: .
dockerfile: dockerfile
I am running the docker-compose file with docker-compose up
and, alternatively, docker-compose up -d
to demonstrate that the container is still running in the detached configuration.
In the first case, I expect the container to run then close. It does. Running docker-compose down
then stops and removes all the containers (first_container) as confirmed with docker-compose ps
.
$ docker-compose up
Creating network "comdockerdevenvironmentscode_default" with the default driver
Creating first_container ... done
Attaching to first_container
first_container exited with code 0
$ docker-compose ps
Name Command State Ports
------------------------------------------
first_container /bin/sh Exit 0
$ docker-compose down
Removing first_container ... done
Removing network comdockerdevenvironmentscode_default
$ docker-compose ps
Name Command State Ports
------------------------------
Now, I rerun docker-compose up again, adding the detached command. Now, the output says it creates the container, but doesn't close it. Great! I should see a status change when running docker-compose ps
, but it still seems to have exited.
$ docker-compose up -d
Creating network "comdockerdevenvironmentscode_default" with the default driver
Creating first_container ... done
$ docker-compose ps
Name Command State Ports
------------------------------------------
first_container /bin/sh Exit 0
Why is this? How can I show that I can attach to the running detached container, but not to the closed container in the other case?
CodePudding user response:
The alpine
container, absent an explict configuration to the contrary, starts a shell (/bin/sh
) by default. The shell exits immediately if stdin
isn't open. Regardless of whether or not you run docker-compose up
with -d
, in all cases stdin
is closed, so your container exits.
If you want the container to run a shell without exiting, then you need to arrange to stdin to remain connected. To get a prompt, you'll also need to have Docker allocate a tty. That means:
version: "3.9"
services:
container1:
image: docker.io/alpine:latest
stdin_open: true
tty: true
Running a container as in the above example means that you can docker attach
to it and access the shell prompt.
Alternately, if you'd like the container to run without exiting, just run a command that won't exit:
version: "3.9"
services:
container1:
image: docker.io/alpine:latest
command: [sleep, inf]
This runs the sleep inf
command, which runs until canceled. A more typical example would run some sort of persistent service like a web server, a database, etc.