Installing Docker and Setting up Traefik
Complete guide to install Docker, Docker Compose, and deploy Traefik reverse proxy with example services
Introduction
Docker simplifies application deployment by using containers. This guide will walk you through installing Docker, setting up Traefik as a reverse proxy, and deploying your first containerized application.
Traefik is a modern reverse proxy that automatically handles SSL certificates and service discovery for your Docker containers.
Prerequisites
- A VPS with Ubuntu 24.04 or newer
- Root or sudo access
- A domain name pointed to your server (for SSL)
- Basic command-line knowledge
Step 1: Install Docker
Remove Old Versions
First, remove any old Docker installations:
sudo apt remove docker docker-engine docker.io containerd runc
Install Dependencies
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
Add Docker’s Official GPG Key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Set Up the Repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
Verify Installation
sudo docker --version
sudo docker run hello-world
You should see a “Hello from Docker!” message.
Step 2: Install Docker Compose Plugin
Docker Compose makes it easy to manage multi-container applications. We’ll use the Docker Compose plugin (v2), which is the modern, recommended approach.
Install Docker Compose Plugin
sudo apt install -y docker-compose-plugin
Verify Installation
docker compose version
Note: The command is docker compose (with a space), not docker-compose (with a hyphen).
Step 3: Configure Docker for Non-Root User
Running Docker as root is not recommended. Let’s add your user to the docker group:
sudo usermod -aG docker $USER
Log out and back in for this to take effect, or run:
newgrp docker
Test without sudo:
docker ps
Step 4: Create Docker Network
Create a dedicated network for Traefik:
docker network create traefik-public
Step 5: Set Up Traefik
Create Directory Structure
mkdir -p ~/traefik
cd ~/traefik
Create Traefik Configuration
Create traefik.yml:
nano traefik.yml
Add the following configuration:
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: your-email@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-public
Replace your-email@example.com with your actual email.
Create Docker Compose File
Create docker-compose.yml:
nano docker-compose.yml
Add:
services:
traefik:
image: traefik:v2.10
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- traefik-public
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.your-domain.com`)"
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$8EVjn/nj$$GiLUZqcbueTFeD23SuB6x0"
networks:
traefik-public:
external: true
Replace traefik.your-domain.com with your actual domain.
Note: The password hash in the example is for the password “changeme”. You should generate your own using:
echo $(htpasswd -nb admin your-password) | sed 's/\$/\$\$/g'
Install htpasswd if needed: sudo apt install apache2-utils
Create Let’s Encrypt Directory
mkdir letsencrypt
chmod 600 letsencrypt
Start Traefik
docker compose up -d
Check Status
docker compose ps
docker compose logs -f traefik
Step 6: Deploy Whoami Example
Now let’s deploy a simple whoami service to test Traefik.
Create Project Directory
mkdir -p ~/whoami
cd ~/whoami
Create Docker Compose File
nano docker-compose.yml
Add:
services:
whoami:
image: traefik/whoami
container_name: whoami
restart: unless-stopped
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.your-domain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
traefik-public:
external: true
Replace whoami.your-domain.com with your subdomain.
Start Whoami Service
docker compose up -d
Test Your Service
Test with curl:
curl https://whoami.your-domain.com
You should see output similar to:
Hostname: whoami
IP: 172.19.0.3
RemoteAddr: 172.19.0.2:54321
GET / HTTP/1.1
Host: whoami.your-domain.com
User-Agent: curl/7.81.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 123.45.67.89
X-Forwarded-Host: whoami.your-domain.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik
X-Real-Ip: 123.45.67.89
This confirms Traefik is correctly routing traffic and automatically handling SSL.
Adding More Services
To add more services behind Traefik, follow this pattern:
services:
my-app:
image: my-app-image:latest
container_name: my-app
restart: unless-stopped
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.your-domain.com`)"
- "traefik.http.routers.my-app.entrypoints=websecure"
- "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
- "traefik.http.services.my-app.loadbalancer.server.port=8080"
networks:
traefik-public:
external: true
Key points:
traefik.enable=true- Enables Traefik routingHost()- Your domain/subdomainentrypoints=websecure- Uses HTTPScertresolver=letsencrypt- Auto SSL certificateloadbalancer.server.port- Internal container port
Updating Containers
To update a container to the latest version:
cd ~/whoami # or your service directory
docker compose pull
docker compose up -d
Traefik will automatically handle SSL certificates and routing during updates.
Performance Optimization
Limit Container Resources
Add to your service in docker-compose.yml:
services:
my-app:
# ... other config
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
Enable Docker Logging Rotation
Edit /etc/docker/daemon.json:
sudo nano /etc/docker/daemon.json
Add:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Restart Docker:
sudo systemctl restart docker
Need Help?
Having issues with Docker or Traefik?
- Check Docker Documentation
- Visit Traefik Documentation
- Join our Discord community
- Email support: shrp@shrp.no
Happy containerizing! 🐳