Docker in 10 Minute (Guide for Beginners)

Ruman
11 min readJan 5, 2025

--

Images, containers, and Dockerfiles: everything a beginner needs to know.

Photo by Pixabay

Content Outline

  • Introduction to Docker and Containers
  • Important Docker Terms
  • Basic Docker Commands — Running and managing Docker images and containers
  • What is a “Dockerfile” ?
  • Building and Running Custom Docker Images
  • Conclusion

Introduction to Docker and Containers

Imagine this: You’re a developer who created an app on your computer. It works perfectly! But when your teammate tries to run it, they get errors because their computer is different from yours. Frustrating, right?

This is where Docker comes in. Docker lets you package your app in a “container” — think of it like a shipping container that holds everything your app needs to run:

  • The app itself
  • All required software
  • Configuration files
  • System settings

Why is this useful?

  1. Works everywhere: Your container runs the same way on any computer
  2. No conflicts: Each container is isolated, so apps don’t interfere with each other
  3. Easy sharing: Send your container to anyone, and it’ll work instantly
  4. Resource friendly: Lighter than virtual machines

Real-world example ??? Think of a container like a food delivery box. It has:

  • The main dish (your app)
  • All needed ingredients (dependencies)
  • Cooking instructions (configuration)
  • Its own space (isolation)

Just like how that box ensures your food arrives exactly as the chef prepared it, Docker ensures your app runs exactly as you built it.

Important Docker Terms

Photo by Pixabay

Here are some key terms / components / concepts you’ll frequently come across when working with Docker:

  • Docker Image: A read-only template containing the operating system, code, and dependencies.
  • Docker Container (or simply Container): A running instance of a Docker image.
  • Image Registry: A storage and distribution system for Docker images.
  • Dockerfile: A script that defines how a Docker image is built.
  • Layer: A modification or addition to a Docker image, forming part of its structure.

Let’s look at each key terms / concepts (using simple examples):

i. Docker Image

Think of it like a recipe:

  • Contains exact instructions to create your app’s environment
  • Includes code, runtime, libraries, dependencies
  • Can’t be changed once created (read-only)
  • Examples: Ubuntu image, Node.js image, or your custom app image

ii. Docker Container

Think of it like a running restaurant:

  • It’s your image in action
  • Multiple containers can run from one image
  • Each container is isolated from others
  • Has its own resources (CPU, memory, network)

iii. Docker Registry

Think of it like an app store:

  • Where Docker images are stored and shared
  • Docker Hub is the most popular registry
  • Companies often have private registries
  • You can push/pull images from registries

iv. Dockerfile

Think of it like a set of building instructions:

  • Text file that creates Docker images
  • Lists steps to set up your environment
  • Each instruction creates a layer
  • Named exactly as ‘Dockerfile’

v. Docker Daemon

Think of it as the kitchen manager:

  • Runs in background on your computer
  • Builds and runs containers
  • Manages Docker objects
  • Handles container lifecycle

vi. Docker Client

Think of it as the waiter taking orders:

  • Command-line tool (docker)
  • Communicates with Docker daemon
  • Client sends commands to Docker daemon
  • Daemon executes and sends back results

vii. Layers

Think of them like steps in a recipe:

  • Each instruction in Dockerfile creates a layer
  • Layers are cached for faster builds
  • Shared between images to save space

✅ Remember :

These components work together like a well-oiled machine. Images are your blueprints, containers are running instances, registry stores them, Dockerfile creates them, daemon manages them, and client controls them.

Basic Docker Commands — Running and managing Docker images and containers

Photo by Lech Pierchała

Docker provides thousands, if not millions, of pre-built images (like ready-made recipes) that you can use for your specific use case. You can either use these images as they are (like following a recipe exactly) or use them as a starting point to create your own custom image (similar to tweaking a recipe to suit your taste).

For example, if you need to test your code on Ubuntu, you can simply pull a pre-built Ubuntu image and run it instead of setting up an entire virtual machine with the Ubuntu OS.

In this section, we’ll cover the following:

  • Pulling and removing Docker images
  • Running containers from docker image with different configurations
  • Managing running containers

Before proceeding, let’s ensure Docker is installed on your local machine. To verify, run the docker command in your terminal. If Docker is properly installed, you should see an output similar to this:

