Is there any way to start an interactive shell in a container using Docker Compose only? I've tried something like this, in my docker-compose.yml:
myapp:
image: alpine:latest
entrypoint: /bin/sh
When I start this container using docker-compose up it's exited immediately. Are there any flags I can add to the entrypoint command, or as an additional option to myapp, to start an interactive shell?
I know there are native docker command options to achieve this, just curious if it's possible using only Docker Compose, too.
You need to include the following lines in your docker-compose.yml:
version: "3"
services:
app:
image: app:1.2.3
stdin_open: true # docker run -i
tty: true # docker run -t
The first corresponds to -i in docker run and the second to -t.
The canonical way to get an interactive shell with docker-compose is to use:
docker-compose run --rm myapp
(With the service name myapp taken from your example. More general: it must be an existing service name in your docker-compose file, myapp is not just a command of your choice. Example: bash instead of myapp would not work here.)
You can set stdin_open: true, tty: true, however that won't actually give you a proper shell with up, because logs are being streamed from all the containers.
You can also use
docker exec -ti <container name> /bin/bash
to get a shell on a running container.
The official getting started example (https://docs.docker.com/compose/gettingstarted/) uses the following docker-compose.yml:
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
After you start this with docker-compose up, you can shell into either your redis container or your web container with:
docker-compose exec redis sh
docker-compose exec web sh
docker-compose run myapp sh should do the deal.
There is some confusion with up/run, but docker-compose run docs have great explanation: https://docs.docker.com/compose/reference/run
If anyone from the future also wanders up here:
docker-compose exec service_name sh
or
docker-compose exec service_name bash
or you can run single lines like
docker-compose exec service_name php -v
That is after you already have your containers up and running.
The service_name is defined in your docker-compose.yml file
Using docker-compose, I found the easiest way to do this is to do a docker ps -a (after starting my containers with docker-compose up) and get the ID of the container I want to have an interactive shell in (let's call it xyz123).
Then it's a simple matter to execute
docker exec -ti xyz123 /bin/bash
and voila, an interactive shell.
This question is very interesting for me because I have problems, when I run container after execution finishes immediately exit and I fixed with -it:
docker run -it -p 3000:3000 -v /app/node_modules -v $(pwd):/app <your_container_id>
And when I must automate it with docker compose:
version: '3'
services:
frontend:
stdin_open: true
tty: true
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /app/node_modules
- .:/app
This makes the trick: stdin_open: true, tty: true
This is a project generated with create-react-app
Dockerfile.dev it looks this that:
FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "run", "start"]
Hope this example will help other to run a frontend(react in example) into docker container.
I prefer
docker-compose exec my_container_name bash
If the yml is called docker-compose.yml it can be launched with a simple $ docker-compose up. The corresponding attachment of a terminal can be simply (consider that the yml has specified a service called myservice):
$ docker-compose exec myservice sh
However, if you are using a different yml file name, such as docker-compose-mycompose.yml, it should be launched using $ docker-compose -f docker-compose-mycompose.yml up. To attach an interactive terminal you have to specify the yml file too, just like:
$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
A addition to this old question, as I only had the case last time. The difference between sh and bash. So it can happen that for some bash doesn't work and only sh does.
So you can:
docker-compose exec CONTAINER_NAME sh
and in most cases: docker-compose exec CONTAINER_NAME bash
use.
If you have time. The difference between sh and bash is well explained here:
https://www.baeldung.com/linux/sh-vs-bash
You can do docker-compose exec SERVICE_NAME sh on the command line. The SERVICE_NAME is defined in your docker-compose.yml. For example,
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
The SERVICE_NAME would be "zookeeper".
According to documentation -> https://docs.docker.com/compose/reference/run/
You can use this docker-compose run --rm app bash
[app] is the name of your service in docker-compose.yml
If I build from the Dockerfile I can run the docker run IMAGE_ID /bin/bash and browse the container.
But if I run docker-compose up -d from docker-compose.yml and run docker attach, it doesn't respond, it stays still in the container terminal and sometimes leaves the container terminal alone
Follow my docker files
Dockerfile
FROM nginx:1.21.6
EXPOSE 80
WORKDIR /etc/nginx
ENTRYPOINT /bin/bash
docker-compose.yml
version: "3.8"
services:
reverse:
build:
dockerfile: Dockerfile
context: ./nginx/docker
image: reverse/nginx
container_name: reverse
ports:
- 80:80
- 443:443
volumes:
- ./nginx:/etc/nginx
tty: true
To be able to provide interactive input after attaching you also need to set stdin_open: true in the docker-compose.yml:
services:
reverse:
# ...
tty: true
stdin_open: true
But depending on what you want to achieve with this probably a better solution would be
docker-compose exec reverse /bin/bash or
docker-compose run reverse /bin/bash.
When I run docker-compose up -d, I want to make each container start → shell run in the background.
I created docker-compose.yml as follows.
version: "3"
services:
test:
image: test:latest
tty: true
stdin_open: true
working_dir: /opt/test
command: bash -c "./test.sh &"
However, when docker - compose up - d is executed, the container is created in exit state.
With the docker-compose up -d command alone, how can I do it in order to start containers → execute shell background through bash → detach?
I have an issue getting an exit code out of docker-compose up.
I have the simplest container that runs a script that always exits with 1:
#!/usr/bin/env sh
exit 1
My Dockerfile:
FROM mhart/alpine-node:6
RUN mkdir /app
WORKDIR /app
And my docker-compose.yml:
version: '2'
services:
test_container:
container_name: test_container
build: .
volumes:
- ${PWD}/run.sh:/app/run.sh
entrypoint: ["/app/run.sh"]
When I run it with:
docker-compose -f docker-compose.yml up --force-recreate test_container
I can see in logs:
Recreating test_container ...
Recreating test_container ... done
Attaching to test_container
test_container exited with code 1
But when I echo $?, I get 0.
Docker version 17.09.0-ce, build afdb6d4. Running on OSX 10.12.6.
Am I doing something wrong? Is that a known issue (I couldn't find anything out there)?
An option --exit-code-from SERVICE can be used with docker-compose up :)
From the documentation:
docker compose up
Options:
--exit-code-from SERVICE Return the exit code of the selected service container.
Implies --abort-on-container-exit.
--abort-on-container-exit Stops all containers if any container was stopped.
Incompatible with -d.
-d Detached mode: Run containers in the background,
print new container names.
Incompatible with --abort-on-container-exit.
Q. How to run docker-compose in detach mode
I am trying to run docker-compose in detach mode but it will exits after just it's run, but I am able run same image in detach mode using 'docker run' command.
Run image using 'docker run' command (works in detach mode)
docker run -itd ubuntu:16.04
below is output of 'docker ps -a' command
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d84edc987359 ubuntu:16.04 "/bin/bash" 4 seconds ago Up 3 seconds romantic_albattani
Run same image using 'docker-compose up -d' command (didn't work in detach mode)
below is my docker-compose.yml file
version: '3'
services:
ubuntu:
image: ubuntu:16.04
'docker-compose ps' command output
Name Command State Ports
----------------------------------------------------
composetesting_ubuntu_1 /bin/bash Exit 0
Update: When using tty: true parameter in docker-compose.yml file as below
version: '3'
services:
ubuntu:
image: ubuntu:16.04
tty: true
then console will not execute any command, like if I type 'ls -l' command console will not responding.
I just had to add tty: true to my docker-compose.yml
version: '2'
services:
ubuntu:
image: ubuntu:16.04
tty: true
Docker version 1.12.5, build 7392c3b
docker-compose version 1.7.1, build 0a9ab35
Above #fewtile42's answer is correct respect to my question. But only using 'tty: true' parameter user will not able to execute any command, so if one also want to execute or interact with console one should also use 'stdin_open: true' parameter.
version: '2'
services:
ubuntu:
image: ubuntu:16.04
tty: true
stdin_open: true