{"id":1078,"date":"2023-03-16T17:13:52","date_gmt":"2023-03-16T17:13:52","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=1078"},"modified":"2023-03-16T17:13:52","modified_gmt":"2023-03-16T17:13:52","slug":"entrypoint-vs-cmd-explained","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=1078","title":{"rendered":"Docker ENTRYPOINT Vs CMD Explained With Examples"},"content":{"rendered":"<p>In this blog we will look at the key differences between <a href=\"https:\/\/devopscube.com\/what-is-docker\/\">Docker<\/a> ENTRYPOINT vs CMD instruction using a practical example.<\/p>\n<h2 id=\"what-is-entrypoint-and-cmd\">What is ENTRYPOINT and CMD<\/h2>\n<p>In a Dockerfile, <code>ENTRYPOINT<\/code> and <code>CMD<\/code> are two different instructions that are used to define how a <a href=\"https:\/\/devopscube.com\/what-is-a-container-and-how-does-it-work\/\">container<\/a> should run.<\/p>\n<p><code>ENTRYPOINT<\/code> is used to specify the main command that should be executed when a container is started using the image. The default ENTRYPOINT command is <code>\/bin\/sh -c<\/code><\/p>\n<p><code>CMD<\/code>, on the other hand, is used to specify the default command and arguments that should be executed when a container is started.<\/p>\n<p>If both <code>ENTRYPOINT<\/code> and <code>CMD<\/code> are specified in a Dockerfile, the command specified in <code>CMD<\/code> will be appended to the <code>ENTRYPOINT<\/code> command. It acts as an argument for ENTRYPOINT. The resulting command will be executed when the container is started.<\/p>\n<p>Lets understand these concepts practically.<\/p>\n<h2 id=\"executing-commands-using-entrypoint-and-cmd\">Executing Commands Using ENTRYPOINT and CMD<\/h2>\n<p>Let&#8217;s take an example of the following Dockerfile. It installs http-tools and starts the ab (<a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/programs\/ab.html?ref=devopscube.com\" rel=\"noreferrer noopener\">apache benchmark<\/a>) utility using CMD and Entrypoint. Both of them perform the same job<\/p>\n<p><strong>Using CMD<\/strong><\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nCMD [\"ab\"]<\/code><\/pre>\n<p><strong>Using ENTRYPOINT:<\/strong><\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nENTRYPOINT [\"ab\"]<\/code><\/pre>\n<p>Now if you run the container from the above Dockerfile images, it will throw the following error.<\/p>\n<pre><code>\u279c  docker run demo\nab: wrong number of arguments\nUsage: ab [options] [http[s]:\/\/]hostname[:port]\/path\nOptions are:\n    -n requests     Number of requests to perform<\/code><\/pre>\n<p>The reason is, <strong>ab command requires an http endpoint<\/strong> as an argument to start the service.<\/p>\n<p>We have two ways to get around this problem. Hardcode the HTTP endpoint argument as shown in the below examples.<\/p>\n<p><strong>Using CMD<\/strong>: The <code>ab<\/code> executable and HTTP URL arguments are added in separate square brackets.<\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nCMD [\"ab\"] [\"http:\/\/google.com\/\"]<\/code><\/pre>\n<p><strong>Using ENTRYPOINT:<\/strong> The executable and argument are separated by commas in the same square bracket.<\/p>\n<p>FROM centos:7 MAINTAINER Devopscube RUN yum -y update &amp;&amp; \\ yum -y install httpd-tools &amp;&amp; \\ yum clean all ENTRYPOINT [&#8220;ab&#8221; , &#8220;http:\/\/google.com\/&#8221; ]<\/p>\n<h2 id=\"difference-between-entrypoint-and-cmd\">Difference Between ENTRYPOINT and CMD<\/h2>\n<p>Lets look at the difference between <code>CMD<\/code> and <code>ENTRYPOINT<\/code> by passing ab commands during docker run.<\/p>\n<p><strong>Using CMD:<\/strong><\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nCMD [\"ab\"]<\/code><\/pre>\n<p>While running the container, just add the full ab command at the end of the docker run command. It will <strong>override the whole CMD<\/strong> specified in the Dockerfile.<\/p>\n<pre><code>docker run ab-demo ab http:\/\/google.com\/<\/code><\/pre>\n<p><strong>Using ENTRYPOINT:<\/strong><\/p>\n<p>If you want to pass the URL argument to ENTRYPOINT, you need to pass the URL alone. The reason is we have the <code>ab<\/code> command as part of the ENTRYPOINT definition.<\/p>\n<p>And the URL you pass in the run command will be appended to the ENTRYPOINT script. In this case, CMD instruction is not required in the Dockerfile.<\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nENTRYPOINT [\"ab\"]<\/code><\/pre>\n<p><strong>Docker Command:<\/strong><\/p>\n<pre><code>docker run ab-demo http:\/\/google.com\/<\/code><\/pre>\n<p>You <strong>can override the whole ENTRYPOINT<\/strong> like you do with CMD using the <code>--entrypoint<\/code> flag as shown below<\/p>\n<pre><code>docker run --entrypoint \"ab\" ab-demo http:\/\/google.com\/<\/code><\/pre>\n<h2 id=\"using-entrypoint-and-cmd-in-same-dockerfile\">Using ENTRYPOINT and CMD in Same Dockerfile<\/h2>\n<p>You can also use both <code>CMD<\/code> and <code>ENTRYPOINT<\/code> instructions to achieve this. Here is how the Dockerfile looks.<\/p>\n<pre><code>FROM centos:7\nMAINTAINER Devopscube\nRUN yum -y update &amp;&amp; \\\n    yum -y install httpd-tools &amp;&amp; \\\n    yum clean all\nENTRYPOINT [\"ab\"]\nCMD [\"http:\/\/dummy-url.com\/\"]<\/code><\/pre>\n<p>When <code>ENTRYPOINT<\/code> and <code>CMD<\/code> used in the same Dockerfile, everything in the CMD instruction will be appended to the ENTRYPOINT as an argument.<\/p>\n<p>If you run a container using the above Dockerfile, at container start, ab script will get executed with the <code>dummy-url.com <\/code>as an argument.<\/p>\n<h2 id=\"entrypoint-and-cmd-in-kubernetes-pod\">ENTRYPOINT and CMD in Kubernetes Pod<\/h2>\n<p>Lets understand how Docker Entrypoint and CMD translates to <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\">Kubernetes<\/a> Pod.<\/p>\n<p>When it comes to Kubernetes Pod, we have the option named &#8220;<code>command<\/code>&#8221; and &#8220;<code>args<\/code>&#8221; in the Pod Specification to override Entrypoint and CMD set in the Docker image.<\/p>\n<p>In Kubernetes Pod if you want to override Docker CMD or Entrypoint, you need to specify the command and args show below.<\/p>\n<pre><code>apiVersion: v1\nkind: Pod\nmetadata:\n  name: my-pod\nspec:\n  containers:\n  - name: my-container\n    image: my-image\n    command: [\"my-script.sh\"]\n    args: [\"arg1\", \"arg2\"]<\/code><\/pre>\n<p>In this example, the <code>entrypoint<\/code> is set to <code>[\"\/bin\/bash\", \"-c\"]<\/code>, which means that when the container starts, it will run the <code>bash<\/code> shell with the <code>-c<\/code> flag to execute the command specified in the <code>command<\/code> field (<code>my-script.sh<\/code>). The <code>args<\/code> field specifies any additional arguments to be passed to <code>my-script.sh<\/code>.<\/p>\n<p>Here is what you should know.<\/p>\n<ol>\n<li>In case a Command or Args is not provided for a container, the defaults specified by the image will be utilized.<\/li>\n<li>However, if you provide a Command without any Args for the container, only the specified Command will be executed while disregarding the default arguments of the image.<\/li>\n<li>On the other hand, if only Args are supplied, the image&#8217;s default command will be used in conjunction with the provided arguments.<\/li>\n<li>Lastly, if both Command and Args are supplied, the defaults of the image will be overridden and the supplied values will be utilized.<\/li>\n<\/ol>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/entrypoint-vs-cmd-explained\/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker ENTRYPOINT Vs CMD Explained With Examples \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/entrypoint-vs-cmd-explained\/<\/p>\n","protected":false},"author":1,"featured_media":1079,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1078","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/1078","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1078"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/1078\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/1079"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}