Printing output of shell script running inside a docker container - docker

I have a Dockerfile in which I have specified an ENTRYPOINT "my_script.sh".In my_script.sh,I am exe.cuting a CURL command.When the docker image with this Dockerfile is built.How should I run it so that output of my_script.sh will be printed on my host.
Dockerfile -
FROM my-company-repo-java-base-image
ADD my_script.sh /root
ENTRYPOINT bash "/root/my_script.sh
my_script.sh
echo "Hello My Script"
curl -x POST "some_api_which_returns_json"
I have built the image using command
docker build
I want to run this image and see output of my_script.sh on my dockerhost.

Given a Docker image whose tag is $DOCKER_IMAGE:
docker container run -it --rm $DOCKER_IMAGE
-i keeps STDIN open
-t allocates a pseudo-TTY
--rm automatically removes the container when it exits
See docker container run for all the options.

Of course you can see the output of shell script. Make sure you delete the old image before building new one when you change the script. Else, your container will keep using the old script over and over. Here's an example
Dockerfile
FROM alpine:3.7
ENTRYPOINT ["/usr/bin/myscript.sh"]
COPY myscript.sh /usr/bin/myscript.sh
myscript.sh
#!/usr/bin/env sh
echo "Hello there"
commands to run:
docker image rm testdocker
docker build --tag testdocker .
docker run testdocker
You should see the line Hello there appears on the terminal

Related

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.

How to continue running scripts when exiting docker containers

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>

Arguments for overridden docker entrypoint

The Entrypoint of a docker image can be modified while running the image using --entrypoint in docker run command. I want to start a script in my image with some arguments at startup. I can get docker to run the script at startup as
docker run -it --rm --entrypoint /my/script/path.sh my-docker-image
How do I pass arguments to my script?
Note that I cannot modify the original dockerfile with which this image was created. Neither do I want to create another docker image with this image as its base.
When your Docker image has an ENTRYPOINT, either via a Dockerfile or provided on the command line with --entrypoint, any arguments on the docker run command line after the image name are passed to the entrypoint script.
So for example, if I have a script like this in myscript.sh:
#!/bin/sh
echo "Here are my arguments: $#"
And I run an image like this:
$ chmod 755 myscript.sh
$ docker run -it --rm -v $PWD/myscript.sh:/myscript.sh \
--entrypoint /myscript.sh alpine one two three
I will see the output:
Here are my arguments: one two three
...and the container will exit, because the entrypoint script didn't arrange to do anything else. You could replace alpine here (which is a minimal docker image) with any other Docker image that has /bin/sh (so, most of them). For example:
$ docker run -it --rm -v $PWD/myscript.sh:/myscript.sh \
--entrypoint /myscript.sh centos one two three
Here are my arguments: one two three
Note that I'm using the -v argument in this example to mount a script on my host into the container, since I didn't want to create a new image for the purposes of this example. You could obviously bake a similar script into your image instead.
For details, read the ENTRYPOINT docs.

How to pass command line arguments to a docker image

I run tests inside docker image and I need to pass custom arguments
all the time.
When I put arguments after image name docker thinks that argument is image name.
docker run -t -i image-name -s test.py
docker run -t -i image-name -- -s test.py
Error:
Failed no image test_arena2.py
Docker version 1.11.2, build b9f10c9
You can build your Dockerfile with a combination of ENTRYPOINT and CMD instructions, which will let you run containers with or without arguments, e.g:
FROM ubuntu
ENTRYPOINT ["/bin/echo"]
CMD ["hello"]
That says the entrypoint is the echo command, and the default argument is hello. Run a container with no arguments:
> docker run temp
hello
Run with arguments and they all get passed to the entrypoint command:
> docker run temp -s stackoverflow
-s stackoverflow
docker run -i is good to be the begin of your command line then set of arguments for the run command only then at the very last -t image with image name provided
Image name should always be at the end of docker run command i.e. as last parameter to the command. Are you fine with passing the values as environment variable using below command
docker run -e "ENV_VAR_NAME=VALUE" -it image_name

Automatically run command inside docker container after starting up + volume mount

I have created my simple own image from .
FROM python:2.7.11
RUN mkdir /extra/later/ \
&& mkdir /yyy
Now I'm able to perform the following steps:
docker run -d -v xxx:/yyy myimage:latest
So now my volume is mounted inside the container. I'm going to access and I'm able to perform commands on that mounted volume inside my container:
docker exec -it container_id bash
bash# tar -cvpzf /mybackup.tar -C /yyy/ .
Is there a way to automate this steps in your Dockerfile or describing the commands in your docker run command?
The commands executed in the Dockerfile build the image, and the volume is attached to a running container, so you will not be able to run your commands inside of the Dockerfile itself and affect the volume.
Instead, you should create a startup script that is the command run by your container (via CMD or ENTRYPOINT in your Dockerfile). Place the logic inside of your startup script to detect that it needs to initialize the volume, and it will run when the container is launched. If you run the script with CMD you will be able to override running that script with any command you pass to docker run which may or may not be a good thing depending on your situation.
Try using the CMD option in the Dockerfile to run the tar command
CMD tar -cvpzf /mybackup.tar -C /yyy/ .
or
CMD ["tar", "-cvpzf", "/mybackup.tar", "-C", "/yyy/", "."]

Resources