# Git-Based Deployment mit Gitea

## Übersicht

Das Git-basierte Deployment Playbook (`deploy-git-based.yml`) ermöglicht Zero-Downtime Deployments mit Gitea als Git-Repository-Server.

## Voraussetzungen

### 1. Gitea Server Setup

Der Gitea Server muss für den Production-Server erreichbar sein. Es gibt zwei Optionen:

#### Option A: Öffentlich erreichbarer Gitea Server (Empfohlen für Production)

```bash
# Gitea muss über das Internet erreichbar sein
git_repo: "git@git.michaelschiemer.de:michael/michaelschiemer.git"
```

**Erforderlich**:
- Öffentliche IP oder Domain für Gitea
- Firewall-Regel für Port 2222 (SSH)
- SSL/TLS für Webinterface (Port 9443/3000)

#### Option B: Gitea auf dem Production-Server

```bash
# Gitea läuft auf demselben Server wie die Anwendung
git_repo: "git@localhost:michael/michaelschiemer.git"
```

**Erforderlich**:
- Gitea Container auf Production-Server deployen
- Docker Compose Setup auf Production-Server
- Lokale SSH-Konfiguration

### 2. SSH Key Setup

Der Deploy-User auf dem Production-Server benötigt einen SSH-Key:

```bash
# Auf dem Production-Server
ssh-keygen -t ed25519 -C "deployment@michaelschiemer" -f ~/.ssh/gitea_deploy_key -N ""

# Public Key zu Gitea hinzufügen (via Web-UI oder API)
cat ~/.ssh/gitea_deploy_key.pub
```

### 3. SSH Keys im Secrets-Verzeichnis

Die SSH Keys müssen im `deployment/infrastructure/secrets/` Verzeichnis liegen:

```bash
deployment/infrastructure/secrets/
├── .gitignore          # Schützt Keys vor versehentlichem Commit
├── gitea_deploy_key    # Private Key
└── gitea_deploy_key.pub  # Public Key
```

**WICHTIG**: Das `secrets/` Verzeichnis ist via `.gitignore` geschützt und darf NIEMALS committed werden!

## Deployment-Ablauf

### 1. SSH Key auf Production-Server kopieren

Das Playbook kopiert automatisch die SSH Keys aus `secrets/` auf den Production-Server:

```yaml
- name: Copy Gitea deploy SSH private key
  copy:
    src: "{{ playbook_dir }}/../secrets/gitea_deploy_key"
    dest: "/home/{{ app_user }}/.ssh/gitea_deploy_key"
    mode: '0600'
```

### 2. SSH-Konfiguration

Das Playbook erstellt automatisch die SSH-Konfiguration:

```ssh
Host localhost
    HostName localhost
    Port 2222
    User git
    IdentityFile ~/.ssh/gitea_deploy_key
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

Host git.michaelschiemer.de
    HostName git.michaelschiemer.de
    Port 2222
    User git
    IdentityFile ~/.ssh/gitea_deploy_key
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
```

### 3. Git Clone

Das Playbook clont das Repository in ein Release-Verzeichnis:

```bash
/var/www/michaelschiemer/
├── releases/
│   ├── 1761524417/     # Timestamp-basierte Releases
│   └── v1.0.0/         # Tag-basierte Releases
├── shared/             # Shared Directories (symlinked)
│   ├── storage/
│   └── .env.production
└── current -> releases/1761524417  # Symlink auf aktives Release
```

### 4. Zero-Downtime Deployment

- Neues Release wird geclont
- Dependencies installiert
- Symlinks erstellt
- `current` Symlink atomar gewechselt
- Health Check durchgeführt
- Bei Fehler: Automatischer Rollback

## Deployment ausführen

### Standard Deployment (main Branch)

```bash
cd deployment/infrastructure
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-git-based.yml
```

### Tag-basiertes Deployment

```bash
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-git-based.yml \
  --extra-vars "release_tag=v1.0.0"
```

### Custom Branch Deployment

```bash
ansible-playbook -i inventories/production/hosts.yml playbooks/deploy-git-based.yml \
  --extra-vars "git_branch=develop"
```

## Konfiguration anpassen

### Git Repository URL ändern

In `deploy-git-based.yml`:

```yaml
vars:
  git_repo: "git@git.michaelschiemer.de:michael/michaelschiemer.git"
  # Oder für lokales Testing:
  # git_repo: "git@localhost:michael/michaelschiemer.git"
```

### Shared Directories anpassen

```yaml
vars:
  shared_dirs:
    - storage/logs
    - storage/cache
    - storage/sessions
    - storage/uploads
    - public/uploads

  shared_files:
    - .env.production
```

## Troubleshooting

### Fehler: "Connection refused" zu Gitea

**Problem**: Der Production-Server kann Gitea nicht erreichen.

**Lösung**:
1. Prüfe, ob Gitea öffentlich erreichbar ist: `nc -zv git.michaelschiemer.de 2222`
2. Prüfe Firewall-Regeln auf dem Gitea-Server
3. Für lokales Testing: Verwende rsync-based Deployment stattdessen

### Fehler: "Permission denied (publickey)"

**Problem**: SSH Key ist nicht korrekt konfiguriert.

**Lösung**:
1. Prüfe, ob der Public Key in Gitea hinzugefügt wurde
2. Prüfe SSH Key Permissions: `chmod 600 ~/.ssh/gitea_deploy_key`
3. Teste SSH-Verbindung manuell: `ssh -p 2222 -i ~/.ssh/gitea_deploy_key git@git.michaelschiemer.de`

### Health Check schlägt fehl

**Problem**: Deployment-Health-Check failed.

**Lösung**:
1. Automatischer Rollback wurde durchgeführt
2. Prüfe Logs: `tail -f /var/www/michaelschiemer/deploy.log`
3. Prüfe Application Logs: `/var/www/michaelschiemer/shared/storage/logs/`

## Comparison: Git-based vs rsync-based

### Git-based Deployment (Dieser Playbook)

**Vorteile**:
- Zero-Downtime durch Symlink-Switch
- Atomare Releases mit Rollback-Fähigkeit
- Git-Historie auf Production-Server
- Einfache Rollbacks zu vorherigen Releases

**Nachteile**:
- Gitea Server muss erreichbar sein
- Zusätzliche Infrastruktur (Gitea)
- SSH Key Management erforderlich

### rsync-based Deployment

**Vorteile**:
- Keine zusätzliche Infrastruktur
- Funktioniert mit lokalem Development-Environment
- Schneller für kleine Änderungen

**Nachteile**:
- Kein Zero-Downtime ohne zusätzliche Logik
- Keine Git-Historie auf Server
- Rollback komplizierter

## Empfehlung

**Für Production**: Git-based Deployment mit öffentlich erreichbarem Gitea Server
**Für Development/Testing**: rsync-based Deployment (bereits implementiert und getestet)

## Related Files

- `deploy-git-based.yml` - Git-based Deployment Playbook
- `deploy-rsync-based.yml` - rsync-based Deployment Playbook (Alternative)
- `rollback-git-based.yml` - Rollback Playbook für Git-Deployments
- `secrets/.gitignore` - Schutz für SSH Keys
