Reputation: 15781
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.
Upvotes: 651
Views: 744340
Reputation: 28040
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. For 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.
Upvotes: 481
Reputation: 8737
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
.
Upvotes: 823
Reputation: 1442
You can get an interactive shell with docker-compose using the following command (considering that the yml
has specified a service called myservice
):
$ docker-compose exec myservice sh
In the case of using a different yml
file name, such as docker-compose-mycompose.yml
, to get the interactive terminal, it is necessary to specify the yml
, like:
$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
Upvotes: 13
Reputation: 219
You can execute the shell
through docker compose run
.
compose.yml:
services:
myapp:
build: .
Dockerfile
FROM alpine:latest
Commandline on host
docker compose run --rm myapp sh -c "/bin/sh"
You might also want to mount some volumes in the compose file to persist whatever you are doing inside the container in compose.yml:
services:
myapp:
build: .
volumes:
- .:/app
I have mounted the current directory on host to the directory /app inside the container.
Upvotes: 1
Reputation: 41
I found the following steps can open an interactive shell, although it's not directly with docker-compose
:
docker-compose up
docker ps -a
docker exec -it containerName bash
Your terminal should now be in the bash shell of the container and you can interact with its content.
Hope this helps.
Upvotes: 1
Reputation: 20370
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
Upvotes: 148
Reputation: 813
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
Upvotes: 72
Reputation: 17546
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
Upvotes: 5
Reputation: 140
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
Upvotes: 2
Reputation: 1846
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.
Upvotes: 11
Reputation: 2293
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".
Upvotes: 4
Reputation: 4960
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
Upvotes: 93
Reputation: 1049
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.
Upvotes: 38