Command line shortcut to connect to a docker container - bash

Is there any shortcut command to connect to a docker container without running docker exec -it 'container_id' bash every time?

Here is a shorter command line shortcut to:
Check if a container is running
If running, connect to a running container using docker exec -it <container> bash command:
Script docker-enter:
#!/bin/bash
name="${1?needs one argument}"
containerId=$(docker ps | awk -v app="$name:" '$2 ~ app{print $1}')
if [[ -n "$containerId" ]]; then
docker exec -it $containerId bash
else
echo "No docker container with name: $name is running"
fi
Then run it as:
docker-enter webapp

I'm using the following alias on OS X:
alias dex='function _dex(){ docker exec -i -t "$(basename $(pwd) | tr -d "[\-_]")_$1_1" /bin/bash -c "export TERM=xterm; exec bash" };_dex'
In the same directory as my docker-files, I run "dex php" to enter the PHP container.

If random id is complicated. Start container with name docker run --name test image and connect with its name docker exec -it test bash.

Related

How to run a bash terminal in a Docker container along with additional commands?

To run a bash terminal in a Docker container I can run the following:
$ docker exec -it <container> /bin/bash
However, I want to execute a command in the container automatically. For example, if I want to open a bash terminal in the container and create a file I would expect to run something like:
docker exec -it <container> /bin/bash -c "touch foo.txt"
However, this doesn't work... Is there a simple way to achieve this? Of course, I could type the command after opening the container, but I want to open a bash terminal and run a command at the same time.
You can run your touch command and then spawn another shell :
docker exec -it <container> /bin/bash -c "touch foo.txt; exec bash"
Works perfectly fine for me
~# docker run -tid --rm --name test ubuntu:20.04
~# docker exec -it test /bin/bash -c "touch /foo.txt"
~# docker exec -it test /bin/bash
root#b6b0efbb13be:/# ls -ltr foo.txt
-rw-r--r-- 1 root root 0 Mar 7 05:35 foo.txt
Easy solution:
docker exec -it <container> touch foo.txt
You can verify
docker exec -it <container> ls
This was tested with alpine image.
Remember that in docker images there is a entrypoint and a command. Now we are editing the command of the default entrypoint for alpine, via docker exec
It depends of the entrypoint if env variablers are load or not, $PATH ..., so other images maybe you need to write /bin/touch or /usr/bin/ls
Good luck!
When you run docker exec -it <container> /bin/bash -c "touch foo.txt", container sends 0 exit code so that it means the task is done and you'll be returned to your host.
When you run docker exec -it <container /bin/bash, bash shell is not terminated until you explicitly type exit or use CTRL+D in bash environment. bash is continuously running.
This is why when you run the second command, it goes to bash, runs your command (touches) and then exits.

Bash Script fails with error: OCI runtime exec failed

I am running the below script and getting error.
#!/bin/bash
webproxy=$(sudo docker ps -a --format "{{.Names}}"|grep webproxy)
webproxycheck="curl -k -s https://localhost:\${nginx_https_port}/HealthCheckService"
if [ -n "$webproxy" ] ; then
sudo docker exec $webproxy sh -c "$webproxycheck"
fi
Here is my docker ps -a output
$sudo docker ps -a --format "{{.Names}}"|grep webproxy
webproxy-dev-01
webproxy-dev2-01
when i run the command individually it works. For Example:
$sudo docker exec webproxy-dev-01 sh -c 'curl -k -s https://localhost:${nginx_https_port}/HealthCheckService'
HEALTHCHECK_OK
$sudo docker exec webproxy-dev2-01 sh -c 'curl -k -s https://localhost:${nginx_https_port}/HealthCheckService'
HEALTHCHECK_OK
Here is the error i get.
$ sh healthcheck.sh
OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"webproxy-dev-01\": executable file not found in $PATH": unknown
Could someone please help me with the error. Any help will be greatly appreciated.
Because the variable contains two tokens (on two separate lines) that's what the variable expands to. You are running
sudo docker exec webproxy-dev-01 webproxy-dev2-01 ...
which of course is an error.
It's not clear what you actually expect to happen, but if you want to loop over those values, that's
for host in $webproxy; do
sudo docker exec "$host" sh -c "$webproxycheck"
done
which will conveniently loop zero times if the variable is empty.
If you just want one value, maybe add head -n 1 to the pipe, or pass a more specific regular expression to grep so it only matches one container. (If you have control over these containers, probably run them with --name so you can unambiguously identify them.)
Based on your given script, you are trying to "exec" the following
sudo docker exec webproxy-dev2-01
webproxy-dev-01 sh -c "curl -k -s https://localhost:${nginx_https_port}/HealthCheckService"
As you see, here is your error.
sudo docker exec webproxy-dev2-01
webproxy-dev-01 [...]
The problem is this line:
webproxy=$(sudo docker ps -a --format "{{.Names}}"|grep webproxy)
which results in the following (you also posted this):
webproxy-dev2-01
webproxy-dev-01
Now, the issue is, that your docker exec command now takes both images names (coming from the variable assignment $webproxy), interpreting the second entry (which is webproxy-dev-01 and sepetrated by \n) as the exec command. This is now intperreted as the given command which is not valid and cannot been found: That's what the error tells you.
A workaround would be the following:
webproxy=$(sudo docker ps -a --format "{{.Names}}"| grep webproxy | head -n 1)
It only graps the first entry of your output. You can of course adapt this to do this in a loop.
A small snippet:
#!/bin/bash
webproxy=$(sudo docker ps -a --format "{{.Names}}"| grep webproxy )
echo ${webproxy}
webproxycheck="curl -k -s https://localhost:\${nginx_https_port}/HealthCheckService"
while IFS= read -r line; do
if [ -n "$line" ] ; then
echo "sudo docker exec ${line} sh -c \"${webproxycheck}\""
fi
done <<< "$webproxy"

