A Dockerfile is a set of instructions for packaging an application. Docker executes those instructions to build an image; containers then run from that image. Putting installation steps in a Dockerfile makes them repeatable across a laptop, a datacenter, and the cloud. section 3.2 section 1.1.1
For a small application, start with these instructions:
- FROM chooses a starting image containing what the application needs to run. ENV sets environment variables, and WORKDIR sets the working directory in the image. section 3.2
- COPY places local files in the image. CMD specifies the command to run when a container starts. section 3.2
- Run `docker image build -t web-ping:v2 .` from the application directory to build and tag an image. section 3.5
Listing 3.1 The web-ping Dockerfile
FROM diamol/node:2e ENV TARGET="blog.sixeyed.com" ENV METHOD="HEAD" ENV INTERVAL="3000" WORKDIR /web-ping COPY app.js . CMD ["node", "/web-ping/app.js"]
The web-ping Dockerfile puts those instructions together: it starts from a Node.js image, copies the application file, and starts it with Node.js. section 3.2
Instruction order affects rebuild time. Docker can reuse an unchanged instruction's cached image layer when its inputs match. Once an instruction breaks the cache, later instructions run again. Put steps that rarely change first and frequently changed application files near the end. For a Java build, copying `pom.xml` and fetching Maven dependencies before copying the rest of the source avoids repeating that expensive fetch when dependencies are unchanged. section 3.5 section 4.2
Use a multi-stage Dockerfile when packaging needs build tools that the running application does not. Each FROM starts a stage; RUN executes a command during the build; and `COPY --from` transfers an artifact from an earlier stage. Only the final stage becomes the output image. A Java build can compile a JAR with Maven, then copy it into an image with a Java runtime. A Go build can copy its binary into a minimal image, leaving the Go toolchain behind. section 4.1 section 4.2 section 4.4
Listing 4.2 Dockerfile for building a Java app with Maven
FROM diamol/maven:2e AS builder WORKDIR /usr/src/iotd COPY pom.xml . RUN mvn -B dependency:go-offline COPY . . RUN mvn package # app FROM diamol/openjdk:2e WORKDIR /app COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar . EXPOSE 80 ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
This Java Dockerfile shows a builder stage that fetches dependencies and packages source code, followed by a runtime stage that copies in the JAR. section 4.2
The same workflow can package Windows applications, but the base image and installation commands must suit Windows. For example, a Windows Dockerfile can install an MSI without a GUI and copy the installed output into a later stage. If an image must target multiple platforms, check both its base image and any OS commands in RUN instructions for portability. section 13.2 section 12.6
Practice: make a build leaner
Build an existing Go application's image, then revise its Dockerfile so the final image is smaller and changing only its HTML does not compile the Go program again. Compare image sizes and rebuild behavior to check both improvements. section 4.6

















