Your First Dockerfile
5 instructions, build your own image and run it
What is a Dockerfile?
So far you have been using images that other people built — nginx, hello-world, Ubuntu. But what if you want to package your own application? That is what a Dockerfile is for.
The file is always named exactly Dockerfile (capital D, no extension).
The 5 Instructions You Need to Know
Dockerfiles have many instructions. You only need five to start:
| Instruction | What it does |
|---|---|
FROM | Start from a base image (every Dockerfile must have this) |
WORKDIR | Set the working directory inside the container |
COPY | Copy a file from your machine into the image |
RUN | Run a shell command during the build (install something, compile, etc.) |
CMD | The command to run when the container starts |
Write Your First Dockerfile
Let us build a simple Java application. Create a folder called my-app and inside it create two files.
File 1: Hello.java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello from inside Docker!");
}
}
File 2: Dockerfile
FROM openjdk:21-slim
WORKDIR /app
COPY Hello.java .
RUN javac Hello.java
CMD ["java", "Hello"]
That is 5 lines. Let us read each one:
| Line | What it does |
|---|---|
FROM openjdk:21-slim | Start from an official Java 21 image (slim = smaller size) |
WORKDIR /app | All following commands happen inside the /app folder |
COPY Hello.java . | Copy Hello.java from your machine into /app inside the image |
RUN javac Hello.java | Compile the Java file during build time |
CMD ["java", "Hello"] | When the container starts, run the Java program |
Build the Image
Open your terminal, navigate into the my-app folder, and run:
docker build -t my-hello-app .
Breaking that command down:
| Part | Meaning |
|---|---|
docker build | Build a new image |
-t my-hello-app | Tag (name) the image as “my-hello-app” |
. | Look for the Dockerfile in the current directory |
Docker will print each step as it runs:
[1/4] FROM openjdk:21-slim
[2/4] WORKDIR /app
[3/4] COPY Hello.java .
[4/4] RUN javac Hello.java
Successfully built 7c3a9f1b2d8e
Successfully tagged my-hello-app:latest
Run Your Image
Now run it just like any other image:
docker run my-hello-app
Output:
Hello from inside Docker!
Verify your image is listed:
docker images
REPOSITORY TAG IMAGE ID SIZE
my-hello-app latest 7c3a9f1b2d8e 432MB
RUN vs CMD — What is the Difference?
This confuses everyone at first:
| Instruction | When it runs | Use it for |
|---|---|---|
RUN | During docker build | Installing software, compiling code, setting up the image |
CMD | When you do docker run | Starting your application |
A Dockerfile can have many RUN instructions but should have only one CMD.
What You Built
- A
Dockerfilewith 5 instructions: FROM, WORKDIR, COPY, RUN, CMD - A custom image using
docker build -t my-hello-app . - A running container from your own image using
docker run my-hello-app
Next: put this to work for QA — run Chrome, Selenium, and your test suite entirely inside Docker without installing anything on Jenkins.