Use when setting up deployment, CI/CD, Docker, or infrastructure -- covers solo-dev deployment patterns, GitHub Actions, Docker best practices, SSL, environment management, and rollback procedures
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Use when setting up deployment, CI/CD, Docker, or infrastructure -- covers solo-dev deployment patterns, GitHub Actions, Docker best practices, SSL, environment management, and rollback procedures
When helping with deployment, CI/CD, Docker, or infrastructure, follow these solo-dev ops patterns. This is practical ops for small teams and individual developers -- not enterprise Kubernetes clusters. The goal is to make deployments boring and reliable.
Core Principles
Automate what you do twice. First time, do it manually and take notes. Second time, write the script. Third time should be ./deploy.sh and walk away.
Reproducible environments. If it works on your machine, it must work on the server. Docker for isolation. .env files for config. Never install packages globally on the server when a container will do.
Fail loudly, recover quietly. Every deployment should scream if something goes wrong (alerts, logs, non-zero exit codes). Recovery should be automatic where possible (health checks, restart policies, rollback triggers).
Secrets never touch git. API keys in .env, loaded at runtime. Docker secrets or environment variables in CI. If you see a secret in a committed file, rotate it immediately -- it's already compromised.
Logs are your debugger. You can't SSH into production and attach a debugger. Structured logging (JSON), log levels, and centralized collection are how you diagnose issues at 2 AM.
Small, frequent deploys. One feature per deploy. If something breaks, you know exactly what caused it. "We deployed 47 changes and something broke" is a nightmare.
Backups are only real if tested. A backup you haven't restored is a hope, not a backup. Test restoration quarterly at minimum.
Step-by-Step Processes
Setting Up a New Service
1. Write the application code (separate concern)
2. Create Dockerfile (or docker-compose.yml for multi-service)
3. Create .env.example with all required variables
4. Build and test locally: docker compose up --build
5. Set up GitHub repo + Actions workflow
6. Configure hosting (VPS, Render, Fly.io, etc.)
7. Set environment variables on the host
8. Deploy and verify health endpoint returns 200
9. Set up domain + SSL (if applicable)
10. Configure monitoring / uptime checks
Deploying an Update
1. Push to main (or merge PR)
2. CI runs: lint -> test -> build -> deploy
3. Health check confirms new version is up
4. If health check fails: auto-rollback to previous version
5. Monitor logs for 15 minutes after deploy
Common Patterns
Dockerfile (Python/FastAPI)
FROM python:3.11-slim
# System deps
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential curl && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install Python deps first (cache layer)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Non-root user
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser
# Health check
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Docker Compose (Multi-Service Local Dev)
version:"3.8"services:server:build:./apps/serverports:-"8000:8000"env_file:.envvolumes:-./apps/server:/app# Hot reload in devrestart:unless-stoppeddepends_on:-redisweb:build:./apps/webports:-"3000:3000"env_file:.envdepends_on:-serverredis:image:redis:7-alpineports:-"6379:6379"volumes:-redis_data:/datavolumes:redis_data:
GitHub Actions (CI/CD)
# .github/workflows/deploy.ymlname:Deployon:push:branches: [main]
pull_request:branches: [main]
jobs:test:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:actions/setup-python@v5with:python-version:"3.11"cache:"pip"-name:Installdepsrun:pipinstall-rrequirements.txt-name:Lintrun:|
pip install ruff
ruff check .
-name:Testrun:python-mpytesttests/-venv:DATABASE_URL:${{secrets.DATABASE_URL}}deploy:needs:testif:github.ref=='refs/heads/main'&&github.event_name=='push'runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4# Option A: SSH to VPS-name:DeploytoVPSuses:appleboy/ssh-action@v1with:host:${{secrets.SERVER_HOST}}username:${{secrets.SERVER_USER}}key:${{secrets.SSH_KEY}}script:|
cd /opt/myapp
git pull origin main
docker compose up -d --build
docker compose exec server python -c "print('OK')"
-name:Healthcheckrun:|
sleep 30
curl -f https://myapp.example.com/health || exit 1
Deployment Script (VPS / Self-Hosted)
#!/bin/bash# deploy.sh -- Run on the server, not locallyset -euo pipefail
APP_DIR="/opt/myapp"
BACKUP_DIR="/opt/myapp-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
echo"=== Deploying at $TIMESTAMP ==="# Backup current versionecho"Backing up..."mkdir -p "$BACKUP_DIR"cp -r "$APP_DIR""$BACKUP_DIR/app_$TIMESTAMP"# Pull latest codeecho"Pulling latest..."cd"$APP_DIR"
git fetch origin main
git reset --hard origin/main
# Rebuild and restartecho"Rebuilding..."
docker compose build --no-cache
docker compose down
docker compose up -d
# Wait for health checkecho"Checking health..."for i in {1..10}; doif curl -sf http://localhost:8000/health > /dev/null; thenecho"Health check passed!"exit 0
fiecho"Attempt $i/10 -- waiting 5s..."sleep 5
done# Rollback on failureecho"HEALTH CHECK FAILED -- Rolling back!"
docker compose down
cp -r "$BACKUP_DIR/app_$TIMESTAMP"/* "$APP_DIR/"
docker compose up -d
echo"Rolled back to previous version"exit 1