cd ..
DOCKER

Dockerfile in Practice: From Your First Image to `docker build`

Dockerfile in practice: from your first image to docker build

Until now, all containers in this series were created from ready-made Docker Hub images — ubuntu, nginx. It’s time to learn how to build your own image, using a Dockerfile.

What is a Dockerfile

A Dockerfile is a text file where we put instructions for Docker to build a container image. By convention, instructions are always written in uppercase (FROM, RUN, CMD…).

How instructions become layers

Each Dockerfile instruction generates a new layer added to the previous ones. Think of it this way:

Base image (ex: ubuntu)          → read-only layer
RUN apt-get install nginx        → read-only layer
COPY config-nginx                → read-only layer
────────────────────────────────
Running container                → read-write layer (on top of everything)

The layers generated during the build (from FROM, RUN, COPY…) are read-only and stored inside the image — they are shared among all containers created from it. Only when a container is created does Docker add a writeable (RW) layer on top, exclusive to that container: that’s where files created or modified during execution end up, as we saw with echo in part 2 of this series.

Writing your first Dockerfile

FROM ubuntu:18.04
RUN apt-get update && apt-get install nginx -y
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Building the image

docker image build -t meu-nginx:1.0 .

The -t gives the image a name and tag (my-nginx:1.0); the . at the end indicates that the Dockerfile and build context are in the current directory.

And to run a container from it:

docker container run -d --name meu-nginx -p 8080:80 meu-nginx:1.0

A detail that prevents giant images

If each RUN generates a permanent layer, package cache installed in one RUN will continue to occupy space in the image even if you delete it in a subsequent RUN — the previous layer, with the cache still inside, remains there. That’s why it’s common to chain installation and cleanup in the same RUN:

RUN apt-get update && apt-get install nginx -y && rm -rf /var/lib/apt/lists/*

Summarizing the command: “delete everything inside the folder where apt stores the package list” — after installing what was needed, this cache is no longer useful inside the final image.

Conclusion

With FROM, RUN, EXPOSE, and CMD, it’s already possible to package a simple application. But the Dockerfile has many more instructions — ENTRYPOINT, ENV, COPY, VOLUME, USER, and others — which we will explore in the next part of the series.

References

What did you think?