ci: add automated Gitea Actions deployment workflow for Synology NAS
Build and Deploy to Synology NAS / test (push) Failing after 1h20m56s
Build and Deploy to Synology NAS / build (push) Failing after 11m7s
Build and Deploy to Synology NAS / deploy (push) Has been cancelled
Build and Deploy to Synology NAS / notify (push) Has been cancelled
Build and Deploy to Synology NAS / test (push) Failing after 1h20m56s
Build and Deploy to Synology NAS / build (push) Failing after 11m7s
Build and Deploy to Synology NAS / deploy (push) Has been cancelled
Build and Deploy to Synology NAS / notify (push) Has been cancelled
- Add Gitea Actions workflow for automated build and deployment - Add deployment script for Synology NAS - Add Docker Compose configurations for production deployment - Add Gitea runner setup - Add comprehensive documentation for CI/CD setup - Add health check endpoint for deployment verification - Update .gitignore for CI/CD artifacts
This commit is contained in:
Executable
+258
@@ -0,0 +1,258 @@
|
||||
#!/bin/bash
|
||||
# Deployment Script für Synology NAS
|
||||
# Dieses Script wird auf der Synology NAS ausgeführt
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# ============================================
|
||||
# Configuration
|
||||
# ============================================
|
||||
PROJECT_DIR="/volume1/docker/laravel-app"
|
||||
DOCKER_IMAGE="laravel-app"
|
||||
COMPOSE_FILE="docker-compose.synology.yml"
|
||||
ENV_FILE=".env.synology"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ============================================
|
||||
# Helper Functions
|
||||
# ============================================
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Pre-deployment Checks
|
||||
# ============================================
|
||||
log_info "Starting deployment process..."
|
||||
|
||||
# Check if running on Synology
|
||||
if [ ! -d "/volume1" ]; then
|
||||
log_error "This script should be run on Synology NAS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Navigate to project directory
|
||||
cd "$PROJECT_DIR" || {
|
||||
log_error "Project directory not found: $PROJECT_DIR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if Docker is installed
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if docker-compose is installed
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log_error "docker-compose is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Load Docker Image
|
||||
# ============================================
|
||||
if [ -f "laravel-app.tar.gz" ]; then
|
||||
log_info "Loading Docker image from artifact..."
|
||||
gunzip -c laravel-app.tar.gz | docker load
|
||||
|
||||
# Tag the image appropriately
|
||||
LOADED_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep laravel-app | head -n1)
|
||||
if [ -n "$LOADED_IMAGE" ]; then
|
||||
docker tag "$LOADED_IMAGE" "${DOCKER_IMAGE}:latest"
|
||||
log_info "Tagged image as ${DOCKER_IMAGE}:latest"
|
||||
fi
|
||||
else
|
||||
log_warn "No Docker image artifact found. Using existing image or building..."
|
||||
|
||||
# Check if Dockerfile exists and build if necessary
|
||||
if [ -f "Dockerfile" ]; then
|
||||
log_info "Building Docker image..."
|
||||
docker build -t "${DOCKER_IMAGE}:latest" .
|
||||
else
|
||||
log_error "Neither Docker artifact nor Dockerfile found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Environment Configuration
|
||||
# ============================================
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
log_warn "Environment file not found: $ENV_FILE"
|
||||
|
||||
if [ -f ".env.synology.example" ]; then
|
||||
log_info "Copying from .env.synology.example..."
|
||||
cp .env.synology.example "$ENV_FILE"
|
||||
log_warn "⚠️ Please configure $ENV_FILE with your settings!"
|
||||
else
|
||||
log_error "No environment configuration found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Backup Current Deployment
|
||||
# ============================================
|
||||
log_info "Creating backup of current deployment..."
|
||||
|
||||
BACKUP_DIR="/volume1/docker/backups/laravel-app"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/backup_${TIMESTAMP}.tar.gz"
|
||||
|
||||
# Backup database if container is running
|
||||
if docker ps --format '{{.Names}}' | grep -q "laravel_postgres"; then
|
||||
log_info "Backing up PostgreSQL database..."
|
||||
docker exec laravel_postgres pg_dump -U ingest_user ingest_db > "$BACKUP_DIR/db_${TIMESTAMP}.sql"
|
||||
fi
|
||||
|
||||
# Keep only last 5 backups
|
||||
log_info "Cleaning old backups (keeping last 5)..."
|
||||
ls -t "$BACKUP_DIR"/db_*.sql 2>/dev/null | tail -n +6 | xargs -r rm
|
||||
|
||||
# ============================================
|
||||
# Stop Current Containers
|
||||
# ============================================
|
||||
log_info "Stopping current containers..."
|
||||
|
||||
if [ -f "$COMPOSE_FILE" ]; then
|
||||
docker-compose -f "$COMPOSE_FILE" down || log_warn "No containers to stop"
|
||||
else
|
||||
log_warn "Compose file not found: $COMPOSE_FILE"
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Clean up old images (optional)
|
||||
# ============================================
|
||||
log_info "Cleaning up old Docker images..."
|
||||
docker image prune -f
|
||||
|
||||
# ============================================
|
||||
# Start New Deployment
|
||||
# ============================================
|
||||
log_info "Starting new deployment..."
|
||||
|
||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||
log_error "Docker Compose file not found: $COMPOSE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pull/use latest images and start services
|
||||
docker-compose -f "$COMPOSE_FILE" up -d --build
|
||||
|
||||
# ============================================
|
||||
# Wait for Services to Start
|
||||
# ============================================
|
||||
log_info "Waiting for services to start..."
|
||||
sleep 10
|
||||
|
||||
# Check if containers are running
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "laravel_app"; then
|
||||
log_error "Laravel app container failed to start"
|
||||
|
||||
# Show logs
|
||||
log_info "Container logs:"
|
||||
docker-compose -f "$COMPOSE_FILE" logs --tail=50
|
||||
|
||||
# Rollback
|
||||
log_warn "Attempting rollback..."
|
||||
docker-compose -f "$COMPOSE_FILE" down
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Post-deployment Tasks
|
||||
# ============================================
|
||||
log_info "Running post-deployment tasks..."
|
||||
|
||||
# Wait for database to be ready
|
||||
log_info "Waiting for database to be ready..."
|
||||
sleep 5
|
||||
|
||||
# Run migrations
|
||||
log_info "Running database migrations..."
|
||||
docker exec laravel_app php artisan migrate --force || log_warn "Migrations failed"
|
||||
|
||||
# Clear caches
|
||||
log_info "Clearing caches..."
|
||||
docker exec laravel_app php artisan cache:clear || log_warn "Cache clear failed"
|
||||
docker exec laravel_app php artisan config:clear || log_warn "Config clear failed"
|
||||
docker exec laravel_app php artisan view:clear || log_warn "View clear failed"
|
||||
|
||||
# Optimize
|
||||
log_info "Optimizing application..."
|
||||
docker exec laravel_app php artisan config:cache || log_warn "Config cache failed"
|
||||
docker exec laravel_app php artisan route:cache || log_warn "Route cache failed"
|
||||
docker exec laravel_app php artisan view:cache || log_warn "View cache failed"
|
||||
|
||||
# ============================================
|
||||
# Health Check
|
||||
# ============================================
|
||||
log_info "Performing health check..."
|
||||
|
||||
MAX_RETRIES=30
|
||||
RETRY_COUNT=0
|
||||
HEALTH_CHECK_URL="http://localhost:8080"
|
||||
|
||||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||
if curl -f -s "$HEALTH_CHECK_URL" > /dev/null 2>&1; then
|
||||
log_info "✅ Application is healthy!"
|
||||
break
|
||||
fi
|
||||
|
||||
log_info "⏳ Waiting for application... ($RETRY_COUNT/$MAX_RETRIES)"
|
||||
sleep 5
|
||||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||
done
|
||||
|
||||
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
|
||||
log_error "Health check failed after $MAX_RETRIES attempts"
|
||||
|
||||
# Show recent logs
|
||||
log_info "Recent application logs:"
|
||||
docker-compose -f "$COMPOSE_FILE" logs --tail=100
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Display Status
|
||||
# ============================================
|
||||
log_info "Deployment completed successfully! 🚀"
|
||||
log_info "Container status:"
|
||||
docker-compose -f "$COMPOSE_FILE" ps
|
||||
|
||||
log_info ""
|
||||
log_info "==================================="
|
||||
log_info "Application URL: http://$(hostname -I | awk '{print $1}'):8080"
|
||||
log_info "==================================="
|
||||
log_info ""
|
||||
log_info "Useful commands:"
|
||||
log_info " - View logs: docker-compose -f $COMPOSE_FILE logs -f"
|
||||
log_info " - Restart: docker-compose -f $COMPOSE_FILE restart"
|
||||
log_info " - Stop: docker-compose -f $COMPOSE_FILE down"
|
||||
log_info " - Shell access: docker exec -it laravel_app sh"
|
||||
|
||||
# ============================================
|
||||
# Cleanup
|
||||
# ============================================
|
||||
log_info "Cleaning up deployment artifacts..."
|
||||
rm -f laravel-app.tar.gz
|
||||
|
||||
log_info "Deployment script completed!"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user