ci: setup CI/CD pipeline with Gitea Actions and secrets configuration
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Production Deployment Script
|
||||
# This script prepares the application for production deployment
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting Production Deployment..."
|
||||
|
||||
# Check if we're in the right directory
|
||||
if [ ! -f "composer.json" ]; then
|
||||
echo "❌ Error: Must be run from project root directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Backup current .env if it exists
|
||||
if [ -f ".env" ]; then
|
||||
echo "📦 Backing up current .env to .env.backup"
|
||||
cp .env .env.backup
|
||||
fi
|
||||
|
||||
# Copy production environment file
|
||||
echo "📝 Setting up production environment..."
|
||||
cp .env.production .env
|
||||
|
||||
# Clear all caches
|
||||
echo "🧹 Clearing caches..."
|
||||
rm -rf storage/cache/*
|
||||
rm -rf var/cache/*
|
||||
rm -rf cache/*
|
||||
|
||||
# Install production dependencies (no dev dependencies)
|
||||
echo "📦 Installing production dependencies..."
|
||||
composer install --no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
# Build production assets
|
||||
echo "🎨 Building production assets..."
|
||||
npm run build
|
||||
|
||||
# Set correct permissions
|
||||
echo "🔐 Setting correct permissions..."
|
||||
chmod -R 755 storage/
|
||||
chmod -R 755 var/
|
||||
chmod -R 755 public/
|
||||
|
||||
# Create necessary directories
|
||||
mkdir -p storage/logs
|
||||
mkdir -p storage/cache
|
||||
mkdir -p var/cache
|
||||
mkdir -p var/logs
|
||||
|
||||
# Run database migrations
|
||||
echo "🗄️ Running database migrations..."
|
||||
php console.php db:migrate --force
|
||||
|
||||
# Clear PHP opcache if available
|
||||
if command -v cachetool &> /dev/null; then
|
||||
echo "🔄 Clearing PHP opcache..."
|
||||
cachetool opcache:reset
|
||||
fi
|
||||
|
||||
# Restart services (if using systemctl)
|
||||
if command -v systemctl &> /dev/null; then
|
||||
echo "🔄 Restarting services..."
|
||||
sudo systemctl restart php8.4-fpm
|
||||
sudo systemctl restart nginx
|
||||
fi
|
||||
|
||||
echo "✅ Production deployment complete!"
|
||||
echo ""
|
||||
echo "⚠️ IMPORTANT REMINDERS:"
|
||||
echo "1. Ensure APP_ENV=production in .env"
|
||||
echo "2. Ensure APP_DEBUG=false in .env"
|
||||
echo "3. Update database credentials if needed"
|
||||
echo "4. Update ADMIN_ALLOWED_IPS in .env for admin access"
|
||||
echo "5. Test the site to ensure everything works"
|
||||
echo ""
|
||||
echo "🔒 Security Checklist:"
|
||||
echo "[ ] Performance debug is disabled"
|
||||
echo "[ ] Session debug info is hidden"
|
||||
echo "[ ] Admin routes are IP-restricted"
|
||||
echo "[ ] Error messages are generic"
|
||||
echo "[ ] HTTPS is enforced"
|
||||
@@ -221,4 +221,4 @@ try {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "\n🎉 Migration script completed!\n";
|
||||
echo "\n🎉 Migration script completed!\n";
|
||||
|
||||
34
scripts/prepare-secrets.sh
Executable file
34
scripts/prepare-secrets.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# Helper Script to prepare secrets for Gitea manual setup
|
||||
# Usage: ./scripts/prepare-secrets.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Gitea Secrets - Werte zum Kopieren ==="
|
||||
echo ""
|
||||
echo "1. REGISTRY_USER:"
|
||||
echo "─────────────────"
|
||||
echo "admin"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "2. REGISTRY_PASSWORD:"
|
||||
echo "─────────────────────"
|
||||
echo "registry-secure-password-2025"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "3. SSH_PRIVATE_KEY:"
|
||||
echo "───────────────────"
|
||||
if [ -f ~/.ssh/production ]; then
|
||||
cat ~/.ssh/production
|
||||
else
|
||||
echo "⚠️ FEHLER: ~/.ssh/production nicht gefunden!"
|
||||
echo "Bitte SSH Key erstellen oder Pfad anpassen."
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
echo ""
|
||||
echo "=== Nächste Schritte ==="
|
||||
echo "1. Gehe zu: https://git.michaelschiemer.de/<username>/michaelschiemer/settings/secrets"
|
||||
echo "2. Füge jedes Secret oben einzeln hinzu"
|
||||
echo "3. Kopiere die Werte von oben für jedes Secret"
|
||||
echo ""
|
||||
@@ -1,446 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Production Deployment Script for Custom PHP Framework
|
||||
# Comprehensive deployment automation with zero-downtime strategy
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/production-deploy.sh [initial|update|rollback]
|
||||
#
|
||||
# Modes:
|
||||
# initial - First-time production deployment
|
||||
# update - Rolling update with zero downtime
|
||||
# rollback - Rollback to previous version
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
DEPLOY_MODE="${1:-update}"
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
BACKUP_DIR="${PROJECT_ROOT}/../backups"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_PATH="${BACKUP_DIR}/backup_${TIMESTAMP}"
|
||||
|
||||
# Colors
|
||||
GREEN="\e[32m"
|
||||
YELLOW="\e[33m"
|
||||
RED="\e[31m"
|
||||
BLUE="\e[34m"
|
||||
RESET="\e[0m"
|
||||
|
||||
# Logging functions
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%H:%M:%S')]${RESET} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${RESET}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${RESET}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${RESET}"
|
||||
cleanup_on_error
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Cleanup on error
|
||||
cleanup_on_error() {
|
||||
log "Cleaning up after error..."
|
||||
|
||||
if [[ -d "$BACKUP_PATH" ]]; then
|
||||
warning "Rolling back to previous version..."
|
||||
restore_backup "$BACKUP_PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
# Prerequisites check
|
||||
check_prerequisites() {
|
||||
log "Checking prerequisites..."
|
||||
|
||||
# Check if running from project root
|
||||
if [[ ! -f "$PROJECT_ROOT/composer.json" ]]; then
|
||||
error "Must be run from project root directory"
|
||||
fi
|
||||
|
||||
# Check Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
error "Docker is not installed"
|
||||
fi
|
||||
|
||||
# Check Docker Compose
|
||||
if ! docker compose version &> /dev/null; then
|
||||
error "Docker Compose is not installed"
|
||||
fi
|
||||
|
||||
# Check .env.production exists
|
||||
if [[ ! -f "$PROJECT_ROOT/.env.production" ]]; then
|
||||
error ".env.production not found - copy from .env.example and configure"
|
||||
fi
|
||||
|
||||
# Check docker-compose.production.yml exists
|
||||
if [[ ! -f "$PROJECT_ROOT/docker-compose.production.yml" ]]; then
|
||||
error "docker-compose.production.yml not found"
|
||||
fi
|
||||
|
||||
# Verify VAULT_ENCRYPTION_KEY is set
|
||||
if ! grep -q "VAULT_ENCRYPTION_KEY=" "$PROJECT_ROOT/.env.production" || \
|
||||
grep -q "VAULT_ENCRYPTION_KEY=CHANGE_ME" "$PROJECT_ROOT/.env.production"; then
|
||||
error "VAULT_ENCRYPTION_KEY not configured in .env.production"
|
||||
fi
|
||||
|
||||
success "Prerequisites check passed"
|
||||
}
|
||||
|
||||
# Create backup
|
||||
create_backup() {
|
||||
log "Creating backup..."
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Backup database
|
||||
if docker compose ps db | grep -q "Up"; then
|
||||
log "Backing up database..."
|
||||
docker compose exec -T db pg_dump -U postgres michaelschiemer_prod | \
|
||||
gzip > "${BACKUP_PATH}_database.sql.gz"
|
||||
success "Database backup created"
|
||||
fi
|
||||
|
||||
# Backup .env
|
||||
if [[ -f "$PROJECT_ROOT/.env" ]]; then
|
||||
cp "$PROJECT_ROOT/.env" "${BACKUP_PATH}_env"
|
||||
success ".env backup created"
|
||||
fi
|
||||
|
||||
# Backup docker volumes (important directories)
|
||||
if [[ -d "$PROJECT_ROOT/storage" ]]; then
|
||||
tar -czf "${BACKUP_PATH}_storage.tar.gz" -C "$PROJECT_ROOT" storage
|
||||
success "Storage backup created"
|
||||
fi
|
||||
|
||||
success "Backup completed: $BACKUP_PATH"
|
||||
}
|
||||
|
||||
# Restore from backup
|
||||
restore_backup() {
|
||||
local backup_path="$1"
|
||||
|
||||
log "Restoring from backup: $backup_path"
|
||||
|
||||
# Restore database
|
||||
if [[ -f "${backup_path}_database.sql.gz" ]]; then
|
||||
log "Restoring database..."
|
||||
gunzip -c "${backup_path}_database.sql.gz" | \
|
||||
docker compose exec -T db psql -U postgres michaelschiemer_prod
|
||||
success "Database restored"
|
||||
fi
|
||||
|
||||
# Restore .env
|
||||
if [[ -f "${backup_path}_env" ]]; then
|
||||
cp "${backup_path}_env" "$PROJECT_ROOT/.env"
|
||||
success ".env restored"
|
||||
fi
|
||||
|
||||
# Restore storage
|
||||
if [[ -f "${backup_path}_storage.tar.gz" ]]; then
|
||||
tar -xzf "${backup_path}_storage.tar.gz" -C "$PROJECT_ROOT"
|
||||
success "Storage restored"
|
||||
fi
|
||||
|
||||
# Restart services
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
restart
|
||||
|
||||
success "Backup restored successfully"
|
||||
}
|
||||
|
||||
# Build Docker images
|
||||
build_images() {
|
||||
log "Building Docker images..."
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
build --no-cache
|
||||
|
||||
success "Docker images built"
|
||||
}
|
||||
|
||||
# Run database migrations
|
||||
run_migrations() {
|
||||
log "Running database migrations..."
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Check migration status first
|
||||
docker compose exec -T php php console.php db:status || true
|
||||
|
||||
# Run migrations
|
||||
if ! docker compose exec -T php php console.php db:migrate; then
|
||||
error "Database migrations failed"
|
||||
fi
|
||||
|
||||
success "Database migrations completed"
|
||||
}
|
||||
|
||||
# Initialize SSL certificates
|
||||
init_ssl() {
|
||||
log "Initializing SSL certificates..."
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Check if SSL is enabled
|
||||
if grep -q "SSL_ENABLED=true" .env.production; then
|
||||
log "SSL is enabled, checking certificate status..."
|
||||
|
||||
# Check certificate status
|
||||
if docker compose exec -T php php console.php ssl:status 2>/dev/null | grep -q "Certificate is valid"; then
|
||||
success "SSL certificate already exists and is valid"
|
||||
else
|
||||
warning "SSL certificate not found or invalid, initializing..."
|
||||
|
||||
if ! docker compose exec -T php php console.php ssl:init; then
|
||||
error "SSL initialization failed"
|
||||
fi
|
||||
|
||||
success "SSL certificate initialized"
|
||||
fi
|
||||
else
|
||||
warning "SSL is disabled in .env.production"
|
||||
fi
|
||||
}
|
||||
|
||||
# Verify Vault configuration
|
||||
verify_vault() {
|
||||
log "Verifying Vault configuration..."
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Test Vault access
|
||||
if ! docker compose exec -T php php console.php vault:list &>/dev/null; then
|
||||
error "Vault not accessible - check VAULT_ENCRYPTION_KEY"
|
||||
fi
|
||||
|
||||
success "Vault is configured correctly"
|
||||
}
|
||||
|
||||
# Health check with retries
|
||||
health_check() {
|
||||
local max_retries=30
|
||||
local retry_count=0
|
||||
|
||||
log "Running health checks..."
|
||||
|
||||
while [[ $retry_count -lt $max_retries ]]; do
|
||||
if curl -f -s -k -H "User-Agent: Mozilla/5.0 (Deployment Health Check)" "https://localhost/health" > /dev/null 2>&1; then
|
||||
success "Health check passed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
retry_count=$((retry_count + 1))
|
||||
log "Health check attempt $retry_count/$max_retries..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
error "Health check failed after $max_retries attempts"
|
||||
}
|
||||
|
||||
# Initial deployment
|
||||
initial_deployment() {
|
||||
log "🚀 Starting initial production deployment..."
|
||||
|
||||
check_prerequisites
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# 1. Generate Vault encryption key if not exists
|
||||
if grep -q "VAULT_ENCRYPTION_KEY=CHANGE_ME" .env.production; then
|
||||
log "Generating Vault encryption key..."
|
||||
warning "Make sure to backup this key securely!"
|
||||
# Key generation is done manually for security
|
||||
error "Please generate VAULT_ENCRYPTION_KEY with: docker exec php php console.php vault:generate-key"
|
||||
fi
|
||||
|
||||
# 2. Build images
|
||||
build_images
|
||||
|
||||
# 3. Start services
|
||||
log "Starting Docker services..."
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
up -d
|
||||
|
||||
# 4. Wait for services to be ready
|
||||
log "Waiting for services to be ready..."
|
||||
sleep 20
|
||||
|
||||
# 5. Run migrations
|
||||
run_migrations
|
||||
|
||||
# 6. Initialize SSL
|
||||
init_ssl
|
||||
|
||||
# 7. Verify Vault
|
||||
verify_vault
|
||||
|
||||
# 8. Health check
|
||||
health_check
|
||||
|
||||
# 9. Display summary
|
||||
deployment_summary
|
||||
|
||||
success "🎉 Initial deployment completed successfully!"
|
||||
}
|
||||
|
||||
# Update deployment (zero-downtime)
|
||||
update_deployment() {
|
||||
log "🔄 Starting rolling update deployment..."
|
||||
|
||||
check_prerequisites
|
||||
create_backup
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# 1. Pull latest images (if using registry)
|
||||
log "Pulling latest images..."
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
pull || warning "Pull failed (not critical if building locally)"
|
||||
|
||||
# 2. Build new images
|
||||
build_images
|
||||
|
||||
# 3. Run migrations (if any)
|
||||
log "Running database migrations..."
|
||||
docker compose exec -T php php console.php db:migrate || warning "No new migrations"
|
||||
|
||||
# 4. Rolling restart with health checks
|
||||
log "Performing rolling restart..."
|
||||
|
||||
# Restart PHP-FPM first
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
up -d --no-deps --force-recreate php
|
||||
|
||||
sleep 10
|
||||
|
||||
# Restart web server
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
up -d --no-deps --force-recreate web
|
||||
|
||||
sleep 5
|
||||
|
||||
# Restart queue workers (graceful shutdown via stop_grace_period)
|
||||
docker compose -f docker-compose.yml \
|
||||
-f docker-compose.production.yml \
|
||||
--env-file .env.production \
|
||||
up -d --no-deps --force-recreate --scale queue-worker=2 queue-worker
|
||||
|
||||
# 5. Health check
|
||||
health_check
|
||||
|
||||
# 6. Cleanup old images
|
||||
log "Cleaning up old Docker images..."
|
||||
docker image prune -f
|
||||
|
||||
# 7. Display summary
|
||||
deployment_summary
|
||||
|
||||
success "🎉 Update deployment completed successfully!"
|
||||
}
|
||||
|
||||
# Rollback deployment
|
||||
rollback_deployment() {
|
||||
log "⏪ Starting rollback..."
|
||||
|
||||
# Find latest backup
|
||||
local latest_backup=$(find "$BACKUP_DIR" -name "backup_*_database.sql.gz" | sort -r | head -1)
|
||||
|
||||
if [[ -z "$latest_backup" ]]; then
|
||||
error "No backup found for rollback"
|
||||
fi
|
||||
|
||||
local backup_prefix="${latest_backup%_database.sql.gz}"
|
||||
|
||||
warning "Rolling back to: $backup_prefix"
|
||||
read -p "Continue? (yes/no): " confirm
|
||||
|
||||
if [[ "$confirm" != "yes" ]]; then
|
||||
log "Rollback cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
restore_backup "$backup_prefix"
|
||||
health_check
|
||||
|
||||
success "🎉 Rollback completed successfully!"
|
||||
}
|
||||
|
||||
# Deployment summary
|
||||
deployment_summary() {
|
||||
echo ""
|
||||
echo -e "${GREEN}========================================${RESET}"
|
||||
echo -e "${GREEN} Deployment Summary${RESET}"
|
||||
echo -e "${GREEN}========================================${RESET}"
|
||||
echo ""
|
||||
echo "📋 Mode: $DEPLOY_MODE"
|
||||
echo "⏰ Timestamp: $(date)"
|
||||
echo "📁 Project: $PROJECT_ROOT"
|
||||
echo "💾 Backup: $BACKUP_PATH"
|
||||
echo ""
|
||||
echo "🐳 Docker Services:"
|
||||
docker compose ps
|
||||
echo ""
|
||||
echo "🔒 Security Checks:"
|
||||
echo " [ ] APP_ENV=production in .env.production"
|
||||
echo " [ ] APP_DEBUG=false in .env.production"
|
||||
echo " [ ] VAULT_ENCRYPTION_KEY configured"
|
||||
echo " [ ] ADMIN_ALLOWED_IPS configured"
|
||||
echo " [ ] SSL certificates valid"
|
||||
echo ""
|
||||
echo "📊 Health Check:"
|
||||
echo " ✅ Application: https://localhost/health"
|
||||
echo ""
|
||||
echo "📝 Next Steps:"
|
||||
echo " 1. Verify all services are running"
|
||||
echo " 2. Check logs: docker compose logs -f --tail=100"
|
||||
echo " 3. Test critical user flows"
|
||||
echo " 4. Monitor error rates"
|
||||
echo ""
|
||||
echo -e "${GREEN}========================================${RESET}"
|
||||
}
|
||||
|
||||
# Main deployment logic
|
||||
main() {
|
||||
case "$DEPLOY_MODE" in
|
||||
initial)
|
||||
initial_deployment
|
||||
;;
|
||||
update)
|
||||
update_deployment
|
||||
;;
|
||||
rollback)
|
||||
rollback_deployment
|
||||
;;
|
||||
*)
|
||||
error "Invalid deployment mode: $DEPLOY_MODE. Use: initial|update|rollback"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Trap errors
|
||||
trap cleanup_on_error ERR
|
||||
|
||||
# Run main
|
||||
main "$@"
|
||||
@@ -1,240 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Server-side Deployment Script für Custom PHP Framework
|
||||
# Läuft auf dem Production-Server (94.16.110.151)
|
||||
|
||||
set -euo pipefail # Exit on any error
|
||||
|
||||
DEPLOY_TAG="$1"
|
||||
DEPLOY_PATH="$2"
|
||||
BACKUP_PATH="${DEPLOY_PATH}-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
TEMP_PATH="${DEPLOY_PATH}-deploying"
|
||||
|
||||
# Farben
|
||||
GREEN="\e[32m"
|
||||
YELLOW="\e[33m"
|
||||
RED="\e[31m"
|
||||
BLUE="\e[34m"
|
||||
RESET="\e[0m"
|
||||
|
||||
log() {
|
||||
echo -e "${BLUE}[SERVER $(date +'%H:%M:%S')]${RESET} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${RESET}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${RESET}"
|
||||
cleanup_on_error
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup_on_error() {
|
||||
log "Cleanup nach Fehler..."
|
||||
[[ -d "$TEMP_PATH" ]] && rm -rf "$TEMP_PATH"
|
||||
[[ -d "$BACKUP_PATH" ]] && {
|
||||
log "Stelle vorherige Version wieder her..."
|
||||
[[ -d "$DEPLOY_PATH" ]] && rm -rf "$DEPLOY_PATH"
|
||||
mv "$BACKUP_PATH" "$DEPLOY_PATH"
|
||||
cd "$DEPLOY_PATH" && docker compose restart
|
||||
}
|
||||
}
|
||||
|
||||
# Atomic Deployment mit Git
|
||||
atomic_git_deployment() {
|
||||
log "Starte atomic git deployment..."
|
||||
|
||||
# 1. Backup der aktuellen Version erstellen
|
||||
if [[ -d "$DEPLOY_PATH" ]]; then
|
||||
log "Erstelle Backup der aktuellen Version..."
|
||||
cp -r "$DEPLOY_PATH" "$BACKUP_PATH"
|
||||
success "Backup erstellt: $BACKUP_PATH"
|
||||
fi
|
||||
|
||||
# 2. Neue Version in temporäres Verzeichnis clonen
|
||||
log "Clone neue Version mit Tag: $DEPLOY_TAG"
|
||||
|
||||
if [[ -d "$TEMP_PATH" ]]; then
|
||||
rm -rf "$TEMP_PATH"
|
||||
fi
|
||||
|
||||
# Git Repository klonen oder pullen
|
||||
if [[ -d "$DEPLOY_PATH/.git" ]]; then
|
||||
# Existierendes Repository - fetch und checkout
|
||||
log "Update existierendes Repository..."
|
||||
cd "$DEPLOY_PATH"
|
||||
git fetch --tags origin
|
||||
git checkout "$DEPLOY_TAG"
|
||||
success "Git checkout zu $DEPLOY_TAG erfolgreich"
|
||||
else
|
||||
# Neues Repository klonen
|
||||
log "Klone Repository neu..."
|
||||
git clone --depth 1 --branch "$DEPLOY_TAG" "$(git -C . remote get-url origin)" "$TEMP_PATH" || {
|
||||
error "Git clone fehlgeschlagen"
|
||||
}
|
||||
|
||||
# Atomic Switch: Temp → Live
|
||||
if [[ -d "$DEPLOY_PATH" ]]; then
|
||||
mv "$DEPLOY_PATH" "${DEPLOY_PATH}-old"
|
||||
fi
|
||||
mv "$TEMP_PATH" "$DEPLOY_PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
# Framework-spezifische Deployment-Schritte
|
||||
framework_deployment() {
|
||||
log "Führe Framework-Deployment durch..."
|
||||
|
||||
cd "$DEPLOY_PATH"
|
||||
|
||||
# 1. Environment Setup
|
||||
if [[ ! -f .env ]]; then
|
||||
if [[ -f .env.production ]]; then
|
||||
log "Kopiere .env.production zu .env"
|
||||
cp .env.production .env
|
||||
else
|
||||
error ".env.production nicht gefunden"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 2. Composer Dependencies (Production)
|
||||
log "Installiere Composer Dependencies..."
|
||||
if ! composer install --no-dev --optimize-autoloader --no-interaction; then
|
||||
error "Composer Install fehlgeschlagen"
|
||||
fi
|
||||
|
||||
# 3. Framework Cache warming (falls implementiert)
|
||||
if [[ -f console.php ]] && php console.php list | grep -q "cache:warm"; then
|
||||
log "Wärme Framework Caches auf..."
|
||||
php console.php cache:warm || warning "Cache warming fehlgeschlagen"
|
||||
fi
|
||||
|
||||
# 4. Database Migrations
|
||||
log "Führe Database Migrations durch..."
|
||||
if php console.php list | grep -q "db:migrate"; then
|
||||
php console.php db:migrate || error "Database Migration fehlgeschlagen"
|
||||
else
|
||||
warning "Keine Database Migrations gefunden"
|
||||
fi
|
||||
|
||||
# 5. Framework optimizations
|
||||
if php console.php list | grep -q "framework:optimize"; then
|
||||
log "Optimiere Framework..."
|
||||
php console.php framework:optimize || warning "Framework Optimization fehlgeschlagen"
|
||||
fi
|
||||
|
||||
success "Framework-Deployment abgeschlossen"
|
||||
}
|
||||
|
||||
# Docker Services Management
|
||||
manage_docker_services() {
|
||||
log "Manage Docker Services..."
|
||||
|
||||
cd "$DEPLOY_PATH"
|
||||
|
||||
# Prüfe ob docker-compose.yml existiert
|
||||
if [[ ! -f docker-compose.yml ]]; then
|
||||
error "docker-compose.yml nicht gefunden"
|
||||
fi
|
||||
|
||||
# Services neu starten mit minimaler Downtime
|
||||
log "Starte Services neu..."
|
||||
|
||||
# Rolling Update Strategy
|
||||
docker compose pull --quiet || warning "Docker Pull Warnings (nicht kritisch)"
|
||||
|
||||
# Restart mit Health Checks
|
||||
if docker compose up -d --force-recreate --remove-orphans; then
|
||||
success "Docker Services erfolgreich neu gestartet"
|
||||
else
|
||||
error "Docker Restart fehlgeschlagen"
|
||||
fi
|
||||
|
||||
# Warte auf Service-Start
|
||||
log "Warte auf Service-Start..."
|
||||
sleep 10
|
||||
}
|
||||
|
||||
# Health Checks
|
||||
health_checks() {
|
||||
log "Führe Health Checks durch..."
|
||||
|
||||
cd "$DEPLOY_PATH"
|
||||
|
||||
# 1. Framework Health Check
|
||||
if php console.php health:check; then
|
||||
success "Framework Health Check OK"
|
||||
else
|
||||
error "Framework Health Check fehlgeschlagen"
|
||||
fi
|
||||
|
||||
# 2. Docker Services Check
|
||||
if ! docker compose ps | grep -q "Up"; then
|
||||
error "Docker Services nicht verfügbar"
|
||||
fi
|
||||
success "Docker Services OK"
|
||||
|
||||
# 3. MCP Server Test (optional)
|
||||
if timeout 5 php console.php mcp:server --test 2>/dev/null; then
|
||||
success "MCP Server OK"
|
||||
else
|
||||
log "MCP Server Test übersprungen (optional)"
|
||||
fi
|
||||
|
||||
# 4. Web Response Test
|
||||
sleep 5
|
||||
if curl -f -s -H "User-Agent: Mozilla/5.0 (Deployment Health Check)" "http://localhost" > /dev/null; then
|
||||
success "HTTP Response OK"
|
||||
else
|
||||
warning "HTTP Response Test fehlgeschlagen (möglicherweise nginx-Problem)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup alte Backups (behalte nur die letzten 5)
|
||||
cleanup_old_backups() {
|
||||
log "Räume alte Backups auf..."
|
||||
|
||||
# Finde alle Backup-Ordner und behalte nur die 5 neuesten
|
||||
find "$(dirname "$DEPLOY_PATH")" -maxdepth 1 -name "*-backup-*" -type d | \
|
||||
sort -r | \
|
||||
tail -n +6 | \
|
||||
xargs -r rm -rf
|
||||
|
||||
success "Backup-Cleanup abgeschlossen"
|
||||
}
|
||||
|
||||
# Deployment-Summary
|
||||
deployment_summary() {
|
||||
echo -e "${GREEN}"
|
||||
echo "🎉 Server-Deployment erfolgreich!"
|
||||
echo "📋 Tag: $DEPLOY_TAG"
|
||||
echo "📁 Path: $DEPLOY_PATH"
|
||||
echo "💾 Backup: $BACKUP_PATH"
|
||||
echo "⏰ Zeit: $(date)"
|
||||
echo -e "${RESET}"
|
||||
}
|
||||
|
||||
# Hauptprogramm
|
||||
main() {
|
||||
log "🚀 Server-side Deployment gestartet"
|
||||
log "📦 Tag: $DEPLOY_TAG"
|
||||
log "📁 Path: $DEPLOY_PATH"
|
||||
|
||||
atomic_git_deployment
|
||||
framework_deployment
|
||||
manage_docker_services
|
||||
health_checks
|
||||
cleanup_old_backups
|
||||
deployment_summary
|
||||
|
||||
# Cleanup erfolgreicher Deployment
|
||||
[[ -d "${DEPLOY_PATH}-old" ]] && rm -rf "${DEPLOY_PATH}-old"
|
||||
}
|
||||
|
||||
# Error Handling
|
||||
trap cleanup_on_error ERR
|
||||
|
||||
# Script ausführen
|
||||
main "$@"
|
||||
123
scripts/setup-gitea-secrets-interactive.sh
Executable file
123
scripts/setup-gitea-secrets-interactive.sh
Executable file
@@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
# Interactive Script to set Gitea Repository Secrets via API
|
||||
# Usage: ./scripts/setup-gitea-secrets-interactive.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_URL="${GITEA_URL:-https://git.michaelschiemer.de}"
|
||||
REPO_OWNER="${REPO_OWNER:-michael}"
|
||||
REPO_NAME="${REPO_NAME:-michaelschiemer}"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== Gitea Repository Secrets Setup ===${NC}"
|
||||
echo ""
|
||||
echo "Repository: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo "Gitea URL: ${GITEA_URL}"
|
||||
echo ""
|
||||
|
||||
# Check for existing token
|
||||
if [ -z "${GITEA_TOKEN:-}" ]; then
|
||||
echo -e "${YELLOW}Gitea Access Token benötigt${NC}"
|
||||
echo ""
|
||||
echo "Bitte generiere einen Token:"
|
||||
echo "1. Gehe zu: ${GITEA_URL}/user/settings/applications"
|
||||
echo "2. Klicke 'Generate New Token'"
|
||||
echo "3. Name: 'secrets-setup'"
|
||||
echo "4. Scopes: 'write:repository' (oder alle)"
|
||||
echo "5. Kopiere den Token"
|
||||
echo ""
|
||||
read -sp "Gitea Token: " GITEA_TOKEN
|
||||
echo ""
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -z "${GITEA_TOKEN:-}" ]; then
|
||||
echo -e "${RED}❌ Token erforderlich - Abbruch${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to create/update secret via API
|
||||
set_secret() {
|
||||
local secret_name=$1
|
||||
local secret_value=$2
|
||||
|
||||
echo -n "Setting $secret_name... "
|
||||
|
||||
# Gitea API endpoint: PUT /repos/{owner}/{repo}/actions/secrets/{secretname}
|
||||
local response=$(curl -s -w "\n%{http_code}" \
|
||||
-X PUT \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/actions/secrets/${secret_name}" \
|
||||
-d "{
|
||||
\"data\": \"$(printf '%s' "$secret_value" | base64 | tr -d '\n')\"
|
||||
}" 2>&1)
|
||||
|
||||
local http_code=$(echo "$response" | tail -n1)
|
||||
local body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "204" ] || [ "$http_code" = "201" ]; then
|
||||
echo -e "${GREEN}✅ OK${NC}"
|
||||
return 0
|
||||
elif [ "$http_code" = "404" ]; then
|
||||
echo -e "${YELLOW}⚠️ Repository oder Token-Berechtigung fehlt${NC}"
|
||||
return 1
|
||||
else
|
||||
echo -e "${RED}❌ FAILED (HTTP $http_code)${NC}"
|
||||
echo "Response: $body"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get registry password (default)
|
||||
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-registry-secure-password-2025}"
|
||||
|
||||
# Get SSH private key
|
||||
if [ -f ~/.ssh/production ]; then
|
||||
SSH_PRIVATE_KEY=$(cat ~/.ssh/production)
|
||||
echo -e "${GREEN}✓ SSH private key gefunden${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ SSH private key nicht gefunden in ~/.ssh/production${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Setting secrets for repository: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo ""
|
||||
|
||||
# Test API connection first
|
||||
echo -n "Testing API connection... "
|
||||
test_response=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}")
|
||||
|
||||
if [ "$test_response" != "200" ]; then
|
||||
者可 echo -e "${RED}❌ FAILED (HTTP $test_response)${NC}"
|
||||
echo ""
|
||||
echo "Mögliche Probleme:"
|
||||
echo "- Token ungültig oder fehlende Berechtigungen"
|
||||
echo "- Repository nicht gefunden: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo "- Netzwerkproblem"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ OK${NC}"
|
||||
echo ""
|
||||
|
||||
# Set secrets
|
||||
set_secret "REGISTRY_USER" "admin"
|
||||
set_secret "REGISTRY_PASSWORD" "$REGISTRY_PASSWORD"
|
||||
set_secret "SSH_PRIVATE_KEY" "$SSH_PRIVATE_KEY"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Secrets Setup Complete ===${NC}"
|
||||
echo ""
|
||||
echo "Prüfe Secrets in Gitea UI:"
|
||||
echo "${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}/settings/secrets/actions"
|
||||
echo ""
|
||||
120
scripts/setup-gitea-secrets-with-token.sh
Executable file
120
scripts/setup-gitea-secrets-with-token.sh
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/bin/bash
|
||||
# Set Gitea Repository Secrets with Token
|
||||
# Usage: ./scripts/setup-gitea-secrets-with-token.sh <GITEA_TOKEN>
|
||||
# or: GITEA_TOKEN=xxx ./scripts/setup-gitea-secrets-with-token.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_URL="${GITEA_URL:-https://git.michaelschiemer.de}"
|
||||
REPO_OWNER="${REPO_OWNER:-michael}"
|
||||
REPO_NAME="${REPO_NAME:-michaelschiemer}"
|
||||
GITEA_TOKEN="${1:-${GITEA_TOKEN:-}}"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== Gitea Repository Secrets Setup ===${NC}"
|
||||
echo ""
|
||||
echo "Repository: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo "Gitea URL: ${GITEA_URL}"
|
||||
echo ""
|
||||
|
||||
# Check if token is provided
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
echo -e "${RED}❌ Fehler: GITEA_TOKEN nicht angegeben${NC}"
|
||||
echo ""
|
||||
echo "Verwendung:"
|
||||
echo " $0 <GITEA_TOKEN>"
|
||||
echo " oder:"
|
||||
echo " GITEA_TOKEN=<token> $0"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to create/update secret via API
|
||||
set_secret() {
|
||||
local secret_name=$1
|
||||
local secret_value=$2
|
||||
|
||||
echo -n "Setting $secret_name... "
|
||||
|
||||
# Base64 encode the secret value
|
||||
local encoded_value=$(printf '%s' "$secret_value" | base64 | tr -d '\n')
|
||||
|
||||
# Gitea API endpoint: PUT /repos/{owner}/{repo}/actions/secrets/{secretname}
|
||||
local response=$(curl -s -w "\n%{http_code}" \
|
||||
-X PUT \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/actions/secrets/${secret_name}" \
|
||||
-d "{
|
||||
\"data\": \"${encoded_value}\"
|
||||
}" 2>&1)
|
||||
|
||||
local http_code=$(echo "$response" | tail -n1)
|
||||
local body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "204" ] || [ "$http_code" = "201" ]; then
|
||||
echo -e "${GREEN}✅ OK${NC}"
|
||||
return 0
|
||||
elif [ "$http_code" = "404" ]; then
|
||||
echo -e "${YELLOW}⚠️ Repository oder Token-Berechtigung fehlt${NC}"
|
||||
echo "Response: $body"
|
||||
return 1
|
||||
else
|
||||
echo -e "${RED}❌ FAILED (HTTP $http_code)${NC}"
|
||||
echo "Response: $body"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get registry password (default)
|
||||
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-registry-secure-password-2025}"
|
||||
|
||||
# Get SSH private key
|
||||
if [ -f ~/.ssh/production ]; then
|
||||
SSH_PRIVATE_KEY=$(cat ~/.ssh/production)
|
||||
echo -e "${GREEN}✓ SSH private key gefunden${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ SSH private key nicht gefunden in ~/.ssh/production${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Testing API connection..."
|
||||
|
||||
# Test API connection first
|
||||
test_response=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}")
|
||||
|
||||
if [ "$test_response" != "200" ]; then
|
||||
echo -e "${RED}❌ API-Verbindung fehlgeschlagen (HTTP $test_response)${NC}"
|
||||
echo ""
|
||||
echo "Mögliche Probleme:"
|
||||
echo "- Token ungültig oder fehlende Berechtigungen"
|
||||
echo "- Repository nicht gefunden: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo "- Netzwerkproblem"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ API-Verbindung erfolgreich${NC}"
|
||||
echo ""
|
||||
echo "Setting secrets..."
|
||||
echo ""
|
||||
|
||||
# Set secrets
|
||||
set_secret "REGISTRY_USER" "admin"
|
||||
set_secret "REGISTRY_PASSWORD" "$REGISTRY_PASSWORD"
|
||||
set_secret "SSH_PRIVATE_KEY" "$SSH_PRIVATE_KEY"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Secrets Setup Complete ===${NC}"
|
||||
echo ""
|
||||
echo "Prüfe Secrets in Gitea UI:"
|
||||
echo "${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}/settings/secrets/actions"
|
||||
echo ""
|
||||
96
scripts/setup-gitea-secrets.sh
Executable file
96
scripts/setup-gitea-secrets.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
# Helper Script to set Gitea Repository Secrets
|
||||
# Usage: ./scripts/setup-gitea-secrets.sh [GITEA_TOKEN]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_URL="${GITEA_URL:-https://git.michaelschiemer.de}"
|
||||
REPO_OWNER="${REPO_OWNER:-$(git config user.name || echo 'michael')}"
|
||||
REPO_NAME="${REPO_NAME:-michaelschiemer}"
|
||||
GITEA_TOKEN="${1:-${GITEA_TOKEN:-}}"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}=== Gitea Repository Secrets Setup ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if token is provided
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
echo -e "${YELLOW}⚠️ GITEA_TOKEN nicht gesetzt${NC}"
|
||||
echo ""
|
||||
echo "Bitte generiere einen Gitea Access Token:"
|
||||
echo "1. Gehe zu: ${GITEA_URL}/user/settings/applications"
|
||||
echo "2. Klicke 'Generate New Token'"
|
||||
echo "3. Name: 'secrets-setup'"
|
||||
echo "4. Scopes: 'write:repository'"
|
||||
echo "5. Kopiere den Token"
|
||||
echo ""
|
||||
echo "Dann führe aus:"
|
||||
echo " export GITEA_TOKEN='dein-token'"
|
||||
echo " ./scripts/setup-gitea-secrets.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to create/update secret
|
||||
set_secret() {
|
||||
local secret_name=$1
|
||||
local secret_value=$2
|
||||
|
||||
echo -n "Setting $secret_name... "
|
||||
|
||||
# Gitea API endpoint for repository secrets
|
||||
local response=$(curl -s -w "\n%{http_code}" \
|
||||
-X PUT \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/actions/secrets/${secret_name}" \
|
||||
-d "{
|
||||
\"data\": \"${secret_value}\"
|
||||
}")
|
||||
|
||||
local http_code=$(echo "$response" | tail -n1)
|
||||
local body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "204" ] || [ "$http_code" = "201" ]; then
|
||||
echo -e "${GREEN}✅ OK${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ FAILED (HTTP $http_code)${NC}"
|
||||
echo "Response: $body"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get registry password (default or from vault)
|
||||
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-registry-secure-password-2025}"
|
||||
|
||||
# Get SSH private key
|
||||
if [ -f ~/.ssh/production ]; then
|
||||
SSH_PRIVATE_KEY=$(cat ~/.ssh/production)
|
||||
echo -e "${GREEN}✓ SSH private key gefunden${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ SSH private key nicht gefunden in ~/.ssh/production${NC}"
|
||||
echo "Bitte SSH key Pfad anpassen oder manuell setzen"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Setting secrets for repository: ${REPO_OWNER}/${REPO_NAME}"
|
||||
echo ""
|
||||
|
||||
# Set secrets
|
||||
set_secret "REGISTRY_USER" "admin"
|
||||
set_secret "REGISTRY_PASSWORD" "$REGISTRY_PASSWORD"
|
||||
set_secret "SSH_PRIVATE_KEY" "$SSH_PRIVATE_KEY"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Secrets Setup Complete ===${NC}"
|
||||
echo ""
|
||||
echo "Prüfe Secrets in Gitea UI:"
|
||||
echo "${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}/enu/repo/settings/secrets"
|
||||
echo ""
|
||||
85
scripts/setup-production-secrets.sh
Executable file
85
scripts/setup-production-secrets.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# Production Secrets Setup Script
|
||||
# ==============================================================================
|
||||
# This script creates Docker Secrets on the production server from .env values
|
||||
# Run this ONCE during initial setup on the production server.
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔐 Docker Secrets Setup for Production"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
# Check if running on production server
|
||||
if [ ! -f /home/deploy/framework/.env ]; then
|
||||
echo "❌ ERROR: /home/deploy/framework/.env not found"
|
||||
echo " Please ensure .env file exists on production server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if Docker Swarm is initialized
|
||||
if ! docker info | grep -q "Swarm: active"; then
|
||||
echo "❌ ERROR: Docker Swarm is not initialized"
|
||||
echo " Run: docker swarm init"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Reading secrets from .env file..."
|
||||
cd /home/deploy/framework
|
||||
|
||||
# Function to create secret from .env
|
||||
create_secret() {
|
||||
local secret_name=$1
|
||||
local env_key=$2
|
||||
|
||||
# Extract value from .env
|
||||
local value=$(grep "^${env_key}=" .env | cut -d'=' -f2- | sed 's/^"\(.*\)"$/\1/')
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
echo "⚠️ WARNING: ${env_key} not found in .env, skipping ${secret_name}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if secret already exists
|
||||
if docker secret ls --format "{{.Name}}" | grep -q "^${secret_name}$"; then
|
||||
echo "ℹ️ Secret '${secret_name}' already exists, skipping..."
|
||||
return
|
||||
fi
|
||||
|
||||
# Create secret
|
||||
echo "$value" | docker secret create "$secret_name" - 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Created secret: ${secret_name}"
|
||||
else
|
||||
echo "❌ Failed to create secret: ${secret_name}"
|
||||
fi
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "🔑 Creating Docker Secrets..."
|
||||
echo ""
|
||||
|
||||
# Create all required secrets
|
||||
create_secret "db_password" "DB_PASSWORD"
|
||||
create_secret "app_key" "APP_KEY"
|
||||
create_secret "vault_encryption_key" "VAULT_ENCRYPTION_KEY"
|
||||
create_secret "shopify_webhook_secret" "SHOPIFY_WEBHOOK_SECRET"
|
||||
create_secret "rapidmail_password" "RAPIDMAIL_PASSWORD"
|
||||
|
||||
echo ""
|
||||
echo "📊 Verifying Secrets..."
|
||||
echo ""
|
||||
|
||||
docker secret ls
|
||||
|
||||
echo ""
|
||||
echo "✅ Secrets setup completed!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Deploy the stack: docker stack deploy -c docker-compose.prod.yml framework"
|
||||
echo " 2. Monitor deployment: watch docker stack ps framework"
|
||||
echo " 3. Check logs: docker service logs framework_web"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user