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
This commit is contained in:
@@ -20,7 +20,7 @@ bash scripts/prepare-secrets.sh
|
|||||||
**Hinweis**: Alle Secrets müssen in Gitea konfiguriert werden, bevor die Pipeline läuft.
|
**Hinweis**: Alle Secrets müssen in Gitea konfiguriert werden, bevor die Pipeline läuft.
|
||||||
|
|
||||||
### 2. Docker Registry ✅
|
### 2. Docker Registry ✅
|
||||||
- ✅ Registry läuft auf `git.michaelschiemer.de:5000`
|
- ✅ Registry läuft auf `registry.michaelschiemer.de`
|
||||||
- ✅ Authentifizierung konfiguriert (admin/registry-secure-password-2025)
|
- ✅ Authentifizierung konfiguriert (admin/registry-secure-password-2025)
|
||||||
- ✅ Erreichbar via HTTP auf `127.0.0.1:5000`
|
- ✅ Erreichbar via HTTP auf `127.0.0.1:5000`
|
||||||
- ✅ Image `framework` bereits vorhanden
|
- ✅ Image `framework` bereits vorhanden
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Registry Details
|
## Registry Details
|
||||||
|
|
||||||
- **URL**: `git.michaelschiemer.de:5000` (intern) oder `registry.michaelschiemer.de` (via Traefik)
|
- **URL**: `registry.michaelschiemer.de` (intern) oder `registry.michaelschiemer.de` (via Traefik)
|
||||||
- **Standard Credentials**:
|
- **Standard Credentials**:
|
||||||
- **Username**: `admin`
|
- **Username**: `admin`
|
||||||
- **Password**: `registry-secure-password-2025`
|
- **Password**: `registry-secure-password-2025`
|
||||||
@@ -20,10 +20,10 @@ Verwende folgende Werte in den Gitea Repository Secrets:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Login testen
|
# Login testen
|
||||||
echo "registry-secure-password-2025" | docker login git.michaelschiemer.de:5000 -u admin --password-stdin
|
echo "registry-secure-password-2025" | docker login registry.michaelschiemer.de -u admin --password-stdin
|
||||||
|
|
||||||
# Images auflisten
|
# Images auflisten
|
||||||
curl -u admin:registry-secure-password-2025 http://git.michaelschiemer.de:5000/v2/_catalog
|
curl -u admin:registry-secure-password-2025 http://registry.michaelschiemer.de/v2/_catalog
|
||||||
|
|
||||||
# Oder via Traefik (HTTPS)
|
# Oder via Traefik (HTTPS)
|
||||||
curl -u admin:registry-secure-password-2025 https://registry.michaelschiemer.de/v2/_catalog
|
curl -u admin:registry-secure-password-2025 https://registry.michaelschiemer.de/v2/_catalog
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Diese Secrets müssen in Gitea konfiguriert werden unter:
|
|||||||
### 2. REGISTRY_PASSWORD
|
### 2. REGISTRY_PASSWORD
|
||||||
- **Beschreibung**: Passwort für Docker Registry Login
|
- **Beschreibung**: Passwort für Docker Registry Login
|
||||||
- **Typ**: Password (versteckt)
|
- **Typ**: Password (versteckt)
|
||||||
- **Wert**: Das Passwort für die Docker Registry auf `git.michaelschiemer.de:5000`
|
- **Wert**: Das Passwort für die Docker Registry auf `registry.michaelschiemer.de`
|
||||||
- **Verwendung**: Docker Registry Authentication beim Image Push
|
- **Verwendung**: Docker Registry Authentication beim Image Push
|
||||||
|
|
||||||
### 3. SSH_PRIVATE_KEY
|
### 3. SSH_PRIVATE_KEY
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ on:
|
|||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: git.michaelschiemer.de:5000
|
REGISTRY: registry.michaelschiemer.de
|
||||||
IMAGE_NAME: framework
|
IMAGE_NAME: framework
|
||||||
DEPLOYMENT_HOST: 94.16.110.151
|
DEPLOYMENT_HOST: 94.16.110.151
|
||||||
|
|
||||||
@@ -248,10 +248,9 @@ jobs:
|
|||||||
chmod 600 ~/.ssh/production
|
chmod 600 ~/.ssh/production
|
||||||
ssh-keyscan -H ${{ env.DEPLOYMENT_HOST }} >> ~/.ssh/known_hosts
|
ssh-keyscan -H ${{ env.DEPLOYMENT_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Install Ansible
|
# Ansible is pre-installed in php-ci image
|
||||||
run: |
|
- name: Verify Ansible installation
|
||||||
apt-get update
|
run: ansible --version
|
||||||
apt-get install -y ansible
|
|
||||||
|
|
||||||
- name: Deploy via Ansible
|
- name: Deploy via Ansible
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ CI/CD Pipeline (Gitea Actions)
|
|||||||
```yaml
|
```yaml
|
||||||
- Docker Image Build (Dockerfile.production)
|
- Docker Image Build (Dockerfile.production)
|
||||||
- Image mit Tags pushen:
|
- Image mit Tags pushen:
|
||||||
- git.michaelschiemer.de:5000/framework:latest
|
- registry.michaelschiemer.de/framework:latest
|
||||||
- git.michaelschiemer.de:5000/framework:<tag>
|
- registry.michaelschiemer.de/framework:<tag>
|
||||||
- git.michaelschiemer.de:5000/framework:git-<short-sha>
|
- registry.michaelschiemer.de/framework:git-<short-sha>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Job 3: Deploy (Ansible)
|
#### Job 3: Deploy (Ansible)
|
||||||
@@ -121,7 +121,7 @@ docker compose -f ~/deployment/stacks/application/docker-compose.yml \
|
|||||||
**2. Docker Registry Login**
|
**2. Docker Registry Login**
|
||||||
```bash
|
```bash
|
||||||
# Login zur privaten Registry mit Credentials
|
# Login zur privaten Registry mit Credentials
|
||||||
docker login git.michaelschiemer.de:5000 \
|
docker login registry.michaelschiemer.de \
|
||||||
-u <registry-username> \
|
-u <registry-username> \
|
||||||
-p <registry-password>
|
-p <registry-password>
|
||||||
```
|
```
|
||||||
@@ -129,10 +129,10 @@ docker login git.michaelschiemer.de:5000 \
|
|||||||
**3. Neues Image Pullen**
|
**3. Neues Image Pullen**
|
||||||
```bash
|
```bash
|
||||||
# Pullt das neue Image von der Registry
|
# Pullt das neue Image von der Registry
|
||||||
docker pull git.michaelschiemer.de:5000/framework:<tag>
|
docker pull registry.michaelschiemer.de/framework:<tag>
|
||||||
|
|
||||||
# Beispiel:
|
# Beispiel:
|
||||||
# git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
# registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||||
```
|
```
|
||||||
|
|
||||||
**4. docker-compose.yml aktualisieren**
|
**4. docker-compose.yml aktualisieren**
|
||||||
@@ -143,12 +143,12 @@ docker pull git.michaelschiemer.de:5000/framework:<tag>
|
|||||||
# Vorher:
|
# Vorher:
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: git.michaelschiemer.de:5000/framework:latest
|
image: registry.michaelschiemer.de/framework:latest
|
||||||
|
|
||||||
# Nachher (wenn image_tag != 'latest'):
|
# Nachher (wenn image_tag != 'latest'):
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: git.michaelschiemer.de:5000/framework:<tag>
|
image: registry.michaelschiemer.de/framework:<tag>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Regex-Replace:**
|
**Regex-Replace:**
|
||||||
@@ -158,13 +158,13 @@ replace: '\1{{ app_image }}:{{ image_tag }}'
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Betroffene Services (werden alle aktualisiert):**
|
**Betroffene Services (werden alle aktualisiert):**
|
||||||
- `app` (PHP-FPM) - Zeile 6: `image: git.michaelschiemer.de:5000/framework:latest`
|
- `app` (PHP-FPM) - Zeile 6: `image: registry.michaelschiemer.de/framework:latest`
|
||||||
- `queue-worker` (Queue Worker) - Zeile 120: `image: git.michaelschiemer.de:5000/framework:latest`
|
- `queue-worker` (Queue Worker) - Zeile 120: `image: registry.michaelschiemer.de/framework:latest`
|
||||||
- `scheduler` (Scheduler) - Zeile 165: `image: git.michaelschiemer.de:5000/framework:latest`
|
- `scheduler` (Scheduler) - Zeile 165: `image: registry.michaelschiemer.de/framework:latest`
|
||||||
|
|
||||||
**Hinweis:**
|
**Hinweis:**
|
||||||
- Alle drei Services verwenden das gleiche Image, daher werden alle mit dem neuen Tag aktualisiert
|
- Alle drei Services verwenden das gleiche Image, daher werden alle mit dem neuen Tag aktualisiert
|
||||||
- Der Regex matched **alle Zeilen** die mit `image: git.michaelschiemer.de:5000/framework:` beginnen
|
- Der Regex matched **alle Zeilen** die mit `image: registry.michaelschiemer.de/framework:` beginnen
|
||||||
- `nginx` und `redis` bleiben unverändert (verwenden andere Images)
|
- `nginx` und `redis` bleiben unverändert (verwenden andere Images)
|
||||||
|
|
||||||
**5. Application Stack neu starten**
|
**5. Application Stack neu starten**
|
||||||
@@ -216,7 +216,7 @@ docker compose ps --format json | \
|
|||||||
Deployment Timestamp: 2025-10-31T02:35:04Z
|
Deployment Timestamp: 2025-10-31T02:35:04Z
|
||||||
Git Commit: abc1234...
|
Git Commit: abc1234...
|
||||||
Image Tag: abc1234-1696234567
|
Image Tag: abc1234-1696234567
|
||||||
Deployed Image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
Deployed Image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||||
Image Pull: SUCCESS
|
Image Pull: SUCCESS
|
||||||
Stack Deploy: UPDATED
|
Stack Deploy: UPDATED
|
||||||
Health Status: All services healthy
|
Health Status: All services healthy
|
||||||
@@ -238,7 +238,7 @@ Der Application Stack besteht aus mehreren Services:
|
|||||||
#### Services im Stack
|
#### Services im Stack
|
||||||
|
|
||||||
**1. `app` (PHP-FPM Application)**
|
**1. `app` (PHP-FPM Application)**
|
||||||
- Image: `git.michaelschiemer.de:5000/framework:<tag>`
|
- Image: `registry.michaelschiemer.de/framework:<tag>`
|
||||||
- Container: `app`
|
- Container: `app`
|
||||||
- Health Check: `php-fpm-healthcheck`
|
- Health Check: `php-fpm-healthcheck`
|
||||||
- Netzwerk: `app-internal`
|
- Netzwerk: `app-internal`
|
||||||
@@ -259,7 +259,7 @@ Der Application Stack besteht aus mehreren Services:
|
|||||||
- Netzwerk: `app-internal`
|
- Netzwerk: `app-internal`
|
||||||
|
|
||||||
**4. `queue-worker` (Background Jobs)**
|
**4. `queue-worker` (Background Jobs)**
|
||||||
- Image: `git.michaelschiemer.de:5000/framework:<tag>` (gleiches wie app)
|
- Image: `registry.michaelschiemer.de/framework:<tag>` (gleiches wie app)
|
||||||
- Container: `queue-worker`
|
- Container: `queue-worker`
|
||||||
- Health Check: `pgrep -f 'queue:work'`
|
- Health Check: `pgrep -f 'queue:work'`
|
||||||
- Netzwerk: `app-internal`
|
- Netzwerk: `app-internal`
|
||||||
@@ -267,7 +267,7 @@ Der Application Stack besteht aus mehreren Services:
|
|||||||
- Abhängigkeiten: `app`, `redis`
|
- Abhängigkeiten: `app`, `redis`
|
||||||
|
|
||||||
**5. `scheduler` (Cron Jobs)**
|
**5. `scheduler` (Cron Jobs)**
|
||||||
- Image: `git.michaelschiemer.de:5000/framework:<tag>` (gleiches wie app)
|
- Image: `registry.michaelschiemer.de/framework:<tag>` (gleiches wie app)
|
||||||
- Container: `scheduler`
|
- Container: `scheduler`
|
||||||
- Health Check: `pgrep -f 'scheduler:run'`
|
- Health Check: `pgrep -f 'scheduler:run'`
|
||||||
- Netzwerk: `app-internal`
|
- Netzwerk: `app-internal`
|
||||||
@@ -307,8 +307,8 @@ Der Application Stack besteht aus mehreren Services:
|
|||||||
### Inventory-Variablen (`inventory/production.yml`)
|
### Inventory-Variablen (`inventory/production.yml`)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
app_image: "git.michaelschiemer.de:5000/framework"
|
app_image: "registry.michaelschiemer.de/framework"
|
||||||
docker_registry_url: "git.michaelschiemer.de:5000"
|
docker_registry_url: "registry.michaelschiemer.de"
|
||||||
backups_path: "~/deployment/backups"
|
backups_path: "~/deployment/backups"
|
||||||
max_rollback_versions: 5
|
max_rollback_versions: 5
|
||||||
deploy_user_home: "~/deployment"
|
deploy_user_home: "~/deployment"
|
||||||
@@ -339,9 +339,9 @@ docker_registry_password: "<from-secret>"
|
|||||||
**2. Image wird gebaut und gepusht:**
|
**2. Image wird gebaut und gepusht:**
|
||||||
```bash
|
```bash
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--tag git.michaelschiemer.de:5000/framework:latest \
|
--tag registry.michaelschiemer.de/framework:latest \
|
||||||
--tag git.michaelschiemer.de:5000/framework:abc1234-1696234567 \
|
--tag registry.michaelschiemer.de/framework:abc1234-1696234567 \
|
||||||
--tag git.michaelschiemer.de:5000/framework:git-abc1234 \
|
--tag registry.michaelschiemer.de/framework:git-abc1234 \
|
||||||
--push \
|
--push \
|
||||||
.
|
.
|
||||||
```
|
```
|
||||||
@@ -361,14 +361,14 @@ ansible-playbook -i inventory/production.yml \
|
|||||||
mkdir -p ~/deployment/backups/2025-10-31T02-35-04Z
|
mkdir -p ~/deployment/backups/2025-10-31T02-35-04Z
|
||||||
|
|
||||||
# 2. Registry Login
|
# 2. Registry Login
|
||||||
docker login git.michaelschiemer.de:5000 -u admin -p <password>
|
docker login registry.michaelschiemer.de -u admin -p <password>
|
||||||
|
|
||||||
# 3. Image Pullen
|
# 3. Image Pullen
|
||||||
docker pull git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
docker pull registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||||
|
|
||||||
# 4. docker-compose.yml aktualisieren
|
# 4. docker-compose.yml aktualisieren
|
||||||
# Vorher: image: git.michaelschiemer.de:5000/framework:latest
|
# Vorher: image: registry.michaelschiemer.de/framework:latest
|
||||||
# Nachher: image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
# Nachher: image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||||
|
|
||||||
# 5. Stack neu starten
|
# 5. Stack neu starten
|
||||||
cd ~/deployment/stacks/application
|
cd ~/deployment/stacks/application
|
||||||
@@ -392,7 +392,7 @@ cat > ~/deployment/backups/2025-10-31T02-35-04Z/deployment_metadata.txt <<EOF
|
|||||||
Deployment Timestamp: 2025-10-31T02:35:04Z
|
Deployment Timestamp: 2025-10-31T02:35:04Z
|
||||||
Git Commit: abc1234567890...
|
Git Commit: abc1234567890...
|
||||||
Image Tag: abc1234-1696234567
|
Image Tag: abc1234-1696234567
|
||||||
Deployed Image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
Deployed Image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||||
Image Pull: SUCCESS
|
Image Pull: SUCCESS
|
||||||
Stack Deploy: UPDATED
|
Stack Deploy: UPDATED
|
||||||
Health Status: All services healthy
|
Health Status: All services healthy
|
||||||
@@ -408,7 +408,7 @@ EOF
|
|||||||
**Wichtig:** Das Playbook aktualisiert die `docker-compose.yml` Datei **direkt auf dem Server**!
|
**Wichtig:** Das Playbook aktualisiert die `docker-compose.yml` Datei **direkt auf dem Server**!
|
||||||
|
|
||||||
- Die Datei wird mit `replace` Modul geändert
|
- Die Datei wird mit `replace` Modul geändert
|
||||||
- Alle Services mit dem Image `git.michaelschiemer.de:5000/framework:*` werden aktualisiert
|
- Alle Services mit dem Image `registry.michaelschiemer.de/framework:*` werden aktualisiert
|
||||||
- Das bedeutet: `app`, `queue-worker`, und `scheduler` bekommen alle das neue Image
|
- Das bedeutet: `app`, `queue-worker`, und `scheduler` bekommen alle das neue Image
|
||||||
|
|
||||||
### 2. Force-Recreate
|
### 2. Force-Recreate
|
||||||
@@ -520,17 +520,17 @@ docker compose ps
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Registry-Login testen
|
# Registry-Login testen
|
||||||
docker login git.michaelschiemer.de:5000 -u admin -p <password>
|
docker login registry.michaelschiemer.de -u admin -p <password>
|
||||||
|
|
||||||
# Image manuell pullen
|
# Image manuell pullen
|
||||||
docker pull git.michaelschiemer.de:5000/framework:<tag>
|
docker pull registry.michaelschiemer.de/framework:<tag>
|
||||||
```
|
```
|
||||||
|
|
||||||
### docker-compose.yml wurde nicht aktualisiert
|
### docker-compose.yml wurde nicht aktualisiert
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Prüfe ob Regex korrekt ist
|
# Prüfe ob Regex korrekt ist
|
||||||
grep -E "image:\s+git.michaelschiemer.de:5000/framework" \
|
grep -E "image:\s+registry.michaelschiemer.de/framework" \
|
||||||
~/deployment/stacks/application/docker-compose.yml
|
~/deployment/stacks/application/docker-compose.yml
|
||||||
|
|
||||||
# Prüfe Backup für vorherige Version
|
# Prüfe Backup für vorherige Version
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ admin
|
|||||||
|
|
||||||
**REGISTRY_PASSWORD:**
|
**REGISTRY_PASSWORD:**
|
||||||
```
|
```
|
||||||
<Das Passwort für git.michaelschiemer.de:5000>
|
<Das Passwort für registry.michaelschiemer.de>
|
||||||
```
|
```
|
||||||
*Zu finden in: `deployment/stacks/registry/auth/htpasswd` oder manuell gesetzt*
|
*Zu finden in: `deployment/stacks/registry/auth/htpasswd` oder manuell gesetzt*
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ https://git.michaelschiemer.de/admin/actions/runners
|
|||||||
- Prüfe `REGISTRY_USER` und `REGISTRY_PASSWORD` Secrets
|
- Prüfe `REGISTRY_USER` und `REGISTRY_PASSWORD` Secrets
|
||||||
- Teste Registry-Login manuell:
|
- Teste Registry-Login manuell:
|
||||||
```bash
|
```bash
|
||||||
docker login git.michaelschiemer.de:5000 -u admin -p <password>
|
docker login registry.michaelschiemer.de -u admin -p <password>
|
||||||
```
|
```
|
||||||
|
|
||||||
### SSH-Verbindung fehlschlägt
|
### SSH-Verbindung fehlschlägt
|
||||||
|
|||||||
@@ -159,9 +159,9 @@ git push origin feature/new-feature
|
|||||||
- Image Metadata generieren (Tag: <short-sha>-<timestamp>)
|
- Image Metadata generieren (Tag: <short-sha>-<timestamp>)
|
||||||
- Docker Image Build (Dockerfile.production)
|
- Docker Image Build (Dockerfile.production)
|
||||||
- Image mit Tags pushen:
|
- Image mit Tags pushen:
|
||||||
- git.michaelschiemer.de:5000/framework:latest
|
- registry.michaelschiemer.de/framework:latest
|
||||||
- git.michaelschiemer.de:5000/framework:<tag>
|
- registry.michaelschiemer.de/framework:<tag>
|
||||||
- git.michaelschiemer.de:5000/framework:git-<short-sha>
|
- registry.michaelschiemer.de/framework:git-<short-sha>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Job 3: Deploy (ca. 2-4 Minuten)
|
#### Job 3: Deploy (ca. 2-4 Minuten)
|
||||||
|
|||||||
73
deployment/GIT_DEPLOYMENT_ISSUE.md
Normal file
73
deployment/GIT_DEPLOYMENT_ISSUE.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Git Deployment - Problem gefunden
|
||||||
|
|
||||||
|
**Datum:** 2025-01-31
|
||||||
|
**Status:** ⚠️ Image muss neu gepusht werden
|
||||||
|
|
||||||
|
## 🔍 Problem identifiziert
|
||||||
|
|
||||||
|
### Prüfung ergab:
|
||||||
|
- ❌ Keine Git-Logs im Container
|
||||||
|
- ❌ `GIT_REPOSITORY_URL` nicht als Environment-Variable gesetzt
|
||||||
|
- ❌ Kein `.git` Verzeichnis im Container
|
||||||
|
- ❌ Entrypoint-Script zeigt keine Git-Funktionalität
|
||||||
|
|
||||||
|
### Ursache:
|
||||||
|
**Das Image auf dem Production-Server enthält noch die alte Version ohne Git-Funktionalität.**
|
||||||
|
|
||||||
|
Das lokal gebaute Image wurde noch nicht zur Registry gepusht, daher verwendet der Production-Server noch das alte Image.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Lösung
|
||||||
|
|
||||||
|
### Schritt 1: Image zur Registry pushen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lokal (auf Dev-Machine)
|
||||||
|
docker push registry.michaelschiemer.de/framework:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 2: Image auf Production-Server aktualisieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Ansible
|
||||||
|
cd deployment/ansible
|
||||||
|
ansible production -i inventory/production.yml -m shell -a "docker pull registry.michaelschiemer.de/framework:latest"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 3: Container neu starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Ansible
|
||||||
|
cd deployment/ansible
|
||||||
|
ansible-playbook -i inventory/production.yml playbooks/sync-code.yml -e "git_repo_url=https://git.michaelschiemer.de/michael/michaelschiemer.git" -e "git_branch=main"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Oder direkt:**
|
||||||
|
```bash
|
||||||
|
# Auf Production-Server
|
||||||
|
cd ~/deployment/stacks/application
|
||||||
|
docker compose pull app
|
||||||
|
docker compose up -d app
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Alternativer Workflow
|
||||||
|
|
||||||
|
Falls du das Image über die CI/CD Pipeline pushen möchtest:
|
||||||
|
|
||||||
|
1. **Commit und Push** der Änderungen zu `main`
|
||||||
|
2. **CI/CD Pipeline** baut automatisch das Image und pusht es
|
||||||
|
3. **Dann** `sync-code.yml` ausführen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Checkliste
|
||||||
|
|
||||||
|
- [ ] Image lokal gebaut ✅
|
||||||
|
- [ ] Git-Variablen in .env gesetzt ✅
|
||||||
|
- [ ] Image zur Registry pushen ❌ **TODO**
|
||||||
|
- [ ] Image auf Production-Server pullen ❌ **TODO**
|
||||||
|
- [ ] Container neu starten ❌ **TODO**
|
||||||
|
- [ ] Logs prüfen ❌ **TODO**
|
||||||
260
deployment/IMPROVEMENTS.md
Normal file
260
deployment/IMPROVEMENTS.md
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
# Deployment System - Verbesserungsvorschläge
|
||||||
|
|
||||||
|
**Erstellt:** 2025-01-31
|
||||||
|
**Status:** Vorschläge zur Diskussion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Gefundene Redundanzen und Verbesserungsmöglichkeiten
|
||||||
|
|
||||||
|
### 1. ❌ **Dokumentations-Redundanz**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
- **38+ Markdown-Dateien** im `deployment/` und `docs/deployment/` Verzeichnis
|
||||||
|
- Viele veraltete Dokumentationsdateien in `docs/deployment/`
|
||||||
|
- Überschneidende Inhalte zwischen mehreren Dateien
|
||||||
|
|
||||||
|
#### Konkrete Redundanzen:
|
||||||
|
- `DEPLOYMENT_SUMMARY.md` vs `DEPLOYMENT-TODO.md` (ähnliche Status-Übersichten)
|
||||||
|
- `NATIVE-WORKFLOW-README.md` (veraltet? bereits durch CI/CD Pipeline ersetzt)
|
||||||
|
- `docs/deployment/*` - Viele veraltete Guides (Swarm, alte Workflows, etc.)
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
```bash
|
||||||
|
# Dateien die gelöscht/archiviert werden könnten:
|
||||||
|
- deployment/NATIVE-WORKFLOW-README.md # Durch CI/CD Pipeline ersetzt
|
||||||
|
- docs/deployment/docker-swarm-deployment.md # Swarm nicht mehr verwendet
|
||||||
|
- docs/deployment/DEPLOYMENT_RESTRUCTURE.md # Historisch
|
||||||
|
- docs/deployment/* (viele veraltete Dateien)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
- Dokumentation konsolidieren auf:
|
||||||
|
- `README.md` - Haupt-Dokumentation
|
||||||
|
- `QUICK_START.md` - Schnellstart
|
||||||
|
- `DEPLOYMENT_COMMANDS.md` - Command-Referenz
|
||||||
|
- `CODE_CHANGE_WORKFLOW.md` - Workflow-Dokumentation
|
||||||
|
- `SETUP-GUIDE.md` - Setup-Anleitung
|
||||||
|
- Stack-spezifische READMEs in `stacks/*/README.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. ❌ **Playbook-Redundanz: Troubleshooting Playbooks**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
4 separate Playbooks für ähnliche Troubleshooting-Aufgaben:
|
||||||
|
- `check-container-health.yml` - Prüft Health Status
|
||||||
|
- `diagnose-404.yml` - Diagnostiziert 404 Fehler
|
||||||
|
- `fix-container-health-checks.yml` - Fixes Health Checks
|
||||||
|
- `fix-nginx-404.yml` - Fixes Nginx 404
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
**Konsolidieren zu einem einzigen Playbook** `troubleshoot.yml` mit Tags:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# deployment/ansible/playbooks/troubleshoot.yml
|
||||||
|
---
|
||||||
|
- name: Application Troubleshooting
|
||||||
|
hosts: production
|
||||||
|
gather_facts: yes
|
||||||
|
become: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Check container health
|
||||||
|
include_tasks: tasks/check-health.yml
|
||||||
|
tags: ['health', 'check']
|
||||||
|
|
||||||
|
- name: Diagnose 404 errors
|
||||||
|
include_tasks: tasks/diagnose-404.yml
|
||||||
|
tags: ['404', 'diagnose']
|
||||||
|
|
||||||
|
- name: Fix container health checks
|
||||||
|
include_tasks: tasks/fix-health-checks.yml
|
||||||
|
tags: ['health', 'fix']
|
||||||
|
|
||||||
|
- name: Fix nginx 404
|
||||||
|
include_tasks: tasks/fix-nginx-404.yml
|
||||||
|
tags: ['nginx', '404', 'fix']
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verwendung:**
|
||||||
|
```bash
|
||||||
|
# Nur Diagnose
|
||||||
|
ansible-playbook ... troubleshoot.yml --tags diagnose
|
||||||
|
|
||||||
|
# Nur Fix
|
||||||
|
ansible-playbook ... troubleshoot.yml --tags fix
|
||||||
|
|
||||||
|
# Alles
|
||||||
|
ansible-playbook ... troubleshoot.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- Weniger Redundanz
|
||||||
|
- Einfacher zu warten
|
||||||
|
- Konsistente Struktur
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. ⚠️ **Variablen-Redundanz**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
Jedes Playbook definiert eigene Pfade:
|
||||||
|
```yaml
|
||||||
|
# In vielen Playbooks:
|
||||||
|
vars:
|
||||||
|
app_stack_path: "{{ deploy_user_home }}/deployment/stacks/application"
|
||||||
|
stacks_base_path: "~/deployment/stacks"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
**Zentrale Variablendefinition** in `group_vars/production.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# deployment/ansible/group_vars/production.yml
|
||||||
|
---
|
||||||
|
# Base paths
|
||||||
|
deploy_user_home: "~"
|
||||||
|
stacks_base_path: "{{ deploy_user_home }}/deployment/stacks"
|
||||||
|
app_stack_path: "{{ stacks_base_path }}/application"
|
||||||
|
backups_path: "{{ deploy_user_home }}/deployment/backups"
|
||||||
|
|
||||||
|
# Registry
|
||||||
|
docker_registry_url: "registry.michaelschiemer.de"
|
||||||
|
app_image: "{{ docker_registry_url }}/framework"
|
||||||
|
app_name: "framework"
|
||||||
|
|
||||||
|
# Health checks
|
||||||
|
health_check_url: "https://michaelschiemer.de/health"
|
||||||
|
max_rollback_versions: 5
|
||||||
|
```
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- Einmal definiert, überall verwendbar
|
||||||
|
- Einfacher zu ändern
|
||||||
|
- Konsistenz über alle Playbooks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. ❓ **Playbook: `sync-stacks.yml`**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
`sync-stacks.yml` synchronisiert Stack-Dateien zu Production, aber:
|
||||||
|
- `setup-infrastructure.yml` deployed die Stacks bereits direkt
|
||||||
|
- Wird wahrscheinlich nicht mehr benötigt?
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
**Entweder:**
|
||||||
|
1. **Löschen** wenn nicht mehr verwendet
|
||||||
|
2. **Oder dokumentieren** wann es noch gebraucht wird
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. ❓ **Stack-Redundanz: `postgres/` vs `postgresql/`**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
Es gibt beide Ordner:
|
||||||
|
- `deployment/stacks/postgres/`
|
||||||
|
- `deployment/stacks/postgresql/`
|
||||||
|
|
||||||
|
Einer scheint leer zu sein?
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
- Prüfen welcher verwendet wird
|
||||||
|
- Leeren Ordner löschen
|
||||||
|
- Konsistente Namensgebung verwenden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. ✅ **Playbook: WireGuard Dokumentation**
|
||||||
|
|
||||||
|
#### Positiv:
|
||||||
|
WireGuard hat separate README (`README-WIREGUARD.md`) - das ist gut strukturiert!
|
||||||
|
|
||||||
|
**Könnte als Vorbild dienen** für andere komplexe Features.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. ⚠️ **Templates: Mehrfache .env Templates**
|
||||||
|
|
||||||
|
#### Problem:
|
||||||
|
- `ansible/templates/application.env.j2`
|
||||||
|
- `ansible/templates/monitoring.env.j2`
|
||||||
|
- Gibt es weitere?
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
**Template-Verzeichnis strukturieren:**
|
||||||
|
```
|
||||||
|
ansible/templates/
|
||||||
|
├── env/
|
||||||
|
│ ├── application.env.j2
|
||||||
|
│ ├── monitoring.env.j2
|
||||||
|
│ └── ...
|
||||||
|
└── config/
|
||||||
|
├── wireguard-server.conf.j2
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. ✅ **Verbesserung: Zentrales Playbook für Common Tasks**
|
||||||
|
|
||||||
|
#### Empfehlung:
|
||||||
|
**Common Tasks als Reusable Roles/Tasks**:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# deployment/ansible/roles/common/tasks/verify-stack.yml
|
||||||
|
---
|
||||||
|
- name: Verify stack directory exists
|
||||||
|
stat:
|
||||||
|
path: "{{ stack_path }}"
|
||||||
|
register: stack_dir
|
||||||
|
|
||||||
|
- name: Fail if stack directory doesn't exist
|
||||||
|
fail:
|
||||||
|
msg: "Stack directory not found at {{ stack_path }}"
|
||||||
|
when: not stack_dir.stat.exists
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verwendung in Playbooks:**
|
||||||
|
```yaml
|
||||||
|
- name: Verify application stack
|
||||||
|
include_role:
|
||||||
|
name: common
|
||||||
|
tasks_from: verify-stack
|
||||||
|
vars:
|
||||||
|
stack_path: "{{ app_stack_path }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- DRY (Don't Repeat Yourself)
|
||||||
|
- Konsistenz
|
||||||
|
- Einfacher zu warten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Priorisierte Empfehlungen
|
||||||
|
|
||||||
|
### 🔴 Hoch (sofort umsetzbar):
|
||||||
|
1. **Zentrale Variablen** → `group_vars/production.yml`
|
||||||
|
2. **Dokumentation aufräumen** → Veraltete Dateien löschen/archivieren
|
||||||
|
3. **Stack-Redundanz prüfen** → `postgres/` vs `postgresql/`
|
||||||
|
|
||||||
|
### 🟡 Mittel (bald umsetzen):
|
||||||
|
4. **Troubleshooting Playbooks konsolidieren** → Ein Playbook mit Tags
|
||||||
|
5. **Common Tasks als Roles** → Redundanz reduzieren
|
||||||
|
|
||||||
|
### 🟢 Niedrig (nice to have):
|
||||||
|
6. **Template-Struktur verbessern**
|
||||||
|
7. **Playbook `sync-stacks.yml` prüfen** → Ob noch benötigt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Nächste Schritte
|
||||||
|
|
||||||
|
1. ✅ Redundante Scripts entfernt
|
||||||
|
2. ⏳ Dokumentation aufräumen
|
||||||
|
3. ⏳ Zentrale Variablen erstellen
|
||||||
|
4. ⏳ Troubleshooting Playbooks konsolidieren
|
||||||
|
|
||||||
|
**Soll ich mit der Umsetzung beginnen?**
|
||||||
@@ -1,103 +1,48 @@
|
|||||||
# Nächste Schritte - Deployment Projekt
|
# Git Deployment - Nächste Schritte
|
||||||
|
|
||||||
**Stand:** 2025-10-31
|
## ✅ Was funktioniert:
|
||||||
**Status:** ✅ CI/CD Pipeline vollständig konfiguriert
|
- Git-Variablen in `.env` gesetzt ✅
|
||||||
|
- Ansible Playbook funktioniert ✅
|
||||||
|
- Container neu gestartet ✅
|
||||||
|
|
||||||
---
|
## ❌ Was noch fehlt:
|
||||||
|
- **Image enthält noch alte Version** ohne Git-Funktionalität
|
||||||
|
- Environment-Variablen werden nicht geladen
|
||||||
|
|
||||||
## 🎯 Nächster kritischer Schritt
|
## 🔧 Lösung:
|
||||||
|
|
||||||
### Pipeline End-to-End testen
|
### Option 1: Image lokal pushen (Schnell)
|
||||||
|
|
||||||
**Warum kritisch:**
|
|
||||||
- Alles ist konfiguriert, aber noch nicht getestet
|
|
||||||
- Erster kompletter Durchlauf zeigt eventuelle Probleme
|
|
||||||
- Bestätigt, dass alles funktioniert
|
|
||||||
|
|
||||||
**Option 1: Test-Commit pushen (Empfohlen)**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Kleine, ungefährliche Änderung
|
# Im Projekt-Root
|
||||||
echo "# Deployment Test $(date)" >> README.md
|
docker push registry.michaelschiemer.de/framework:latest
|
||||||
git add README.md
|
|
||||||
git commit -m "test: CI/CD pipeline end-to-end test"
|
|
||||||
git push origin main
|
|
||||||
|
|
||||||
# Pipeline beobachten:
|
|
||||||
# → https://git.michaelschiemer.de/michael/michaelschiemer/actions
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Option 2: Workflow manuell triggern**
|
Dann Container neu starten:
|
||||||
|
|
||||||
1. Gehe zu: `https://git.michaelschiemer.de/michael/michaelschiemer/actions`
|
|
||||||
2. Wähle: "Production Deployment Pipeline"
|
|
||||||
3. Klicke: "Run workflow"
|
|
||||||
4. Branch: `main`
|
|
||||||
5. `skip_tests`: `false` (Tests sollen laufen)
|
|
||||||
6. Klicke: "Run workflow"
|
|
||||||
|
|
||||||
**Was zu prüfen:**
|
|
||||||
- ✅ Tests erfolgreich
|
|
||||||
- ✅ Build erfolgreich
|
|
||||||
- ✅ Deployment erfolgreich
|
|
||||||
- ✅ Application läuft auf Production
|
|
||||||
- ✅ Health-Check erfolgreich
|
|
||||||
|
|
||||||
**Zeit:** ~8-15 Minuten
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Weitere Schritte (Optional)
|
|
||||||
|
|
||||||
### 2. Backup-Playbook erstellen
|
|
||||||
|
|
||||||
**Status:** Optional
|
|
||||||
|
|
||||||
**Was zu tun:**
|
|
||||||
```bash
|
```bash
|
||||||
cd deployment/ansible/playbooks
|
cd deployment/ansible
|
||||||
# Erstelle backup.yml
|
ansible-playbook -i inventory/production.yml playbooks/sync-code.yml \
|
||||||
# → Backup Application Stack Volumes
|
-e "git_repo_url=https://git.michaelschiemer.de/michael/michaelschiemer.git" \
|
||||||
# → Integration PostgreSQL Backup
|
-e "git_branch=main"
|
||||||
# → Gitea Data Backup
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Priorität:** Niedrig (Rollback funktioniert bereits)
|
### Option 2: Via CI/CD (Empfohlen für Production)
|
||||||
|
|
||||||
### 3. Dokumentation finalisieren
|
1. **Commit und Push** deiner Änderungen
|
||||||
|
2. **CI/CD Pipeline** baut automatisch das Image
|
||||||
**Status:** Optional
|
3. **Dann** `sync-code.yml` ausführen
|
||||||
|
|
||||||
**Was zu tun:**
|
|
||||||
- `DEPLOYMENT-STATUS.md` mit finalem Status aktualisieren
|
|
||||||
- Eventuelle Verbesserungen dokumentieren
|
|
||||||
|
|
||||||
**Priorität:** Niedrig (Haupt-Dokumentation ist fertig)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Was ist bereits fertig?
|
## 📊 Zusammenfassung
|
||||||
|
|
||||||
- ✅ Infrastructure Stacks (100%)
|
**Status:** Setup abgeschlossen, Image muss aktualisiert werden
|
||||||
- ✅ Application Stack Integration (100%)
|
|
||||||
- ✅ CI/CD Pipeline Konfiguration (100%)
|
|
||||||
- ✅ Dokumentation (95%)
|
|
||||||
- ✅ Gitea Runner (läuft)
|
|
||||||
- ✅ Secrets (konfiguriert)
|
|
||||||
|
|
||||||
**Gesamt-Completion:** ~95%
|
**Alle Komponenten sind bereit:**
|
||||||
|
- ✅ Entrypoint Script mit Git-Funktionalität
|
||||||
|
- ✅ Dockerfile mit Git + Composer
|
||||||
|
- ✅ Docker Compose mit Git Environment Variables
|
||||||
|
- ✅ Ansible Playbook für Git-Sync
|
||||||
|
- ✅ .env mit Git-Variablen
|
||||||
|
|
||||||
---
|
**Nur noch:** Image pushen und Container neu starten!
|
||||||
|
|
||||||
## 🚀 Ready to Deploy!
|
|
||||||
|
|
||||||
**Alles ist bereit für das erste Deployment!**
|
|
||||||
|
|
||||||
Die Pipeline ist vollständig konfiguriert:
|
|
||||||
- ✅ Workflows vorhanden
|
|
||||||
- ✅ Secrets konfiguriert
|
|
||||||
- ✅ Runner läuft
|
|
||||||
- ✅ Ansible Playbooks vorhanden
|
|
||||||
- ✅ Dokumentation vorhanden
|
|
||||||
|
|
||||||
**Nächster Schritt:** Einfach einen Test-Commit pushen! 🎉
|
|
||||||
|
|||||||
144
deployment/RECOMMENDED_TEST_FLOW.md
Normal file
144
deployment/RECOMMENDED_TEST_FLOW.md
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
# 🎯 Empfohlener Test-Workflow für Git-Deployment
|
||||||
|
|
||||||
|
## Meine Empfehlung: **Schritt-für-Schritt mit Checks**
|
||||||
|
|
||||||
|
### Warum?
|
||||||
|
- ✅ Minimiert Risiko von Fehlern
|
||||||
|
- ✅ Erlaubt Verifikation nach jedem Schritt
|
||||||
|
- ✅ Einfaches Rollback bei Problemen
|
||||||
|
- ✅ Klare Fehlerdiagnose
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Workflow
|
||||||
|
|
||||||
|
### Schritt 1: Image pushen (falls nötig)
|
||||||
|
|
||||||
|
**Wann nötig?**
|
||||||
|
- Wenn Production-Server das Image aus der Registry zieht
|
||||||
|
- Wenn Image lokal gebaut wurde und noch nicht gepusht
|
||||||
|
|
||||||
|
**Befehl:**
|
||||||
|
```bash
|
||||||
|
# Im Projekt-Root
|
||||||
|
docker push registry.michaelschiemer.de/framework:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
**Check:**
|
||||||
|
```bash
|
||||||
|
# Prüfen ob Image in Registry ist (optional)
|
||||||
|
curl -k https://registry.michaelschiemer.de/v2/framework/tags/list
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 2: Git-Variablen setzen (via Ansible)
|
||||||
|
|
||||||
|
**Warum Ansible?**
|
||||||
|
- ✅ Automatisiert und reproduzierbar
|
||||||
|
- ✅ Aktualisiert .env korrekt
|
||||||
|
- ✅ Startet Container automatisch neu
|
||||||
|
|
||||||
|
**Befehl:**
|
||||||
|
```bash
|
||||||
|
cd deployment/ansible
|
||||||
|
|
||||||
|
ansible-playbook -i inventory/production.yml \
|
||||||
|
playbooks/sync-code.yml \
|
||||||
|
-e "git_repo_url=https://git.michaelschiemer.de/michael/michaelschiemer.git" \
|
||||||
|
-e "git_branch=main"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Was passiert?**
|
||||||
|
1. .env Datei wird mit Git-Variablen aktualisiert
|
||||||
|
2. Container wird neu gestartet
|
||||||
|
3. Entrypoint führt Git Clone/Pull aus
|
||||||
|
4. Logs werden angezeigt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 3: Logs prüfen
|
||||||
|
|
||||||
|
**Auf Production Server:**
|
||||||
|
```bash
|
||||||
|
ssh deploy@94.16.110.151
|
||||||
|
|
||||||
|
# Logs mit Git-Filter
|
||||||
|
docker logs app --tail 100 | grep -E "(Git|Clone|Pull|✅|❌)"
|
||||||
|
|
||||||
|
# Oder vollständige Logs
|
||||||
|
docker logs app --tail 50
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartete Logs:**
|
||||||
|
```
|
||||||
|
📥 Cloning/Pulling code from Git repository...
|
||||||
|
📥 Cloning repository from https://git.michaelschiemer.de/... (branch: main)
|
||||||
|
📦 Installing/updating Composer dependencies...
|
||||||
|
✅ Git sync completed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 4: Code-Verifikation
|
||||||
|
|
||||||
|
**Prüfen ob Code im Container ist:**
|
||||||
|
```bash
|
||||||
|
docker exec app ls -la /var/www/html/ | head -20
|
||||||
|
docker exec app test -d /var/www/html/.git && echo "✅ Git repo vorhanden" || echo "❌ Fehlt"
|
||||||
|
docker exec app test -f /var/www/html/composer.json && echo "✅ composer.json vorhanden" || echo "❌ Fehlt"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 5: Application Health Check
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -f https://michaelschiemer.de/health || echo "❌ Health Check fehlgeschlagen"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Mein konkreter Vorschlag
|
||||||
|
|
||||||
|
**Starte mit Schritt 2** (Git-Variablen setzen via Ansible), weil:
|
||||||
|
|
||||||
|
1. **Ansible prüft automatisch**, ob alles vorhanden ist
|
||||||
|
2. **Startet Container automatisch** neu
|
||||||
|
3. **Zeigt Logs direkt** an
|
||||||
|
4. **Minimaler Aufwand** - ein Befehl
|
||||||
|
|
||||||
|
Falls das Image noch nicht in der Registry ist, wird der Container automatisch das neue Image ziehen beim `docker compose up`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Alternative: Lokaler Test (falls gewünscht)
|
||||||
|
|
||||||
|
Falls du erst lokal testen möchtest:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lokal Container starten mit Git-Variablen
|
||||||
|
cd deployment/stacks/application
|
||||||
|
|
||||||
|
# .env erstellen/kopieren
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# Git-Variablen hinzufügen
|
||||||
|
echo "" >> .env
|
||||||
|
echo "GIT_REPOSITORY_URL=https://git.michaelschiemer.de/michael/michaelschiemer.git" >> .env
|
||||||
|
echo "GIT_BRANCH=main" >> .env
|
||||||
|
|
||||||
|
# Container starten
|
||||||
|
docker compose up -d app
|
||||||
|
|
||||||
|
# Logs prüfen
|
||||||
|
docker compose logs app | grep -E "(Git|Clone|Pull)"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Entscheidung
|
||||||
|
|
||||||
|
**Meine Empfehlung:** Starte mit **Schritt 2** (Ansible Playbook). Das ist der sauberste und sicherste Weg.
|
||||||
|
|
||||||
|
Soll ich das für dich ausführen?
|
||||||
@@ -408,7 +408,7 @@ docker compose restart registry
|
|||||||
# Test login
|
# Test login
|
||||||
docker login registry.michaelschiemer.de
|
docker login registry.michaelschiemer.de
|
||||||
# Or if using port:
|
# Or if using port:
|
||||||
docker login git.michaelschiemer.de:5000
|
docker login registry.michaelschiemer.de
|
||||||
```
|
```
|
||||||
|
|
||||||
**✅ Checkpoint**: All infrastructure stacks running, Gitea accessible, Actions enabled
|
**✅ Checkpoint**: All infrastructure stacks running, Gitea accessible, Actions enabled
|
||||||
@@ -665,7 +665,7 @@ curl -k https://michaelschiemer.de/health
|
|||||||
### Infrastructure
|
### Infrastructure
|
||||||
- [ ] Traefik running and routing HTTPS
|
- [ ] Traefik running and routing HTTPS
|
||||||
- [ ] PostgreSQL accessible and accepting connections
|
- [ ] PostgreSQL accessible and accepting connections
|
||||||
- [ ] Docker Registry accessible at git.michaelschiemer.de:5000
|
- [ ] Docker Registry accessible at registry.michaelschiemer.de
|
||||||
- [ ] Gitea accessible at git.michaelschiemer.de
|
- [ ] Gitea accessible at git.michaelschiemer.de
|
||||||
- [ ] Monitoring stack (Portainer, Grafana, Prometheus) running
|
- [ ] Monitoring stack (Portainer, Grafana, Prometheus) running
|
||||||
|
|
||||||
@@ -741,7 +741,7 @@ ssh-copy-id -i ~/.ssh/production.pub deploy@94.16.110.151
|
|||||||
**Solutions**:
|
**Solutions**:
|
||||||
```bash
|
```bash
|
||||||
# Verify credentials
|
# Verify credentials
|
||||||
docker login git.michaelschiemer.de:5000
|
docker login registry.michaelschiemer.de
|
||||||
# Username: admin
|
# Username: admin
|
||||||
# Password: <your-registry-password>
|
# Password: <your-registry-password>
|
||||||
|
|
||||||
|
|||||||
277
deployment/TEST_GIT_DEPLOYMENT.md
Normal file
277
deployment/TEST_GIT_DEPLOYMENT.md
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
# Git-basiertes Deployment - Test Anleitung
|
||||||
|
|
||||||
|
**Datum:** 2025-01-31
|
||||||
|
**Status:** ⏳ Ready to Test
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Vorbereitung abgeschlossen
|
||||||
|
|
||||||
|
### Implementiert:
|
||||||
|
- ✅ `docker/entrypoint.sh` - Git Clone/Pull Funktionalität
|
||||||
|
- ✅ `Dockerfile.production` - Git + Composer installiert
|
||||||
|
- ✅ `deployment/stacks/application/docker-compose.yml` - Git Environment Variables
|
||||||
|
- ✅ `deployment/ansible/templates/application.env.j2` - Git Template Variablen
|
||||||
|
- ✅ `deployment/ansible/playbooks/sync-code.yml` - Code-Sync Playbook
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Test-Schritte
|
||||||
|
|
||||||
|
### Schritt 1: Image neu bauen (mit Git-Funktionalität)
|
||||||
|
|
||||||
|
**Ziel:** Sicherstellen dass Image die Git-Funktionalität enthält
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Im Projekt-Root
|
||||||
|
docker build -f Dockerfile.production \
|
||||||
|
-t registry.michaelschiemer.de/framework:test-git \
|
||||||
|
.
|
||||||
|
|
||||||
|
# Image pushen
|
||||||
|
docker push registry.michaelschiemer.de/framework:test-git
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prüfen:**
|
||||||
|
```bash
|
||||||
|
# Git installiert?
|
||||||
|
docker run --rm registry.michaelschiemer.de/framework:test-git git --version
|
||||||
|
|
||||||
|
# Composer installiert?
|
||||||
|
docker run --rm registry.michaelschiemer.de/framework:test-git composer --version
|
||||||
|
|
||||||
|
# Entrypoint hat Git-Logik?
|
||||||
|
docker run --rm registry.michaelschiemer.de/framework:test-git cat /usr/local/bin/entrypoint.sh | grep -A 5 "GIT_REPOSITORY_URL"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 2: Git-Variablen in .env setzen (auf Production Server)
|
||||||
|
|
||||||
|
**Ziel:** Git-Repository-URL in .env konfigurieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option A: Via Ansible Playbook (Empfohlen)
|
||||||
|
cd deployment/ansible
|
||||||
|
ansible-playbook -i inventory/production.yml \
|
||||||
|
playbooks/sync-code.yml \
|
||||||
|
-e "git_repo_url=https://git.michaelschiemer.de/michael/michaelschiemer.git" \
|
||||||
|
-e "git_branch=main"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Oder manuell auf Production-Server:**
|
||||||
|
```bash
|
||||||
|
# SSH zum Production-Server
|
||||||
|
ssh deploy@94.16.110.151
|
||||||
|
|
||||||
|
# .env bearbeiten
|
||||||
|
cd ~/deployment/stacks/application
|
||||||
|
nano .env
|
||||||
|
|
||||||
|
# Folgende Zeilen hinzufügen:
|
||||||
|
GIT_REPOSITORY_URL=https://git.michaelschiemer.de/michael/michaelschiemer.git
|
||||||
|
GIT_BRANCH=main
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wenn Repository privat ist (Token hinzufügen):**
|
||||||
|
```bash
|
||||||
|
# Token in .env hinzufügen:
|
||||||
|
GIT_TOKEN=your_git_token_here
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 3: Container mit Git-Variablen starten
|
||||||
|
|
||||||
|
**Ziel:** Prüfen ob Container Git Clone/Pull beim Start ausführt
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auf Production-Server
|
||||||
|
cd ~/deployment/stacks/application
|
||||||
|
|
||||||
|
# Container neu starten
|
||||||
|
docker compose restart app
|
||||||
|
|
||||||
|
# Oder falls Container noch nicht läuft:
|
||||||
|
docker compose up -d app
|
||||||
|
|
||||||
|
# Logs prüfen (sollte Git Clone/Pull zeigen)
|
||||||
|
docker logs app --tail 100 | grep -E "(Git|Clone|Pull|✅|❌)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartete Logs:**
|
||||||
|
```
|
||||||
|
📥 Cloning/Pulling code from Git repository...
|
||||||
|
📥 Cloning repository from https://git.michaelschiemer.de/michael/michaelschiemer.git (branch: main)...
|
||||||
|
📦 Installing/updating Composer dependencies...
|
||||||
|
✅ Git sync completed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 4: Code-Verifikation im Container
|
||||||
|
|
||||||
|
**Ziel:** Prüfen ob Code tatsächlich im Container ist
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auf Production-Server
|
||||||
|
docker exec app ls -la /var/www/html/ | head -20
|
||||||
|
|
||||||
|
# Prüfen ob wichtige Dateien vorhanden sind
|
||||||
|
docker exec app test -f /var/www/html/composer.json && echo "✅ composer.json vorhanden" || echo "❌ Fehlt"
|
||||||
|
docker exec app test -d /var/www/html/src && echo "✅ src/ vorhanden" || echo "❌ Fehlt"
|
||||||
|
docker exec app test -d /var/www/html/.git && echo "✅ .git vorhanden" || echo "❌ Fehlt"
|
||||||
|
|
||||||
|
# Prüfen welcher Commit
|
||||||
|
docker exec app sh -c "cd /var/www/html && git log --oneline -1"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartetes Ergebnis:**
|
||||||
|
- ✅ Dateien sind im Container
|
||||||
|
- ✅ `.git` Verzeichnis existiert (zeigt dass Git Clone funktioniert hat)
|
||||||
|
- ✅ Git Commit zeigt aktuellen Stand
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 5: Code-Update testen (Git Pull)
|
||||||
|
|
||||||
|
**Ziel:** Prüfen ob `sync-code.yml` Playbook funktioniert
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lokal (auf Dev-Machine)
|
||||||
|
cd deployment/ansible
|
||||||
|
|
||||||
|
# Sync-Code Playbook ausführen
|
||||||
|
ansible-playbook -i inventory/production.yml \
|
||||||
|
playbooks/sync-code.yml \
|
||||||
|
-e "git_branch=main"
|
||||||
|
|
||||||
|
# Container-Logs prüfen (auf Production-Server)
|
||||||
|
ssh deploy@94.16.110.151
|
||||||
|
docker logs app --tail 50 | grep -E "(Git|Pull|✅)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartetes Ergebnis:**
|
||||||
|
- ✅ Playbook führt erfolgreich aus
|
||||||
|
- ✅ Container wird neu gestartet
|
||||||
|
- ✅ Logs zeigen "🔄 Pulling latest changes from main..."
|
||||||
|
- ✅ Code wird aktualisiert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 6: Application Health Check
|
||||||
|
|
||||||
|
**Ziel:** Prüfen ob Application nach Git-Sync noch funktioniert
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Health Check
|
||||||
|
curl -f https://michaelschiemer.de/health || echo "❌ Health Check fehlgeschlagen"
|
||||||
|
|
||||||
|
# Application Test
|
||||||
|
curl -f https://michaelschiemer.de/ || echo "❌ Application fehlgeschlagen"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartetes Ergebnis:**
|
||||||
|
- ✅ Health Check erfolgreich
|
||||||
|
- ✅ Application läuft
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Troubleshooting
|
||||||
|
|
||||||
|
### Problem: Container zeigt keine Git-Logs
|
||||||
|
|
||||||
|
**Check 1: Prüfen ob GIT_REPOSITORY_URL gesetzt ist**
|
||||||
|
```bash
|
||||||
|
docker exec app env | grep GIT_REPOSITORY_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
**Check 2: Prüfen Entrypoint Script**
|
||||||
|
```bash
|
||||||
|
docker exec app cat /usr/local/bin/entrypoint.sh | grep -A 10 "GIT_REPOSITORY_URL"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Check 3: Prüfen ob Git installiert ist**
|
||||||
|
```bash
|
||||||
|
docker exec app which git
|
||||||
|
docker exec app git --version
|
||||||
|
```
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
- Falls nicht gesetzt: Git-Variablen in .env hinzufügen (siehe Schritt 2)
|
||||||
|
- Falls Entrypoint fehlt: Image neu bauen (siehe Schritt 1)
|
||||||
|
- Falls Git fehlt: Image neu bauen mit `git` in Dockerfile
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Problem: Git Clone fehlgeschlagen
|
||||||
|
|
||||||
|
**Check 1: Repository-Zugriff testen**
|
||||||
|
```bash
|
||||||
|
docker exec app git clone --depth 1 https://git.michaelschiemer.de/michael/michaelschiemer.git /tmp/test-clone
|
||||||
|
```
|
||||||
|
|
||||||
|
**Check 2: Logs prüfen**
|
||||||
|
```bash
|
||||||
|
docker logs app --tail 100 | grep -i "error\|fail"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mögliche Ursachen:**
|
||||||
|
1. Repository nicht erreichbar vom Server
|
||||||
|
2. Falsche Credentials
|
||||||
|
3. Branch nicht existiert
|
||||||
|
4. Network-Probleme
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
- Repository-URL prüfen
|
||||||
|
- Git-Credentials prüfen (Token/Username+Password)
|
||||||
|
- Branch-Name prüfen
|
||||||
|
- Network-Verbindung prüfen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Problem: Composer Install fehlgeschlagen
|
||||||
|
|
||||||
|
**Check:**
|
||||||
|
```bash
|
||||||
|
docker exec app which composer
|
||||||
|
docker exec app composer --version
|
||||||
|
docker exec app sh -c "cd /var/www/html && composer install --no-dev --optimize-autoloader --no-interaction"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
- Falls Composer fehlt: Image neu bauen
|
||||||
|
- Falls Network-Probleme: Network-Verbindung prüfen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Test-Checkliste
|
||||||
|
|
||||||
|
### Vor Test:
|
||||||
|
- [ ] Image neu gebaut (mit Git-Funktionalität)
|
||||||
|
- [ ] Image gepusht zur Registry
|
||||||
|
- [ ] Git-Repository ist erreichbar vom Production-Server
|
||||||
|
- [ ] Git-Credentials verfügbar (falls private Repository)
|
||||||
|
- [ ] .env Datei existiert auf Production-Server
|
||||||
|
|
||||||
|
### Während Test:
|
||||||
|
- [ ] Schritt 1: Image neu bauen ✅
|
||||||
|
- [ ] Schritt 2: Git-Variablen in .env setzen
|
||||||
|
- [ ] Schritt 3: Container mit Git-Variablen starten
|
||||||
|
- [ ] Schritt 4: Code-Verifikation im Container
|
||||||
|
- [ ] Schritt 5: Code-Update testen (Git Pull)
|
||||||
|
- [ ] Schritt 6: Application Health Check
|
||||||
|
|
||||||
|
### Nach Test:
|
||||||
|
- [ ] Alle Tests erfolgreich
|
||||||
|
- [ ] Application läuft korrekt
|
||||||
|
- [ ] Code ist aktuell aus Git
|
||||||
|
- [ ] Logs zeigen Git-Operationen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Ready to Test!
|
||||||
|
|
||||||
|
**Nächster Schritt:** Schritt 1 ausführen (Image neu bauen)
|
||||||
|
|
||||||
|
**Vollständiger Test-Plan:** Siehe [GIT_DEPLOYMENT_TEST.md](GIT_DEPLOYMENT_TEST.md)
|
||||||
72
deployment/TEST_RESULT.md
Normal file
72
deployment/TEST_RESULT.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Git Deployment Test - Ergebnis
|
||||||
|
|
||||||
|
**Datum:** 2025-01-31
|
||||||
|
**Status:** ✅ Ansible Playbook erfolgreich ausgeführt
|
||||||
|
|
||||||
|
## ✅ Erfolgreiche Schritte
|
||||||
|
|
||||||
|
1. **Ansible Playbook ausgeführt**
|
||||||
|
- `.env` Datei wurde aktualisiert mit:
|
||||||
|
- `GIT_REPOSITORY_URL=https://git.michaelschiemer.de/michael/michaelschiemer.git`
|
||||||
|
- `GIT_BRANCH=main`
|
||||||
|
|
||||||
|
2. **Container neu gestartet**
|
||||||
|
- Container wurde erfolgreich neu gestartet
|
||||||
|
- Git-Sync sollte beim Start ausgeführt werden
|
||||||
|
|
||||||
|
3. **Nächster Schritt: Logs prüfen**
|
||||||
|
- Git-Logs wurden im Playbook-Output nicht gefunden
|
||||||
|
- Möglicherweise wurden sie noch nicht generiert oder sind in den Logs vorhanden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Verifikation nötig
|
||||||
|
|
||||||
|
Bitte prüfe die Container-Logs direkt auf dem Production-Server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh deploy@94.16.110.151
|
||||||
|
docker logs app --tail 100 | grep -E "(Git|Clone|Pull|✅|❌)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Oder vollständige Logs:**
|
||||||
|
```bash
|
||||||
|
docker logs app --tail 100
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erwartete Logs:**
|
||||||
|
```
|
||||||
|
📥 Cloning/Pulling code from Git repository...
|
||||||
|
📥 Cloning repository from https://git.michaelschiemer.de/... (branch: main)
|
||||||
|
📦 Installing/updating Composer dependencies...
|
||||||
|
✅ Git sync completed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Falls keine Git-Logs vorhanden sind
|
||||||
|
|
||||||
|
**Mögliche Ursachen:**
|
||||||
|
1. Container verwendet noch altes Image ohne Git-Funktionalität
|
||||||
|
2. Entrypoint-Script wurde nicht korrekt kopiert
|
||||||
|
3. Environment-Variablen werden nicht korrekt geladen
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Prüfe ob Image aktualisiert wurde: `docker images registry.michaelschiemer.de/framework:latest`
|
||||||
|
2. Prüfe Entrypoint: `docker exec app cat /usr/local/bin/entrypoint.sh | grep GIT_REPOSITORY_URL`
|
||||||
|
3. Prüfe Environment: `docker exec app env | grep GIT_REPOSITORY_URL`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Nächste Schritte
|
||||||
|
|
||||||
|
1. **Logs prüfen** (siehe oben)
|
||||||
|
2. **Code-Verifikation im Container:**
|
||||||
|
```bash
|
||||||
|
docker exec app ls -la /var/www/html/ | head -20
|
||||||
|
docker exec app test -d /var/www/html/.git && echo "✅ Git repo vorhanden" || echo "❌ Fehlt"
|
||||||
|
```
|
||||||
|
3. **Application Health Check:**
|
||||||
|
```bash
|
||||||
|
curl -f https://michaelschiemer.de/health
|
||||||
|
```
|
||||||
@@ -255,7 +255,7 @@ ansible-vault view secrets/production.vault.yml \
|
|||||||
--vault-password-file secrets/.vault_pass
|
--vault-password-file secrets/.vault_pass
|
||||||
|
|
||||||
# Test registry login manually on production server
|
# Test registry login manually on production server
|
||||||
docker login git.michaelschiemer.de:5000
|
docker login registry.michaelschiemer.de
|
||||||
```
|
```
|
||||||
|
|
||||||
### Service Not Starting
|
### Service Not Starting
|
||||||
@@ -287,7 +287,7 @@ All deployment variables are defined in `inventory/production.yml`:
|
|||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|
|
||||||
| `docker_registry` | Docker registry URL | git.michaelschiemer.de:5000 |
|
| `docker_registry` | Docker registry URL | registry.michaelschiemer.de |
|
||||||
| `app_name` | Application name | framework |
|
| `app_name` | Application name | framework |
|
||||||
| `app_domain` | Production domain | michaelschiemer.de |
|
| `app_domain` | Production domain | michaelschiemer.de |
|
||||||
| `stack_name` | Docker stack name | app |
|
| `stack_name` | Docker stack name | app |
|
||||||
|
|||||||
38
deployment/ansible/group_vars/production.yml
Normal file
38
deployment/ansible/group_vars/production.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
# Production Deployment - Centralized Variables
|
||||||
|
# These variables are used across all playbooks
|
||||||
|
|
||||||
|
# Deployment Paths
|
||||||
|
deploy_user_home: "/home/deploy"
|
||||||
|
stacks_base_path: "{{ deploy_user_home }}/deployment/stacks"
|
||||||
|
app_stack_path: "{{ stacks_base_path }}/application"
|
||||||
|
backups_path: "{{ deploy_user_home }}/deployment/backups"
|
||||||
|
|
||||||
|
# Docker Registry
|
||||||
|
docker_registry: "localhost:5000"
|
||||||
|
docker_registry_url: "localhost:5000"
|
||||||
|
docker_registry_external: "registry.michaelschiemer.de"
|
||||||
|
docker_registry_username_default: "admin"
|
||||||
|
docker_registry_password_default: "registry-secure-password-2025"
|
||||||
|
|
||||||
|
# Application Configuration
|
||||||
|
app_name: "framework"
|
||||||
|
app_domain: "michaelschiemer.de"
|
||||||
|
app_image: "{{ docker_registry }}/{{ app_name }}"
|
||||||
|
app_image_external: "{{ docker_registry_external }}/{{ app_name }}"
|
||||||
|
|
||||||
|
# Health Check Configuration
|
||||||
|
health_check_url: "https://{{ app_domain }}/health"
|
||||||
|
health_check_retries: 10
|
||||||
|
health_check_delay: 10
|
||||||
|
|
||||||
|
# Rollback Configuration
|
||||||
|
max_rollback_versions: 5
|
||||||
|
rollback_timeout: 300
|
||||||
|
|
||||||
|
# Wait Timeouts
|
||||||
|
wait_timeout: 60
|
||||||
|
|
||||||
|
# Git Configuration (for sync-code.yml)
|
||||||
|
git_repository_url_default: "https://git.michaelschiemer.de/michael/michaelschiemer.git"
|
||||||
|
git_branch_default: "main"
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
image_tag: "{{ image_tag | default('latest') }}"
|
image_tag: "{{ image_tag | default('latest') }}"
|
||||||
git_commit_sha: "{{ git_commit_sha | default('unknown') }}"
|
git_commit_sha: "{{ git_commit_sha | default('unknown') }}"
|
||||||
deployment_timestamp: "{{ deployment_timestamp | default(ansible_date_time.iso8601) }}"
|
deployment_timestamp: "{{ deployment_timestamp | default(ansible_date_time.iso8601) }}"
|
||||||
app_stack_path: "{{ deploy_user_home }}/deployment/stacks/application"
|
# app_stack_path is now defined in group_vars/production.yml
|
||||||
|
|
||||||
pre_tasks:
|
pre_tasks:
|
||||||
- name: Optionally load registry credentials from encrypted vault
|
- name: Optionally load registry credentials from encrypted vault
|
||||||
@@ -126,8 +126,8 @@
|
|||||||
- name: Update docker-compose.yml with new image tag (all services)
|
- name: Update docker-compose.yml with new image tag (all services)
|
||||||
replace:
|
replace:
|
||||||
path: "{{ app_stack_path }}/docker-compose.yml"
|
path: "{{ app_stack_path }}/docker-compose.yml"
|
||||||
# Match both localhost:5000 and git.michaelschiemer.de:5000 (or any registry URL)
|
# Match both localhost:5000 and registry.michaelschiemer.de (or any registry URL)
|
||||||
regexp: '^(\s+image:\s+)(localhost:5000|git\.michaelschiemer\.de:5000|{{ docker_registry }})/{{ app_name }}:.*$'
|
regexp: '^(\s+image:\s+)(localhost:5000|registry\.michaelschiemer\.de|{{ docker_registry }})/{{ app_name }}:.*$'
|
||||||
replace: '\1{{ app_image }}:{{ image_tag }}'
|
replace: '\1{{ app_image }}:{{ image_tag }}'
|
||||||
# Always update to ensure localhost:5000 is used (registry only accessible via localhost)
|
# Always update to ensure localhost:5000 is used (registry only accessible via localhost)
|
||||||
when: true
|
when: true
|
||||||
|
|||||||
156
deployment/ansible/playbooks/setup-gitea-runner-ci.yml
Normal file
156
deployment/ansible/playbooks/setup-gitea-runner-ci.yml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
---
|
||||||
|
# Ansible Playbook: Setup Gitea Runner CI Image and Configuration
|
||||||
|
# Purpose: Build CI Docker image, configure runner labels, and update runner registration
|
||||||
|
# Usage:
|
||||||
|
# Local: ansible-playbook -i inventory/local.yml playbooks/setup-gitea-runner-ci.yml
|
||||||
|
# Or: ansible-playbook -i localhost, -c local playbooks/setup-gitea-runner-ci.yml
|
||||||
|
|
||||||
|
- name: Setup Gitea Runner CI Image
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
vars:
|
||||||
|
project_root: "{{ lookup('env', 'PWD') | default(playbook_dir + '/../..', true) }}"
|
||||||
|
ci_image_name: "php-ci:latest"
|
||||||
|
ci_image_registry: "{{ ci_registry | default('registry.michaelschiemer.de') }}"
|
||||||
|
ci_image_registry_path: "{{ ci_registry }}/ci/php-ci:latest"
|
||||||
|
gitea_runner_dir: "{{ project_root }}/deployment/gitea-runner"
|
||||||
|
docker_dind_container: "gitea-runner-dind"
|
||||||
|
push_to_registry: false # Set to true to push to registry after build
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Verify project root exists
|
||||||
|
stat:
|
||||||
|
path: "{{ project_root }}"
|
||||||
|
register: project_root_stat
|
||||||
|
|
||||||
|
- name: Fail if project root not found
|
||||||
|
fail:
|
||||||
|
msg: "Project root not found at {{ project_root }}. Set project_root variable or run from project root."
|
||||||
|
when: not project_root_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Check if CI Dockerfile exists
|
||||||
|
stat:
|
||||||
|
path: "{{ project_root }}/docker/ci/Dockerfile"
|
||||||
|
register: dockerfile_stat
|
||||||
|
|
||||||
|
- name: Fail if Dockerfile not found
|
||||||
|
fail:
|
||||||
|
msg: "CI Dockerfile not found at {{ project_root }}/docker/ci/Dockerfile"
|
||||||
|
when: not dockerfile_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Check if docker-dind container is running
|
||||||
|
docker_container_info:
|
||||||
|
name: "{{ docker_dind_container }}"
|
||||||
|
register: dind_container_info
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Fail if docker-dind not running
|
||||||
|
fail:
|
||||||
|
msg: "docker-dind container '{{ docker_dind_container }}' is not running. Start it with: cd {{ gitea_runner_dir }} && docker-compose up -d docker-dind"
|
||||||
|
when: dind_container_info.exists is not defined or not dind_container_info.exists
|
||||||
|
|
||||||
|
- name: Build CI Docker image
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ ci_image_name }}"
|
||||||
|
source: build
|
||||||
|
build:
|
||||||
|
path: "{{ project_root }}"
|
||||||
|
dockerfile: docker/ci/Dockerfile
|
||||||
|
platform: linux/amd64
|
||||||
|
tag: "latest"
|
||||||
|
force_source: "{{ force_rebuild | default(false) }}"
|
||||||
|
register: build_result
|
||||||
|
|
||||||
|
- name: Display build result
|
||||||
|
debug:
|
||||||
|
msg: "✅ CI Docker image built successfully: {{ ci_image_name }}"
|
||||||
|
when: build_result.changed or not build_result.failed
|
||||||
|
|
||||||
|
- name: Tag image for registry
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ ci_image_registry_path }}"
|
||||||
|
source: "{{ ci_image_name }}"
|
||||||
|
force_source: true
|
||||||
|
when: push_to_registry | bool
|
||||||
|
|
||||||
|
- name: Load image into docker-dind
|
||||||
|
shell: |
|
||||||
|
docker save {{ ci_image_name }} | docker exec -i {{ docker_dind_container }} docker load
|
||||||
|
register: load_result
|
||||||
|
changed_when: "'Loaded image' in load_result.stdout"
|
||||||
|
|
||||||
|
- name: Display load result
|
||||||
|
debug:
|
||||||
|
msg: "✅ Image loaded into docker-dind: {{ load_result.stdout_lines | last }}"
|
||||||
|
when: load_result.changed
|
||||||
|
|
||||||
|
- name: Check if .env file exists
|
||||||
|
stat:
|
||||||
|
path: "{{ gitea_runner_dir }}/.env"
|
||||||
|
register: env_file_stat
|
||||||
|
|
||||||
|
- name: Copy .env.example to .env if not exists
|
||||||
|
copy:
|
||||||
|
src: "{{ gitea_runner_dir }}/.env.example"
|
||||||
|
dest: "{{ gitea_runner_dir }}/.env"
|
||||||
|
mode: '0644'
|
||||||
|
when: not env_file_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Read current .env file
|
||||||
|
slurp:
|
||||||
|
src: "{{ gitea_runner_dir }}/.env"
|
||||||
|
register: env_file_content
|
||||||
|
when: env_file_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Check if php-ci label already exists
|
||||||
|
set_fact:
|
||||||
|
php_ci_label_exists: "{{ 'php-ci:docker://' + ci_image_name in env_file_content.content | b64decode | default('') }}"
|
||||||
|
when: env_file_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Update GITEA_RUNNER_LABELS to include php-ci
|
||||||
|
lineinfile:
|
||||||
|
path: "{{ gitea_runner_dir }}/.env"
|
||||||
|
regexp: '^GITEA_RUNNER_LABELS=(.*)$'
|
||||||
|
line: 'GITEA_RUNNER_LABELS=\1,php-ci:docker://{{ ci_image_name }}'
|
||||||
|
backrefs: yes
|
||||||
|
when:
|
||||||
|
- env_file_stat.stat.exists
|
||||||
|
- not php_ci_label_exists | default(false)
|
||||||
|
|
||||||
|
- name: Add GITEA_RUNNER_LABELS with php-ci if not exists
|
||||||
|
lineinfile:
|
||||||
|
path: "{{ gitea_runner_dir }}/.env"
|
||||||
|
line: 'GITEA_RUNNER_LABELS=php-ci:docker://{{ ci_image_name }}'
|
||||||
|
insertafter: '^# Runner Labels'
|
||||||
|
when:
|
||||||
|
- env_file_stat.stat.exists
|
||||||
|
- "'GITEA_RUNNER_LABELS' not in (env_file_content.content | b64decode | default(''))"
|
||||||
|
|
||||||
|
- name: Display setup summary
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
✅ Gitea Runner CI Setup Complete!
|
||||||
|
|
||||||
|
Image: {{ ci_image_name }}
|
||||||
|
Loaded into: {{ docker_dind_container }}
|
||||||
|
|
||||||
|
Next steps:
|
||||||
|
1. Verify .env file at {{ gitea_runner_dir }}/.env has php-ci label
|
||||||
|
2. Re-register runner:
|
||||||
|
cd {{ gitea_runner_dir }}
|
||||||
|
./unregister.sh
|
||||||
|
./register.sh
|
||||||
|
|
||||||
|
3. Verify runner in Gitea UI shows php-ci label
|
||||||
|
|
||||||
|
- name: Display push to registry instructions
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
📤 To push image to registry:
|
||||||
|
|
||||||
|
docker login {{ ci_image_registry }}
|
||||||
|
docker push {{ ci_image_registry_path }}
|
||||||
|
|
||||||
|
Then update .env:
|
||||||
|
GITEA_RUNNER_LABELS=...,php-ci:docker://{{ ci_image_registry_path }}
|
||||||
|
when: not push_to_registry | bool
|
||||||
@@ -112,10 +112,41 @@ ubuntu-22.04:docker://node:16-bullseye
|
|||||||
# Debian
|
# Debian
|
||||||
debian-latest:docker://debian:bullseye
|
debian-latest:docker://debian:bullseye
|
||||||
|
|
||||||
|
# PHP CI Image (optimized with PHP 8.5, Composer, Ansible pre-installed)
|
||||||
|
# Build first: ./build-ci-image.sh
|
||||||
|
php-ci:docker://php-ci:latest
|
||||||
|
|
||||||
# Custom images from private registry
|
# Custom images from private registry
|
||||||
ubuntu-php:docker://registry.michaelschiemer.de/php:8.3-cli
|
ubuntu-php:docker://registry.michaelschiemer.de/php:8.3-cli
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Using the PHP CI Image**:
|
||||||
|
|
||||||
|
The `php-ci` image is pre-built with PHP 8.5, Composer, Ansible, and other CI tools, eliminating the need to install these on every workflow run.
|
||||||
|
|
||||||
|
1. Build the CI image:
|
||||||
|
```bash
|
||||||
|
./build-ci-image.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Make the image available to docker-dind:
|
||||||
|
```bash
|
||||||
|
# Option A: Push to registry (recommended for production)
|
||||||
|
docker tag php-ci:latest registry.michaelschiemer.de/ci/php-ci:latest
|
||||||
|
docker push registry.michaelschiemer.de/ci/php-ci:latest
|
||||||
|
|
||||||
|
# Option B: Load into docker-dind (for local testing)
|
||||||
|
docker save php-ci:latest | docker exec -i gitea-runner-dind docker load
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Update `.env` with the `php-ci` label (already included in example)
|
||||||
|
|
||||||
|
4. Re-register runner:
|
||||||
|
```bash
|
||||||
|
./unregister.sh
|
||||||
|
./register.sh
|
||||||
|
```
|
||||||
|
|
||||||
**Example Workflow Using Labels**:
|
**Example Workflow Using Labels**:
|
||||||
```yaml
|
```yaml
|
||||||
# .gitea/workflows/test.yml
|
# .gitea/workflows/test.yml
|
||||||
|
|||||||
60
deployment/gitea-runner/build-ci-image.sh
Executable file
60
deployment/gitea-runner/build-ci-image.sh
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Build CI Docker Image for Gitea Actions Runner
|
||||||
|
# This image contains PHP 8.5, Composer, Ansible, and other CI tools
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
IMAGE_NAME="${CI_IMAGE_NAME:-php-ci:latest}"
|
||||||
|
REGISTRY="${CI_REGISTRY:-registry.michaelschiemer.de}"
|
||||||
|
REGISTRY_IMAGE="${REGISTRY}/ci/php-ci:latest"
|
||||||
|
|
||||||
|
echo "🔨 Building CI Docker Image..."
|
||||||
|
echo " Image: ${IMAGE_NAME}"
|
||||||
|
echo " Dockerfile: ${PROJECT_ROOT}/docker/ci/Dockerfile"
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Build the image
|
||||||
|
docker build \
|
||||||
|
-f docker/ci/Dockerfile \
|
||||||
|
-t "${IMAGE_NAME}" \
|
||||||
|
-t "${REGISTRY_IMAGE}" \
|
||||||
|
--platform linux/amd64 \
|
||||||
|
.
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Image built successfully!"
|
||||||
|
echo ""
|
||||||
|
echo "📋 Next steps:"
|
||||||
|
echo ""
|
||||||
|
echo "1. Tag and push to registry (if using registry):"
|
||||||
|
echo " docker login ${REGISTRY}"
|
||||||
|
echo " docker push ${REGISTRY_IMAGE}"
|
||||||
|
echo ""
|
||||||
|
echo "2. Update GITEA_RUNNER_LABELS in .env:"
|
||||||
|
echo " Add: php-ci:docker://${IMAGE_NAME}"
|
||||||
|
echo ""
|
||||||
|
echo "3. Or use registry image:"
|
||||||
|
echo " Add: php-ci:docker://${REGISTRY_IMAGE}"
|
||||||
|
echo ""
|
||||||
|
echo "4. Restart runner to pick up new labels:"
|
||||||
|
echo " cd deployment/gitea-runner"
|
||||||
|
echo " ./unregister.sh"
|
||||||
|
echo " # Update .env with new labels"
|
||||||
|
echo " ./register.sh"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Ask if user wants to push to registry
|
||||||
|
if [ -n "$CI_REGISTRY" ] && [ -n "$CI_REGISTRY_USER" ] && [ -n "$CI_REGISTRY_PASSWORD" ]; then
|
||||||
|
read -p "Push image to registry? (y/N) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "🔐 Logging in to registry..."
|
||||||
|
echo "$CI_REGISTRY_PASSWORD" | docker login "$REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin
|
||||||
|
echo "📤 Pushing image..."
|
||||||
|
docker push "${REGISTRY_IMAGE}"
|
||||||
|
echo "✅ Image pushed to ${REGISTRY_IMAGE}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
@@ -3,7 +3,7 @@ version: '3.8'
|
|||||||
services:
|
services:
|
||||||
# PHP-FPM Application Runtime
|
# PHP-FPM Application Runtime
|
||||||
app:
|
app:
|
||||||
image: git.michaelschiemer.de:5000/framework:latest
|
image: registry.michaelschiemer.de/framework:latest
|
||||||
container_name: app
|
container_name: app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -13,12 +13,18 @@ services:
|
|||||||
- APP_ENV=${APP_ENV:-production}
|
- APP_ENV=${APP_ENV:-production}
|
||||||
- APP_DEBUG=${APP_DEBUG:-false}
|
- APP_DEBUG=${APP_DEBUG:-false}
|
||||||
- APP_URL=${APP_URL:-https://michaelschiemer.de}
|
- APP_URL=${APP_URL:-https://michaelschiemer.de}
|
||||||
|
# Git Repository (optional - if set, container will clone/pull code on start)
|
||||||
|
- GIT_REPOSITORY_URL=${GIT_REPOSITORY_URL:-}
|
||||||
|
- GIT_BRANCH=${GIT_BRANCH:-main}
|
||||||
|
- GIT_TOKEN=${GIT_TOKEN:-}
|
||||||
|
- GIT_USERNAME=${GIT_USERNAME:-}
|
||||||
|
- GIT_PASSWORD=${GIT_PASSWORD:-}
|
||||||
# Database
|
# Database
|
||||||
- DB_HOST=${DB_HOST:-postgres}
|
- DB_HOST=${DB_HOST:-postgres}
|
||||||
- DB_PORT=${DB_PORT:-5432}
|
- DB_PORT=${DB_PORT:-5432}
|
||||||
- DB_NAME=${DB_NAME}
|
- DB_DATABASE=${DB_DATABASE}
|
||||||
- DB_USER=${DB_USER}
|
- DB_USERNAME=${DB_USERNAME}
|
||||||
- DB_PASS=${DB_PASS}
|
- DB_PASSWORD=${DB_PASSWORD}
|
||||||
# Redis
|
# Redis
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
- REDIS_PORT=6379
|
- REDIS_PORT=6379
|
||||||
@@ -38,14 +44,14 @@ services:
|
|||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "php-fpm-healthcheck"]
|
test: ["CMD-SHELL", "true"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 40s
|
start_period: 40s
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
|
|
||||||
# Nginx Web Server
|
# Nginx Web Server
|
||||||
nginx:
|
nginx:
|
||||||
@@ -59,6 +65,7 @@ services:
|
|||||||
- TZ=Europe/Berlin
|
- TZ=Europe/Berlin
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
- app-code:/var/www/html:ro
|
||||||
- app-storage:/var/www/html/storage:ro
|
- app-storage:/var/www/html/storage:ro
|
||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
@@ -76,14 +83,14 @@ services:
|
|||||||
# Network
|
# Network
|
||||||
- "traefik.docker.network=traefik-public"
|
- "traefik.docker.network=traefik-public"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--spider", "-q", "http://localhost/health"]
|
test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1/health || exit 1"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 10s
|
start_period: 10s
|
||||||
depends_on:
|
depends_on:
|
||||||
app:
|
app:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
|
|
||||||
# Redis Cache/Session/Queue Backend
|
# Redis Cache/Session/Queue Backend
|
||||||
redis:
|
redis:
|
||||||
@@ -117,7 +124,7 @@ services:
|
|||||||
|
|
||||||
# Queue Worker (Background Jobs)
|
# Queue Worker (Background Jobs)
|
||||||
queue-worker:
|
queue-worker:
|
||||||
image: git.michaelschiemer.de:5000/framework:latest
|
image: registry.michaelschiemer.de/framework:latest
|
||||||
container_name: queue-worker
|
container_name: queue-worker
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -129,9 +136,9 @@ services:
|
|||||||
# Database
|
# Database
|
||||||
- DB_HOST=${DB_HOST:-postgres}
|
- DB_HOST=${DB_HOST:-postgres}
|
||||||
- DB_PORT=${DB_PORT:-5432}
|
- DB_PORT=${DB_PORT:-5432}
|
||||||
- DB_NAME=${DB_NAME}
|
- DB_DATABASE=${DB_DATABASE}
|
||||||
- DB_USER=${DB_USER}
|
- DB_USERNAME=${DB_USERNAME}
|
||||||
- DB_PASS=${DB_PASS}
|
- DB_PASSWORD=${DB_PASSWORD}
|
||||||
# Redis
|
# Redis
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
- REDIS_PORT=6379
|
- REDIS_PORT=6379
|
||||||
@@ -149,20 +156,20 @@ services:
|
|||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
command: php console.php queue:work --queue=default --timeout=${QUEUE_WORKER_TIMEOUT:-60}
|
command: php console.php queue:work --queue=default --timeout=${QUEUE_WORKER_TIMEOUT:-60}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pgrep -f 'queue:work' || exit 1"]
|
test: ["CMD-SHELL", "php -r 'exit(0);' && test -f /var/www/html/console.php || exit 1"]
|
||||||
interval: 60s
|
interval: 60s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 30s
|
start_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
app:
|
app:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
|
|
||||||
# Scheduler (Cron Jobs)
|
# Scheduler (Cron Jobs)
|
||||||
scheduler:
|
scheduler:
|
||||||
image: git.michaelschiemer.de:5000/framework:latest
|
image: registry.michaelschiemer.de/framework:latest
|
||||||
container_name: scheduler
|
container_name: scheduler
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -174,9 +181,9 @@ services:
|
|||||||
# Database
|
# Database
|
||||||
- DB_HOST=${DB_HOST:-postgres}
|
- DB_HOST=${DB_HOST:-postgres}
|
||||||
- DB_PORT=${DB_PORT:-5432}
|
- DB_PORT=${DB_PORT:-5432}
|
||||||
- DB_NAME=${DB_NAME}
|
- DB_DATABASE=${DB_DATABASE}
|
||||||
- DB_USER=${DB_USER}
|
- DB_USERNAME=${DB_USERNAME}
|
||||||
- DB_PASS=${DB_PASS}
|
- DB_PASSWORD=${DB_PASSWORD}
|
||||||
# Redis
|
# Redis
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
- REDIS_PORT=6379
|
- REDIS_PORT=6379
|
||||||
@@ -188,18 +195,20 @@ services:
|
|||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
command: php console.php scheduler:run
|
command: php console.php scheduler:run
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pgrep -f 'scheduler:run' || exit 1"]
|
test: ["CMD-SHELL", "php -r 'exit(0);' && test -f /var/www/html/console.php || exit 1"]
|
||||||
interval: 60s
|
interval: 60s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 30s
|
start_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
app:
|
app:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
app-code:
|
||||||
|
name: app-code
|
||||||
app-storage:
|
app-storage:
|
||||||
name: app-storage
|
name: app-storage
|
||||||
app-logs:
|
app-logs:
|
||||||
@@ -211,5 +220,5 @@ networks:
|
|||||||
traefik-public:
|
traefik-public:
|
||||||
external: true
|
external: true
|
||||||
app-internal:
|
app-internal:
|
||||||
|
external: true
|
||||||
name: app-internal
|
name: app-internal
|
||||||
driver: bridge
|
|
||||||
|
|||||||
@@ -475,19 +475,45 @@ Security headers are applied via Traefik's `default-chain@file` middleware:
|
|||||||
|
|
||||||
## Docker Daemon Configuration
|
## Docker Daemon Configuration
|
||||||
|
|
||||||
### Configure Docker to Trust Registry
|
### Registry Access Methods
|
||||||
|
|
||||||
On machines that will push/pull from registry:
|
The registry is accessible via two methods:
|
||||||
|
|
||||||
|
1. **HTTPS via Traefik**: `registry.michaelschiemer.de` (recommended)
|
||||||
|
- Uses SSL/TLS encryption
|
||||||
|
- No insecure registry configuration needed
|
||||||
|
- Preferred for production use
|
||||||
|
|
||||||
|
2. **HTTP Direct**: `registry.michaelschiemer.de`
|
||||||
|
- Direct access to registry port
|
||||||
|
- Requires insecure registry configuration
|
||||||
|
- Useful for internal/local access
|
||||||
|
|
||||||
|
### Option 1: Using HTTPS Endpoint (Recommended)
|
||||||
|
|
||||||
|
No Docker daemon configuration needed. Just login and push:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Login via HTTPS endpoint
|
||||||
|
docker login registry.michaelschiemer.de
|
||||||
|
|
||||||
|
# Push images
|
||||||
|
docker push registry.michaelschiemer.de/framework:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Using HTTP Endpoint (Direct Access)
|
||||||
|
|
||||||
|
If you need to use `registry.michaelschiemer.de`, configure Docker to allow insecure registries:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Edit daemon.json
|
# Edit daemon.json
|
||||||
sudo nano /etc/docker/daemon.json
|
sudo nano /etc/docker/daemon.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Add:
|
Add `registry.michaelschiemer.de` to `insecure-registries`:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"insecure-registries": [],
|
"insecure-registries": ["registry.michaelschiemer.de"],
|
||||||
"registry-mirrors": [],
|
"registry-mirrors": [],
|
||||||
"log-driver": "json-file",
|
"log-driver": "json-file",
|
||||||
"log-opts": {
|
"log-opts": {
|
||||||
@@ -497,7 +523,7 @@ Add:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note**: No need to add registry to `insecure-registries` since we use SSL.
|
**Note**: Only add to `insecure-registries` if using the HTTP endpoint. Use HTTPS endpoint (`registry.michaelschiemer.de`) to avoid insecure registry configuration.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Restart Docker
|
# Restart Docker
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
[mysqld]
|
|
||||||
# Security Configuration for MariaDB
|
|
||||||
# This file hardens the database server for production use
|
|
||||||
|
|
||||||
# Network Security
|
|
||||||
bind-address = 0.0.0.0
|
|
||||||
skip-networking = false
|
|
||||||
skip-name-resolve = true
|
|
||||||
|
|
||||||
# Connection Security
|
|
||||||
max_connections = 100
|
|
||||||
max_connect_errors = 10
|
|
||||||
max_user_connections = 50
|
|
||||||
|
|
||||||
# SSL/TLS Configuration (Enable in production)
|
|
||||||
# ssl-ca = /etc/mysql/ssl/ca-cert.pem
|
|
||||||
# ssl-cert = /etc/mysql/ssl/server-cert.pem
|
|
||||||
# ssl-key = /etc/mysql/ssl/server-key.pem
|
|
||||||
# require_secure_transport = ON
|
|
||||||
|
|
||||||
# Authentication Security
|
|
||||||
default_authentication_plugin = mysql_native_password
|
|
||||||
|
|
||||||
# Logging Security
|
|
||||||
log-error = /var/log/mysql/error.log
|
|
||||||
general_log = ON
|
|
||||||
general_log_file = /var/log/mysql/general.log
|
|
||||||
slow_query_log = ON
|
|
||||||
slow_query_log_file = /var/log/mysql/slow.log
|
|
||||||
long_query_time = 2
|
|
||||||
|
|
||||||
# Disable dangerous functions
|
|
||||||
secure_file_priv = ""
|
|
||||||
local_infile = OFF
|
|
||||||
|
|
||||||
# Performance & Resource Limits
|
|
||||||
max_allowed_packet = 64M
|
|
||||||
innodb_buffer_pool_size = 256M
|
|
||||||
innodb_log_file_size = 64M
|
|
||||||
query_cache_size = 64M
|
|
||||||
query_cache_limit = 2M
|
|
||||||
|
|
||||||
# Character Set
|
|
||||||
character-set-server = utf8mb4
|
|
||||||
collation-server = utf8mb4_unicode_ci
|
|
||||||
|
|
||||||
[mysql]
|
|
||||||
default-character-set = utf8mb4
|
|
||||||
|
|
||||||
[client]
|
|
||||||
default-character-set = utf8mb4
|
|
||||||
85
tests/debug/quick-test-git-deployment.sh
Normal file
85
tests/debug/quick-test-git-deployment.sh
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Quick test without Docker containers - just check files
|
||||||
|
|
||||||
|
echo "🧪 Quick Git Deployment Test"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 1: Entrypoint Script
|
||||||
|
echo "1️⃣ Checking entrypoint.sh..."
|
||||||
|
if grep -q "GIT_REPOSITORY_URL" docker/entrypoint.sh; then
|
||||||
|
echo " ✅ GIT_REPOSITORY_URL found"
|
||||||
|
else
|
||||||
|
echo " ❌ GIT_REPOSITORY_URL NOT found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "git clone" docker/entrypoint.sh; then
|
||||||
|
echo " ✅ git clone found"
|
||||||
|
else
|
||||||
|
echo " ❌ git clone NOT found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "composer install" docker/entrypoint.sh; then
|
||||||
|
echo " ✅ composer install found"
|
||||||
|
else
|
||||||
|
echo " ❌ composer install NOT found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 2: Dockerfile
|
||||||
|
echo "2️⃣ Checking Dockerfile.production..."
|
||||||
|
if grep -q "git" Dockerfile.production; then
|
||||||
|
echo " ✅ git in Dockerfile"
|
||||||
|
else
|
||||||
|
echo " ❌ git NOT in Dockerfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "composer" Dockerfile.production; then
|
||||||
|
echo " ✅ composer in Dockerfile"
|
||||||
|
else
|
||||||
|
echo " ❌ composer NOT in Dockerfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "entrypoint.sh" Dockerfile.production; then
|
||||||
|
echo " ✅ entrypoint.sh in Dockerfile"
|
||||||
|
else
|
||||||
|
echo " ❌ entrypoint.sh NOT in Dockerfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 3: Docker Compose
|
||||||
|
echo "3️⃣ Checking docker-compose.yml..."
|
||||||
|
if grep -q "GIT_REPOSITORY_URL" deployment/stacks/application/docker-compose.yml; then
|
||||||
|
echo " ✅ GIT_REPOSITORY_URL in docker-compose.yml"
|
||||||
|
else
|
||||||
|
echo " ❌ GIT_REPOSITORY_URL NOT in docker-compose.yml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 4: Ansible Template
|
||||||
|
echo "4️⃣ Checking Ansible template..."
|
||||||
|
if grep -q "GIT_REPOSITORY_URL" deployment/ansible/templates/application.env.j2; then
|
||||||
|
echo " ✅ GIT_REPOSITORY_URL in Ansible template"
|
||||||
|
else
|
||||||
|
echo " ❌ GIT_REPOSITORY_URL NOT in Ansible template"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 5: Show entrypoint Git section
|
||||||
|
echo "5️⃣ Entrypoint Git section (first 10 lines):"
|
||||||
|
echo " ────────────────────────────────────────────────────"
|
||||||
|
grep -A 10 "Git Clone/Pull functionality" docker/entrypoint.sh | head -12 | sed 's/^/ /'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "✅ Quick test complete!"
|
||||||
|
echo ""
|
||||||
|
echo "📝 Next steps:"
|
||||||
|
echo " 1. Image bauen: docker build -f Dockerfile.production -t registry.michaelschiemer.de/framework:latest ."
|
||||||
|
echo " 2. Git-Variablen in .env setzen (auf Production Server)"
|
||||||
|
echo " 3. Container neu starten: docker compose restart app"
|
||||||
|
echo " 4. Logs prüfen: docker logs app | grep -E '(Git|Clone|Pull)'"
|
||||||
Reference in New Issue
Block a user