APEX Educational Institute

Docker for Beginners: Containerize Your First App (Step by Step)

Understand containers vs virtual machines, write a Dockerfile, build and run an image, map ports, use volumes and run an app with a database using Docker Compose.

Beginner | 3 min read | Updated

"It works on my machine" is one of the oldest problems in software. Docker solves it by packaging your application with everything it needs (runtime, libraries, configuration) into a container that runs the same way on a laptop, a test server or the cloud.

Image vs container

  • An image is a read-only template: your app plus its environment.
  • A container is a running instance of an image. You can run many containers from one image.

Containers vs virtual machines

ContainerVirtual machine
IncludesApp + libraries; shares the host kernelFull guest operating system
Start timeSecondsMinutes
SizeMegabytesGigabytes
IsolationProcess levelHardware level (stronger)

Install and check

Install Docker Desktop (Windows/macOS) or Docker Engine (Linux), then:

bash
docker --version
docker run hello-world

Step 1: A small app

app.py:

python
from flask import Flask
app = Flask(__name__)

@app.get("/")
def home():
    return {"status": "ok", "message": "Hello from a container"}

requirements.txt:

text
flask==3.0.3
gunicorn==23.0.0

Step 2: Write a Dockerfile

dockerfile
FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]

Copying requirements.txt before the rest of the code lets Docker cache the dependency layer. Changing your code then does not reinstall every package on each build.

Step 3: Build and run

bash
docker build -t course-api:1.0 .
docker run -d -p 8080:8000 --name course-api course-api:1.0
curl http://localhost:8080

-p 8080:8000 maps port 8080 on your machine to port 8000 inside the container.

Everyday commands

CommandPurpose
docker psRunning containers (-a for all)
docker logs -f course-apiFollow container logs
docker exec -it course-api shOpen a shell inside the container
docker stop course-apiStop it
docker rm course-apiRemove the container
docker imagesList images
docker system pruneClean unused data (careful)

Volumes: keep data after a container is removed

Containers are disposable. Anything written inside is lost when the container is removed. Use a volume for databases and uploads:

bash
docker volume create pgdata
docker run -d --name db -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16

Docker Compose: app + database together

compose.yaml:

yaml
services:
  api:
    build: .
    ports:
      - "8080:8000"
    environment:
      DATABASE_URL: postgres://postgres:secret@db:5432/postgres
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
bash
docker compose up -d --build
docker compose logs -f api
docker compose down

Services reach each other by service name: the API connects to the host db.

Best practices

  • Use small official base images (-slim or -alpine) and pin versions.
  • Add a .dockerignore file (.git, node_modules, .env) to keep images small and secret-free.
  • Never bake passwords into images; pass them as environment variables or secrets at runtime.
  • Run as a non-root user in production images.
  • One main process per container.

Interview questions

  • `CMD` vs `ENTRYPOINT`? ENTRYPOINT sets the fixed executable; CMD provides default arguments that can be overridden at docker run.
  • `COPY` vs `ADD`? Both copy files; ADD can also extract archives and fetch URLs. Prefer COPY for clarity.
  • What is a multi-stage build? Using one stage to compile or build and a smaller final stage that contains only the runtime output.

Next steps

Containerize one of your own projects, then deploy it with a CI/CD pipeline. Learn Kubernetes, Terraform and AIOps in the DevOps + AI course.

Master it hands-on

Cloud + AI

DevOps + AI (AIOps)

Linux, Git, CI/CD, Docker, Kubernetes, Terraform, cloud and AIOps.

16 weeks Beginner to Advanced
Online LiveRecorded Course