What a Docker image is and why you build one

A Docker image is a blueprint for a container — a frozen snapshot of an application, its code, its dependencies, and the operating system layer it needs to run. When you start a container, Docker reads that image and spins up a working copy. Building your own image means you can package something specific: your application with exactly the right version of Python, the exact libraries it needs, and your configuration baked in.

You build an image when you want to run the same application the same way on your laptop, on a colleague's machine, or on a server in production. Instead of saying "install Node 18, then npm install, then set this environment variable", you hand someone an image. They run it, and it works.

The most common way to build an image is with a Dockerfile — a text file that lists the steps Docker should follow. You write the steps, Docker executes them in order, and saves the result as an image you can reuse, share, or upload to a registry.

Key Takeaways

  • A Dockerfile is a plain text file containing step-by-step instructions; each instruction creates a layer that Docker stacks to form the final image.
  • The docker build command reads your Dockerfile, executes each instruction, and saves the result as an image with a name and tag you choose.
  • You must have Docker installed and running on your machine, and your Dockerfile must be in the same directory where you run the build command.
  • After building, you can run containers from that image, push it to a registry like Docker Hub, or share it with others as a file.

Install Docker and verify it works

Before you build an image, Docker itself must be installed and running. Go to docker.com/products/docker-desktop and download Docker Desktop for your operating system — Windows, Mac, or Linux. Run the installer and follow the prompts. On Windows and Mac, Docker Desktop is a graphical application you launch; on Linux, you install the Docker Engine package for your distribution.

After installation, open a terminal or command prompt and type this command:

docker --version

If you see a version number like "Docker version 24.0.0", Docker is installed. If you see "command not found" or "is not recognized", Docker is not in your system path — restart your computer and try again. On Mac and Windows, also make sure Docker Desktop is actually running; look for the Docker icon in your menu bar or system tray.

Create a Dockerfile in your project directory

A Dockerfile is a text file with no file extension. Create it in the root directory of your project — the folder that holds your application code. You can create it with any text editor: Notepad, VS Code, Sublime, whatever you use for code.

Name the file exactly Dockerfile (capital D, no extension). Docker looks for this name by default when you run the build command.

Here is a simple example for a Python application:

FROM python:3.11-slim WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD ["python", "app.py"]

Each line is an instruction. FROM says which base image to start with — in this case, Python 3.11 in a minimal Linux container. WORKDIR sets the working directory inside the container to /app. COPY copies your files from your machine into the container. RUN executes a command during the build — here, installing Python packages. CMD specifies what command runs when the container starts.

For a Node.js application, you would use FROM node:18-alpine instead, and adjust the RUN and CMD lines to match Node commands. The structure stays the same.

Understand the most common Dockerfile instructions

FROM is always first. It names the base image you are building on top of. You can find base images on Docker Hub — search for "python", "node", "ubuntu", or whatever you need. The format is FROM imagename:tag. The tag is usually a version number; python:3.11-slim means Python 3.11 in a stripped-down Linux image, while python:3.11 means the full version with more tools included.

WORKDIR sets the directory where commands run inside the container. If you do not set it, commands run in the root directory, which is messy. Set it once near the top, usually to something like /app or /home/appuser.

COPY takes files from your machine and puts them in the container. COPY . . means "copy everything in the current directory to the working directory in the container". You can also copy specific files: COPY requirements.txt . copies only that file.

RUN executes a command during the build process. Use it to install packages, compile code, or set up configuration. Each RUN instruction creates a new layer, so combining multiple commands with && keeps the image smaller: RUN apt-get update && apt-get install -y curl.

CMD specifies the default command when the container starts. Write it as a list: CMD ["python", "app.py"] or CMD ["node", "server.js"]. Only one CMD per Dockerfile; if you write two, the second one wins.

ENV sets environment variables inside the container. ENV DATABASE_URL=postgres://localhost makes that variable available to your application. EXPOSE documents which port your application listens on — EXPOSE 8000 — but does not actually open it; you do that when you run the container.

Build the image with the docker build command

Open a terminal, navigate to the directory containing your Dockerfile, and run:

docker build -t myapp:1.0 .

Break this down: docker build is the command. -t myapp:1.0 sets the name and tag — myapp is the image name, 1.0 is the version tag. The . at the end means "use the Dockerfile in the current directory". You must be in the same folder as your Dockerfile for this to work.

Docker will print output as it runs each instruction. You will see lines like "Step 1/5 : FROM python:3.11-slim" and "Step 2/5 : WORKDIR /app". If something fails, Docker stops and shows you the error. Common mistakes: forgetting to include a requirements.txt file when your Dockerfile tries to copy it, or using a base image that does not exist.

When the build finishes successfully, you will see "Successfully tagged myapp:1.0". The image is now saved on your machine and ready to use.

Run a container from your image to test it

After building, test the image by running a container from it:

docker run myapp:1.0

Docker starts a container using your image and runs the CMD instruction you specified in the Dockerfile. If your application prints output, you will see it in the terminal. If it listens on a port — say, port 8000 — you need to map that port to your machine:

docker run -p 8000:8000 myapp:1.0

The -p 8000:8000 flag means "forward port 8000 on my machine to port 8000 in the container". Now you can visit localhost:8000 in your browser and reach the application inside the container.

If the container exits immediately or shows an error, check your Dockerfile. Common issues: the CMD command does not exist in the image, or the application crashes because a required file or environment variable is missing. Review the Dockerfile, fix the problem, rebuild with docker build, and try again.

Share your image or save it for later

Once your image works, you can share it. The easiest way is to push it to Docker Hub, a free registry where Docker images live. Create a free account at hub.docker.com, then log in from your terminal:

docker login

Docker will ask for your username and password. After you log in, tag your image with your Docker Hub username:

docker tag myapp:1.0 yourusername/myapp:1.0

Then push it:

docker push yourusername/myapp:1.0

Now anyone can pull and run your image with docker run yourusername/myapp:1.0. If you do not want to use Docker Hub, you can save the image as a file and share it directly. Run:

docker save myapp:1.0 > myapp.tar

This creates a file called myapp.tar. Someone else can load it with docker load < myapp.tar and then run it. This method works for private images or when you do not have internet access.

Frequently Asked Questions

What is the difference between a Docker image and a container?

An image is the blueprint — a static file that sits on your disk. A container is a running instance of that image, like the difference between a recipe and a meal. You build an image once and run many containers from it.

Do I have to use a Dockerfile, or are there other ways to build an image?

Dockerfile is the standard and recommended way. You can also commit a running container to an image with docker commit, but this is rarely done in practice because it is hard to reproduce and does not document what is inside.

Why does my build fail with "file not found"?

The most common reason is that your Dockerfile tries to copy a file that does not exist in your project directory. Check that the file name matches exactly — Linux is case-sensitive. Also verify you are running docker build from the correct directory.

Can I build an image without Docker Desktop?

Yes, if you install Docker Engine directly on Linux. Docker Desktop is a wrapper that includes a Linux virtual machine on Windows and Mac, but on Linux you can install the engine alone and use the same commands.

How do I update an image after I have already built it?

Edit your Dockerfile, then run docker build again with the same image name and a new tag — for example, docker build -t myapp:2.0 .. Docker caches layers, so if you only changed a few lines, the rebuild is fast.