Reputation: 20448
I'd like to enter a docker container in interactive mode with the commad /bin/bash using a docker-compose.yml only. There is a similar question here on stack overflow: Interactive shell using Docker Compose Answers provided there didn't work. This is what my docker-compose.yml looks like:
version: "3"
services:
server:
image: golang:1.11.1
volumes:
- './server:/go'
ports:
- '8080:8080'
command: '-ti'
entrypoint:
- '/bin/bash'
This is my console in and output:
[bluebrown@firefly gowild]$ docker-compose up --build
Recreating gowild_server_1 ... done
Attaching to gowild_server_1
server_1 | bash: cannot set terminal process group (-1): Inappropriate ioctl for device
server_1 | bash: no job control in this shell
server_1 | root@d5884893075a:/go# exit
gowild_server_1 exited with code 0
Reading the above-mentioned post I tried of course also to substitute:
command: '-ti'
for these two lines:
stdin_open: true
tty: true
but when doing this docker compose gets stuck while attaching:
[bluebrown@firefly gowild]$ docker-compose up --build
Recreating gowild_server_1 ... done
Attaching to gowild_server_1
And nothing happens further. No error and exit nor a 'done' message.
When trying it with sh
instead of bash
it says the following for the command: '-it
:
server_1 | /bin/sh: 0: Illegal option -t
And also gets stuck just like with bash while attaching when substituting it.
Note that I can build and run the server without the command and entrypoint simply using the following:
docker-compose up
docker-compose run --service-ports server
Still my question is how to do it using docker-compose and an entrypoint, so It can be done with docker-compose up
only.
Update: I'm using Linux manjaro
Upvotes: 4
Views: 13959
Reputation: 20448
In that particular use case the solution should be like below. The reason for this is usually /bin/bash is used with -ti
to enter a shell inside the container.
The same thing can be done with compose by using the run command with a particular service. Note that I am exposing the service ports too.
docker-compose run --service-ports server bash
https://docs.docker.com/compose/reference/run/
If the container is already running then exec
should be enough.
Upvotes: 2
Reputation: 1907
I think the issue here is that docker-compose could potentially run multiple containers .. so it can't generally attach to stdin of a particular container. Clearly, in your case with only a single container, there should be no confusion so it could do it - but that would change behaviour if you later added another container to the yml, which would be confusing and essentially a bug at that point.
So .. compose is not the right tool for this job.
I have a little bash script called dockersh
which makes it easy to drop into a shell of any docker image:
#!/bin/sh
IMAGE=$1
shift
# sanitise the name a little
NAME=$(echo $IMAGE | tr '/:' '-')
# generate a random ID in case we have multiple running
ID=$(env LC_CTYPE=C tr -dc "a-z0-9" < /dev/urandom | head -c 10)
docker run --rm -ti \
--name $NAME-$ID \
-v $PWD:/mnt/$(basename $PWD) \
-v $HOME/.ssh:/root/.ssh \
$IMAGE \
"$@"
The .ssh
mount is useful for cloning git repos etc. On linux, you could alternatively do that by mounting $SSH_AUTH_SOCK
into the container, but that doesn't work on mac (at least for me).
For your case above, you can run as:
dockersh golang:1.11.1 bash
Although you might want to make this a little less generic for yourself and expose ports and mount into /go
etc.
Upvotes: 1