Why does docker run -t keep the bash process from exiting and stopping the container - bash

I understand that a docker container will stop once the main process (the command) ends.
I also understand that the -t will allocate a pseudo TTY
docker run -t <image> <command>
Now, when I run bash by default the container stops immediately, which is expected
docker run fedora bash
docker -ps =>(this gives empty list)
But when I run bash with -t like this
docker run -t fedora bash
[CTRL+C]
docker ps =>(this shows one running container)
Why does -t keep the bash process running? Although the same -t will not keep, for example, echo running
docker run -t fedora echo "hello"
[CTRL+C]
docker ps =>(this shows empty list although we added -t)

When you use bash without -t it exits with status 0 immediately since you're not supplying any command to bash using -c option.
By using -t you are allocating a pseudo-tty to bash process. However you're not using another important -i option that keeps STDIN open even if not attached. Without -i you cannot type anything inside the bash hence bash keeps running waiting for the next command.
echo command exits with status 0 immediately because echo is not an interactive process like bash.
So right way to start bash is:
docker run -it fedora bash
As per official documentation:
For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it.

Related

Docker run to execute script in mount without exiting container automatically?

I have a simple bash script 'test.sh' in the root of mounted folder :
#!/bin/bash
Rscript -e "source('/home/rstudio/mount-folder/src/controller.R')";
However, when i try to mount folder and start the container with docker run as follows:
docker run -d -p 8000:8787 -e ROOT=true -e DISABLE_AUTH=true --name container -v mount-folder/:/home/rstudio/ image_name /home/rstudio/test.sh
above run command starts the container but exits automatically.
I am looking for a docker run command that starts the container , mounts the folder and then executes the bash script which is in the mount-folder without exiting the container.
(** dont want to go with docker exec command as it is not suitable for my use case for other reasons)
Dockerfile:
FROM rocker/rstudio:4.0.2
//some RUN commands to install necessary r packages
EXPOSE 8787
CMD tail -f /dev/null
Other details :
Image that i am using is rstudio server from rocker and container runs on AWS ubuntu machine.
Edit :
have also tried adding CMD tail -f /dev/null at the end of dockerfile as suggested in http://bigdatums.net/2017/11/07/how-to-keep-docker-containers-running/ even then the container exits.
Docker containers shutdown automatically when run in detached mode. I think this article proposes a nice solution:
http://bigdatums.net/2017/11/07/how-to-keep-docker-containers-running/
You could add tail -f /dev/null as the last command in your bash script instead so that the script will never halt unless it is told to do so.
When you do docker run [options] image_name [cmd] the command you specify becomes the command for the container and replaces any the command specified in the dockerfile (that's why adding CMD tail -f /dev/null doesn't do anything). If you ran your container without the /home/rstudio/test.sh at the end, it should stay running.
The solution would be to update your script to add the tail command at the end.
#!/bin/bash
Rscript -e "source('/home/rstudio/mount-folder/src/controller.R')";
exec tail -f /dev/null
If you can't update that script, you could instead add it to the command being passed to the container, with something like:
docker run [options] image_name bash -c '/home/rstudio/test.sh && exec tail -f /dev/null'

Unable to Find Entrypoint For Nextcloud (Alpine-based Version) For a Cron Container

I'm using Docker with Rancher v1.6, setting up a Nextcloud stack.
I would like to use a dedicated container for running cron tasks every 15 minutes.
The "normal" Nextcloud Docker image can simply use the following:
entrypoint: |
bash -c 'bash -s <<EOF
trap "break;exit" SIGHUP SIGINT SIGTERM
while /bin/true; do
su -s "/bin/bash" -c "/usr/local/bin/php /var/www/html/cron.php" www-data
echo $$(date) - Running cron finished
sleep 900
done
EOF'
(Pulled from this GitHub post)
However, the Alpine-based image does not have bash, and so it cannot be used.
I found this script in the list of examples:
#!/bin/sh
set -eu
exec busybox crond -f -l 0 -L /dev/stdout
However, I cannot seem to get that working with my docker-compose.yml file.
I don't want to use an external file, just to have the script entirely in the docker-compose.yml file, to make preparation and changes a bit easier.
Thank you!

Windows docker command line cannot accept inner commands

I have windows docker installed and when I run this on command line:
docker stop $(docker ps -q)
I get:
unknown shorthand flag: 'q' in -q)
But when running:
docker ps -q
Everything is alright. Any clues?
The $(sub command) is a syntax of the bash shell (along with many other command shells on Linux). If you try to run this from a Windows command prompt, it will not be correctly expanded before running the rest of the command and you'll see the errors you're encountering. Try installing and running the commands on bash for Windows.
I used this in Windows:
powershell docker stop $(docker ps -aq)
You can try a little trick to stop all containers :
docker ps -a -q | xargs -n 1 -P 8 -I {} docker stop {}
It does not contain $ symbol, so should be correct
You can also enable Bash shell within Powershell on recent releases of Windows 10 and the use the $ command

Run Docker by using shell script from remote machine?

Hi i want to up a docker jenkins container and add jobs by using jenkins-CLI command, these process done successfully when i did manually and by using shell script also. But the main problem is when i am trying to execute this script from remote machine docker container is starting but when i am trying to execute commands in docker container from remote machine it's showing error
cannot enable tty mode on non tty input
cannot enable tty mode on non tty input
My script on docker machine
b="branch1"
sed -i "s/master/$b/g" /root/docker/config.xml
#Run docker jenkins base image
docker run -d -P localhost:5000/jenkins_base2
#Printing docker container
export c=($(docker ps))
echo "${c[8]}"
export x="${c[8]}"
sleep 5
#Copying Config file
docker exec -it ${c[8]} bash -c 'scp root#192.168.0.86:/root/docker/config.xml /root/'
sleep 25
#creating job using jenkins CLI
docker exec -ti ${c[8]} bash -c 'java -jar /opt/apache-tomcat-7.0.68/webapps/jenkins/WEB-INF/jenkins-cli.jar -s http://localhost:8080/ create-job $b < /root/config.xml '
script on remote machine
ssh 192.168.0.86 sh docker.sh
Try ssh with -tt option.
ssh -tt 192.168.0.86 sh docker.sh

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

Resources