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:

InstructionWhat it does
FROMStart from a base image (every Dockerfile must have this)
WORKDIRSet the working directory inside the container
COPYCopy a file from your machine into the image
RUNRun a shell command during the build (install something, compile, etc.)
CMDThe 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:

LineWhat it does
FROM openjdk:21-slimStart from an official Java 21 image (slim = smaller size)
WORKDIR /appAll following commands happen inside the /app folder
COPY Hello.java .Copy Hello.java from your machine into /app inside the image
RUN javac Hello.javaCompile 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:

PartMeaning
docker buildBuild a new image
-t my-hello-appTag (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:

InstructionWhen it runsUse it for
RUNDuring docker buildInstalling software, compiling code, setting up the image
CMDWhen you do docker runStarting your application

A Dockerfile can have many RUN instructions but should have only one CMD.

What You Built

  • A Dockerfile with 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.