If you don’t see this, it means Docker isn’t installed. Follow the instructions in this guide to set it up: Docker Installation Guide.

Now that Docker is set up on your machine, let’s get started with running a pre-built Docker image and interacting with containers!!

Think of Docker like a restaurant franchise system.

Let’s understand how to run and manage Docker images:

Pulling and Managing Docker Images

Pull an image from Docker Hub :

docker pull python:3.9

Pull specific version :

docker pull python:3.9-slim

Output will look something like this:

See all the local ( including the downloaded pre-build ones) images :

docker images

Output will look something like this:

You can also removes a specific Docker image:

docker rmi python:3.9-slim

Remove all unused images (free space):

docker image prune

Running Containers from Image

To run a Docker container, use the docker run command followed by the image tag, like this: docker run image_tag/image_name.

You can also configure the container using various flags. Here are some commonly used flags you can take advantage of:

  • -it: Get an interactive terminal (when you need to type commands)
  • -d: Run in background (for services/servers)
  • -v: Share files between your computer and container
  • --name: Give container a friendly name
  • --memory: Set maximum RAM usage
  • --cpus: Limit CPU usage
  • --gpus: Enable GPU access

I will explain these flags using different commands.

Basic run command :

docker run python:3.9-slim

Run container in Interactive terminal :

docker run -it python:3.9 bash

Output will look something like this:

Run container in background (detached) :

docker run -d python:3.9

Run with name :

docker run --name my-python python:3.9

Run container with defined resource limits :

docker run -memory=512m -cpus=2 python:3.9

Run with port mapping :

docker run -p 5000:5000 python:3.9

Set environment variables when running container :

docker run -e DB_HOST=localhost python:3.9

Mount volume (share files) to container :

docker run -v /local/path:/container/path python:3.9

Allow gpu access to container :

docker run --gpus all python:3.9

Managing Running / Stopped Containers

There are various commands available to manage containers, whether they are running or stopped. Let’s go through them one by one.

See what’s running :

docker ps

Output will look something like this:

See all containers (including stopped) :

docker ps -a

Output will look something like this:

Stop a container :

docker stop container_id

Start an existing stopped container :

docker start container_id

Restarts a running or stopped container :

docker restart container_id

Remove a stopped container :

docker rm container_id

Monitor running container resource usage :

docker stats container_name_or_id

Output will look something like this:

Some Pro Tips to Keep in Mind :

  • Always name your containers with --name for easier reference
  • Use docker ps -a to find containers taking up space
  • Clean up regularly with docker system prune
  • Start with interactive mode (-it) when learning/debugging
  • Use background mode (-d) for running services

What is a “Dockerfile” ?

Photo by Antoni Shkraba

A Dockerfile is like a recipe that tells Docker how to build an image. It’s basically a text file which contains a series of instructions that define what should be included in the image and how it should behave. Each instruction in the Dockerfile creates a new layer in the resulting Docker image.

Let’s look at 👇🏻

Key Roles of a Dockerfile :

i. Base Image Specification (FROM):

  • Defines the starting point for the image, such as a specific operating system or a pre-built environment (e.g., ubuntu, node, python).
  • Example: FROM ubuntu:20.04

ii. Application Code Integration (COPY):

  • Copies your application code and files into the image.
  • Example: COPY . /app

iii. Environment Setup (RUN):

  • Allows you to install software, copy files, and configure settings required by the application.
  • Example: Installing dependencies with RUN apt-get install -y curl or RUN pip install -r requirements.txt

iv. Port Declaration (EXPOSE) :

  • Specifies the network ports that the container will listen on at runtime.
  • Example: EXPOSE 5000 declares that the container listens on port 5000.
  • Note: To make this port accessible from outside the container, you must explicitly map it when running the container using the -p flag.

v. Command Specification (CMD):

  • Defines the commands to run when the container starts, such as starting a server or an application.
  • Example: CMD ["python", "app.py"]

Example Dockerfile

A Dockerfile looks something like this :

# Use an official Python runtime as the base image
FROM python:3.9-slim

# Set environment variables
ENV APP_ENV=production
ENV APP_PORT=5000

# Set the working directory inside the container
WORKDIR /app

# Copy application code into the container
COPY . /app

# Install dependencies
RUN pip install -r requirements.txt

