Back to Blog
Tutorial9 min read
Docker Deployment for Side Projects: A Practical Guide
How I deploy and manage multiple projects on a single VPS using Docker, Traefik, and simple automation.
By Koral|
DockerDevOpsDeployment
Why Docker for Side Projects?
When you're running multiple projects on a single VPS, Docker solves several problems:
- **Isolation** - Each project runs in its own environment
- **Consistency** - Development matches production exactly
- **Easy deployment** - Pull and run, no dependency hell
- **Resource efficiency** - Share the server without conflicts
My Setup
I run 8+ projects on a single $20/month VPS using:
- **Docker** - Container runtime
- **Docker Compose** - Multi-container orchestration
- **Traefik** - Reverse proxy and SSL
- **GitHub Actions** - Automated deployments
The Traefik Setup
Traefik automatically handles routing and SSL certificates:
# traefik/docker-compose.yml
version: '3'
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./letsencrypt:/letsencrypt
networks:
- web
networks:
web:
external: trueProject Configuration
Each project has its own docker-compose.yml:
# myproject/docker-compose.yml
version: '3'
services:
app:
build: .
labels:
- "traefik.enable=true"
- "traefik.http.routers.myproject.rule=Host(`myproject.koralktech.io`)"
- "traefik.http.routers.myproject.tls.certresolver=letsencrypt"
networks:
- web
networks:
web:
external: trueDeployment Workflow
Option 1: Manual Deployment
ssh server
cd /opt/myproject
git pull
docker compose build
docker compose up -dOption 2: GitHub Actions (Preferred)
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: root
key: ${{ secrets.SSH_KEY }}
script: |
cd /opt/myproject
git pull
docker compose build
docker compose up -dMonitoring
Basic health monitoring with a simple script:
#!/bin/bash
# check-services.sh
SERVICES=("insights.koralktech.io" "stocks.koralktech.io")
for service in "${SERVICES[@]}"; do
status=$(curl -s -o /dev/null -w "%{http_code}" "https://$service")
if [ "$status" != "200" ]; then
echo "ALERT: $service returned $status"
# Send notification
fi
doneCommon Issues and Fixes
Container won't start
docker logs container_name
# Check for missing environment variables or port conflictsOut of disk space
docker system prune -a
# Removes unused images, containers, networksSSL certificate issues
# Check Traefik logs
docker logs traefik
# Usually a DNS or rate limit issueCost Breakdown
My monthly infrastructure cost:
- VPS (4GB RAM, 2 CPU): $20
- Domain: ~$1/month
- **Total: ~$21/month** for 8 projects
Tips for Beginners
- **Start with one project** - Get comfortable before adding complexity
- **Use environment variables** - Never hardcode secrets
- **Set up backups** - Database dumps to cloud storage
- **Monitor disk space** - Docker images add up fast
- **Document everything** - Future you will thank present you
Docker transforms deployment from a scary task into a repeatable process.
Enjoyed this post?
Connect on LinkedIn to follow my journey building products in public.