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
I have a docker-compose.yml file that starts two services: amazon/dynamodb-local on 8000 port and django-service. django-service runs tests that are dependent on dynamodb-local.
Here is working docker-compose.yml:
version: '3.8'
services:
dynamodb-local:
image: "amazon/dynamodb-local:latest"
container_name: dynamodb-local
ports:
- "8000:8000"
django-service:
depends_on:
- dynamodb-local
image: django-service
build:
dockerfile: Dockerfile
context: .
env_file:
- envs/tests.env
volumes:
- ./:/app
command: sh -c 'cd /app && pytest tests/integration/ -vv'
Now I need to run this without docker-compose, only using docker itself. I try to do following:
docker network create -d bridge net // create a network for dynamodb-local and django-service
docker run --network=net --rm -p 8000:8000 -d amazon/dynamodb-local:latest // run cont. att. to network
docker run --network=net --rm --env-file ./envs/tests.env -v `pwd`:/app django-service /bin/sh -c 'env && cd /app && pytest tests/integration -vv'
I can see that both services start, but I can't connect to the dynamo-db.
Where is the problem? Any comment or help is appreciated!
Through the docker-compose.yml, the amazon/dynamodb-local container has a name defined (container_name: dynamodb-local, If we do not set this property, docker-compose will use the service's name as container name). This enables other containers in the same network to address the container through its name.
In the docker-run command, we do not set an explicit container name. We can set an explicit container name by executing docker run ... --name dynamodb-local .... More details can be found in the corresponding docker run documentation.
I'm new to Docker and having trouble running the docker image https://github.com/mpolden/echoip#docker-image. What am I doing wrong? Any help would be greatly appreciated!
$ docker run mpolden/echoip -a ./GeoLite2-ASN.mmdb -c ./GeoLite2-City.mmdb -f ./GeoLite2-Country.mmdb
echoip: open ./GeoLite2-Country.mmdb: no such file or directory
The files are in the same directory. To test on your end, download the files: GeoLite2-ASN.mmdb, GeoLite2-City.mmdb, GeoLite2-Country.mmdb: https://gofile.io/d/G4i6hb
Having a docker-compose.yml would make this much easier to run:
version: "3.7"
services:
echoip:
image: mpolden/echoip
command: "echoip -a ./GeoLite2-ASN.mmdb -c ./GeoLite2-City.mmdb -f ./GeoLite2-Country.mmdb"
ports:
- "8080:8080"
restart: unless-stopped
The files are in the same directory
Docker containers cannot access the host filesystem unless it is mounted as a volume. For example, you could mount the current directory to /data in the container...
docker run --rm -v "${PWD}:/data" -p 8080:8080 mpolden/echoip \
-a /data/GeoLite2-ASN.mmdb \
-c /data/GeoLite2-City.mmdb \
-f /data/GeoLite2-Country.mmdb \
-l 0.0.0.0:8080
A Docker Compose config might look like this
version: "3.8"
services:
echoip:
image: mpolden/echoip
command: >
-l 0.0.0.0:8080
-a /data/GeoLite2-ASN.mmdb
-c /data/GeoLite2-City.mmdb
-f /data/GeoLite2-Country.mmdb
ports:
- "8080:8080"
volumes:
- "./:/data"
restart: unless-stopped
I'm learning about Docker and I'm at first steps.
I've to 'refresh' postgres image from compose file to initialize db scripts as YOSIFKIT here do through shell (https://github.com/docker-library/postgres/issues/193).
here is my Docker file:
FROM postgres:9.6.7
COPY docker-postgresql-9.6.7/prova.sql /docker-entrypoint-initdb.d/
and here is my compose file:
version: '3'
services:
postgresql_rdbms:
restart: always
image: postgres-prova
build:
context: ../
dockerfile: docker-postgresql-9.6.7/Dockerfile
command: bash -c "docker run -it --rm postgres-prova ls -ln /docker-entrypoint-initdb.d && docker run -it --rm postgres-prova && postgres"
environment:
PG_PASSWORD: postgres
ports:
- "5432:5432"
volumes:
- /srv/docker/postgresql:/var/lib/postgresql
HOW can I insert a command in a compose-file to do "docker run -it --rm imageToReload" ???
Because I've seen that "command:" in compose file works inside the container, but I want operate ON the container, on a upper level (=manage the container from the compose file, after the container creation)
Thank you very much
From what I understand you want docker-compose to delete/remove the container after every run so that the build is run each time and a fresh prova.sql file can be copied into the image each time the service is brought up. The --force-recreate flag is probably what you need.
The command directive within the yaml file provides the command that is run inside the container.
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