47.13 docker init: generate a Dockerfile, Compose file and .dockerignore
Chala mitrano! Writing a Dockerfile for a new project takes a lot of time at first. The 'docker init' command looks at your project and creates a Dockerfile, compose.yaml and .dockerignore. Today we run it on Node, Python and Go projects and understand the files it makes.
चला मित्रांनो! नवीन project साठी Dockerfile लिहायला सुरुवातीला खूप वेळ जातो. 'docker init' हा command project बघून Dockerfile, compose.yaml आणि .dockerignore तयार करतो. आज Node, Python आणि Go project वर तो चालवून तयार files समजून घेऊ.
चलो दोस्तों! नए project के लिए Dockerfile लिखने में शुरू में बहुत समय लगता है. 'docker init' command project देखकर Dockerfile, compose.yaml और .dockerignore बना देता है. आज Node, Python और Go project पर चलाकर बनी files समझेंगे.
1. Start from a blank page
A fresher at Meesho is told to containerize a small Node API by evening. She opens an empty Dockerfile and does not know where to begin: which base image, which user, which port, what to ignore.
docker init is a helper command that asks a few questions about your project and then writes good starting files for you. It does not build or run anything. It only writes files that you can read and change.
It comes with Docker Desktop and with recent Docker Engine installs that include the init plugin. We will check that first.
2. Before you start
Step 1: Check that docker init is available
Why: If the plugin is missing, the command simply fails, and learners think Docker is broken.
What: docker init is a CLI plugin. A plugin is an extra command that sits in a plugins folder.
Example 1: Check the version
Type this:
docker init --version
You will see:
Version: v1.4.0
Git commit: 6d1d8b4
What it means: The plugin is installed. Your version number may differ.
Example 2: When it is missing
Type this:
docker init
You will see:
docker: 'init' is not a docker command.
See 'docker --help'
What it means: Install Docker Desktop, or update Docker Engine from the official repo as in lesson 47.5.
Example 3: See the help
Type this:
docker init --help
You will see:
Usage: docker init [OPTIONS]
Creates Docker-related starter files for your project
What it means: Short help. The real work is in the questions it asks.
Step 2: Know the languages it supports
Why: You should know what it can detect before you trust it.
What: docker init has templates for Go, Python, Node, Rust, ASP.NET Core, PHP with Apache, Java, and an Other option for a generic file.
Example 4: Run it in an empty folder
Type this:
mkdir empty && cd empty
docker init
You will see:
? What application platform does your project use?
Go
Python
Node
Rust
ASP.NET Core
PHP with Apache
Java
> Other
What it means: In an empty folder it cannot detect anything, so it asks you.
Example 5: Let it detect
Type this:
cd ../shop-api && ls
docker init
You will see:
package.json server.js
? What application platform does your project use? Node (detected)
What it means: It saw package.json and guessed Node.
Example 6: Leave without writing
Type this:
(press Ctrl+C at any question)
You will see:
^C
(no files written)
What it means: Nothing is written until you answer every question.
3. A Node API
Step 3: Answer the questions
Why: A Paytm team wants every service to start the same way.
What: docker init asks for the version, the package manager, the start command and the port. Each answer goes into the files.
Example 7: Make a tiny app
Type this:
mkdir shop-api && cd shop-api
npm init -y > /dev/null
npm install express@4 > /dev/null
printf 'const e=require("express")();\ne.get("/",(q,r)=>r.send("Paytm shop API"));\ne.listen(3000);\n' > server.js
ls
You will see:
node_modules package-lock.json package.json server.js
What it means: A real project with a lock file.
Example 8: Run docker init
Type this:
docker init
You will see:
? What application platform does your project use? Node
? What version of Node do you want to use? 20
? Which package manager do you want to use? npm
? What command do you want to use to start the app? node server.js
? What port does your server listen on? 3000
CREATED: .dockerignore
CREATED: Dockerfile
CREATED: compose.yaml
CREATED: README.Docker.md
What it means: Four files are created.
Example 9: See the files
Type this:
ls -a
You will see:
.. .dockerignore Dockerfile README.Docker.md compose.yaml node_modules package-lock.json package.json server.js
What it means: README.Docker.md has short notes on how to build and deploy.
Step 4: Read the generated Dockerfile
Why: Never run a file you have not read.
What: The generated Dockerfile uses a small base image, installs only production packages, and runs as a normal user, not root.
Example 10: Look at the important lines
Type this:
grep -E '^(FROM|ENV|RUN|USER|COPY|EXPOSE|CMD)' Dockerfile
You will see:
FROM node:20-alpine
ENV NODE_ENV production
RUN --mount=type=bind,source=package.json,target=package.json \
USER node
COPY . .
EXPOSE 3000
CMD node server.js
What it means: alpine keeps it small. USER node means it does not run as root. EXPOSE notes the port.
Example 11: The cache mount line
Type this:
grep -A3 'RUN --mount' Dockerfile
You will see:
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
What it means: A cache mount keeps the npm download cache between builds, so the second build is faster.
Example 12: Comments explain each part
Type this:
grep -c '^#' Dockerfile
You will see:
22
What it means: Many comment lines. Read them; they teach good habits.
Step 5: Read .dockerignore and compose.yaml
Why: A big build context makes builds slow and can leak files into the image.
What: .dockerignore lists files Docker must not send to the build. compose.yaml describes how to run the app.
Example 13: The ignore list
Type this:
grep -v '^#' .dockerignore | grep -v '^$' | head -6
You will see:
**/.git
**/.env
**/node_modules
**/Dockerfile*
**/compose*
README.md
What it means: node_modules and .env stay out. Your local secrets never enter the image.
Example 14: The compose file
Type this:
grep -v '^ *#' compose.yaml | grep -v '^$'
You will see:
services:
server:
build:
context: .
environment:
NODE_ENV: production
ports:
- 3000:3000
What it means: One service named server, built from this folder, on port 3000.
Example 15: Commented database example
Type this:
grep -c 'db:' compose.yaml
You will see:
2
What it means: A Postgres example is included as comments. Remove the # marks when you need it.
Step 6: Build and run with Compose
Why: Now we check that the files actually work.
What: docker compose up --build builds the image and starts the service.
Example 16: Start it
Type this:
docker compose up --build -d
You will see:
[+] Building 14.2s (12/12) FINISHED
[+] Running 2/2
✔ Network shop-api_default Created
✔ Container shop-api-server-1 Started
What it means: Built and running in the background.
Example 17: Test it
Type this:
curl -s localhost:3000
You will see:
Paytm shop API
What it means: The API answers from the container.
Example 18: Check the user and size
Type this:
docker compose exec server whoami
docker images shop-api-server --format '{{.Size}}'
You will see:
node
141MB
What it means: It runs as node, not root, and the image is small.
4. Python and Go
Step 7: A Python Flask app
Why: Data teams at Swiggy write small Python APIs every week.
What: For Python, docker init asks for the version, the port and the start command, and uses requirements.txt.
Example 19: Make the app
Type this:
mkdir menu && cd menu
printf 'flask==3.0.3\ngunicorn==22.0.0\n' > requirements.txt
printf 'from flask import Flask\napp=Flask(__name__)\n@app.get("/")\ndef h(): return "Swiggy menu"\n' > app.py
You will see:
(no output)
What it means: Two files: dependencies and code.
Example 20: Run docker init
Type this:
docker init
You will see:
? What application platform does your project use? Python
? What version of Python do you want to use? 3.12
? What port do you want your app to listen on? 8000
? What is the command you use to run your app? gunicorn 'app:app' --bind=0.0.0.0:8000
CREATED: Dockerfile ...
What it means: gunicorn is a production web server for Python.
Example 21: Build and test
Type this:
docker compose up --build -d
curl -s localhost:8000
You will see:
Swiggy menu
What it means: Same flow, different language.
Step 8: A Go service
Why: Go services at companies like Zerodha are known for tiny images.
What: For Go, docker init writes a multi-stage Dockerfile: one stage compiles, a second small stage only runs the program.
Example 22: Make the app
Type this:
mkdir quote && cd quote
go mod init quote
printf 'package main\nimport ("fmt";"net/http")\nfunc main(){http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request){fmt.Fprint(w,"Zerodha quote")});http.ListenAndServe(":8080",nil)}\n' > main.go
You will see:
go: creating new go.mod: module quote
What it means: A one-file web server.
Example 23: See the two stages
Type this:
docker init # answer Go, 1.23, ., 8080
grep -E '^FROM' Dockerfile
You will see:
FROM --platform=$BUILDPLATFORM golang:1.23 AS build
FROM alpine:latest AS final
What it means: Stage one has the Go compiler; stage two does not.
Example 24: Compare sizes
Type this:
docker compose up --build -d
docker images quote-server --format '{{.Size}}'
curl -s localhost:8080
You will see:
19.8MB
Zerodha quote
What it means: Under 20 MB, because the compiler is not in the final image.
5. Make it yours
Step 9: When files already exist
Why: Running docker init in a project that already has a Dockerfile could overwrite your work.
What: docker init warns you and asks before it overwrites anything.
Example 25: Run it again
Type this:
docker init
You will see:
WARNING: The following Docker files already exist in this directory:
- Dockerfile
- compose.yaml
? Do you want to overwrite them? No
What it means: Answer No to keep your files.
Example 26: Back up first
Type this:
cp Dockerfile Dockerfile.mine
docker init # answer Yes to overwrite
diff Dockerfile.mine Dockerfile | head -3
You will see:
5c5
< FROM node:18
> FROM node:20-alpine
What it means: Now you can compare and keep the best parts.
Example 27: Keep files in Git
Type this:
git add Dockerfile compose.yaml .dockerignore
git commit -m 'Add Docker files'
You will see:
[main 3e4f5a6] Add Docker files
3 files changed, 98 insertions(+)
What it means: Commit them so the whole team uses the same files.
Step 10: Edit the generated files
Why: Generated files are a start, not the final answer.
What: Common changes: pin the base image version, add a health check, and add a database service.
Example 28: Pin the base image
Type this:
sed -i 's/FROM alpine:latest AS final/FROM alpine:3.20 AS final/' Dockerfile
grep 'AS final' Dockerfile
You will see:
FROM alpine:3.20 AS final
What it means: latest can change any day. A fixed tag keeps builds repeatable.
Example 29: Add a health check
Type this:
printf 'HEALTHCHECK --interval=30s CMD wget -qO- localhost:8080 || exit 1\n' >> Dockerfile
docker compose up --build -d
sleep 35; docker ps --format '{{.Names}} {{.Status}}'
You will see:
quote-server-1 Up 40 seconds (healthy)
What it means: Docker now checks the app every 30 seconds.
Example 30: Enable the database block
Type this:
grep -n '# *db:' compose.yaml
You will see:
22:# db:
What it means: Remove the # marks from that block to add Postgres, then add a password through a secret file, never in the file itself.
Step 11: Clean up
Why: Three practice apps are running now.
What: docker compose down stops and removes the containers and network of one project.
Example 31: Stop each project
Type this:
cd ~/shop-api && docker compose down
You will see:
[+] Running 2/2
✔ Container shop-api-server-1 Removed
✔ Network shop-api_default Removed
What it means: Run it in each project folder.
Example 32: Remove images too
Type this:
docker compose down --rmi local
You will see:
✔ Image quote-server Removed
What it means: --rmi local removes images that Compose built.
Example 33: Check
Type this:
docker ps --format '{{.Names}}'
You will see:
(no output)
What it means: Nothing is left running.
Ravindra Bagale's Tip
Files made by docker init are a starting point. Pin the base image version, add a health check, and never write passwords in compose.yaml.
docker init ने बनवलेल्या files फक्त सुरुवात आहेत. Base image चा version pin करा, health check जोडा, आणि passwords कधीही compose.yaml मध्ये लिहू नका.
docker init से बनी files सिर्फ़ शुरुआत हैं. Base image का version pin कीजिए, health check जोड़िए, और passwords कभी compose.yaml में मत लिखिए.
Check yourself
Q1. Does docker init build or run anything?
No. It only writes starter files.
Q2. Which four files does it create?
Dockerfile, compose.yaml, .dockerignore and README.Docker.md.
Q3. Why does the generated Dockerfile use USER?
So the app does not run as root.
Q4. Why is the Go image so small?
It uses two stages; the final stage has no compiler.
Q5. What happens if a Dockerfile already exists?
docker init warns you and asks before overwriting.
Friends, docker init makes the start easy, but reading and understanding the files is our job. Try it on Node, Python and Go. Did you understand? Let us try it once more. If not, look at Picture 1 again.
मित्रांनो, docker init मुळे सुरुवात सोपी होते, पण files वाचून समजून घेणं आपली जबाबदारी आहे. Node, Python, Go तिन्हीवर try करा. समजलं का? चला, पुन्हा एकदा करून पाहू. नसेल तर Picture 1 परत बघा.
दोस्तों, docker init से शुरुआत आसान होती है, पर files पढ़कर समझना हमारी ज़िम्मेदारी है. Node, Python, Go तीनों पर try कीजिए. समझ आया? चलिए, एक बार फिर करके देखते हैं। नहीं तो Picture 1 फिर देखिए.
Lab: try at home
- Check
docker init --versionon your machine. - Create the Node API and run docker init, then read every comment in the Dockerfile.
- Do the same for the Python and Go apps and compare image sizes.
- Pin the base image and add a HEALTHCHECK, then see the (healthy) status.
- Run docker init again and answer No to keep your files.
Recap
- docker init writes Dockerfile, compose.yaml, .dockerignore and README.Docker.md.
- It detects Node, Python, Go and more.
- Generated files use small images and a non-root user.
- Always read, pin versions and add health checks.
- Commit the files so the team shares them.
Revision card
Interview card