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.
This question is related to
shell
docker
interactive
docker-compose
If anyone from the future also wanders up here:
docker-compose exec container_name sh
or
docker-compose exec container_name bash
or you can run single lines like
docker-compose exec container_name php -v
That is after you already have your containers up and running
In the official getting started example (https://docs.docker.com/compose/gettingstarted/) with the following docker-compose.yml
:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
After you start this with docker-compose up
, you can easily 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
The canonical way to get an interactive shell with docker-compose is to use:
docker-compose run --rm myapp
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.
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
.
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.
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".
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.
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
Source: Stackoverflow.com