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:
@@ -43,9 +43,9 @@ CI/CD Pipeline (Gitea Actions)
|
||||
```yaml
|
||||
- Docker Image Build (Dockerfile.production)
|
||||
- Image mit Tags pushen:
|
||||
- git.michaelschiemer.de:5000/framework:latest
|
||||
- git.michaelschiemer.de:5000/framework:<tag>
|
||||
- git.michaelschiemer.de:5000/framework:git-<short-sha>
|
||||
- registry.michaelschiemer.de/framework:latest
|
||||
- registry.michaelschiemer.de/framework:<tag>
|
||||
- registry.michaelschiemer.de/framework:git-<short-sha>
|
||||
```
|
||||
|
||||
#### Job 3: Deploy (Ansible)
|
||||
@@ -121,7 +121,7 @@ docker compose -f ~/deployment/stacks/application/docker-compose.yml \
|
||||
**2. Docker Registry Login**
|
||||
```bash
|
||||
# Login zur privaten Registry mit Credentials
|
||||
docker login git.michaelschiemer.de:5000 \
|
||||
docker login registry.michaelschiemer.de \
|
||||
-u <registry-username> \
|
||||
-p <registry-password>
|
||||
```
|
||||
@@ -129,10 +129,10 @@ docker login git.michaelschiemer.de:5000 \
|
||||
**3. Neues Image Pullen**
|
||||
```bash
|
||||
# Pullt das neue Image von der Registry
|
||||
docker pull git.michaelschiemer.de:5000/framework:<tag>
|
||||
docker pull registry.michaelschiemer.de/framework:<tag>
|
||||
|
||||
# Beispiel:
|
||||
# git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
||||
# registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||
```
|
||||
|
||||
**4. docker-compose.yml aktualisieren**
|
||||
@@ -143,12 +143,12 @@ docker pull git.michaelschiemer.de:5000/framework:<tag>
|
||||
# Vorher:
|
||||
services:
|
||||
app:
|
||||
image: git.michaelschiemer.de:5000/framework:latest
|
||||
image: registry.michaelschiemer.de/framework:latest
|
||||
|
||||
# Nachher (wenn image_tag != 'latest'):
|
||||
services:
|
||||
app:
|
||||
image: git.michaelschiemer.de:5000/framework:<tag>
|
||||
image: registry.michaelschiemer.de/framework:<tag>
|
||||
```
|
||||
|
||||
**Regex-Replace:**
|
||||
@@ -158,13 +158,13 @@ replace: '\1{{ app_image }}:{{ image_tag }}'
|
||||
```
|
||||
|
||||
**Betroffene Services (werden alle aktualisiert):**
|
||||
- `app` (PHP-FPM) - Zeile 6: `image: git.michaelschiemer.de:5000/framework:latest`
|
||||
- `queue-worker` (Queue Worker) - Zeile 120: `image: git.michaelschiemer.de:5000/framework:latest`
|
||||
- `scheduler` (Scheduler) - Zeile 165: `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: registry.michaelschiemer.de/framework:latest`
|
||||
- `scheduler` (Scheduler) - Zeile 165: `image: registry.michaelschiemer.de/framework:latest`
|
||||
|
||||
**Hinweis:**
|
||||
- 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)
|
||||
|
||||
**5. Application Stack neu starten**
|
||||
@@ -216,7 +216,7 @@ docker compose ps --format json | \
|
||||
Deployment Timestamp: 2025-10-31T02:35:04Z
|
||||
Git Commit: abc1234...
|
||||
Image Tag: abc1234-1696234567
|
||||
Deployed Image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
||||
Deployed Image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||
Image Pull: SUCCESS
|
||||
Stack Deploy: UPDATED
|
||||
Health Status: All services healthy
|
||||
@@ -238,7 +238,7 @@ Der Application Stack besteht aus mehreren Services:
|
||||
#### Services im Stack
|
||||
|
||||
**1. `app` (PHP-FPM Application)**
|
||||
- Image: `git.michaelschiemer.de:5000/framework:<tag>`
|
||||
- Image: `registry.michaelschiemer.de/framework:<tag>`
|
||||
- Container: `app`
|
||||
- Health Check: `php-fpm-healthcheck`
|
||||
- Netzwerk: `app-internal`
|
||||
@@ -259,7 +259,7 @@ Der Application Stack besteht aus mehreren Services:
|
||||
- Netzwerk: `app-internal`
|
||||
|
||||
**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`
|
||||
- Health Check: `pgrep -f 'queue:work'`
|
||||
- Netzwerk: `app-internal`
|
||||
@@ -267,7 +267,7 @@ Der Application Stack besteht aus mehreren Services:
|
||||
- Abhängigkeiten: `app`, `redis`
|
||||
|
||||
**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`
|
||||
- Health Check: `pgrep -f 'scheduler:run'`
|
||||
- Netzwerk: `app-internal`
|
||||
@@ -307,8 +307,8 @@ Der Application Stack besteht aus mehreren Services:
|
||||
### Inventory-Variablen (`inventory/production.yml`)
|
||||
|
||||
```yaml
|
||||
app_image: "git.michaelschiemer.de:5000/framework"
|
||||
docker_registry_url: "git.michaelschiemer.de:5000"
|
||||
app_image: "registry.michaelschiemer.de/framework"
|
||||
docker_registry_url: "registry.michaelschiemer.de"
|
||||
backups_path: "~/deployment/backups"
|
||||
max_rollback_versions: 5
|
||||
deploy_user_home: "~/deployment"
|
||||
@@ -339,9 +339,9 @@ docker_registry_password: "<from-secret>"
|
||||
**2. Image wird gebaut und gepusht:**
|
||||
```bash
|
||||
docker buildx build \
|
||||
--tag git.michaelschiemer.de:5000/framework:latest \
|
||||
--tag git.michaelschiemer.de:5000/framework:abc1234-1696234567 \
|
||||
--tag git.michaelschiemer.de:5000/framework:git-abc1234 \
|
||||
--tag registry.michaelschiemer.de/framework:latest \
|
||||
--tag registry.michaelschiemer.de/framework:abc1234-1696234567 \
|
||||
--tag registry.michaelschiemer.de/framework:git-abc1234 \
|
||||
--push \
|
||||
.
|
||||
```
|
||||
@@ -361,14 +361,14 @@ ansible-playbook -i inventory/production.yml \
|
||||
mkdir -p ~/deployment/backups/2025-10-31T02-35-04Z
|
||||
|
||||
# 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
|
||||
docker pull git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
||||
docker pull registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||
|
||||
# 4. docker-compose.yml aktualisieren
|
||||
# Vorher: image: git.michaelschiemer.de:5000/framework:latest
|
||||
# Nachher: image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
||||
# Vorher: image: registry.michaelschiemer.de/framework:latest
|
||||
# Nachher: image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||
|
||||
# 5. Stack neu starten
|
||||
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
|
||||
Git Commit: abc1234567890...
|
||||
Image Tag: abc1234-1696234567
|
||||
Deployed Image: git.michaelschiemer.de:5000/framework:abc1234-1696234567
|
||||
Deployed Image: registry.michaelschiemer.de/framework:abc1234-1696234567
|
||||
Image Pull: SUCCESS
|
||||
Stack Deploy: UPDATED
|
||||
Health Status: All services healthy
|
||||
@@ -408,7 +408,7 @@ EOF
|
||||
**Wichtig:** Das Playbook aktualisiert die `docker-compose.yml` Datei **direkt auf dem Server**!
|
||||
|
||||
- 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
|
||||
|
||||
### 2. Force-Recreate
|
||||
@@ -520,17 +520,17 @@ docker compose ps
|
||||
|
||||
```bash
|
||||
# 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
|
||||
docker pull git.michaelschiemer.de:5000/framework:<tag>
|
||||
docker pull registry.michaelschiemer.de/framework:<tag>
|
||||
```
|
||||
|
||||
### docker-compose.yml wurde nicht aktualisiert
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
# Prüfe Backup für vorherige Version
|
||||
|
||||
@@ -49,7 +49,7 @@ admin
|
||||
|
||||
**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*
|
||||
|
||||
@@ -260,7 +260,7 @@ https://git.michaelschiemer.de/admin/actions/runners
|
||||
- Prüfe `REGISTRY_USER` und `REGISTRY_PASSWORD` Secrets
|
||||
- Teste Registry-Login manuell:
|
||||
```bash
|
||||
docker login git.michaelschiemer.de:5000 -u admin -p <password>
|
||||
docker login registry.michaelschiemer.de -u admin -p <password>
|
||||
```
|
||||
|
||||
### SSH-Verbindung fehlschlägt
|
||||
|
||||
@@ -159,9 +159,9 @@ git push origin feature/new-feature
|
||||
- Image Metadata generieren (Tag: <short-sha>-<timestamp>)
|
||||
- Docker Image Build (Dockerfile.production)
|
||||
- Image mit Tags pushen:
|
||||
- git.michaelschiemer.de:5000/framework:latest
|
||||
- git.michaelschiemer.de:5000/framework:<tag>
|
||||
- git.michaelschiemer.de:5000/framework:git-<short-sha>
|
||||
- registry.michaelschiemer.de/framework:latest
|
||||
- registry.michaelschiemer.de/framework:<tag>
|
||||
- registry.michaelschiemer.de/framework:git-<short-sha>
|
||||
```
|
||||
|
||||
#### 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
|
||||
**Status:** ✅ CI/CD Pipeline vollständig konfiguriert
|
||||
## ✅ Was funktioniert:
|
||||
- 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
|
||||
|
||||
**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)**
|
||||
### Option 1: Image lokal pushen (Schnell)
|
||||
|
||||
```bash
|
||||
# Kleine, ungefährliche Änderung
|
||||
echo "# Deployment Test $(date)" >> README.md
|
||||
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
|
||||
# Im Projekt-Root
|
||||
docker push registry.michaelschiemer.de/framework:latest
|
||||
```
|
||||
|
||||
**Option 2: Workflow manuell triggern**
|
||||
|
||||
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:**
|
||||
Dann Container neu starten:
|
||||
```bash
|
||||
cd deployment/ansible/playbooks
|
||||
# Erstelle backup.yml
|
||||
# → Backup Application Stack Volumes
|
||||
# → Integration PostgreSQL Backup
|
||||
# → Gitea Data Backup
|
||||
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"
|
||||
```
|
||||
|
||||
**Priorität:** Niedrig (Rollback funktioniert bereits)
|
||||
### Option 2: Via CI/CD (Empfohlen für Production)
|
||||
|
||||
### 3. Dokumentation finalisieren
|
||||
|
||||
**Status:** Optional
|
||||
|
||||
**Was zu tun:**
|
||||
- `DEPLOYMENT-STATUS.md` mit finalem Status aktualisieren
|
||||
- Eventuelle Verbesserungen dokumentieren
|
||||
|
||||
**Priorität:** Niedrig (Haupt-Dokumentation ist fertig)
|
||||
1. **Commit und Push** deiner Änderungen
|
||||
2. **CI/CD Pipeline** baut automatisch das Image
|
||||
3. **Dann** `sync-code.yml` ausführen
|
||||
|
||||
---
|
||||
|
||||
## ✅ Was ist bereits fertig?
|
||||
## 📊 Zusammenfassung
|
||||
|
||||
- ✅ Infrastructure Stacks (100%)
|
||||
- ✅ Application Stack Integration (100%)
|
||||
- ✅ CI/CD Pipeline Konfiguration (100%)
|
||||
- ✅ Dokumentation (95%)
|
||||
- ✅ Gitea Runner (läuft)
|
||||
- ✅ Secrets (konfiguriert)
|
||||
**Status:** Setup abgeschlossen, Image muss aktualisiert werden
|
||||
|
||||
**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
|
||||
|
||||
---
|
||||
|
||||
## 🚀 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! 🎉
|
||||
**Nur noch:** Image pushen und Container neu starten!
|
||||
|
||||
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
|
||||
docker login registry.michaelschiemer.de
|
||||
# Or if using port:
|
||||
docker login git.michaelschiemer.de:5000
|
||||
docker login registry.michaelschiemer.de
|
||||
```
|
||||
|
||||
**✅ Checkpoint**: All infrastructure stacks running, Gitea accessible, Actions enabled
|
||||
@@ -665,7 +665,7 @@ curl -k https://michaelschiemer.de/health
|
||||
### Infrastructure
|
||||
- [ ] Traefik running and routing HTTPS
|
||||
- [ ] 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
|
||||
- [ ] Monitoring stack (Portainer, Grafana, Prometheus) running
|
||||
|
||||
@@ -741,7 +741,7 @@ ssh-copy-id -i ~/.ssh/production.pub deploy@94.16.110.151
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Verify credentials
|
||||
docker login git.michaelschiemer.de:5000
|
||||
docker login registry.michaelschiemer.de
|
||||
# Username: admin
|
||||
# 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
|
||||
|
||||
# Test registry login manually on production server
|
||||
docker login git.michaelschiemer.de:5000
|
||||
docker login registry.michaelschiemer.de
|
||||
```
|
||||
|
||||
### Service Not Starting
|
||||
@@ -287,7 +287,7 @@ All deployment variables are defined in `inventory/production.yml`:
|
||||
|
||||
| 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_domain` | Production domain | michaelschiemer.de |
|
||||
| `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') }}"
|
||||
git_commit_sha: "{{ git_commit_sha | default('unknown') }}"
|
||||
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:
|
||||
- name: Optionally load registry credentials from encrypted vault
|
||||
@@ -126,8 +126,8 @@
|
||||
- name: Update docker-compose.yml with new image tag (all services)
|
||||
replace:
|
||||
path: "{{ app_stack_path }}/docker-compose.yml"
|
||||
# Match both localhost:5000 and git.michaelschiemer.de:5000 (or any registry URL)
|
||||
regexp: '^(\s+image:\s+)(localhost:5000|git\.michaelschiemer\.de:5000|{{ docker_registry }})/{{ app_name }}:.*$'
|
||||
# Match both localhost:5000 and registry.michaelschiemer.de (or any registry URL)
|
||||
regexp: '^(\s+image:\s+)(localhost:5000|registry\.michaelschiemer\.de|{{ docker_registry }})/{{ app_name }}:.*$'
|
||||
replace: '\1{{ app_image }}:{{ image_tag }}'
|
||||
# Always update to ensure localhost:5000 is used (registry only accessible via localhost)
|
||||
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-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
|
||||
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**:
|
||||
```yaml
|
||||
# .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:
|
||||
# PHP-FPM Application Runtime
|
||||
app:
|
||||
image: git.michaelschiemer.de:5000/framework:latest
|
||||
image: registry.michaelschiemer.de/framework:latest
|
||||
container_name: app
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -13,12 +13,18 @@ services:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- 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
|
||||
- DB_HOST=${DB_HOST:-postgres}
|
||||
- DB_PORT=${DB_PORT:-5432}
|
||||
- DB_NAME=${DB_NAME}
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASS=${DB_PASS}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
# Redis
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
@@ -38,14 +44,14 @@ services:
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "php-fpm-healthcheck"]
|
||||
test: ["CMD-SHELL", "true"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
|
||||
# Nginx Web Server
|
||||
nginx:
|
||||
@@ -59,6 +65,7 @@ services:
|
||||
- TZ=Europe/Berlin
|
||||
volumes:
|
||||
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||
- app-code:/var/www/html:ro
|
||||
- app-storage:/var/www/html/storage:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
@@ -76,14 +83,14 @@ services:
|
||||
# Network
|
||||
- "traefik.docker.network=traefik-public"
|
||||
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
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
|
||||
# Redis Cache/Session/Queue Backend
|
||||
redis:
|
||||
@@ -117,7 +124,7 @@ services:
|
||||
|
||||
# Queue Worker (Background Jobs)
|
||||
queue-worker:
|
||||
image: git.michaelschiemer.de:5000/framework:latest
|
||||
image: registry.michaelschiemer.de/framework:latest
|
||||
container_name: queue-worker
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -129,9 +136,9 @@ services:
|
||||
# Database
|
||||
- DB_HOST=${DB_HOST:-postgres}
|
||||
- DB_PORT=${DB_PORT:-5432}
|
||||
- DB_NAME=${DB_NAME}
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASS=${DB_PASS}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
# Redis
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
@@ -149,20 +156,20 @@ services:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
command: php console.php queue:work --queue=default --timeout=${QUEUE_WORKER_TIMEOUT:-60}
|
||||
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
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
redis:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
|
||||
# Scheduler (Cron Jobs)
|
||||
scheduler:
|
||||
image: git.michaelschiemer.de:5000/framework:latest
|
||||
image: registry.michaelschiemer.de/framework:latest
|
||||
container_name: scheduler
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -174,9 +181,9 @@ services:
|
||||
# Database
|
||||
- DB_HOST=${DB_HOST:-postgres}
|
||||
- DB_PORT=${DB_PORT:-5432}
|
||||
- DB_NAME=${DB_NAME}
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASS=${DB_PASS}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
# Redis
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
@@ -188,18 +195,20 @@ services:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
command: php console.php scheduler:run
|
||||
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
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
redis:
|
||||
condition: service_healthy
|
||||
condition: service_started
|
||||
|
||||
volumes:
|
||||
app-code:
|
||||
name: app-code
|
||||
app-storage:
|
||||
name: app-storage
|
||||
app-logs:
|
||||
@@ -211,5 +220,5 @@ networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
app-internal:
|
||||
external: true
|
||||
name: app-internal
|
||||
driver: bridge
|
||||
|
||||
@@ -475,19 +475,45 @@ Security headers are applied via Traefik's `default-chain@file` middleware:
|
||||
|
||||
## 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
|
||||
# Edit daemon.json
|
||||
sudo nano /etc/docker/daemon.json
|
||||
```
|
||||
|
||||
Add:
|
||||
Add `registry.michaelschiemer.de` to `insecure-registries`:
|
||||
```json
|
||||
{
|
||||
"insecure-registries": [],
|
||||
"insecure-registries": ["registry.michaelschiemer.de"],
|
||||
"registry-mirrors": [],
|
||||
"log-driver": "json-file",
|
||||
"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
|
||||
# Restart Docker
|
||||
|
||||
Reference in New Issue
Block a user