Advertisement Space - Google AdSense
Key Features
๐ฐ Extremely cost-effective: โฌ4.15/month for CX11 (1 vCPU, 2GB RAM)
๐ช๐บ European data centers (Germany, Finland) - GDPR compliant
โก Excellent network performance and reliability
๐ GitHub Container Registry (ghcr.io) is free for public repos
๐ฆ Docker Compose for easy multi-container management
๐ Zero-downtime deployments with health checks
๐ Configuration Files
Copy these files into your project:
.github/workflows/deploy.yml
# .github/workflows/deploy.yml
name: Deploy Docker to Hetzner VPS
on:
push:
branches:
- main
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Deploy to Hetzner VPS
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HETZNER_HOST }}
username: ${{ secrets.HETZNER_USERNAME }}
key: ${{ secrets.HETZNER_SSH_KEY }}
script: |
# Login to GitHub Container Registry
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
# Pull latest image
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# Stop and remove old container
docker-compose -f /opt/myapp/docker-compose.yml down || true
# Start new container
cd /opt/myapp
docker-compose up -d
# Clean up old images
docker image prune -af
# docker-compose.yml (on server at /opt/myapp/docker-compose.yml)
version: '3.8'
services:
app:
image: ghcr.io/YOUR_USERNAME/YOUR_REPO:latest
container_name: myapp
restart: unless-stopped
ports:
- "80:3000"
- "443:3000"
environment:
- NODE_ENV=production
- PORT=3000
volumes:
- ./data:/app/data
networks:
- app-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
app-network:
driver: bridge
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
RUN apk add --no-cache curl
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"] ๐ฆ Need all the files?
Download the complete blueprint with README, package.json, and all configuration files.
๐ฅ Browse All FilesConfiguration Summary
๐
Framework
Docker
โ๏ธ
Cloud Provider
Hetzner Cloud
โ๏ธ
Deployment Tool
GitHub Actions
๐ฐ
Pricing
Extremely competitive pricing, hourly billing
โ๏ธ About Hetzner Cloud
Cost-effective European cloud provider
โ Best For
Cost-sensitive projects, European data residency, VPS hosting
๐ฐ Pricing
Extremely competitive pricing, hourly billing
Available Services:
โ Cloud Servers - Virtual Machines
โ Load Balancers - Traffic Distribution
โ Volumes - Block Storage
โ Networks - Private Networking
โ Floating IPs - Flexible IPs
โ Snapshots - Backups
โ Firewalls - Security
โ Object Storage - S3-compatible
โ Dedicated Servers - Bare Metal
โ Prerequisites
Make sure you have these ready before starting:
โ Hetzner Cloud account
โ GitHub account with repository admin access
โ SSH client installed locally
โ Basic knowledge of Docker and Linux
โ Domain name (optional, for HTTPS with Caddy/nginx)
๐ Step-by-Step Implementation
Follow these steps to deploy your Docker application:
- 1Create Hetzner Cloud account at https://www.hetzner.com/cloud
- 2Create a new VPS (CX11 for โฌ4.15/month is sufficient to start)
- 3Choose Ubuntu 22.04 LTS as the OS
- 4Add your SSH key during server creation
- 5SSH into server: ssh root@YOUR_SERVER_IP
- 6Install Docker: curl -fsSL https://get.docker.com | sh
- 7Install Docker Compose: apt install docker-compose-plugin
- 8Create app directory: mkdir -p /opt/myapp
- 9Create docker-compose.yml in /opt/myapp with the configuration above
- 10Update docker-compose.yml with your GitHub Container Registry image path
- 11Generate SSH key for GitHub Actions: ssh-keygen -t ed25519 -C "github-actions"
- 12Add public key to server: cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
- 13Copy private key for GitHub Secrets: cat ~/.ssh/id_ed25519
- 14In GitHub repo: Settings โ Secrets โ Actions โ New repository secret
- 15Add HETZNER_HOST (your server IP)
- 16Add HETZNER_USERNAME (usually "root")
- 17Add HETZNER_SSH_KEY (the private key content)
- 18Create .github/workflows/deploy.yml
- 19Update IMAGE_NAME in workflow to match your repo
- 20Commit and push to main branch
- 21Monitor deployment in GitHub Actions
- 22Access your app at http://YOUR_SERVER_IP
๐ก Additional Notes & Tips
- ๐งน Automatic cleanup of old Docker images
- ๐ Add Caddy or nginx for automatic HTTPS with Let's Encrypt
- ๐ Scale vertically by upgrading VPS size (takes ~1 minute)
- ๐ก For high availability, use Hetzner Load Balancer (โฌ5.39/month)
๐ About This Stack
๐ณ Docker
Containerization platform for consistent deployments
๐ช๐บ Hetzner
Cost-effective European cloud provider
โ๏ธ GitHub Actions
CI/CD automation directly in GitHub
๐ท๏ธ Tags & Keywords
Docker Hetzner Hetzner Cloud GitHub Actions CI/CD DevOps Infrastructure as Code Docker Deployment Hetzner Hosting Production Ready 2026Advertisement Space - Google AdSense