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

- 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:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -0,0 +1,290 @@
#!/bin/bash
set -uo pipefail
# Test script for deployment with new docker-compose files and secret management
# This script validates the deployment configuration and tests secret loading
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SECRETS_DIR="$PROJECT_ROOT/secrets"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test results
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0
print_header() {
echo ""
echo -e "${BLUE}????????????????????????????????????????????????????????????????????${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}????????????????????????????????????????????????????????????????????${NC}"
}
print_test() {
echo -e "${YELLOW}[TEST]${NC} $1"
}
print_success() {
echo -e "${GREEN}[?]${NC} $1"
((TESTS_PASSED++))
}
print_error() {
echo -e "${RED}[?]${NC} $1"
((TESTS_FAILED++))
}
run_test() {
((TESTS_TOTAL++))
local test_name="$1"
shift
print_test "$test_name"
if "$@" 2>/dev/null; then
print_success "$test_name"
return 0
else
print_error "$test_name"
return 1
fi
}
# Cleanup function
cleanup() {
echo ""
echo -e "${YELLOW}Cleaning up test artifacts...${NC}"
# Remove test secrets directory
if [ -d "$SECRETS_DIR" ] && [ -f "$SECRETS_DIR/.test-marker" ]; then
rm -rf "$SECRETS_DIR"
print_success "Test secrets directory removed"
fi
}
trap cleanup EXIT
print_header "?? Testing Deployment with New Docker Compose Files & Secret Management"
# ============================================================================
# Phase 1: Validate Docker Compose Files
# ============================================================================
print_header "Phase 1: Validating Docker Compose Files"
run_test "docker-compose.base.yml exists" test -f "$PROJECT_ROOT/docker-compose.base.yml"
run_test "docker-compose.local.yml exists" test -f "$PROJECT_ROOT/docker-compose.local.yml"
run_test "docker-compose.staging.yml exists" test -f "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "docker-compose.production.yml exists" test -f "$PROJECT_ROOT/docker-compose.production.yml"
# Validate docker-compose syntax
if command -v docker-compose &> /dev/null || command -v docker &> /dev/null; then
run_test "docker-compose.base.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml config > /dev/null 2>&1"
run_test "docker-compose.local.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1"
run_test "docker-compose.staging.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1"
run_test "docker-compose.production.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1"
else
print_error "docker-compose or docker not available, skipping syntax validation"
fi
# ============================================================================
# Phase 2: Validate Secret Configuration
# ============================================================================
print_header "Phase 2: Validating Secret Configuration"
# Check that secrets are defined in docker-compose.base.yml
run_test "secrets section exists in docker-compose.base.yml" grep -q "^secrets:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "db_root_password secret defined" grep -q "db_root_password:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "db_user_password secret defined" grep -q "db_user_password:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "redis_password secret defined" grep -q "redis_password:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "app_key secret defined" grep -q "app_key:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "vault_encryption_key secret defined" grep -q "vault_encryption_key:" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "git_token secret defined" grep -q "git_token:" "$PROJECT_ROOT/docker-compose.base.yml"
# Check that production uses secrets
run_test "production uses db_user_password secret" grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses redis_password secret" grep -q "redis_password" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses app_key secret" grep -q "app_key" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses vault_encryption_key secret" grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.production.yml"
# Check that staging uses secrets
run_test "staging uses db_user_password secret" grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses redis_password secret" grep -q "redis_password" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses app_key secret" grep -q "app_key" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses vault_encryption_key secret" grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.staging.yml"
# ============================================================================
# Phase 3: Create Test Secrets
# ============================================================================
print_header "Phase 3: Creating Test Secrets"
# Create test secrets directory
mkdir -p "$SECRETS_DIR"
echo "test-marker" > "$SECRETS_DIR/.test-marker"
# Create test secret files
echo "test-db-root-password-12345" > "$SECRETS_DIR/db_root_password.txt"
echo "test-db-user-password-67890" > "$SECRETS_DIR/db_user_password.txt"
echo "test-redis-password-abcde" > "$SECRETS_DIR/redis_password.txt"
echo "test-app-key-base64encoded123456789012345678901234567890" > "$SECRETS_DIR/app_key.txt"
echo "test-vault-encryption-key-32charslong12345678" > "$SECRETS_DIR/vault_encryption_key.txt"
echo "test-git-token-ghp_test12345678901234567890" > "$SECRETS_DIR/git_token.txt"
# Set secure permissions
chmod 600 "$SECRETS_DIR"/*.txt 2>/dev/null || true
run_test "Test secrets directory created" test -d "$SECRETS_DIR"
run_test "db_root_password.txt created" test -f "$SECRETS_DIR/db_root_password.txt"
run_test "db_user_password.txt created" test -f "$SECRETS_DIR/db_user_password.txt"
run_test "redis_password.txt created" test -f "$SECRETS_DIR/redis_password.txt"
run_test "app_key.txt created" test -f "$SECRETS_DIR/app_key.txt"
run_test "vault_encryption_key.txt created" test -f "$SECRETS_DIR/vault_encryption_key.txt"
run_test "git_token.txt created" test -f "$SECRETS_DIR/git_token.txt"
# ============================================================================
# Phase 4: Test Secret File References
# ============================================================================
print_header "Phase 4: Validating Secret File References"
# Check that docker-compose files reference correct secret file paths
run_test "base.yml references ./secrets/db_root_password.txt" grep -q "./secrets/db_root_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "base.yml references ./secrets/db_user_password.txt" grep -q "./secrets/db_user_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "base.yml references ./secrets/redis_password.txt" grep -q "./secrets/redis_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "base.yml references ./secrets/app_key.txt" grep -q "./secrets/app_key.txt" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "base.yml references ./secrets/vault_encryption_key.txt" grep -q "./secrets/vault_encryption_key.txt" "$PROJECT_ROOT/docker-compose.base.yml"
run_test "base.yml references ./secrets/git_token.txt" grep -q "./secrets/git_token.txt" "$PROJECT_ROOT/docker-compose.base.yml"
# ============================================================================
# Phase 5: Test *_FILE Pattern Support
# ============================================================================
print_header "Phase 5: Testing *_FILE Pattern Support"
# Check that docker-compose files use *_FILE pattern
run_test "production uses DB_PASSWORD_FILE pattern" grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses REDIS_PASSWORD_FILE pattern" grep -q "REDIS_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "redis_password" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses APP_KEY_FILE pattern" grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "app_key" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production uses VAULT_ENCRYPTION_KEY_FILE pattern" grep -q "VAULT_ENCRYPTION_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "staging uses DB_PASSWORD_FILE pattern" grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses APP_KEY_FILE pattern" grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "app_key" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses VAULT_ENCRYPTION_KEY_FILE pattern" grep -q "VAULT_ENCRYPTION_KEY_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.staging.yml"
run_test "staging uses GIT_TOKEN_FILE pattern" grep -q "GIT_TOKEN_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "git_token" "$PROJECT_ROOT/docker-compose.staging.yml"
# ============================================================================
# Phase 6: Test DockerSecretsResolver Integration
# ============================================================================
print_header "Phase 6: Testing DockerSecretsResolver Integration"
# Check that DockerSecretsResolver exists
run_test "DockerSecretsResolver.php exists" test -f "$PROJECT_ROOT/src/Framework/Config/DockerSecretsResolver.php"
# Check that Environment.php uses DockerSecretsResolver
run_test "Environment.php imports DockerSecretsResolver" grep -q "DockerSecretsResolver" "$PROJECT_ROOT/src/Framework/Config/Environment.php"
run_test "Environment.php resolves secrets via *_FILE pattern" grep -q "secretsResolver->resolve" "$PROJECT_ROOT/src/Framework/Config/Environment.php"
# Test secret resolution logic
if command -v php &> /dev/null; then
PHP_TEST_SCRIPT=$(cat <<'PHPEOF'
<?php
require_once __DIR__ . '/vendor/autoload.php';
use App\Framework\Config\DockerSecretsResolver;
$resolver = new DockerSecretsResolver();
// Test 1: Resolve secret from file
$variables = [
'DB_PASSWORD_FILE' => __DIR__ . '/secrets/db_user_password.txt',
];
$result = $resolver->resolve('DB_PASSWORD', $variables);
if ($result === 'test-db-user-password-67890') {
echo "? Secret resolution works\n";
exit(0);
} else {
echo "? Secret resolution failed: got '$result'\n";
exit(1);
}
PHPEOF
)
echo "$PHP_TEST_SCRIPT" > "$PROJECT_ROOT/test_secret_resolver.php"
run_test "DockerSecretsResolver resolves secrets correctly" bash -c "cd '$PROJECT_ROOT' && php test_secret_resolver.php > /dev/null 2>&1"
# Cleanup
rm -f "$PROJECT_ROOT/test_secret_resolver.php"
else
print_error "PHP not available, skipping DockerSecretsResolver test"
fi
# ============================================================================
# Phase 7: Test EncryptedEnvLoader Integration
# ============================================================================
print_header "Phase 7: Testing EncryptedEnvLoader Integration"
run_test "EncryptedEnvLoader.php exists" test -f "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
run_test "EncryptedEnvLoader loads system environment" grep -q "loadSystemEnvironment" "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
run_test "EncryptedEnvLoader supports encryption key" grep -q "ENCRYPTION_KEY" "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
# ============================================================================
# Phase 8: Test Entrypoint Script
# ============================================================================
print_header "Phase 8: Testing Entrypoint Script"
run_test "entrypoint.sh exists" test -f "$PROJECT_ROOT/docker/entrypoint.sh"
run_test "entrypoint.sh loads secrets from *_FILE pattern" grep -q "_FILE" "$PROJECT_ROOT/docker/entrypoint.sh" || grep -q "DockerSecretsResolver" "$PROJECT_ROOT/docker/entrypoint.sh"
run_test "entrypoint.sh is executable" test -x "$PROJECT_ROOT/docker/entrypoint.sh" || [ -f "$PROJECT_ROOT/docker/entrypoint.sh" ]
# ============================================================================
# Phase 9: Validate Service Configuration
# ============================================================================
print_header "Phase 9: Validating Service Configuration"
# Check that services reference secrets correctly
run_test "production php service uses secrets" grep -A 5 "php:" "$PROJECT_ROOT/docker-compose.production.yml" | grep -q "secrets:" || grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "production queue-worker uses secrets" grep -A 10 "queue-worker:" "$PROJECT_ROOT/docker-compose.production.yml" | grep -q "secrets:" || grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml"
run_test "staging-app uses secrets" grep -A 10 "staging-app:" "$PROJECT_ROOT/docker-compose.staging.yml" | grep -q "secrets:" || grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.staging.yml"
# ============================================================================
# Phase 10: Test Docker Compose Override Chain
# ============================================================================
print_header "Phase 10: Testing Docker Compose Override Chain"
# Test that override chain works correctly
if command -v docker-compose &> /dev/null || command -v docker &> /dev/null; then
run_test "local override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1)"
run_test "staging override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1)"
run_test "production override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1)"
else
print_error "docker-compose not available, skipping override chain test"
fi
# ============================================================================
# Summary
# ============================================================================
print_header "Test Summary"
echo ""
echo -e "Total Tests: ${TESTS_TOTAL}"
echo -e "${GREEN}Passed: ${TESTS_PASSED}${NC}"
echo -e "${RED}Failed: ${TESTS_FAILED}${NC}"
echo ""
if [ $TESTS_FAILED -eq 0 ]; then
echo -e "${GREEN}? All tests passed!${NC}"
echo ""
echo -e "${BLUE}Next steps:${NC}"
echo " 1. Deploy secrets to your server using Ansible Vault"
echo " 2. Run: docker-compose -f docker-compose.base.yml -f docker-compose.production.yml up -d"
echo " 3. Verify secrets are loaded correctly in containers"
exit 0
else
echo -e "${RED}? Some tests failed. Please review the errors above.${NC}"
exit 1
fi

View File

@@ -0,0 +1,328 @@
#!/bin/bash
#
# Script zum Testen der Docker Registry Credentials
# Testet sowohl HTTP als auch HTTPS Zugriff auf die Registry
#
set -euo pipefail
# Farben für Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default-Werte
REGISTRY_USER="${REGISTRY_USER:-admin}"
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-}"
REGISTRY_DOMAIN="${REGISTRY_DOMAIN:-registry.michaelschiemer.de}"
REGISTRY_HOST="${REGISTRY_HOST:-94.16.110.151}"
REGISTRY_PORT="${REGISTRY_PORT:-5000}"
# Funktionen
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}"
}
# Prüfe ob Docker verfügbar ist
check_docker() {
if ! command -v docker >/dev/null 2>&1; then
print_error "Docker ist nicht installiert oder nicht im PATH"
exit 1
fi
if ! docker info >/dev/null 2>&1; then
print_error "Docker daemon läuft nicht oder keine Berechtigung"
exit 1
fi
print_success "Docker ist verfügbar"
}
# Prüfe ob curl verfügbar ist
check_curl() {
if ! command -v curl >/dev/null 2>&1; then
print_warning "curl ist nicht verfügbar, installiere..."
if command -v apk >/dev/null 2>&1; then
apk add --no-cache curl ca-certificates >/dev/null 2>&1
elif command -v apt-get >/dev/null 2>&1; then
apt-get update >/dev/null 2>&1 && apt-get install -y curl ca-certificates >/dev/null 2>&1
else
print_error "curl kann nicht automatisch installiert werden"
return 1
fi
fi
print_success "curl ist verfügbar"
}
# Teste HTTP-Zugriff auf Registry
test_http_connectivity() {
local test_url="$1"
print_info "Teste HTTP-Zugriff auf $test_url..."
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://${test_url}/v2/" 2>&1 || echo "000")
if [ "$HTTP_CODE" = "401" ]; then
print_success "Registry erreichbar über HTTP (Status: 401 - Auth erforderlich, das ist gut!)"
return 0
elif [ "$HTTP_CODE" = "200" ]; then
print_success "Registry erreichbar über HTTP (Status: 200 - keine Auth erforderlich)"
return 0
elif [ "$HTTP_CODE" = "000" ]; then
print_error "Registry nicht erreichbar über HTTP (curl Fehler)"
return 1
else
print_warning "Registry antwortet über HTTP (Status: $HTTP_CODE)"
return 1
fi
}
# Teste HTTPS-Zugriff auf Registry
test_https_connectivity() {
local test_url="$1"
print_info "Teste HTTPS-Zugriff auf $test_url..."
HTTPS_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" "https://${test_url}/v2/" 2>&1 || echo "000")
if [ "$HTTPS_CODE" = "401" ]; then
print_success "Registry erreichbar über HTTPS (Status: 401 - Auth erforderlich, das ist gut!)"
return 0
elif [ "$HTTPS_CODE" = "200" ]; then
print_success "Registry erreichbar über HTTPS (Status: 200 - keine Auth erforderlich)"
return 0
elif [ "$HTTPS_CODE" = "404" ]; then
print_warning "Registry Route nicht gefunden über HTTPS (Status: 404)"
print_info "Möglicherweise ist Traefik-Routing nicht richtig konfiguriert"
return 1
elif [ "$HTTPS_CODE" = "000" ]; then
print_error "Registry nicht erreichbar über HTTPS (curl Fehler)"
return 1
else
print_warning "Registry antwortet über HTTPS (Status: $HTTPS_CODE)"
return 1
fi
}
# Teste Docker Login
test_docker_login() {
local registry_url="$1"
local use_http="${2:-false}"
print_info "Teste Docker Login bei $registry_url..."
if [ -z "$REGISTRY_PASSWORD" ]; then
print_error "REGISTRY_PASSWORD ist nicht gesetzt!"
print_info "Setze es mit: export REGISTRY_PASSWORD='dein-passwort'"
return 1
fi
# Docker Login versuchen
set +e
LOGIN_OUTPUT=$(echo "$REGISTRY_PASSWORD" | docker login "$registry_url" -u "$REGISTRY_USER" --password-stdin 2>&1)
LOGIN_EXIT_CODE=$?
set -e
if [ $LOGIN_EXIT_CODE -eq 0 ]; then
print_success "Docker Login erfolgreich!"
echo "$LOGIN_OUTPUT" | grep -i "Login Succeeded" || true
return 0
else
print_error "Docker Login fehlgeschlagen (Exit Code: $LOGIN_EXIT_CODE)"
if echo "$LOGIN_OUTPUT" | grep -qi "unauthorized\|401"; then
print_warning "Fehler: Unauthorized (401)"
print_info "Die Credentials sind falsch:"
print_info " - Username: $REGISTRY_USER"
print_info " - Password Länge: ${#REGISTRY_PASSWORD} Zeichen"
print_info ""
print_info "Mögliche Lösungen:"
print_info " 1. Prüfe REGISTRY_USER in Gitea Secrets (sollte 'admin' sein)"
print_info " 2. Prüfe REGISTRY_PASSWORD in Gitea Secrets"
print_info " 3. Prüfe das Passwort in deployment/stacks/registry/auth/htpasswd auf dem Server"
fi
if echo "$LOGIN_OUTPUT" | grep -qi "HTTP response to HTTPS client"; then
print_warning "Fehler: Docker versucht HTTPS, aber Registry läuft auf HTTP"
print_info "Lösung: Docker-daemon muss mit --insecure-registry=$registry_url konfiguriert werden"
fi
if echo "$LOGIN_OUTPUT" | grep -qi "certificate\|tls"; then
print_warning "Fehler: SSL/TLS Problem"
print_info "Lösung: Prüfe SSL-Zertifikat-Konfiguration"
fi
echo ""
echo "Vollständiger Fehler-Output:"
echo "$LOGIN_OUTPUT" | while IFS= read -r line; do
echo " $line"
done
return 1
fi
}
# Teste Registry API Zugriff
test_registry_api() {
local registry_url="$1"
local protocol="${2:-http}"
print_info "Teste Registry API Zugriff über $protocol..."
API_URL="${protocol}://${registry_url}/v2/_catalog"
if [ "$protocol" = "https" ]; then
API_RESPONSE=$(curl -k -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" -s "$API_URL" 2>&1)
else
API_RESPONSE=$(curl -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" -s "$API_URL" 2>&1)
fi
if echo "$API_RESPONSE" | grep -qi "repositories"; then
print_success "Registry API Zugriff erfolgreich!"
echo "$API_RESPONSE" | jq '.' 2>/dev/null || echo "$API_RESPONSE"
return 0
elif echo "$API_RESPONSE" | grep -qi "unauthorized\|401"; then
print_error "Registry API Zugriff fehlgeschlagen: Unauthorized"
return 1
else
print_warning "Registry API Antwort: $API_RESPONSE"
return 1
fi
}
# Hauptfunktion
main() {
print_header "Docker Registry Credentials Test"
# Prüfungen
check_docker
check_curl
# Zeige Konfiguration
print_info "Verwendete Konfiguration:"
echo " REGISTRY_USER: $REGISTRY_USER"
echo " REGISTRY_PASSWORD: ${REGISTRY_PASSWORD:+*** (${#REGISTRY_PASSWORD} Zeichen)}"
echo " REGISTRY_DOMAIN: $REGISTRY_DOMAIN"
echo " REGISTRY_HOST: $REGISTRY_HOST"
echo " REGISTRY_PORT: $REGISTRY_PORT"
if [ -z "$REGISTRY_PASSWORD" ]; then
print_error ""
print_error "REGISTRY_PASSWORD ist nicht gesetzt!"
print_info ""
print_info "Verwendung:"
echo " export REGISTRY_PASSWORD='dein-passwort'"
echo " ./scripts/test-registry-credentials.sh"
echo ""
print_info "Oder in CI/CD:"
echo " REGISTRY_PASSWORD=\"\${{ secrets.REGISTRY_PASSWORD }}\" ./scripts/test-registry-credentials.sh"
exit 1
fi
echo ""
# Test-Ergebnisse
HTTP_AVAILABLE=false
HTTPS_AVAILABLE=false
HTTP_LOGIN_SUCCESS=false
HTTPS_LOGIN_SUCCESS=false
# Test 1: HTTP Connectivity
print_header "Test 1: HTTP Connectivity"
if test_http_connectivity "${REGISTRY_HOST}:${REGISTRY_PORT}"; then
HTTP_AVAILABLE=true
fi
# Test 2: HTTPS Connectivity
print_header "Test 2: HTTPS Connectivity"
if test_https_connectivity "$REGISTRY_DOMAIN"; then
HTTPS_AVAILABLE=true
fi
# Test 3: Docker Login über HTTP
if [ "$HTTP_AVAILABLE" = true ]; then
print_header "Test 3: Docker Login über HTTP"
if test_docker_login "${REGISTRY_HOST}:${REGISTRY_PORT}" "http"; then
HTTP_LOGIN_SUCCESS=true
fi
else
print_warning "Überspringe HTTP Login Test (Registry nicht erreichbar)"
fi
# Test 4: Docker Login über HTTPS
if [ "$HTTPS_AVAILABLE" = true ]; then
print_header "Test 4: Docker Login über HTTPS"
if test_docker_login "$REGISTRY_DOMAIN" "https"; then
HTTPS_LOGIN_SUCCESS=true
fi
else
print_warning "Überspringe HTTPS Login Test (Registry nicht erreichbar)"
fi
# Test 5: Registry API (nur wenn Login erfolgreich)
if [ "$HTTP_LOGIN_SUCCESS" = true ] || [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
print_header "Test 5: Registry API Zugriff"
if [ "$HTTP_LOGIN_SUCCESS" = true ]; then
test_registry_api "${REGISTRY_HOST}:${REGISTRY_PORT}" "http" || true
fi
if [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
test_registry_api "$REGISTRY_DOMAIN" "https" || true
fi
fi
# Zusammenfassung
print_header "Zusammenfassung"
if [ "$HTTP_LOGIN_SUCCESS" = true ] || [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
print_success "✅ Credentials sind korrekt und funktionieren!"
if [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
print_success "✅ HTTPS Login funktioniert (empfohlen)"
print_info "Verwende in Workflows: registry.michaelschiemer.de"
fi
if [ "$HTTP_LOGIN_SUCCESS" = true ]; then
print_warning "⚠️ HTTP Login funktioniert (Fallback)"
print_info "Verwende in Workflows: ${REGISTRY_HOST}:${REGISTRY_PORT}"
print_info "HINWEIS: Benötigt insecure-registry Konfiguration im Docker-daemon"
fi
exit 0
else
print_error "❌ Credentials funktionieren nicht!"
print_info ""
print_info "Nächste Schritte:"
print_info "1. Prüfe REGISTRY_USER in Gitea Secrets"
print_info "2. Prüfe REGISTRY_PASSWORD in Gitea Secrets"
print_info "3. Prüfe das Passwort in deployment/stacks/registry/auth/htpasswd auf dem Server"
print_info "4. Prüfe ob die Registry läuft: docker ps | grep registry"
print_info "5. Prüfe Registry-Logs: docker logs registry"
exit 1
fi
}
# Script ausführen
main "$@"

74
scripts/test/test-security.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# Security Configuration Test Script
# Tests production security configuration
GREEN="\e[32m"
YELLOW="\e[33m"
RED="\e[31m"
RESET="\e[0m"
BASE_URL="https://localhost"
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
echo -e "${YELLOW}Testing Production Security Configuration${RESET}"
echo "================================================"
# Function to test HTTP endpoint
test_endpoint() {
local path=$1
local expected_status=$2
local description=$3
echo -e "\n${YELLOW}Testing: ${description}${RESET}"
echo "Endpoint: ${path}"
response=$(curl -s -o /dev/null -w "%{http_code}" \
-H "User-Agent: $USER_AGENT" \
"${BASE_URL}${path}" 2>/dev/null)
if [ "$response" = "$expected_status" ]; then
echo -e "${GREEN}✓ PASS${RESET} - Got expected status: $response"
else
echo -e "${RED}✗ FAIL${RESET} - Expected: $expected_status, Got: $response"
fi
}
# Test blocked routes in production (should return 404)
echo -e "\n${YELLOW}=== Testing Blocked Routes ===${RESET}"
test_endpoint "/admin/discovery" "404" "Admin Discovery Route (blocked in production)"
test_endpoint "/admin/routes" "404" "Admin Routes Route (blocked in production)"
test_endpoint "/admin/performance" "404" "Admin Performance Route (blocked in production)"
test_endpoint "/debug" "404" "Debug Route (blocked in production)"
# Test IP-restricted routes (should return 403 from external IPs, but might be 200 from localhost)
echo -e "\n${YELLOW}=== Testing IP-Restricted Routes ===${RESET}"
test_endpoint "/admin" "200" "Admin Route (IP-restricted, should work from localhost)"
test_endpoint "/health" "200" "Health Route (IP-restricted, should work from localhost)"
# Test normal routes (should work)
echo -e "\n${YELLOW}=== Testing Normal Routes ===${RESET}"
test_endpoint "/" "200" "Home Route (should work)"
test_endpoint "/api/version" "200" "API Version Route (should work)"
echo -e "\n${YELLOW}=== Environment Configuration Test ===${RESET}"
# Check if APP_ENV is set correctly
if [ -f .env ]; then
APP_ENV=$(grep "^APP_ENV=" .env | cut -d'=' -f2)
APP_DEBUG=$(grep "^APP_DEBUG=" .env | cut -d'=' -f2)
echo "APP_ENV: $APP_ENV"
echo "APP_DEBUG: $APP_DEBUG"
if [ "$APP_ENV" = "production" ] && [ "$APP_DEBUG" = "false" ]; then
echo -e "${GREEN}✓ PASS${RESET} - Production environment correctly configured"
else
echo -e "${RED}✗ FAIL${RESET} - Environment not configured for production"
fi
else
echo -e "${RED}✗ FAIL${RESET} - .env file not found"
fi
echo -e "\n${YELLOW}Security test completed.${RESET}"
echo -e "\n${YELLOW}Note: For full production testing, deploy to production server and test from external IP.${RESET}"

View File

@@ -0,0 +1,37 @@
#!/bin/bash
echo "🧪 Testing Upload System with CSRF Protection"
echo "=============================================="
BASE_URL="https://localhost"
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
echo ""
echo "📋 Test 1: CSRF Token Generation"
echo "--------------------------------"
CSRF_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" "$BASE_URL/api/csrf/token?action=/api/images&method=post")
if [ $? -eq 0 ] && [[ $CSRF_RESPONSE == *"form_id"* ]]; then
echo "✅ CSRF API working"
echo "Response: $CSRF_RESPONSE"
else
echo "❌ CSRF API failed"
exit 1
fi
echo ""
echo "🌐 Test 2: Test Page Check"
echo "-------------------------"
HTTP_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" "$BASE_URL/admin/test/upload")
if [ "$HTTP_STATUS" = "200" ]; then
echo "✅ Test page accessible: $BASE_URL/admin/test/upload"
else
echo "❌ Test page not accessible (HTTP $HTTP_STATUS)"
fi
echo ""
echo "📊 Summary: System ready for browser testing!"
echo "Open: $BASE_URL/admin/test/upload"

140
scripts/test/test-ssl.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/bin/bash
#
# SSL Test Script for michaelschiemer.de
# Quick verification of SSL certificate and HTTPS connectivity
#
DOMAIN="michaelschiemer.de"
SERVER_IP="94.16.110.151"
# Colors
GREEN="\e[32m"
YELLOW="\e[33m"
RED="\e[31m"
BLUE="\e[34m"
RESET="\e[0m"
log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${RESET} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${RESET} $1"; }
log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
echo "=== SSL Test for $DOMAIN ==="
echo
# Test 1: DNS Resolution
log_info "Testing DNS resolution..."
resolved_ip=$(dig +short "$DOMAIN" | head -1)
if [[ "$resolved_ip" == "$SERVER_IP" ]]; then
log_success "DNS: $DOMAIN$resolved_ip"
else
log_warning "DNS: $DOMAIN$resolved_ip (expected: $SERVER_IP)"
fi
echo
# Test 2: Port Connectivity
log_info "Testing port connectivity..."
if nc -z "$DOMAIN" 443 2>/dev/null; then
log_success "Port 443: Accessible ✓"
else
log_error "Port 443: Not accessible ✗"
fi
if nc -z "$DOMAIN" 80 2>/dev/null; then
log_success "Port 80: Accessible ✓"
else
log_error "Port 80: Not accessible ✗"
fi
echo
# Test 3: HTTP to HTTPS Redirect
log_info "Testing HTTP to HTTPS redirect..."
http_response=$(curl -I -s "http://$DOMAIN" | head -1)
if echo "$http_response" | grep -q "301\|302"; then
log_success "HTTP Redirect: Working ✓"
curl -I -s "http://$DOMAIN" | grep -i "location:" || true
else
log_warning "HTTP Redirect: $http_response"
fi
echo
# Test 4: HTTPS Connection
log_info "Testing HTTPS connection..."
if curl -sSf "https://$DOMAIN" > /dev/null 2>&1; then
log_success "HTTPS Connection: Working ✓"
else
log_error "HTTPS Connection: Failed ✗"
log_info "Trying with --insecure flag..."
if curl -sSf --insecure "https://$DOMAIN" > /dev/null 2>&1; then
log_warning "HTTPS works with --insecure (certificate issue)"
else
log_error "HTTPS completely broken"
fi
fi
echo
# Test 5: SSL Certificate Details
log_info "Checking SSL certificate..."
cert_info=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -text 2>/dev/null)
if [[ -n "$cert_info" ]]; then
echo "Certificate Details:"
echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -dates 2>/dev/null
# Check if Let's Encrypt
if echo "$cert_info" | grep -q "Let's Encrypt"; then
log_success "Certificate: Let's Encrypt ✓"
else
log_warning "Certificate: Not Let's Encrypt (might be self-signed)"
fi
# Check expiration
exp_date=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [[ -n "$exp_date" ]]; then
exp_timestamp=$(date -d "$exp_date" +%s 2>/dev/null || echo "")
current_timestamp=$(date +%s)
if [[ -n "$exp_timestamp" ]] && [[ $exp_timestamp -gt $current_timestamp ]]; then
days_left=$(( (exp_timestamp - current_timestamp) / 86400 ))
if [[ $days_left -gt 30 ]]; then
log_success "Certificate Expiry: $days_left days remaining ✓"
else
log_warning "Certificate Expiry: $days_left days remaining (renew soon)"
fi
else
log_error "Certificate: Expired or invalid ✗"
fi
fi
else
log_error "Could not retrieve certificate information"
fi
echo
# Test 6: SSL Labs Grade (optional, requires internet)
log_info "SSL Labs test available at:"
echo "https://www.ssllabs.com/ssltest/analyze.html?d=$DOMAIN"
echo
# Test 7: Framework Health Check
log_info "Testing framework health endpoint..."
health_status=$(curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN/ping" 2>/dev/null)
if [[ "$health_status" == "200" ]]; then
log_success "Framework Health: OK ✓"
elif [[ "$health_status" == "404" ]]; then
log_warning "Framework Health: Endpoint not found (might be disabled)"
else
log_error "Framework Health: HTTP $health_status"
fi
# Summary
echo
echo "=== Test Summary ==="
echo "Domain: $DOMAIN"
echo "Target IP: $SERVER_IP"
echo
echo "Next steps if issues found:"
echo "1. Check DNS: dig +short $DOMAIN"
echo "2. Check firewall: nmap -p 80,443 $DOMAIN"
echo "3. Check containers: ssh deploy@$SERVER_IP 'docker compose ps'"
echo "4. Check nginx logs: ssh deploy@$SERVER_IP 'docker compose logs web'"
echo "5. Regenerate SSL: ./setup-production-ssl.sh"

View File

@@ -0,0 +1,111 @@
#!/bin/bash
# Upload System Test Script
# Tests the complete JavaScript upload system with CSRF protection
echo "🧪 Testing Upload System with CSRF Protection"
echo "================================================"
BASE_URL="https://localhost"
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
# Test 1: CSRF Token Generation
echo ""
echo "📋 Test 1: CSRF Token Generation"
echo "--------------------------------"
CSRF_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" \
"$BASE_URL/api/csrf/token?action=/api/images&method=post")
if [ $? -eq 0 ] && [[ $CSRF_RESPONSE == *"form_id"* ]]; then
echo "✅ CSRF API reachable and returns tokens"
echo "Response: $CSRF_RESPONSE"
# Extract tokens using simple text manipulation
FORM_ID=$(echo "$CSRF_RESPONSE" | sed -n 's/.*"form_id":"\([^"]*\)".*/\1/p')
TOKEN=$(echo "$CSRF_RESPONSE" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
echo "Form ID: $FORM_ID"
echo "Token: ${TOKEN:0:20}..."
else
echo "❌ CSRF API test failed"
echo "Response: $CSRF_RESPONSE"
exit 1
fi
# Test 2: Test Page Accessibility
echo ""
echo "🌐 Test 2: Test Page Accessibility"
echo "----------------------------------"
HTTP_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
"$BASE_URL/admin/test/upload")
if [ "$HTTP_STATUS" = "200" ]; then
echo "✅ Test page accessible at /admin/test/upload"
else
echo "❌ Test page not accessible (HTTP $HTTP_STATUS)"
fi
# Test 3: Upload API Endpoint Check
echo ""
echo "📤 Test 3: Upload API Endpoint Check"
echo "------------------------------------"
# Test without file (should return error about missing file)
UPLOAD_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" \
-H "X-CSRF-Form-ID: $FORM_ID" -H "X-CSRF-Token: $TOKEN" \
-X POST "$BASE_URL/api/images")
if [[ $UPLOAD_RESPONSE == *"No image file uploaded"* ]]; then
echo "✅ Upload API reachable and CSRF validation working"
echo "Expected error: No image file uploaded"
else
echo "❌ Upload API test failed"
echo "Response: $UPLOAD_RESPONSE"
fi
# Test 4: JavaScript Files Accessibility
echo ""
echo "📜 Test 4: JavaScript Files Accessibility"
echo "-----------------------------------------"
JS_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
"$BASE_URL/js/test-upload.js")
if [ "$JS_STATUS" = "200" ]; then
echo "✅ JavaScript test file accessible"
else
echo "❌ JavaScript test file not accessible (HTTP $JS_STATUS)"
fi
UPLOAD_JS_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
"$BASE_URL/js/utils/upload.js")
if [ "$UPLOAD_JS_STATUS" = "200" ]; then
echo "✅ Upload utility accessible"
else
echo "❌ Upload utility not accessible (HTTP $UPLOAD_JS_STATUS)"
fi
# Summary
echo ""
echo "📊 Test Summary"
echo "==============="
echo "✅ CSRF token generation: Working"
echo "✅ Test page: Available at $BASE_URL/admin/test/upload"
echo "✅ Upload API: Ready for file uploads"
echo "✅ JavaScript modules: Accessible"
echo ""
echo "🎯 Next Steps:"
echo "1. Open browser: $BASE_URL/admin/test/upload"
echo "2. Select image files and test upload"
echo "3. Check browser console for debug info"
echo "4. Test console commands: await testCsrfTokens()"
echo ""
echo "🔧 Manual Browser Tests:"
echo "- Open DevTools Console"
echo "- Run: await uploadManager.getCsrfTokens('/api/images', 'post')"
echo "- Select image files in the form"
echo "- Click Upload Files button"
echo "- Watch progress and results"

9
scripts/test/test-workflow.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
# Script to test Gitea workflows locally with act
# Maps custom runner labels to Docker images
act -P php-ci=php-ci:latest \
-P docker-build=docker:latest \
-P ubuntu-latest=ubuntu:latest \
-P ubuntu-22.04=ubuntu:22.04 \
"$@"