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: true

Project 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: true

Deployment Workflow

Option 1: Manual Deployment

ssh server
cd /opt/myproject
git pull
docker compose build
docker compose up -d

Option 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 -d

Monitoring

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
done

Common Issues and Fixes

Container won't start

docker logs container_name
# Check for missing environment variables or port conflicts

Out of disk space

docker system prune -a
# Removes unused images, containers, networks

SSL certificate issues

# Check Traefik logs
docker logs traefik
# Usually a DNS or rate limit issue

Cost 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.