How to bash into a docker container

trying to bash into container and do a for loop which simply performs a command (which works on a single file by the way). it even seems to echo the right command...what did I forget
Untitled
for pdf in *.pdf ;
do
docker run --rm -v "$(pwd):/home/docker" leofcardoso/pdf2pdfocr -g jpeg2000 -v -i '\'''$pdf''\''';
done
You can bash in a container with this commands:
To see the docker container id
docker container ls
To enter in bash inside a container.
docker exec -it CONTAINER_ID bash
First thing, you are not allocating tty in the docker run command and the docker container dies soon after converting files. Here is main process of container
#!/bin/bash
cd /home/docker
exec pdf2pdfocr.py "$#"
So, in this case, the life of this container is the life of exec pdf2pdfocr.py "$#" command.
As mentioned by #Fra, override the entrypoint and run the command manually.
docker run --rm -v "$(pwd):/home/docker" -it --entrypoint /bin/bash leofcardoso/pdf2pdfocr
but in the above run command, docker container will do not a thing and will just allocate the tty and the bash will open. So you can convert files inside your containers using docker exec and then run pdf2pdfocr.py -g jpeg2000 -v -i mypdf.pdf
So, if you want to run with override entry point then you can try.
docker run -it --rm --entrypoint /bin/bash -v "$(pwd):/home/docker" leofcardoso/pdf2pdfocr -c "pdf2pdfocr.py -g jpeg2000 -v -i mypdf.pdf"
or with the bash script
#!/bin/bash
for pdf in *.pdf ;
do
echo "converting $pdf"
docker run -it --rm --entrypoint /bin/bash -v "$(pwd):/home/docker" leofcardoso/pdf2pdfocr -c "pdf2pdfocr.py -g jpeg2000 -v -i $pdf"
done
But the container will die after completing the conversion.

Bash script to get into a running container and then run another bash script from that container

I have a shell script which runs as follows :
image_id=$(docker ps -a | grep postgres | awk -F' ' '{print $1}')
full_id=$(docker ps -a --no-trunc -q | grep $image_id)
docker exec -i -t $full_id bash
When I run this from the base linux OS, I expect to actually enter the postgres container which is a running container. But the issue is that the shell script hangs on 3rd line during ' docker exec' step.
My end goal is using the bash script, enter a running postgres container and run another bash script inside that container.
However the same command when I run it from command line, it works fine and gets me into the postgres container.
Please help, I have spent hours and hours to solve this but no progress.
Thanks again
Your setup is a bit more complex than it needs to be.
Docker ps can filter containers directly with the --filter= option
docker ps --no-trunc --quiet --filter="ancestor=postgres"
You can also --name containers when you run them which will be less fraught with danger than the script you are attempting
docker run --detach --name postgres_whatever postgres
docker exec -ti postgres_whatever bash
I'm not sure that your script is hanging as opposed to sitting there waiting for input. Try running a command directly
Using naming
exec_test.sh
#!/usr/bin/env bash
docker exec postgres_whatever echo "I have run the test"
When run
$ ./exec_test.sh
I have run the test
Without naming
exec_filter_test.sh
#!/usr/bin/env bash
id=$(docker ps --no-trunc --quiet --filter="ancestor=postgres")
[ -z "$id" ] && echo "no id" && exit 1
docker exec "${id}" echo "I have run the test"
When run
$ ./exec_filter_test.sh
I have run the test

How to detect fully interactive shell in bash from docker?

I'm wanting to detect in "docker run" whether -ti has been passed to the entrypoint script.
docker run --help for -t -i
-i, --interactive=false Keep STDIN open even if not attached
-t, --tty=false Allocate a pseudo-TTY
I have tried the following but even when tested locally (not inside docker) it didn't work and printed out "Not interactive" always.
#!/bin/bash
[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
entrypoint.sh:
#!/bin/bash
set -e
if [ -t 0 ] ; then
echo "(interactive shell)"
else
echo "(not interactive shell)"
fi
/bin/bash -c "$#"
Dockerfile:
FROM debian:7.8
COPY entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod 755 /usr/bin/entrypoint.sh
ENTRYPOINT ["/usr/bin/entrypoint.sh"]
CMD ["/bin/bash"]
build the image:
$ docker build -t is_interactive .
run the image interactively:
$ docker run -ti --rm is_interactive "/bin/bash"
(interactive shell)
root#dd7dd9bf3f4e:/$ echo something
something
root#dd7dd9bf3f4e:/$ echo $HOME
/root
root#dd7dd9bf3f4e:/$ exit
exit
run the image not interactively:
$ docker run --rm is_interactive "echo \$HOME"
(not interactive shell)
/root
$
This stackoverflow answer helped me find [ -t 0 ].

Resources