TMOTTM
TMOTTM

Reputation: 3391

How to create and run a Docker container based on a minimal image?

I would like to build a container based on an image defined in a Dockerfile as follows:

FROM alpine:3.7
RUN touch test.txt
RUN echo "Hello Worl" > ./test.txt

After issuing docker image build -t test_alp ., I can find the image in the list of available images:

me@ub:test_dockerfile$ docker image build -t test_alp .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine:3.7
 ---> 6d1ef012b567
Step 2/3 : RUN touch test.txt
 ---> Running in 70a9056b0421
Removing intermediate container 70a9056b0421
 ---> 87b4ee2e9839
Step 3/3 : RUN echo "Hello Worl" > ./test.txt
 ---> Running in b48af2120d80
Removing intermediate container b48af2120d80
 ---> 7326560e8a47
Successfully built 7326560e8a47
Successfully tagged test_alp:latest

me@ub:test_dockerfile$ docker image list
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
test_alp              latest              7326560e8a47        46 seconds ago      4.21MB

Then I create a container and start it.

me@ub:test_dockerfile$ docker create --name cont_alp 7326560e8a47
0f857d36e5b594afab7133513faf1dc3c62269a50af0e28e15564852fc379b10

(In between question: could I also create the container using docker create test_alp?)

me@ub:test_dockerfile$ docker container ls -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
0f857d36e5b5        7326560e8a47          "/bin/sh"                11 seconds ago      Created                                      cont_alp
me@ub:test_dockerfile$ docker start cont_alp
cont_alp
me@ub:test_dockerfile$ docker container ls -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                     PORTS                    NAMES
0f857d36e5b5        7326560e8a47          "/bin/sh"                24 seconds ago      Exited (0) 4 seconds ago                            cont_alp

As you see, the container immediately returns to the Exited state. Why is that?

Upvotes: 0

Views: 649

Answers (2)

brunocrt
brunocrt

Reputation: 780

Because your RUN command (echo) exited after execution! Generally docker containers run long execution daemon commands like server side applications...

You can do this by putting the commands you want to execute into a script with a loop, and setting the script to be the command Docker runs when it starts a container:

CMD /script.sh

Upvotes: 1

Zeitounator
Zeitounator

Reputation: 44799

alpine:3.7 (as all other versions...) runs sh as a default command.

You are not changing the default container command in your build. When your run your container it will launch that command. Since there is no tty attached to ssh and you did not ask for an interactive run, sh has nothing to process and exists.

2 ways to get into your container for tests:

  1. run the container from scratch interactively:
docker run -it --rm --name cont_alp test_alp:latest
  1. run the container in the background with a long lasting command and execute sh to connect to it:
docker run -d --rm --name cont_alp test_alp:latest sh -c "while true; do sleep 2000; done"
docker exec -it cont_alp sh

If you want to launch your containers based on the above image by default with the long lasting command, you can add it to your Dockerfile. (Note that I also reduced the number of needed layers by running touch and echo in a single run. But do you need touch anyway...)

FROM alpine:3.7
RUN touch test.txt && echo "Hello World" > test.txt
CMD ["/bin/sh", "-c", "while true; do sleep 2000; done"]

Upvotes: 2

Related Questions