Use Case: You need to run a custom shell script in your Docker container with arguments passed to the script. These arguments decide how the script should be run inside the container.
In this guide we will look int to running custom shell scripts inside a docker container with command line arguments.
The key Dockerfile instructions used for this use case are
- ENTRYPOINT: Here you will specify the command that has to be executed when the container starts.
- CMD: Even CMD instruction is used to specify the command to be executed when the container starts.
But there are few differences between a ENTRYPOINT and CMD instruction. It is very important to know the difference.
Executing Commands Using CMD Vs ENTRYPOINT
- Lets take the following Dockerfile example. It installs http-tools an starts the ab (apache benchmark) utility using CMD and Entrypoint. Both does the same job.
Using CMD:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all CMD ["ab"]
Using ENTRYPOINT:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all ENTRYPOINT ["ab"]
- If you build this image and run the container, it will throw the following error. The reason is, ab command requires a http endpoint as argument to start the service.
➜ docker run demo ab: wrong number of arguments Usage: ab [options] [http[s]://]hostname[:port]/path Options are: -n requests Number of requests to perform
- We have two ways to get around this problem. Hardcode the http endpoint argument as shown below.
Using CMD:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all CMD ["ab"] ["http://google.com/"]
Using ENTRYPOINT:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all ENTRYPOINT ["ab" , "http://google.com/" ]
- Or, you can pass the ab command with the http endpoint at the end of the docker run command. Here is the
key difference between CMD and ENTRYPOINT
Using CMD:
Just add the full ab command at the end of the docker run command. It will override the whole CMD specified in the Dockerfile.
Dockerfile:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all CMD ["ab"]
Docker Command:
docker run ab-demo ab http://google.com/
Using ENTRYPOINT:
You cannot override the whole ENTRYPOINT. So if you want to pass URL argument for ab using ENTRYPOINT, you just need to pass the URL as the ab command is part of ENTRYPOINT and the URL you pass in the run command will be overridden by CMD and gets appended to the ENTRYPOINT script. In this case, CMD instruction is not required in the Dockerfile
Dockerfile:
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all ENTRYPOINT ["ab"]
Docker Command:
docker run ab-demo http://google.com/
You can also use both CMD and ENTRYPOINT instruction to achieve this. Here is how the Dockerfile looks.
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd-tools && \ yum clean all ENTRYPOINT ["ab"] CMD ["http://dummy-url.com/"]
When ENTRYPOINT and CMD used in the same Dockerfile, everything in the CMD instruction will be appended to the ENTRYPOINT as argument. If you run a container using the above Dockerfile, at container start, ab script will get executed with the dummy-url as an argument.
How To Run Custom Script Inside Docker
In this example, we have a custom shell script which accepts three command line arguments ($1, $2 & $3). If you pass true
as the the first argument, the script will run in a infinite loop. Other two arguments are just to print the values.
Step 1: Create a script.sh file and copy the following contents.
#!/bin/bash set -x while $1 do echo "Press [CTRL+C] to stop.." sleep 5 echo "My second and third argument is $2 & $3" done
Step 2: You should have the script.sh is the same folder where you have the Dockerfile. Create the Dockerfile with the following contents which copies the script to container and runs it it ENTRYPOINT using the arguments from CMD. We are passing true as the first argument, so the script will run in an infinite loop echoing batman and superman arguments as outputs.
FROM centos:7 MAINTAINER Devopscube RUN yum -y update && \ yum -y install httpd && \ yum clean all COPY ./script.sh / RUN chmod +x /script.sh ENTRYPOINT ["/script.sh"] CMD ["true", "batman", "superman"]
Step 3: Lets build this Dockerfile with image name script-demo.
docker build -t script-demo .
Step 4: Now lets create a container named demo using script-demo image.
docker run --name demo -d script-demo
You can check the container logs using the following command.
docker logs demo -f
Step 4: You can also pass the CMD arguments at the end of docker run command. It will override the arguments passed in the Dockerfile. For example,
docker run --name demo -d script-demo true batman superman
The post Running Custom Scripts In Docker With Arguments – ENTRYPOINT Vs CMD appeared first on DevopsCube.
Comments
Post a Comment