๐Ÿณ

Docker Hello World

๐Ÿง‘โ€๐ŸŽ“ Apprenticeโฑ๏ธ 45 minutes

๐Ÿ“‹ Suggested prerequisites

  • โ€ขBasic terminal
  • โ€ข4GB RAM minimum

What you'll build

You'll install Docker and create your first container: a Node.js app packaged to work identically on any computer. You'll learn to run Ubuntu containers, databases like PostgreSQL, and use volumes to avoid losing data. When you're done, you'll have a Dockerized app with its Dockerfile, docker-compose.yml, and the ability to spin up services with one command. It's the foundation for working in teams where "it works on my machine" will no longer be a problem.


Step 1: Install Docker

SystemInstallation
macOSDocker Desktop
WindowsDocker Desktop
Linux`curl -fsSL https://get.docker.com

Verify:

docker --version
docker run hello-world

โš ๏ธ Windows: You need WSL2 enabled. Docker Desktop guides you through installation.


Step 2: Your first container

# Download and run Ubuntu in seconds
docker run -it ubuntu bash

# Now you're INSIDE the container
cat /etc/os-release   # You'll see "Ubuntu"
apt update            # Works like real Linux
exit                  # Exit the container

What happened? Docker downloaded an Ubuntu image (~30MB, not 4GB) and ran it isolated from your system.


Step 3: Run useful services

Docker shines when you need databases or services without permanent installation:

# PostgreSQL ready in 10 seconds
docker run -d --name my-postgres \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  postgres:16-alpine

# Redis for caching
docker run -d --name my-redis -p 6379:6379 redis:alpine

# Adminer (web interface for databases)
docker run -d --name adminer -p 8080:8080 adminer

Open http://localhost:8080 to see Adminer running.

โš ๏ธ PROBLEM: If you run docker rm my-postgres, you lose ALL the data. Keep reading to fix this.


Step 4: Volumes (Persistent Data)

The most common beginner mistake: They create a database, save data, remove the container... and lose everything.

Why does this happen?

WITHOUT VOLUME:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      Container          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚    Database     โ”‚    โ”‚  โ† Data lives INSIDE
โ”‚  โ”‚   (your data)   โ”‚    โ”‚     the container
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ†“
   docker rm postgres
        โ†“
   ๐Ÿ’€ DATA LOST

WITH VOLUME:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      Container          โ”‚      โ”‚     Volume      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚ โ”€โ”€โ”€โ”€ โ”‚  (your disk)    โ”‚
โ”‚  โ”‚    Database     โ”‚โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”‚   your data     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ†“
        โ†“                         Data is stored
   docker rm postgres             OUTSIDE container
        โ†“                                โ†“
   Container removed              โœ… DATA SAFE

Create PostgreSQL with persistent volume

# Create a named volume
docker volume create postgres_data

# Run PostgreSQL using that volume
docker run -d --name my-postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_USER=dev \
  -e POSTGRES_DB=myapp \
  -p 5432:5432 \
  -v postgres_data:/var/lib/postgresql/data \
  postgres:16-alpine

The magic is in -v postgres_data:/var/lib/postgresql/data:

  • postgres_data = volume name on your machine
  • /var/lib/postgresql/data = where Postgres stores data inside the container

Test that it works

# Connect and create a table
docker exec -it my-postgres psql -U dev -d myapp -c "CREATE TABLE test (id INT);"
docker exec -it my-postgres psql -U dev -d myapp -c "INSERT INTO test VALUES (1), (2), (3);"

# Remove the container
docker stop my-postgres && docker rm my-postgres

# Create a new one with the SAME volume
docker run -d --name my-postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_USER=dev \
  -e POSTGRES_DB=myapp \
  -p 5432:5432 \
  -v postgres_data:/var/lib/postgresql/data \
  postgres:16-alpine

# Verify the data is still there
docker exec -it my-postgres psql -U dev -d myapp -c "SELECT * FROM test;"
# Result: 1, 2, 3 โœ…

Volume commands

CommandWhat it does
docker volume create nameCreate a volume
docker volume lsList all volumes
docker volume inspect nameSee details (real location)
docker volume rm nameDelete volume (and its data!)
docker volume pruneDelete unused volumes

Mount types

TypeSyntaxUse case
Named Volume-v my_volume:/dataProduction, databases
Bind Mount-v ./local:/dataDevelopment, live reload
Anonymous-v /dataTemporary, not recommended

Bind Mount example for development:

# Your local code syncs with the container
docker run -d --name my-app \
  -v $(pwd):/app \
  -p 3000:3000 \
  node:20-alpine npm start

Change a file โ†’ the container sees it immediately.


Step 5: Create your own image

Now that you understand containers and volumes, create your own image.

Create a docker-hello folder with these 3 files:

Dockerfile:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]

index.js:

console.log("Hello from Docker! ๐Ÿณ");
console.log("Date:", new Date().toISOString());
console.log("Node version:", process.version);

package.json:

{ "name": "docker-hello", "version": "1.0.0" }

Build and run:

docker build -t my-app .
docker run my-app

Step 6: Install Portainer (Visual Management)

Portainer is a web interface for Docker. Perfect for beginners:

# Create a volume to persist data
docker volume create portainer_data

# Install Portainer
docker run -d -p 9000:9000 \
  --name portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

Open http://localhost:9000 and create your admin user.

What can you do with Portainer?

  • See all your containers in a table
  • Start/stop/remove with one click
  • View logs in real-time
  • Create containers without commands
  • Manage images, volumes, networks

๐Ÿ’ก Tip: Keep Portainer running always. It's like "Finder" or "Explorer" but for Docker.


๐Ÿ› ๏ธ Management tools

ToolTypeIdeal for
PortainerLocal/server UIVisual Docker management
Docker DesktopDesktop appMac/Windows, includes basic UI
LazydockerTerminal TUITerminal fans

For production deployment

ToolDescriptionCost
EasyPanelDeploy like Heroku, but on your VPSFree self-hosted
CoolifyOpen source, very completeFree self-hosted
DokkuMini-Heroku on your serverFree
CapRoverSimple PaaS with Let's EncryptFree

๐ŸŽฏ Recommendation for beginners: Use Portainer to learn, then EasyPanel or Coolify when you want easy deployment.


Essential commands

CommandWhat it does
docker run -d nameRun in background
docker psList active containers
docker ps -aList ALL (even stopped)
docker logs nameView logs
docker logs -f nameReal-time logs
docker stop nameStop container
docker rm nameRemove container
docker imagesList downloaded images
docker rmi nameRemove image
docker system pruneClean all unused

If something failed

ErrorCauseSolution
daemon not runningDocker not runningOpen Docker Desktop
permission deniedNo permissionsLinux: sudo usermod -aG docker $USER and restart session
port already in usePort occupiedChange port: -p 9001:9000
no space leftDisk full of imagesdocker system prune -a
cannot connect to localhostContainer not exposing portAdd -p port:port

What you learned

โœ… Install Docker and verify it works โœ… Run pre-made containers (Ubuntu, Postgres, Redis) โœ… Use volumes to not lose data (beginner's #1 mistake) โœ… Create your own image with Dockerfile โœ… Use Portainer for visual management โœ… Essential commands for daily use


Next steps

โ†’ Consume a JSON API โ€” Connect your app with real data โ†’ Deploy with Docker โ€” Take your container to production โ†’ Docker Basics (theory) โ€” Understand containers vs VMs