Files
michaelschiemer/deployment/CODE_CHANGE_WORKFLOW.md
Michael Schiemer c087d372c2 Update Docker Registry URLs to HTTPS endpoint (registry.michaelschiemer.de)
- Replace git.michaelschiemer.de:5000 (HTTP) with registry.michaelschiemer.de (HTTPS)
- Update all Ansible playbooks and configuration files
- Update CI/CD workflows to use HTTPS registry endpoint
- Update Docker Compose files with new registry URL
- Update documentation and scripts

Benefits:
- Secure HTTPS connection (no insecure registry config needed)
- Consistent use of HTTPS endpoint via Traefik
- Better security practices for production deployment
2025-10-31 14:35:39 +01:00

12 KiB

Codeänderungen pushen und deployen

Übersicht

Dieses Dokument erklärt, wie Codeänderungen gepusht werden und automatisch in Production deployed werden.

Quick Start:

git add .
git commit -m "feat: Add new feature"
git push origin main

→ Automatisches Deployment startet (~8-15 Minuten)

📖 Verwandte Dokumentation:


Normaler Workflow: Codeänderungen deployen

Schritt 1: Code lokal ändern

# Änderungen in deinem lokalen Repository machen
# z.B. Datei bearbeiten: src/App/Controller/HomeController.php

# Änderungen anzeigen
git status

# Änderungen anschauen
git diff

Schritt 2: Änderungen committen

# Änderungen zum Staging hinzufügen
git add .

# Oder nur spezifische Dateien
git add src/App/Controller/HomeController.php

# Commit erstellen
git commit -m "feat: Add new feature to home controller"

Commit-Message Konventionen:

  • feat: - Neue Feature
  • fix: - Bug-Fix
  • refactor: - Code-Refactoring
  • docs: - Dokumentation
  • test: - Tests
  • chore: - Wartungsaufgaben

Schritt 3: Code zu Gitea pushen

# Zu main branch pushen (triggert automatisches Deployment)
git push origin main

# Oder zu anderem Branch pushen (kein Auto-Deploy)
git push origin feature/new-feature

Schritt 4: Automatisches Deployment

Was passiert automatisch:

  1. Git Push → Gitea erhält den Push
  2. Workflow wird getriggert (bei Push zu main Branch)
  3. CI/CD Pipeline startet:
    • Tests laufen
    • Docker Image wird gebaut
    • Image wird zur Registry gepusht
    • Ansible Deployment wird ausgeführt
    • Application Stack wird aktualisiert

Zeitdauer: ~8-15 Minuten für komplettes Deployment


Deployment-Trigger

Automatisches Deployment (bei Push zu main)

Workflow: .gitea/workflows/production-deploy.yml

on:
  push:
    branches:
      - main
    paths-ignore:
      - 'docs/**'
      - '**.md'
      - '.github/**'

Bedeutung:

  • Push zu main Branch → Deployment startet automatisch
  • Push zu anderen Branches → Kein Deployment
  • Push nur von Markdown-Dateien → Kein Deployment (wegen paths-ignore)

Beispiel:

# Triggert Deployment
git push origin main

# Triggert KEIN Deployment (nur Markdown)
git commit -m "docs: Update README" --only README.md
git push origin又问

# Triggert KEIN Deployment (anderer Branch)
git checkout -b feature/new-feature
git push origin feature/new-feature

Manuelles Deployment (Workflow-Dispatch)

Workflow kann manuell gestartet werden:

  1. Gehe zu: https://git.michaelschiemer.de/michael/michaelschiemer/actions
  2. Wähle: "Production Deployment Pipeline"
  3. Klicke: "Run workflow"
  4. Wähle Branch (z.B. main oder anderer Branch)
  5. Optionale Einstellungen:
    • skip_tests: true (nur in Notfällen!)
  6. Klicke: "Run workflow"

Verwendung:

  • Deployment von anderem Branch (z.B. develop, staging)
  • Deployment ohne Code-Änderung (z.B. nach Config-Änderung)
  • Notfall-Deployment mit skip_tests: true

Workflow-Details

Was passiert bei jedem Push zu main?

Job 1: Tests (ca. 2-5 Minuten)

- PHP 8.3 Setup
- Composer Dependencies installieren
- Pest Tests ausführen
- PHPStan Code Quality Check
- Code Style Check (composer cs)

Bei Fehler: Pipeline stoppt, kein Deployment

Job 2: Build (ca. 3-5 Minuten)

