Running Custom Scripts In Docker With Arguments – ENTRYPOINT Vs CMD
- Last Updated On: June 20, 2019
- By: devopscube
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. The default ENTRYPOINT command is
/bin/sh -c
- CMD: It acts as an argument for ENTRYPOINT.
Executing Commands Using CMD Vs ENTRYPOINT
- Let’s 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 an 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 false spiderman hulk
Here "false spiderman hulk"
will override "true", "batman", "superman"
present in the docker image
devopscube
Other Interesting Blogs
Puppet Hiera Tutorial – Beginners Guide
When you write a puppet module, you might not want to put all the data in to the module because all the
Kubernetes Tutorials For Beginners: Getting Started Guide
Official kubernetes (k8s) website says, Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. It groups containers that
Linux Command Line Tips for Increasing Productivity
When it comes to Linux, most of the time you would be working on the command line. With the advent of configuration
Comments
Give another words at Step 4 so it becomes meaningful
Thanks for the Tip Berk. We have made the changes
thank you man, this article was really helpful for me
Is there any tutorials for building a Jenkins Pipeline for Ruby on Rails as a Docker image.