fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
128
deployment/scripts/README.md
Normal file
128
deployment/scripts/README.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Deployment Scripts
|
||||
|
||||
Sammlung von nützlichen Scripts für Deployment und Wartung.
|
||||
|
||||
## Quick-Start Scripts
|
||||
|
||||
### staging-quick-start.sh
|
||||
|
||||
Interaktives Script für Staging-Deployment-Aufgaben.
|
||||
|
||||
**Verwendung**:
|
||||
```bash
|
||||
cd ~/deployment
|
||||
./scripts/staging-quick-start.sh
|
||||
```
|
||||
|
||||
**Funktionen**:
|
||||
- PostgreSQL-Staging Stack starten
|
||||
- PostgreSQL-Production Stack starten
|
||||
- Networks prüfen
|
||||
- Container-Status anzeigen
|
||||
- Datenbank-Verbindungen testen
|
||||
- Health-Checks durchführen
|
||||
- Logs anzeigen
|
||||
|
||||
**Beispiel**:
|
||||
```bash
|
||||
# Auf Production-Server
|
||||
cd ~/deployment
|
||||
./scripts/staging-quick-start.sh
|
||||
|
||||
# Wähle Option 3: Beide PostgreSQL-Stacks starten
|
||||
# Wähle Option 10: Alles verifizieren
|
||||
```
|
||||
|
||||
### production-quick-start.sh
|
||||
|
||||
Interaktives Script für Production-Deployment-Aufgaben.
|
||||
|
||||
**Verwendung**:
|
||||
```bash
|
||||
cd ~/deployment
|
||||
./scripts/production-quick-start.sh
|
||||
```
|
||||
|
||||
**Funktionen**:
|
||||
- PostgreSQL-Production Stack starten
|
||||
- Networks prüfen
|
||||
- Container-Status anzeigen
|
||||
- Datenbank-Verbindungen testen
|
||||
- Health-Checks durchführen
|
||||
- Logs anzeigen
|
||||
|
||||
## Test-Scripts
|
||||
|
||||
### test-pipeline-prerequisites.sh
|
||||
|
||||
Prüft alle Voraussetzungen für CI/CD Pipeline-Tests.
|
||||
|
||||
**Verwendung:**
|
||||
```bash
|
||||
cd /home/michael/dev/michaelschiemer
|
||||
./deployment/scripts/test-pipeline-prerequisites.sh
|
||||
```
|
||||
|
||||
**Prüft:**
|
||||
- Gitea Runner Status
|
||||
- Workflow-Dateien
|
||||
- Ansible Playbooks
|
||||
- Docker Compose Files
|
||||
- Dockerfile
|
||||
- SSH Configuration
|
||||
- Docker Registry Access
|
||||
- Git Repository Configuration
|
||||
|
||||
**Ausgabe:**
|
||||
- ✓ Grüne Checks für erfolgreiche Prüfungen
|
||||
- ✗ Rote Checks für Fehler
|
||||
- ⚠ Gelbe Warnungen für optionale Probleme
|
||||
|
||||
### test-backup.sh
|
||||
|
||||
Führt ein Test-Backup aus und verifiziert die Ergebnisse.
|
||||
|
||||
**Verwendung:**
|
||||
```bash
|
||||
cd /home/michael/dev/michaelschiemer
|
||||
./deployment/scripts/test-backup.sh
|
||||
```
|
||||
|
||||
**Führt aus:**
|
||||
- Backup-Playbook mit Test-Konfiguration
|
||||
- Backup-Verifikation
|
||||
- Zeigt Backup-Location und nächste Schritte
|
||||
|
||||
**Nach dem Test:**
|
||||
```bash
|
||||
# Auf Server verifizieren
|
||||
ssh deploy@94.16.110.151
|
||||
ls -lh ~/deployment/backups/backup_*/
|
||||
cat ~/deployment/backups/backup_*/backup_metadata.txt
|
||||
```
|
||||
|
||||
## Weitere Scripts
|
||||
|
||||
Weitere nützliche Scripts können hier hinzugefügt werden:
|
||||
- Rollback-Scripts
|
||||
- Monitoring-Scripts
|
||||
- Cleanup-Scripts
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Docker und Docker Compose installiert
|
||||
- Bash Shell
|
||||
- Zugriff auf Production-Server
|
||||
- Stacks im erwarteten Pfad: `~/deployment/stacks/`
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Scripts nutzen folgende Umgebungsvariablen (optional):
|
||||
- `STACKS_BASE_PATH`: Basis-Pfad für Stacks (Standard: `~/deployment/stacks`)
|
||||
|
||||
**Beispiel**:
|
||||
```bash
|
||||
export STACKS_BASE_PATH=/opt/deployment/stacks
|
||||
./scripts/staging-quick-start.sh
|
||||
```
|
||||
|
||||
319
deployment/scripts/production-quick-start.sh
Executable file
319
deployment/scripts/production-quick-start.sh
Executable file
@@ -0,0 +1,319 @@
|
||||
#!/bin/bash
|
||||
# Production Quick-Start Script
|
||||
# Automatisiert häufige Production-Deployment-Aufgaben
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
STACKS_BASE_PATH="${STACKS_BASE_PATH:-~/deployment/stacks}"
|
||||
POSTGRESQL_PRODUCTION_PATH="${STACKS_BASE_PATH}/postgresql-production"
|
||||
PRODUCTION_STACK_PATH="${STACKS_BASE_PATH}/production"
|
||||
|
||||
# Functions
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_error "Docker ist nicht installiert oder nicht im PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker ps &> /dev/null; then
|
||||
print_error "Docker daemon läuft nicht oder keine Berechtigung"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Docker ist verfügbar"
|
||||
}
|
||||
|
||||
check_networks() {
|
||||
print_header "Networks prüfen"
|
||||
|
||||
local networks=("traefik-public" "postgres-production-internal" "app-internal")
|
||||
local all_exist=true
|
||||
|
||||
for network in "${networks[@]}"; do
|
||||
if docker network inspect "$network" &> /dev/null; then
|
||||
print_success "Network '$network' existiert"
|
||||
else
|
||||
print_warning "Network '$network' existiert nicht"
|
||||
all_exist=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$all_exist" = false ]; then
|
||||
print_info "Fehlende Networks werden beim Stack-Start automatisch erstellt"
|
||||
fi
|
||||
}
|
||||
|
||||
start_postgresql_production() {
|
||||
print_header "PostgreSQL-Production Stack starten"
|
||||
|
||||
if [ ! -d "$POSTGRESQL_PRODUCTION_PATH" ]; then
|
||||
print_error "PostgreSQL-Production Stack nicht gefunden: $POSTGRESQL_PRODUCTION_PATH"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd "$POSTGRESQL_PRODUCTION_PATH"
|
||||
|
||||
# Check if .env exists
|
||||
if [ ! -f ".env" ]; then
|
||||
print_warning ".env-Datei nicht gefunden. Erstelle Beispiel-Konfiguration..."
|
||||
cat > .env <<EOF
|
||||
POSTGRES_DB=michaelschiemer
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
|
||||
BACKUP_RETENTION_DAYS=7
|
||||
BACKUP_SCHEDULE=0 2 * * *
|
||||
EOF
|
||||
print_warning "Bitte POSTGRES_PASSWORD in .env anpassen!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Starte PostgreSQL-Production Stack..."
|
||||
docker compose up -d
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
print_info "Warte auf PostgreSQL-Production..."
|
||||
local max_attempts=30
|
||||
local attempt=0
|
||||
|
||||
while [ $attempt -lt $max_attempts ]; do
|
||||
if docker exec postgres-production pg_isready -U postgres -d michaelschiemer &> /dev/null; then
|
||||
print_success "PostgreSQL-Production ist bereit"
|
||||
return 0
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
sleep 2
|
||||
done
|
||||
|
||||
print_error "PostgreSQL-Production ist nicht bereit nach $max_attempts Versuchen"
|
||||
return 1
|
||||
}
|
||||
|
||||
verify_connections() {
|
||||
print_header "Datenbank-Verbindungen verifizieren"
|
||||
|
||||
# Check Production
|
||||
if docker ps | grep -q postgres-production; then
|
||||
print_info "Teste Production-Datenbank-Verbindung..."
|
||||
if docker exec postgres-production pg_isready -U postgres -d michaelschiemer &> /dev/null; then
|
||||
print_success "PostgreSQL-Production erreichbar"
|
||||
else
|
||||
print_error "PostgreSQL-Production nicht erreichbar"
|
||||
fi
|
||||
else
|
||||
print_warning "PostgreSQL-Production Container läuft nicht"
|
||||
fi
|
||||
}
|
||||
|
||||
show_status() {
|
||||
print_header "Container-Status"
|
||||
|
||||
echo "PostgreSQL-Production Container:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "postgres-production" || echo "Keine PostgreSQL-Production Container gefunden"
|
||||
|
||||
echo ""
|
||||
echo "Production Application Container:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "^(app|php|queue-worker|scheduler|nginx)" || echo "Keine Production-Container gefunden"
|
||||
}
|
||||
|
||||
show_logs() {
|
||||
local container=$1
|
||||
local lines=${2:-50}
|
||||
|
||||
if docker ps --format "{{.Names}}" | grep -q "^${container}$"; then
|
||||
print_header "Logs: $container (letzte $lines Zeilen)"
|
||||
docker logs --tail "$lines" "$container"
|
||||
else
|
||||
print_warning "Container '$container' läuft nicht"
|
||||
fi
|
||||
}
|
||||
|
||||
test_production_connection() {
|
||||
print_header "Production-Datenbank-Verbindung testen"
|
||||
|
||||
local app_container="php"
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^${app_container}$"; then
|
||||
# Try alternative names
|
||||
app_container=$(docker ps --format "{{.Names}}" | grep -E "^(app|php)" | head -1)
|
||||
if [ -z "$app_container" ]; then
|
||||
print_warning "Production Application Container läuft nicht"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
print_info "Teste Verbindung von $app_container zu postgres-production..."
|
||||
|
||||
# Test network connectivity
|
||||
if docker exec "$app_container" nc -zv postgres-production 5432 &> /dev/null; then
|
||||
print_success "Network-Verbindung zu postgres-production erfolgreich"
|
||||
else
|
||||
print_error "Network-Verbindung zu postgres-production fehlgeschlagen"
|
||||
print_info "Prüfe, ob $app_container im postgres-production-internal Network ist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test database connection
|
||||
print_info "Teste Datenbank-Verbindung..."
|
||||
if docker exec "$app_container" php -r "
|
||||
\$host = getenv('DB_HOST') ?: 'postgres-production';
|
||||
\$db = getenv('DB_DATABASE') ?: 'michaelschiemer';
|
||||
\$user = getenv('DB_USERNAME') ?: 'postgres';
|
||||
\$pass = getenv('DB_PASSWORD') ?: file_get_contents(getenv('DB_PASSWORD_FILE') ?: '/dev/null');
|
||||
if (!\$pass) {
|
||||
echo 'DB_PASSWORD nicht verfügbar\n';
|
||||
exit(1);
|
||||
}
|
||||
try {
|
||||
\$dsn = \"pgsql:host=\$host;port=5432;dbname=\$db\";
|
||||
\$pdo = new PDO(\$dsn, \$user, trim(\$pass));
|
||||
echo 'Connection successful: ' . \$pdo->query('SELECT version()')->fetchColumn() . \"\n\";
|
||||
exit(0);
|
||||
} catch (Exception \$e) {
|
||||
echo 'Connection failed: ' . \$e->getMessage() . \"\n\";
|
||||
exit(1);
|
||||
}
|
||||
" 2>&1; then
|
||||
print_success "Datenbank-Verbindung erfolgreich"
|
||||
else
|
||||
print_warning "Datenbank-Verbindungstest fehlgeschlagen (DB_PASSWORD möglicherweise nicht gesetzt)"
|
||||
fi
|
||||
}
|
||||
|
||||
health_check() {
|
||||
print_header "Health-Checks"
|
||||
|
||||
# Basic health check
|
||||
print_info "Basic Health Check: https://michaelschiemer.de/health"
|
||||
if curl -f -k -s https://michaelschiemer.de/health > /dev/null 2>&1; then
|
||||
print_success "Basic Health Check erfolgreich"
|
||||
else
|
||||
print_warning "Basic Health Check fehlgeschlagen (Service möglicherweise nicht verfügbar)"
|
||||
fi
|
||||
|
||||
# Extended health check
|
||||
print_info "Extended Health Check: https://michaelschiemer.de/admin/health/api/summary"
|
||||
local health_summary=$(curl -f -k -s https://michaelschiemer.de/admin/health/api/summary 2>/dev/null || echo "")
|
||||
if [ -n "$health_summary" ]; then
|
||||
local overall_status=$(echo "$health_summary" | grep -o '"overall_status":"[^"]*"' | cut -d'"' -f4 || echo "unknown")
|
||||
print_info "Overall Health Status: $overall_status"
|
||||
if [ "$overall_status" = "healthy" ]; then
|
||||
print_success "Extended Health Check erfolgreich"
|
||||
else
|
||||
print_warning "Extended Health Check zeigt: $overall_status"
|
||||
fi
|
||||
else
|
||||
print_warning "Extended Health Check Endpoint nicht verfügbar"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main menu
|
||||
show_menu() {
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Production Quick-Start Script${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
echo "1) PostgreSQL-Production Stack starten"
|
||||
echo "2) Networks prüfen"
|
||||
echo "3) Container-Status anzeigen"
|
||||
echo "4) Production-Datenbank-Verbindung testen"
|
||||
echo "5) Health-Checks durchführen"
|
||||
echo "6) Logs anzeigen (PostgreSQL-Production)"
|
||||
echo "7) Logs anzeigen (Production App)"
|
||||
echo "8) Alles verifizieren"
|
||||
echo "0) Beenden"
|
||||
echo ""
|
||||
read -p "Wähle eine Option: " choice
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_header "Production Quick-Start Script"
|
||||
|
||||
check_docker
|
||||
|
||||
while true; do
|
||||
show_menu
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
start_postgresql_production
|
||||
;;
|
||||
2)
|
||||
check_networks
|
||||
;;
|
||||
3)
|
||||
show_status
|
||||
;;
|
||||
4)
|
||||
test_production_connection
|
||||
;;
|
||||
5)
|
||||
health_check
|
||||
;;
|
||||
6)
|
||||
show_logs "postgres-production" 50
|
||||
;;
|
||||
7)
|
||||
local app_container=$(docker ps --format "{{.Names}}" | grep -E "^(app|php)" | head -1)
|
||||
if [ -n "$app_container" ]; then
|
||||
show_logs "$app_container" 50
|
||||
else
|
||||
print_warning "Production Application Container läuft nicht"
|
||||
fi
|
||||
;;
|
||||
8)
|
||||
check_networks
|
||||
verify_connections
|
||||
show_status
|
||||
test_production_connection
|
||||
health_check
|
||||
;;
|
||||
0)
|
||||
print_info "Beende..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Ungültige Option"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "Drücke Enter um fortzufahren..."
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
|
||||
376
deployment/scripts/staging-quick-start.sh
Executable file
376
deployment/scripts/staging-quick-start.sh
Executable file
@@ -0,0 +1,376 @@
|
||||
#!/bin/bash
|
||||
# Staging Quick-Start Script
|
||||
# Automatisiert häufige Staging-Deployment-Aufgaben
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
STACKS_BASE_PATH="${STACKS_BASE_PATH:-~/deployment/stacks}"
|
||||
POSTGRESQL_PRODUCTION_PATH="${STACKS_BASE_PATH}/postgresql-production"
|
||||
POSTGRESQL_STAGING_PATH="${STACKS_BASE_PATH}/postgresql-staging"
|
||||
STAGING_STACK_PATH="${STACKS_BASE_PATH}/staging"
|
||||
|
||||
# Functions
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_error "Docker ist nicht installiert oder nicht im PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker ps &> /dev/null; then
|
||||
print_error "Docker daemon läuft nicht oder keine Berechtigung"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Docker ist verfügbar"
|
||||
}
|
||||
|
||||
check_networks() {
|
||||
print_header "Networks prüfen"
|
||||
|
||||
local networks=("traefik-public" "staging-internal" "postgres-staging-internal" "postgres-production-internal" "app-internal")
|
||||
local all_exist=true
|
||||
|
||||
for network in "${networks[@]}"; do
|
||||
if docker network inspect "$network" &> /dev/null; then
|
||||
print_success "Network '$network' existiert"
|
||||
else
|
||||
print_warning "Network '$network' existiert nicht"
|
||||
all_exist=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$all_exist" = false ]; then
|
||||
print_info "Fehlende Networks werden beim Stack-Start automatisch erstellt"
|
||||
fi
|
||||
}
|
||||
|
||||
start_postgresql_production() {
|
||||
print_header "PostgreSQL-Production Stack starten"
|
||||
|
||||
if [ ! -d "$POSTGRESQL_PRODUCTION_PATH" ]; then
|
||||
print_error "PostgreSQL-Production Stack nicht gefunden: $POSTGRESQL_PRODUCTION_PATH"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd "$POSTGRESQL_PRODUCTION_PATH"
|
||||
|
||||
# Check if .env exists
|
||||
if [ ! -f ".env" ]; then
|
||||
print_warning ".env-Datei nicht gefunden. Erstelle Beispiel-Konfiguration..."
|
||||
cat > .env <<EOF
|
||||
POSTGRES_DB=michaelschiemer
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
|
||||
BACKUP_RETENTION_DAYS=7
|
||||
BACKUP_SCHEDULE=0 2 * * *
|
||||
EOF
|
||||
print_warning "Bitte POSTGRES_PASSWORD in .env anpassen!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Starte PostgreSQL-Production Stack..."
|
||||
docker compose up -d
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
print_info "Warte auf PostgreSQL-Production..."
|
||||
local max_attempts=30
|
||||
local attempt=0
|
||||
|
||||
while [ $attempt -lt $max_attempts ]; do
|
||||
if docker exec postgres-production pg_isready -U postgres -d michaelschiemer &> /dev/null; then
|
||||
print_success "PostgreSQL-Production ist bereit"
|
||||
return 0
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
sleep 2
|
||||
done
|
||||
|
||||
print_error "PostgreSQL-Production ist nicht bereit nach $max_attempts Versuchen"
|
||||
return 1
|
||||
}
|
||||
|
||||
start_postgresql_staging() {
|
||||
print_header "PostgreSQL-Staging Stack starten"
|
||||
|
||||
if [ ! -d "$POSTGRESQL_STAGING_PATH" ]; then
|
||||
print_error "PostgreSQL-Staging Stack nicht gefunden: $POSTGRESQL_STAGING_PATH"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd "$POSTGRESQL_STAGING_PATH"
|
||||
|
||||
# Check if .env exists
|
||||
if [ ! -f ".env" ]; then
|
||||
print_warning ".env-Datei nicht gefunden. Erstelle Beispiel-Konfiguration..."
|
||||
cat > .env <<EOF
|
||||
POSTGRES_DB=michaelschiemer_staging
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
|
||||
BACKUP_RETENTION_DAYS=3
|
||||
BACKUP_SCHEDULE=0 3 * * *
|
||||
EOF
|
||||
print_warning "Bitte POSTGRES_PASSWORD in .env anpassen!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Starte PostgreSQL-Staging Stack..."
|
||||
docker compose up -d
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
print_info "Warte auf PostgreSQL-Staging..."
|
||||
local max_attempts=30
|
||||
local attempt=0
|
||||
|
||||
while [ $attempt -lt $max_attempts ]; do
|
||||
if docker exec postgres-staging pg_isready -U postgres -d michaelschiemer_staging &> /dev/null; then
|
||||
print_success "PostgreSQL-Staging ist bereit"
|
||||
return 0
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
sleep 2
|
||||
done
|
||||
|
||||
print_error "PostgreSQL-Staging ist nicht bereit nach $max_attempts Versuchen"
|
||||
return 1
|
||||
}
|
||||
|
||||
verify_connections() {
|
||||
print_header "Datenbank-Verbindungen verifizieren"
|
||||
|
||||
# Check Production
|
||||
if docker ps | grep -q postgres-production; then
|
||||
print_info "Teste Production-Datenbank-Verbindung..."
|
||||
if docker exec postgres-production pg_isready -U postgres -d michaelschiemer &> /dev/null; then
|
||||
print_success "PostgreSQL-Production erreichbar"
|
||||
else
|
||||
print_error "PostgreSQL-Production nicht erreichbar"
|
||||
fi
|
||||
else
|
||||
print_warning "PostgreSQL-Production Container läuft nicht"
|
||||
fi
|
||||
|
||||
# Check Staging
|
||||
if docker ps | grep -q postgres-staging; then
|
||||
print_info "Teste Staging-Datenbank-Verbindung..."
|
||||
if docker exec postgres-staging pg_isready -U postgres -d michaelschiemer_staging &> /dev/null; then
|
||||
print_success "PostgreSQL-Staging erreichbar"
|
||||
else
|
||||
print_error "PostgreSQL-Staging nicht erreichbar"
|
||||
fi
|
||||
else
|
||||
print_warning "PostgreSQL-Staging Container läuft nicht"
|
||||
fi
|
||||
}
|
||||
|
||||
show_status() {
|
||||
print_header "Container-Status"
|
||||
|
||||
echo "PostgreSQL-Container:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(postgres-production|postgres-staging)" || echo "Keine PostgreSQL-Container gefunden"
|
||||
|
||||
echo ""
|
||||
echo "Staging-Container:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "staging-" || echo "Keine Staging-Container gefunden"
|
||||
}
|
||||
|
||||
show_logs() {
|
||||
local container=$1
|
||||
local lines=${2:-50}
|
||||
|
||||
if docker ps --format "{{.Names}}" | grep -q "^${container}$"; then
|
||||
print_header "Logs: $container (letzte $lines Zeilen)"
|
||||
docker logs --tail "$lines" "$container"
|
||||
else
|
||||
print_warning "Container '$container' läuft nicht"
|
||||
fi
|
||||
}
|
||||
|
||||
test_staging_connection() {
|
||||
print_header "Staging-Datenbank-Verbindung testen"
|
||||
|
||||
if ! docker ps | grep -q staging-app; then
|
||||
print_warning "staging-app Container läuft nicht"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Teste Verbindung von staging-app zu postgres-staging..."
|
||||
|
||||
# Test network connectivity
|
||||
if docker exec staging-app nc -zv postgres-staging 5432 &> /dev/null; then
|
||||
print_success "Network-Verbindung zu postgres-staging erfolgreich"
|
||||
else
|
||||
print_error "Network-Verbindung zu postgres-staging fehlgeschlagen"
|
||||
print_info "Prüfe, ob staging-app im postgres-staging-internal Network ist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test database connection (if DB_PASSWORD is available)
|
||||
print_info "Teste Datenbank-Verbindung..."
|
||||
if docker exec staging-app php -r "
|
||||
\$host = getenv('DB_HOST') ?: 'postgres-staging';
|
||||
\$db = getenv('DB_DATABASE') ?: 'michaelschiemer_staging';
|
||||
\$user = getenv('DB_USERNAME') ?: 'postgres';
|
||||
\$pass = getenv('DB_PASSWORD') ?: file_get_contents(getenv('DB_PASSWORD_FILE') ?: '/dev/null');
|
||||
if (!\$pass) {
|
||||
echo 'DB_PASSWORD nicht verfügbar\n';
|
||||
exit(1);
|
||||
}
|
||||
try {
|
||||
\$dsn = \"pgsql:host=\$host;port=5432;dbname=\$db\";
|
||||
\$pdo = new PDO(\$dsn, \$user, trim(\$pass));
|
||||
echo 'Connection successful: ' . \$pdo->query('SELECT version()')->fetchColumn() . \"\n\";
|
||||
exit(0);
|
||||
} catch (Exception \$e) {
|
||||
echo 'Connection failed: ' . \$e->getMessage() . \"\n\";
|
||||
exit(1);
|
||||
}
|
||||
" 2>&1; then
|
||||
print_success "Datenbank-Verbindung erfolgreich"
|
||||
else
|
||||
print_warning "Datenbank-Verbindungstest fehlgeschlagen (DB_PASSWORD möglicherweise nicht gesetzt)"
|
||||
fi
|
||||
}
|
||||
|
||||
health_check() {
|
||||
print_header "Health-Checks"
|
||||
|
||||
# Basic health check
|
||||
print_info "Basic Health Check: https://staging.michaelschiemer.de/health"
|
||||
if curl -f -k -s https://staging.michaelschiemer.de/health > /dev/null 2>&1; then
|
||||
print_success "Basic Health Check erfolgreich"
|
||||
else
|
||||
print_warning "Basic Health Check fehlgeschlagen (Service möglicherweise nicht verfügbar)"
|
||||
fi
|
||||
|
||||
# Extended health check
|
||||
print_info "Extended Health Check: https://staging.michaelschiemer.de/admin/health/api/summary"
|
||||
local health_summary=$(curl -f -k -s https://staging.michaelschiemer.de/admin/health/api/summary 2>/dev/null || echo "")
|
||||
if [ -n "$health_summary" ]; then
|
||||
local overall_status=$(echo "$health_summary" | grep -o '"overall_status":"[^"]*"' | cut -d'"' -f4 || echo "unknown")
|
||||
print_info "Overall Health Status: $overall_status"
|
||||
if [ "$overall_status" = "healthy" ]; then
|
||||
print_success "Extended Health Check erfolgreich"
|
||||
else
|
||||
print_warning "Extended Health Check zeigt: $overall_status"
|
||||
fi
|
||||
else
|
||||
print_warning "Extended Health Check Endpoint nicht verfügbar"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main menu
|
||||
show_menu() {
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Staging Quick-Start Script${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
echo "1) PostgreSQL-Production Stack starten"
|
||||
echo "2) PostgreSQL-Staging Stack starten"
|
||||
echo "3) Beide PostgreSQL-Stacks starten"
|
||||
echo "4) Networks prüfen"
|
||||
echo "5) Container-Status anzeigen"
|
||||
echo "6) Staging-Datenbank-Verbindung testen"
|
||||
echo "7) Health-Checks durchführen"
|
||||
echo "8) Logs anzeigen (PostgreSQL-Staging)"
|
||||
echo "9) Logs anzeigen (staging-app)"
|
||||
echo "10) Alles verifizieren"
|
||||
echo "0) Beenden"
|
||||
echo ""
|
||||
read -p "Wähle eine Option: " choice
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_header "Staging Quick-Start Script"
|
||||
|
||||
check_docker
|
||||
|
||||
while true; do
|
||||
show_menu
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
start_postgresql_production
|
||||
;;
|
||||
2)
|
||||
start_postgresql_staging
|
||||
;;
|
||||
3)
|
||||
start_postgresql_production
|
||||
start_postgresql_staging
|
||||
;;
|
||||
4)
|
||||
check_networks
|
||||
;;
|
||||
5)
|
||||
show_status
|
||||
;;
|
||||
6)
|
||||
test_staging_connection
|
||||
;;
|
||||
7)
|
||||
health_check
|
||||
;;
|
||||
8)
|
||||
show_logs "postgres-staging" 50
|
||||
;;
|
||||
9)
|
||||
show_logs "staging-app" 50
|
||||
;;
|
||||
10)
|
||||
check_networks
|
||||
verify_connections
|
||||
show_status
|
||||
test_staging_connection
|
||||
health_check
|
||||
;;
|
||||
0)
|
||||
print_info "Beende..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Ungültige Option"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "Drücke Enter um fortzufahren..."
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
|
||||
61
deployment/scripts/test-backup.sh
Executable file
61
deployment/scripts/test-backup.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
# Test Backup Playbook
|
||||
# Führt ein Test-Backup aus und verifiziert die Ergebnisse
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ANSIBLE_DIR="$SCRIPT_DIR/../ansible"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Backup Playbook Test"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Check if we're in the right directory
|
||||
if [ ! -f "$ANSIBLE_DIR/playbooks/backup.yml" ]; then
|
||||
echo "Error: backup.yml not found at $ANSIBLE_DIR/playbooks/backup.yml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if inventory exists
|
||||
if [ ! -f "$ANSIBLE_DIR/inventory/production.yml" ]; then
|
||||
echo "Error: production.yml inventory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if vault password file exists
|
||||
VAULT_PASS_FILE="$ANSIBLE_DIR/secrets/.vault_pass"
|
||||
if [ ! -f "$VAULT_PASS_FILE" ]; then
|
||||
echo "Warning: Vault password file not found at $VAULT_PASS_FILE"
|
||||
echo "Creating empty vault password file..."
|
||||
touch "$VAULT_PASS_FILE"
|
||||
chmod 600 "$VAULT_PASS_FILE"
|
||||
fi
|
||||
|
||||
echo "Running backup playbook..."
|
||||
echo ""
|
||||
|
||||
cd "$ANSIBLE_DIR"
|
||||
|
||||
ansible-playbook -i inventory/production.yml \
|
||||
playbooks/backup.yml \
|
||||
--vault-password-file "$VAULT_PASS_FILE" \
|
||||
-e "backup_retention_days=1" \
|
||||
-e "verify_backups=true"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Backup Test Complete"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Verify backup files were created on the server"
|
||||
echo "2. Check backup metadata file"
|
||||
echo "3. (Optional) Test restore process"
|
||||
echo ""
|
||||
echo "To verify backups on server:"
|
||||
echo " ssh deploy@94.16.110.151"
|
||||
echo " ls -lh ~/backups/backup_*/"
|
||||
echo " cat ~/backups/backup_*/backup_metadata.txt"
|
||||
|
||||
230
deployment/scripts/test-pipeline-prerequisites.sh
Executable file
230
deployment/scripts/test-pipeline-prerequisites.sh
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
# Test Pipeline Prerequisites
|
||||
# Prüft alle Voraussetzungen für CI/CD Pipeline Tests
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "=========================================="
|
||||
echo "CI/CD Pipeline Prerequisites Check"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
ERRORS=0
|
||||
WARNINGS=0
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
check_pass() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
check_fail() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
((ERRORS++))
|
||||
}
|
||||
|
||||
check_warn() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
((WARNINGS++))
|
||||
}
|
||||
|
||||
# 1. Check Gitea Runner
|
||||
echo "1. Checking Gitea Runner..."
|
||||
if [ -d "deployment/gitea-runner" ]; then
|
||||
cd deployment/gitea-runner
|
||||
if docker compose ps 2>/dev/null | grep -q "gitea-runner.*Up"; then
|
||||
check_pass "Gitea Runner container is running"
|
||||
else
|
||||
check_fail "Gitea Runner container is not running"
|
||||
echo " Run: cd deployment/gitea-runner && docker compose up -d"
|
||||
fi
|
||||
|
||||
if docker compose ps 2>/dev/null | grep -q "gitea-runner-dind.*Up"; then
|
||||
check_pass "Gitea Runner DinD container is running"
|
||||
else
|
||||
check_fail "Gitea Runner DinD container is not running"
|
||||
fi
|
||||
|
||||
if [ -f "data/.runner" ]; then
|
||||
check_pass "Gitea Runner is registered (data/.runner exists)"
|
||||
else
|
||||
check_warn "Gitea Runner may not be registered (data/.runner missing)"
|
||||
echo " Run: ./register.sh"
|
||||
fi
|
||||
cd - > /dev/null
|
||||
else
|
||||
check_fail "deployment/gitea-runner directory not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 2. Check Workflow Files
|
||||
echo "2. Checking Workflow Files..."
|
||||
if [ -f ".gitea/workflows/build-image.yml" ]; then
|
||||
check_pass "build-image.yml workflow exists"
|
||||
else
|
||||
check_fail ".gitea/workflows/build-image.yml not found"
|
||||
fi
|
||||
|
||||
if [ -f ".gitea/workflows/manual-deploy.yml" ]; then
|
||||
check_pass "manual-deploy.yml workflow exists"
|
||||
else
|
||||
check_warn ".gitea/workflows/manual-deploy.yml not found (optional)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 3. Check Ansible Playbooks
|
||||
echo "3. Checking Ansible Playbooks..."
|
||||
ANSIBLE_PLAYBOOKS=(
|
||||
"deployment/ansible/playbooks/deploy-application-code.yml"
|
||||
"deployment/ansible/playbooks/install-composer-dependencies.yml"
|
||||
"deployment/ansible/playbooks/deploy-image.yml"
|
||||
"deployment/ansible/playbooks/backup.yml"
|
||||
)
|
||||
|
||||
for playbook in "${ANSIBLE_PLAYBOOKS[@]}"; do
|
||||
if [ -f "$playbook" ]; then
|
||||
check_pass "$(basename $playbook) exists"
|
||||
else
|
||||
check_fail "$playbook not found"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# 4. Check Ansible Inventory
|
||||
echo "4. Checking Ansible Inventory..."
|
||||
if [ -f "deployment/ansible/inventory/production.yml" ]; then
|
||||
check_pass "Ansible inventory file exists"
|
||||
else
|
||||
check_fail "deployment/ansible/inventory/production.yml not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 5. Check Docker Compose Files
|
||||
echo "5. Checking Docker Compose Files..."
|
||||
if [ -f "deployment/stacks/production/docker-compose.base.yml" ]; then
|
||||
check_pass "Production docker-compose.base.yml exists"
|
||||
else
|
||||
check_fail "Production docker-compose.base.yml not found"
|
||||
fi
|
||||
|
||||
if [ -f "deployment/stacks/production/docker-compose.production.yml" ]; then
|
||||
check_pass "Production docker-compose.production.yml exists"
|
||||
else
|
||||
check_fail "Production docker-compose.production.yml not found"
|
||||
fi
|
||||
|
||||
if [ -f "deployment/stacks/staging/docker-compose.base.yml" ]; then
|
||||
check_pass "Staging docker-compose.base.yml exists"
|
||||
else
|
||||
check_warn "Staging docker-compose.base.yml not found (optional for staging tests)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 6. Check Dockerfile
|
||||
echo "6. Checking Dockerfile..."
|
||||
if [ -f "Dockerfile.production" ]; then
|
||||
check_pass "Dockerfile.production exists"
|
||||
else
|
||||
check_fail "Dockerfile.production not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 7. Check SSH Key (if exists locally)
|
||||
echo "7. Checking SSH Configuration..."
|
||||
if [ -f "$HOME/.ssh/production" ] || [ -f "$HOME/.ssh/id_rsa" ] || [ -f "$HOME/.ssh/id_ed25519" ]; then
|
||||
check_pass "SSH key found (local check only)"
|
||||
echo " Note: SSH_PRIVATE_KEY secret must be configured in Gitea"
|
||||
else
|
||||
check_warn "No SSH key found locally (may be configured in Gitea secrets)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 8. Check Registry Access (if possible)
|
||||
echo "8. Checking Docker Registry Access..."
|
||||
REGISTRY="registry.michaelschiemer.de"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
if curl -s -k --connect-timeout 5 "https://${REGISTRY}/v2/" >/dev/null 2>&1 || \
|
||||
curl -s --connect-timeout 5 "http://94.16.110.151:5000/v2/" >/dev/null 2>&1; then
|
||||
check_pass "Docker Registry is accessible"
|
||||
else
|
||||
check_warn "Docker Registry may not be accessible (check network/firewall)"
|
||||
fi
|
||||
else
|
||||
check_warn "curl not available, skipping registry check"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 9. Check Git Repository
|
||||
echo "9. Checking Git Repository..."
|
||||
if git remote get-url origin 2>/dev/null | grep -q "git.michaelschiemer.de"; then
|
||||
check_pass "Git remote points to Gitea"
|
||||
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
|
||||
echo " Remote: $REMOTE_URL"
|
||||
else
|
||||
check_warn "Git remote may not point to Gitea"
|
||||
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "not configured")
|
||||
echo " Remote: $REMOTE_URL"
|
||||
fi
|
||||
|
||||
# Check for staging and main branches
|
||||
if git show-ref --verify --quiet refs/heads/staging 2>/dev/null; then
|
||||
check_pass "staging branch exists locally"
|
||||
else
|
||||
check_warn "staging branch not found locally (may need to fetch)"
|
||||
fi
|
||||
|
||||
if git show-ref --verify --quiet refs/heads/main 2>/dev/null; then
|
||||
check_pass "main branch exists locally"
|
||||
else
|
||||
check_warn "main branch not found locally (may need to fetch)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "=========================================="
|
||||
echo "Summary"
|
||||
echo "=========================================="
|
||||
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All checks passed!${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Verify Gitea Secrets are configured:"
|
||||
echo " https://git.michaelschiemer.de/michael/michaelschiemer/settings/secrets/actions"
|
||||
echo ""
|
||||
echo "2. Test Staging Pipeline:"
|
||||
echo " git checkout staging"
|
||||
echo " echo '# Test' >> README.md"
|
||||
echo " git commit -m 'test: CI/CD pipeline'"
|
||||
echo " git push origin staging"
|
||||
echo ""
|
||||
echo "3. Monitor Pipeline:"
|
||||
echo " https://git.michaelschiemer.de/michael/michaelschiemer/actions"
|
||||
exit 0
|
||||
elif [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${YELLOW}⚠ Checks passed with warnings${NC}"
|
||||
echo " Warnings: $WARNINGS"
|
||||
echo ""
|
||||
echo "Review warnings above and proceed with testing."
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Checks failed${NC}"
|
||||
echo " Errors: $ERRORS"
|
||||
echo " Warnings: $WARNINGS"
|
||||
echo ""
|
||||
echo "Please fix the errors above before testing the pipeline."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user