How to continue running scripts when exiting docker containers - docker

My script is as follows:
# start a ubuntu container in the background
docker run -it --name ub -d ubuntu /bin/bash
sleep 1
# run a command in the container
docker exec -it ub bash
echo 234
# exit the container
exit
sleep 1
# do something else
echo 123
But the script would just stop right after exit and hang there. Does anyone know why is that?
p.s: My Docker version is: 17.03.0-ce, build 60ccb22

You have given -it during the run command. which opens up the /bin/bash of your container and waits there. The next command wont get executed until the first command execution is completed.
It's better to create a script file and move it inside the container while making the docker. and run the script on starting the docker. You may specify that using a CMD in the docker file.
You won't be needing an additional exec command.
The corresponding Dockerfile would be
FROM ubuntu:latest
COPY <path-to-script> <dest>
CMD [" <path-to-script> "]
You have to create the script file along with the Dockerfile. Build the docker using the command
docker build -t <image-name> <location of Dockerfile>
The execution command would be
docker run -d --name <name> -d ubuntu <path-to-script>

Related

Batch file not executing a command

I am trying to create a .bat file that will back-up the database inside the container. After the first command (that is used to enter the container) the next one is ignored.
docker exec -it CONTAINER_NAME /bin/bash
cd /var/opt/mssql/data
Any ideas why? If I'm trying to manually write cd /var/opt/mssql/data in the opened cmd it works.
When running docker exec -it CONTAINER_NAME /bin/bash, you are opening a bash-shell INSIDE the docker container.
The next command, i.e. cd /var/opt/mssql/data, is only executed, if the previous command, docker exec -it CONTAINER_NAME /bin/bash has exited successfully, which means that the shell on the docker container has been closed/exited.
This means that cd /var/opt/mssql/data is then executed on the local machine and not inside the docker container.
To run a command inside the docker container, use the following command
docker exec -it CONTAINER_NAME /bin/bash -c "<command>"
Although it may be better to create a script inside the container during the build process or mount a script inside the docker container while starting the container and then simply call this script with the above mentioned command.

Any commands hang inside docker container

Any commands hang terminal inside docker container.
I login in container with docker exec -t php-zts /bin/bash
And then print any elementary command (date, ls, cd /, etc.)
Command hang
When I press ctrl+c I going back to host machine.
But, if I run any command without container - it's work normally
docker exec -t php-zts date
Wed Jan 26 00:04:38 UTC 2022
tty is enabled in docker-compose.yml
docker system prune and all cleanups can not help me.
I can't identify the problem and smashed my brain. Please help :(
The solution is to use the flag -i/--interactive with docker run. Here is a relevant section of the documentation:
--interactive , -i Keep STDIN open even if not attached
You can try to run your container using -i for interactive and -t for tty which will allow you to navigate and execute commands inside the container
docker run -it --rm alpine
In the other hand you can run the container with docker run then execute commands inside that container like so:
tail -f /dev/null will keep your container running.
-d will run the command in the background.
docker run --rm -d --name container1 alpine tail -f /dev/null
or
docker run --rm -itd --name container1 alpine sh # You can use -id or -td or -itd
This will allow you to run commands from inside the container.
you can choose sh, bash, or any other shell you prefer.
docker exec -it container1 alpine sh

Run a command line when starting a docker container

As far as I'm concerned you can run a command line when building an image with RUN or when running a container with CMD. Is there anyway to do so when starting a docker container?
My goal is to run the gcloud datastore automatically just after typing docker start my_container_name.
If this is possible, which changes should I apply to my Dockerfile?
(I have already installed all the packages required and I can run that command after docker run --name my_container_name -i -t my_image_name but I want it to be run also when starting the container)
Docker execute RUN command when you build the image.
Docker execute ENTRYPOINT command when you start the container. CMD goes as arguments to ENTRYPOINT. Both of these can be overridden when you create a container from an image. Their purpose in Dockerfile is to provide defaults for future when you or someone else will be creating containers from this image.
Consider the example:
FROM debian:buster
RUN apt update && apt install procps
ENTRYPOINT ["/usr/bin/ps"]
CMD ["aux"]
The RUN command adds ps command to the image, ENTRYPOINT and CMD are not executed but they will be when you run the container:
# create a container named 'ps' using default CMD and ENTRYPOINT
docker run --name ps my_image
# equivalent to /usr/bin/ps aux
# start the existing container 'ps'
docker start ps
# equivalent to /usr/bin/ps aux
# override CMD
docker run my_image au
# equivalent to /usr/bin/ps au
# override both CMD and ENTRYPOINT
docker run --entrypoint=/bin/bash my_image -c 'echo "Hello, world!"'
# will print Hello, world! instead of using ps aux
# no ENTRYPOINT, only CMD
docker run --entrypoint="" my_image /bin/bash -c 'echo "Hello, world!"'
# the output is the same as above
Each time you use docker run you create a container. The used ENTRYPOINT and CMD are saved as container properties and executed each time you start the container.

