{"id":983,"date":"2024-04-29T16:42:43","date_gmt":"2024-04-29T16:42:43","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=983"},"modified":"2024-04-29T16:42:43","modified_gmt":"2024-04-29T16:42:43","slug":"create-dockerfile-using-docker-init","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=983","title":{"rendered":"Docker init: The Ultimate Guide to Creating Dockerfiles"},"content":{"rendered":"<p>In this blog, you will learn to create Dockerfile using Docker built-in command <strong><code>docker init<\/code><\/strong>. We will also look at practical examples of Dockerizing applications using <strong>docker init<\/strong>.<\/p>\n<p>Are you tired of <strong>writing Dockerfiles <\/strong>manually?<\/p>\n<p>Don&#8217;t worry, Docker has created a command-line utility tool called <strong><code>docker init<\/code><\/strong> to make the Dockerfile creating process easy.<\/p>\n<p>Let&#8217;s learn all about the utility in this blog.<\/p>\n<h2 id=\"what-is-docker-init\">What is docker init?<\/h2>\n<p><a href=\"https:\/\/docs.docker.com\/reference\/cli\/docker\/init\/?ref=devopscube.com\" rel=\"noreferrer noopener\">Docker init<\/a> is a command line utility that automates the creation of a Dockerfile based on the language the application is built in.<\/p>\n<p>Docker init comes with <strong>Docker Desktop<\/strong> by default. If you have <a href=\"https:\/\/devopscube.com\/what-is-docker\/\">Docker<\/a> Desktop <strong>version 4.19.0 or later<\/strong> installed in your system you can use the <strong>docker init<\/strong> command.<\/p>\n<p><code>docker init<\/code> command analyzes your project directory and proposes suitable configurations based on detected programming languages or frameworks in your workspace.<\/p>\n<p>By running the <strong><code>docker init<\/code><\/strong> command on your project workspace, it will create the following files based on your project.<\/p>\n<ol>\n<li><strong>Dockerfile<\/strong> : To <a href=\"https:\/\/devopscube.com\/build-docker-image\/\">build the docker image.<\/a><\/li>\n<li><strong>compose.yaml:<\/strong> For multi container applications<\/li>\n<li><strong>.dockerignore<\/strong>: File exclusions to <a href=\"https:\/\/devopscube.com\/reduce-docker-image-size\/\">reduce the Docker image size<\/a>.<\/li>\n<\/ol>\n<p>Using docker init is pretty simple. Go to your project directory and run the <strong><code>docker init<\/code><\/strong> command.<\/p>\n<p>It will prompt a few questions related to your application; Once you have answered the prompts, docker init will create the files instantly.<\/p>\n<p><strong><code>docker init<\/code> uses templates<\/strong>, to create Dockerfile based on the programming language you choose.<\/p>\n<p>You can select the following options after running the <strong><code>docker init<\/code><\/strong> command<\/p>\n<ol>\n<li>GO<\/li>\n<li>Python<\/li>\n<li>Node<\/li>\n<li>Rust<\/li>\n<li>ASP.NET<\/li>\n<li>Other &#8211; Select this option if your application is not mentioned in the above options.<\/li>\n<\/ol>\n<p>Even though it creates the files following all best practices, you can further customize them based on your requirements<\/p>\n<p><strong>Note<\/strong>: If any of these files are already present in your workspace, <strong>docker init will overwrite<\/strong> the files. It will ask for confirmation before overwriting the files.<\/p>\n<blockquote><p><strong>Note<\/strong>: Dont confuse <strong>d<code>ocker init<\/code> with  <code>docker-init<\/code><\/strong>. <code>docker-init<\/code> is a process that acts as the init process (PID 1) within a Docker container.<\/p><\/blockquote>\n<h2 id=\"docker-init-workflow\">Docker Init Workflow<\/h2>\n<p>The following diagram shows the docker init workflow.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/docker-init-3-1.gif\" class=\"kg-image\" alt=\"Docker Init Workflow explained\" loading=\"lazy\" width=\"723\" height=\"956\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/docker-init-3-1.gif 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/docker-init-3-1.gif 723w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Here is how it works.<\/p>\n<ol>\n<li>Developer runs the <strong>docker init<\/strong> command inside the project directory.<\/li>\n<li><strong>docker init <\/strong>then scans your project code files and prompts you with configration questions.<\/li>\n<li>Once you have answered all the promtp docker init will create the Dockerfile, <code>compose.yaml<\/code>, and <code>.dockerignore<\/code> files in an instant.<\/li>\n<\/ol>\n<h2 id=\"how-to-use-docker-init\">How to Use Docker Init<\/h2>\n<p>In this section we will learn to use docker init using practical examples.<\/p>\n<p>We will try hands-on examples of docker init using simple Python and Go projects.<\/p>\n<p>For demonstration purposes, we are going to create a simple<strong> Hello World<\/strong> web application for each programming language and generate <code>Dockerfile<\/code> file using <strong><code>docker init<\/code><\/strong>.<\/p>\n<p>The examples used in this guide are hosted on Github.  You can clone the repository using the following command.<\/p>\n<pre><code>git clone https:\/\/github.com\/techiescamp\/docker-init<\/code><\/pre>\n<h3 id=\"generating-python-dockerfile\">Generating Python Dockerfile<\/h3>\n<p>For Python, we are going to create a Python file for the Python Flask application, create two files <strong>app.py<\/strong> and <strong>requiremts.txt,<\/strong> and copy the below content into the files<\/p>\n<pre><code>#app.py\n\n# app.py\nfrom flask import Flask\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef hello_docker():\n    return '&lt;h1&gt; hello world &lt;\/h1'\n\nif __name__ == '__main__':\n    app.run(debug=True, host='0.0.0.0')<\/code><\/pre>\n<pre><code>#requiremts.txt\n\nflask\ngunicorn<\/code><\/pre>\n<p>As you can see the <code><strong>app.py<\/strong><\/code> file has the code for the flask application and the <code>requiremts.txt<\/code> file has the dependencies needed to run the flask application.<\/p>\n<p>The dependency txt file is important because, without the dependency file, docker init will not automatically detect the language of your application.<\/p>\n<p>Of course, you can also select the languages manually.<\/p>\n<p>Once you have created both files, run the below init command in the same directory where the files are to start the process<\/p>\n<pre><code>docker init<\/code><\/pre>\n<p>Docker init will check your files and ask some questions.<\/p>\n<p>You can see it has automatically detected a Python-based application<\/p>\n<p>Press ENTER to select Python and it will ask for the<strong> Python version, listening port, and command to run the app<\/strong> with suggested default values and that is so cool.<\/p>\n<p>You can either select the default value by pressing ENTER or provide custom the values you want as shown in the following gif.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/docker-init-4-1.gif\" class=\"kg-image\" alt=\"docker init Dockerfile creation workflow.\" loading=\"lazy\" width=\"991\" height=\"667\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/docker-init-4-1.gif 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/docker-init-4-1.gif 991w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Once you have answered all questions <code>docker init<\/code> will create three files .<strong>dockerignore<\/strong>, <strong>compose.yaml<\/strong>, and <strong>Dockerfile<\/strong> as shown in the below directory structure<\/p>\n<pre><code>.\n\u251c\u2500\u2500 .dockerignore\n\u251c\u2500\u2500 Dockerfile\n\u251c\u2500\u2500 app.py\n\u251c\u2500\u2500 compose.yaml\n\u2514\u2500\u2500 requirements.txt<\/code><\/pre>\n<p>Here is an example of created <strong><code>Dockerfile<\/code><\/strong>. I have removed the generated comments for demo purposes.<\/p>\n<pre><code>ARG PYTHON_VERSION=3.11.6\nFROM python:${PYTHON_VERSION}-slim as base\n\nENV PYTHONDONTWRITEBYTECODE=1\nENV PYTHONUNBUFFERED=1\n\nWORKDIR \/app\n\nARG UID=10001\nRUN adduser \\\n    --disabled-password \\\n    --gecos \"\" \\\n    --home \"\/nonexistent\" \\\n    --shell \"\/sbin\/nologin\" \\\n    --no-create-home \\\n    --uid \"${UID}\" \\\n    appuser\n\nRUN --mount=type=cache,target=\/root\/.cache\/pip \\\n    --mount=type=bind,source=requirements.txt,target=requirements.txt \\\n    python -m pip install -r requirements.txt\n\nUSER appuser\n\nCOPY . .\n\nEXPOSE 8000\n\nCMD python3 app.py\n<\/code><\/pre>\n<p>As you can see it created a full fledged <strong><code>Dockerfile<\/code><\/strong> with the following best practices.<\/p>\n<ol>\n<li>Added a minimal base image.<\/li>\n<li>It added a<strong> non-priveleged<\/strong> user for security best practice.<\/li>\n<li>It added <strong>cache directory<\/strong> for speeding up subsequent installs by avoiding unnecessary downloads.<\/li>\n<\/ol>\n<p>Without making any changes to the generated <code>Dockerfile<\/code>, I ran the docker build command and it worked perfectly fine.<\/p>\n<pre><code>docker build -t flask-app:1.0 .<\/code><\/pre>\n<p>It built a image of <strong>size 161MB<\/strong>. Then I ran the <a href=\"https:\/\/devopscube.com\/slimtoolkit-to-shrink-docker-images\/\">SlimtoolKit<\/a> on the build image and the <a href=\"https:\/\/devopscube.com\/reduce-docker-image-size\/\">image size reduced<\/a> to 25MB.<\/p>\n<p>I verified it the image is working as expected by deploying the image and it worked perfectly fine.<\/p>\n<pre><code>docker run -d -p 8000:8000 flask-app:1.0<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-193-2.png\" class=\"kg-image\" alt=\"running application built using docker init Dockerfile\" loading=\"lazy\" width=\"505\" height=\"299\"><\/figure>\n<p>Also, if you are are Docker compose user, you can directly use the following compose command to build and run the image using the generated compose.yaml file.<\/p>\n<pre><code>docker compose up --build<\/code><\/pre>\n<p>For demonstration purposes, we haven&#8217;t made any customizations to the <code>Dockerfile<\/code>. When working on real-world projects, you will need to use approved container-based images and add other required instructions such as proxies, etc., based on your organization&#8217;s standards.<\/p>\n<h3 id=\"generating-go-dockerfile\">Generating Go Dockerfile<\/h3>\n<p>For this example, we are going to dockerize a Go web application using <code>docker init<\/code>.<\/p>\n<p>Create a file <strong><code>app.go<\/code>,<\/strong> and copy the below content into the files<\/p>\n<pre><code>package main\n\nimport (\n    \"fmt\"\n    \"net\/http\"\n)\n\nfunc helloHandler(w http.ResponseWriter, r *http.Request) {\n    fmt.Fprintf(w, \"Hello, World!\")\n}\n\nfunc main() {\n    http.HandleFunc(\"\/\", helloHandler)\n    fmt.Println(\"Server listening on port 8080\")\n    http.ListenAndServe(\":8080\", nil)\n}<\/code><\/pre>\n<p>Then run the below command in the same directory as the Go file, which will create a module file for the Go application.<\/p>\n<p>Same as the above Python example without the module file, docker init will not automatically detect the language.<\/p>\n<pre><code>go mod init app<\/code><\/pre>\n<p>This will create a <strong>go.mod<\/strong> file that has the dependencies to run the Go web application.<\/p>\n<pre><code>#app.go\n\nmodule app\n\ngo 1.22.2\n<\/code><\/pre>\n<p>Once both files have been created, run the below init command in the same directory where the files are to start the process<\/p>\n<pre><code>docker init<\/code><\/pre>\n<p>Docker init will check your files and ask some questions for conformation as given below<\/p>\n<p>You can see it has automatically detected a Go based application<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-161-3.png\" class=\"kg-image\" alt=\"docker init output\" loading=\"lazy\" width=\"930\" height=\"494\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-161-3.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-161-3.png 930w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Press ENTER to select Go and it will ask for the <strong>Go version, relative directory, listening port<\/strong> to run the app as shown below<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-162-3.png\" class=\"kg-image\" alt=\"docker init confirmation questions \" loading=\"lazy\" width=\"930\" height=\"403\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-162-3.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-162-3.png 930w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Once you have answered all confirmation questions docker init will create three files .<strong>dockerignore<\/strong>, <strong>compose.yaml<\/strong>, and <strong>Dockerfile<\/strong> as shown in the below directory structure<\/p>\n<pre><code>.\n\u251c\u2500\u2500 Dockerfile\n\u251c\u2500\u2500 app.go\n\u251c\u2500\u2500 .dockerignore\n\u251c\u2500\u2500 compose.yaml\n\u2514\u2500\u2500 go.mod<\/code><\/pre>\n<p>Your Dockerfile be created as shown below<\/p>\n<pre><code>\nARG GO_VERSION=1.22.2\nFROM golang:${GO_VERSION} AS build\nWORKDIR \/src\nRUN --mount=type=cache,target=\/go\/pkg\/mod\/ \\\n    --mount=type=bind,source=go.sum,target=go.sum \\\n    --mount=type=bind,source=go.mod,target=go.mod \\\n    go mod download -x\nRUN --mount=type=cache,target=\/go\/pkg\/mod\/ \\\n    --mount=type=bind,target=. \\\n    CGO_ENABLED=0 go build -o \/bin\/server .\nFROM alpine:latest AS final\nRUN --mount=type=cache,target=\/var\/cache\/apk \\\n    apk --update add \\\n        ca-certificates \\\n        tzdata \\\n        &amp;&amp; \\\n        update-ca-certificates\nARG UID=10001\nRUN adduser \\\n    --disabled-password \\\n    --gecos \"\" \\\n    --home \"\/nonexistent\" \\\n    --shell \"\/sbin\/nologin\" \\\n    --no-create-home \\\n    --uid \"${UID}\" \\\n    appuser\nUSER appuser\nCOPY --from=build \/bin\/server \/bin\/\nEXPOSE 8000\nENTRYPOINT [ \"\/bin\/server\" ]\n<\/code><\/pre>\n<p>You can see the Dockerfile is created with every best practice to create a Docker Image more securely.<\/p>\n<p>Also, you can compare the Go Dockerfile created by docker init is similar to the Python Dockerfile in the above example.<\/p>\n<p>Furthermore, customize the Dockerfile based on your requirements and use it to Dockerize the Go web application.<\/p>\n<h2 id=\"advantages-of-using-docker-init\">Advantages of using docker init<\/h2>\n<p>Following are the advantages for using docker init.<\/p>\n<ol>\n<li>Creates Dockerfile, compose.yaml, and .dockerignore in an instance, thus saving time taken to write these files.<\/li>\n<li>Creates <a href=\"https:\/\/devopscube.com\/lint-dockerfiles-using-hadolint\/\">Dockerfile with best practices<\/a> to make the Docker image more secure.<\/li>\n<li>Creates Dockerfile and compose.yaml with an explanation and instruction of what each line does, <strong>even a beginner could understand<\/strong> what&#8217;s on the Dockerfile.<\/li>\n<li>It will be <strong>helpful for beginners<\/strong> to create and understand Dockerfile with ease.<\/li>\n<li>Docker init creates a Dockerfile to make the Docker Image as light as possible.<\/li>\n<\/ol>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this blog, you learned about docker init, that eases dockerize process of your applications.<\/p>\n<p>Also, we have gone through examples on how to create Dockerfile, compose.yaml, and .dockerignore files based on the language of the application.<\/p>\n<p>I believe this blog gives you good information about the docker init utility and how to use it.<\/p>\n<p>Give it a try and you will love it.<\/p>\n<p>Also, how are you creating Dockerfiles in your current projects?<\/p>\n<p>Share your process in the comment section.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/create-dockerfile-using-docker-init\/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker init: The Ultimate Guide to Creating Dockerfiles \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/create-dockerfile-using-docker-init\/<\/p>\n","protected":false},"author":1,"featured_media":984,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-983","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\/983","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=983"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/983\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/984"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}