# Declare the port on which the app will run
EXPOSE 5000

# Define the command to run the application
CMD ["python", "app.py"]

Generally, a Dockerfile begins by specifying the base image, followed by copying the application code into the image. Next, it includes all the necessary RUN commands to be executed during the image build process, such as installing dependencies. Finally, the entry point for the Docker image is defined to specify how the container should start.

Few things in regards of Dockerfile:

  • Must be named exactly “Dockerfile”
  • Each instruction creates a layer
  • Instructions run in order, top to bottom

Now that we have a clear understanding of Dockerfile, let’s proceed to create our own custom image using it.

Building and Running Your Own Docker Image

Photo by David Kanigan

To better understand how to build custom images, we’ll create a Flask API, build an image for it, and run the Flask API inside a container.

We’ll go through it step by step.

You can find the project code here : https://github.com/rumanxyz/docker-flask-app

1. Project Structure

First, let’s set up our project:

./docker-flask-app/
├── Dockerfile
├── app.py
└── requirements.txt

2. Application Files

requirements.txt

Here, we will specify all the necessary Python packages required to run the API.

flask==2.3.3

app.py

Flask API which will be running on port 5000

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/hello', methods=['GET'])
def hello():
return jsonify({"message": "Hello from Docker!"})

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Dockerfile

# define base image
FROM python:3.10-slim

# set working directory
WORKDIR /app

# copy requirements first (for better caching)
COPY requirements.txt .

# install dependencies
RUN pip install -r requirements.txt

# copy application code
COPY . .

# expose port to acess conrainer
EXPOSE 5000

# run command
CMD ["python", "app.py"]

Now that we’ve written our application files, let’s test them locally first. When you run the Flask app, you’ll see an output similar to this:

If we open http://127.0.0.1:5000/api/hello locally, we’ll see an API response similar to this:

Now that we’ve confirmed our API is working, let’s proceed to build a Docker image for it.

3. Building the Docker Image

Let’s build the image with no cache (clean build)

docker build --no-cache -t my-flask-api:1.0 .

Please Note :

  • -t tags your image (name:version)
  • . means use current directory
  • Always version your images (1.0, 1.1, etc.)

On running the build command you’ll see something like this:

Now, Let’s check the docker images and see if image was build or not. We can do this by running docker images . And here you can see my-flask-api image with version 1.0 created recently.

Now, let’s check the Docker images to see if the image was built successfully. We can do this by running docker images. You should see the my-flask-api image with version 1.0, created recently.

4. Running Your Container

Run container with environment variables and custom name

# Run with environment variables
docker run -d -p 5000:5000 \
--name my-api-test \
-e FLASK_ENV=development \
my-flask-api:1.0

Here “my-flask-api:1.0” is the docker image which we created.

If we run docker ps , then you’ll see the container running.

Now let’s go and test the API.

5. Testing Your API

We can test this with the curl command :

curl http://localhost:5000/api/hello

The output I received after running this is:

We successfully created a Flask app, dockerized it using a Dockerfile, ran the container with the image, and finally tested the API.

But some common issues you may see and [possible] solution :

Port already in use:

  • Stop other containers using port 5000
  • Or use different port: -p 5001:5000

Container exits immediately:

  • Check logs: docker logs my-api
  • Make sure CMD is correct
  • Try running in interactive mode

Can’t access API:

  • Verify container is running
  • Check port mapping
  • Ensure host=’0.0.0.0' in Flask app

Conclusion

Docker has become an important tool in modern software development, simplifying how we build, ship, and run applications. Through this article, we’ve covered the fundamentals — from understanding containers and images to running pre-built images and creating your own custom containers. By mastering basic Docker commands and understanding Dockerfile syntax, you’re now equipped to containerize your applications.

Remember that Docker’s real power lies in its consistency and portability —

“it works on my machine” becomes “it works everywhere.”

As you continue your Docker journey, explore Docker Compose for managing multiple containers, dive into container networking, and learn about container orchestration with tools like Kubernetes. The official Docker documentation (docs.docker.com) is an excellent resource for deeper exploration of these topics.

If you enjoyed this article, your applause would be greatly appreciated!

--

--

Ruman
Ruman

Written by Ruman

Senior ML Engineer | Sharing what I know, work on, learn and come across :)

Responses (1)