# How I write a Dockerfile without copying random examples

A beginner-friendly guide to Dockerfile basics, base images, copy steps, dependencies, commands, ports, and using a Dockerfile Builder.

- Date: 2026-09-27
- URL: https://ilham.dev/posts/how-to-write-a-dockerfile-without-copying-random-examples/
- Markdown: https://ilham.dev/posts/how-to-write-a-dockerfile-without-copying-random-examples/index.md
- Tags: docker, dockerfile, devops, tools
- Reading time: 2 min


A Dockerfile is a recipe for building an image. The clearer the recipe, the easier the container is to rebuild and debug.

The [Dockerfile Builder](/tools/dockerfile-builder/) tool gives me a safe place to test the idea before I put it into a script, server, or production workflow.

## The simple mental model

A Dockerfile is a recipe for building an image. The clearer the recipe, the easier the container is to rebuild and debug.

I try to reduce the tool to one question: what input do I have, what output do I expect, and what would make the result unsafe or misleading?

## Step 1: Choose a base image that matches the runtime

Choose a base image that matches the runtime.

Start with a small example first. A small example is easier to inspect than a real production-sized case.

## Step 2: Set a working directory

Set a working directory.

## Step 3: Copy dependency files first when possible

Copy dependency files first when possible.

## Step 4: Install dependencies

Install dependencies.

## Step 5: Copy the application code

Copy the application code.

## Step 6: Expose the port only as documentation

Expose the port only as documentation.

## Step 7: Set the command the container should run

Set the command the container should run.

## My checklist

Before I trust the result, I check:

- Choose a base image that matches the runtime.
- Set a working directory.
- Copy dependency files first when possible.
- Install dependencies.
- Copy the application code.
- Expose the port only as documentation.
- Set the command the container should run.

The tool saves time, but the important part is still understanding the input and reviewing the output before using it somewhere important.