File created in interactive session within container dissapears after exiting container (container running in background)

Objective
Essentially what I am trying to accomplish is to install a bunch of software but store the commands run in the Dockerfile in the end. I was planning on recording the installation process by running the "script" function to record the commands run on the command line. I would like to know why it doesn't work but if there is a better way of doing it, I am all ears!
The issue
I'm sure there is a simple answer to this but I can't seem to figure it out. When I create a dummy file within my docker container it dissapears when I exit the container even though the container is running in the background.
Attempt
This is my Dockerfile
##Filename = Dockerfile
FROM centos:7
WORKDIR /dummy_folder
CMD ["echo", "hello world"]
I build the image and run it in the background.
docker build -t my_test_image:v1.0 .
docker run -d e9e949b5d85a tail -f /dev/null
Now I can see my container running in the background
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f4da7a1b74d e9e949b5d85a "tail -f /dev/null" 14 minutes ago Up 14 minutes trusting_poincare
If I create an interactive session and just dump a file in /dummy_folder and exit. When I create a new interactive session /dummy_folder is empty again.
docker run -it e9e949b5d85a /bin/bash
echo "dummy" > dummy
exit
docker run -it e9e949b5d85a /bin/bash
ls -alh /dummy_folder
P.S tail -f /dev/null is just a trick I use to keep the container running in the background as just running it with the flag -d doesn't work for centos containers apparently.
I am running Docker version 19.03.8, build afacb8b
Thanks
Sabri
You're creating a new container every time your run docker run ... . What I think you're trying to do is run a shell on the same container you started with docker run -d e9e949b5d85a tail -f /dev/null. If so, the Docker command your'e looking for is exec
Start an interactive session using the container ID (not the image ID) and do your stuff
docker exec -it 6f4da7a1b74d /bin/bash
$ echo "dummy" > dummy
$ exit
And then check the contents again with exec
docker exec 6f4da7a1b74d ls -alh /dummy_folder

re-running a script in a docker container

I have created a docker image that includes some python code and a shell script that can execute it. It is going to process a bunch of images from the host system.
This command should create a new contaier and run it.
sudo docker run -v /host/folder:/container/folder opencv:latest bash /extract-embeddings.sh
At the end, the container exits. If I type the same command, then another container is created and exited at completion. But how is the correct usage of containers? Should I use restart, start or run (and then clean up exited containers after)? It just seems unnessary to create a new container each time.
I basically just want a docker image containing some code and 3-4 different commands I can execute whenever needed.
And the docker start command doesn't seem to accept "bash /extract-embeddings.sh" as parameters, instead things bash and extract-embeddings.sh are containers. So maybe I am misunderstanding the lifecycle of containers or the usage.
edit:
Got it to work with:
docker run -t -d --name opencv -v /host/folder:/container/folder
docker exec -it opencv bash /extract-embeddings.sh
You can write the Dockerfile to create your docker image and keep the scripts into it-
Dockerfile:
FROM opencv:latest
COPY ./your-script /some_folder
Create image:
docker build -t my_image .
Run your container:
docker run -d --name my_container
Run the script inside the container:
docker exec -it <container_id_or_name> bash /some_folder/your-script
Build your own docker image that starts with opencv:latest and give the command you run as the entrypoint. Dockerfile could be like
FROM opencv:latest
CMD ["/bin/bash", "/extract-embeddings.sh"]
Use docker create to create a named container.
sudo docker create --name=processmyimage -v /host/folder:/container/folder myopencv:latest
Then use docker start each time you want to run it.
sudo docker start processmyimage
This works well if there is only one command you want to run. If there is more than one command, I would take the approach of building an image that runs unrelated command forever (like a tail -f < /dev/null). Then you can use
sudo docker exec -d /bin/bash < cmd-to-run >
for each command

Resources