- Docker Buildx Setup
- Image Metadata generieren (Tag: <short-sha>-<timestamp>)
- Docker Image Build (Dockerfile.production)
- Image mit Tags pushen:
  - registry.michaelschiemer.de/framework:latest
  - registry.michaelschiemer.de/framework:<tag>
  - registry.michaelschiemer.de/framework:git-<short-sha>

Job 3: Deploy (ca. 2-4 Minuten)

- SSH Setup (mit Secret)
- Ansible Installation
- Ansible Playbook ausführen:
  - Image Pull
  - docker-compose.yml Update
  - Stack Neustart
- Health-Check (10x versuche)
- Rollback bei Fehler

Branching-Strategie

Empfohlener Workflow

main (Production)
  ↓
develop (Entwicklung/Testing)
  ↓
feature/* (Feature Branches)

Workflow-Beispiele

1. Feature entwickeln

# Feature Branch erstellen
git checkout -b feature/user-authentication

# Änderungen machen
# ... Code schreiben ...

# Committen
git add .
git commit -m "feat: Add user authentication"

# Zu Gitea pushen (kein Auto-Deploy)
git push origin feature/user-authentication

# Pull Request erstellen in Gitea
# → Code Review
# → Merge zu develop (oder main)

2. Direkt zu Production deployen

# Änderungen lokal
git checkout main
# ... Änderungen machen ...
git add .
git commit -m "fix: Critical bug fix"

# Pushen → Triggert automatisches Deployment
git push origin main

# Pipeline läuft automatisch:
# ✅ Tests
# ✅ Build
# ✅ Deploy

3. Hotfix (Notfall)

# Hotfix Branch von main
git checkout -b hotfix/critical-security-fix main

# Fix implementieren
# ... Code schreiben ...
git add .
git commit -m "fix: Critical security vulnerability"

# Direkt zu main mergen
git checkout main
git merge hotfix/critical-security-fix Ker

# Pushen → Auto-Deploy
git push origin main

# Optional: Manuelles Deployment mit skip_tests
# (nur wenn Tests lokal bereits erfolgreich)

Deployment-Status prüfen

1. Pipeline-Status in Gitea

https://git.michaelschiemer.de/michael/michaelschiemer/actions

Status-Anzeigen:

  • 🟢 Grüner Haken = Erfolgreich
  • 🔴 Roter Haken = Fehlgeschlagen
  • 🟡 Gelber Kreis = Läuft gerade

2. Logs ansehen

  1. Gehe zu Actions
  2. Klicke auf den Workflow-Run
  3. Klicke auf Job (z.B. "Deploy to Production Server")
  4. Klicke auf Step (z.B. "Deploy via Ansible")
  5. Logs ansehen

3. Application-Status prüfen

# SSH zum Production-Server
ssh deploy@94.16.110.151

# Container-Status prüfen
cd ~/deployment/stacks/application
docker compose ps

# Logs ansehen
docker compose logs -f app

# Health-Check manuell
curl https://michaelschiemer.de/health

Deployment verhindern

Temporäres Deployment verhindern

Option 1: Push zu anderem Branch

# Entwickle auf Feature-Branch
git checkout -b feature/my-feature
git push origin feature/my-feature
# → Kein Auto-Deploy

Option CT 2: [skip ci] in Commit-Message

# Workflow wird übersprungen
git commit -m "docs: Update documentation [skip ci]"
git push origin main

Hinweis: [skip ci] wird aktuell nicht unterstützt, da kein entsprechender Filter im Workflow ist.

Deployment-Trigger deaktivieren

Temporär (Workflow anpassen):

# In .gitea/workflows/production-deploy.yml
on:
  push:
    branches:
      - main
  # workflow_dispatch:  # Kommentiere aus für temporäres Deaktivieren

Besser: Nutze Feature-Branches für Entwicklung ohne Auto-Deploy.


Häufige Szenarien

Szenario 1: Kleine Bug-Fix

# 1. Bug-Fix lokal implementieren
git checkout main
# ... Fix implementieren ...
git add .
git commit -m "fix: Resolve login issue"

# 2. Pushen → Auto-Deploy
git push origin main

# 3. Pipeline beobachten
# → Tests ✅
# → Build ✅
# → Deploy ✅

# 4. Verifizieren
curl https://michaels chasing.de/health

Szenario 2: Große Feature-Entwicklung

# 1. Feature-Branch erstellen
git checkout -b feature/new-dashboard

# 2. Feature entwickeln
# ... viele Commits ...

# 3. Regelmäßig pushen (kein Auto-Deploy)
git push origin feature/new-dashboard

# 4. Pull Request erstellen in Gitea
# → Code Review
# → Diskussion

# 5. Merge zu main (triggert Auto-Deploy)
# → Via Gitea UI: "Merge Pull Request"
# → Oder lokal:
git checkout main
git merge feature/new-dashboard
git push origin main

Szenario 3: Config-Änderung ohne Code-Änderung

# Beispiel: .env Variablen ändern
# (wird über Ansible Template generiert, daher direkt auf Server ändern)

# Oder: docker-compose.yml anpassen
# Änderungen machen
git add .
git commit -m "chore: Update docker-compose configuration"
git push origin main

# → Pipeline läuft
# → Build: Keine Code-Änderung, aber Image wird neu getaggt
# → Deploy: docker-compose.yml wird aktualisiert

Szenario 4: Notfall-Rollback

# Option 1: Rollback via Ansible Playbook
cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/rollback.yml \
  -e "rollback_timestamp=2025-10-31T01-20-15Z"

# Option 2: Alten Commit pushen
git log --oneline
# Finde letzten funktionierenden Commit
git checkout <commit-hash>
git checkout -b rollback/previous-version
git push origin rollback/previous-version

# Manuell zu main mergen oder direkt:
git checkout main
git reset --hard <commit-hash>
git push origin main --force  # ⚠️ Vorsicht!
# → Triggert Auto-Deploy mit altem Code

Best Practices

1. Commits

  • Klare, beschreibende Commit-Messages entweder
  • Atomic Commits (ein Feature = ein Commit)
  • Regelmäßig pushen (nicht alles auf einmal)

2. Testing

  • Tests lokal ausführen vor Push:
    composer cs        # Code Style
    make phpstan       # Static Analysis
    ./vendor/bin/pest  # Tests
    

3. Deployment

  • Niemals direkt zu main pushen ohne lokale Tests
  • Feature-Branches für größere Änderungen
  • Pull Requests für Code Review
  • Pipeline-Status beobachten nach Push

4. Rollback-Plan

  • Immer Backup vor größeren Änderungen
  • Rollback-Playbook bereit halten
  • Deployment-Metadaten dokumentieren

Troubleshooting

Pipeline schlägt fehl

Problem: Tests fehlgeschlagen

# Tests lokal ausführen
./vendor/bin/pest

# Fehler beheben
# ... Code anpassen ...
git add .
git commit -m "fix: Fix failing tests"
git push origin main

Problem: Build fehlgeschlagen

# Docker Build lokal testen
docker build -f Dockerfile.production -t test-image .

# Fehler beheben
# ... Dockerfile anpassen ...
git add .
git commit -m "fix: Fix Docker build"
git push origin main

Problem: Deployment fehlgeschlagen

# SSH zum Server
ssh deploy@94.16.110.151

# Logs prüfen
cd ~/deployment/stacks/application
docker compose logs app

# Manuell rollback
cd ~/deployment/ansible
ansible-playbook -i inventory/production.yml playbooks/rollback.yml

Deployment läuft zu lange

Pipeline hängt:

  • Prüfe Runner-Status: docker compose ps in deployment/gitea-runner
  • Prüfe Runner-Logs: docker compose logs gitea-runner
  • Prüfe Workflow-Logs in Gitea UI

Deployment hängt:

  • Prüfe Server-Status: ssh deploy@94.16.110.151 "docker ps"
  • Prüfe Container-Logs: docker compose logs
  • Prüfe Disk-Space: df -h

Zusammenfassung

Normaler Workflow

  1. Code ändern lokal
  2. Committen mit klarer Message
  3. Push zu main → Auto-Deploy startet
  4. Pipeline beobachten in Gitea Actions
  5. Verifizieren auf Production

Wichtige Commands

# Änderungen pushen (triggert Auto-Deploy)
git push origin main

# Feature entwickeln (kein Auto-Deploy)
git checkout -b feature/my-feature
git push origin feature/my-feature

# Pipeline-Status prüfen
# → https://git.michaelschiemer.de/michael/michaelschiemer/actions

# Application-Status prüfen
ssh deploy@94.16.110.151 "cd ~/deployment/stacks/application && docker compose ps"

Deployment-Zeit

  • Gesamt: ~8-15 Minuten
  • Tests: ~2-5 Minuten
  • Build: ~3-5 Minuten
  • Deploy: ~2-4 Minuten
  • Health-Check: ~1 Minute

Ready to deploy! 🚀