- Modify root checks to allow running as root in CI environments - Add conditional check: only prevent root when not in CI (CI env var not set) - Updated scripts: - scripts/gitea-deploy.sh - scripts/gitea-deploy-simple.sh - scripts/deploy.sh - scripts/auto-deploy.sh - scripts/setup-gitea-runner.sh This fixes the 'This script should not be run as root' error in Gitea Actions where containers run as root by default.
222 lines
5.6 KiB
Bash
Executable File
222 lines
5.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Auto-Deploy Script für Portfolio
|
|
# Führt automatisch Tests, Build und Deployment durch
|
|
|
|
set -e
|
|
|
|
# Configuration
|
|
PROJECT_NAME="portfolio"
|
|
CONTAINER_NAME="portfolio-app"
|
|
IMAGE_NAME="portfolio-app"
|
|
PORT=3000
|
|
BACKUP_PORT=3001
|
|
LOG_FILE="./logs/portfolio-deploy.log"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Logging function
|
|
log() {
|
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
# Check if running as root (skip in CI environments)
|
|
if [[ $EUID -eq 0 ]] && [[ -z "$CI" ]]; then
|
|
error "This script should not be run as root (use CI=true to override)"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if Docker is running
|
|
if ! sudo docker info > /dev/null 2>&1; then
|
|
error "Docker is not running. Please start Docker and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if we're in the right directory
|
|
if [ ! -f "package.json" ] || [ ! -f "Dockerfile" ]; then
|
|
error "Please run this script from the project root directory"
|
|
exit 1
|
|
fi
|
|
|
|
log "🚀 Starting automatic deployment for $PROJECT_NAME"
|
|
|
|
# Step 1: Code Quality Checks
|
|
log "📋 Step 1: Running code quality checks..."
|
|
|
|
# Check for uncommitted changes
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
warning "You have uncommitted changes. Committing them..."
|
|
git add .
|
|
git commit -m "Auto-commit before deployment $(date)"
|
|
fi
|
|
|
|
# Pull latest changes
|
|
log "📥 Pulling latest changes..."
|
|
git pull origin production || {
|
|
error "Failed to pull latest changes"
|
|
exit 1
|
|
}
|
|
|
|
# Run linting
|
|
log "🔍 Running ESLint..."
|
|
npm run lint || {
|
|
error "ESLint failed. Please fix the issues before deploying."
|
|
exit 1
|
|
}
|
|
|
|
# Run tests
|
|
log "🧪 Running tests..."
|
|
npm run test || {
|
|
error "Tests failed. Please fix the issues before deploying."
|
|
exit 1
|
|
}
|
|
|
|
success "✅ Code quality checks passed"
|
|
|
|
# Step 2: Build Application
|
|
log "🔨 Step 2: Building application..."
|
|
|
|
# Build Next.js application
|
|
log "📦 Building Next.js application..."
|
|
npm run build || {
|
|
error "Build failed"
|
|
exit 1
|
|
}
|
|
|
|
success "✅ Application built successfully"
|
|
|
|
# Step 3: Docker Operations
|
|
log "🐳 Step 3: Docker operations..."
|
|
|
|
# Build Docker image
|
|
log "🏗️ Building Docker image..."
|
|
sudo docker build -t "$IMAGE_NAME:latest" . || {
|
|
error "Docker build failed"
|
|
exit 1
|
|
}
|
|
|
|
# Tag with timestamp
|
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
sudo docker tag "$IMAGE_NAME:latest" "$IMAGE_NAME:$TIMESTAMP"
|
|
|
|
success "✅ Docker image built successfully"
|
|
|
|
# Step 4: Deployment
|
|
log "🚀 Step 4: Deploying application..."
|
|
|
|
# Check if container is running
|
|
if [ "$(sudo docker inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null)" = "true" ]; then
|
|
log "📦 Stopping existing container..."
|
|
sudo docker stop "$CONTAINER_NAME" || true
|
|
sudo docker rm "$CONTAINER_NAME" || true
|
|
fi
|
|
|
|
# Check if port is available
|
|
if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null ; then
|
|
warning "Port $PORT is in use. Trying backup port $BACKUP_PORT"
|
|
DEPLOY_PORT=$BACKUP_PORT
|
|
else
|
|
DEPLOY_PORT=$PORT
|
|
fi
|
|
|
|
# Start new container
|
|
log "🚀 Starting new container on port $DEPLOY_PORT..."
|
|
sudo docker run -d \
|
|
--name "$CONTAINER_NAME" \
|
|
--restart unless-stopped \
|
|
-p "$DEPLOY_PORT:3000" \
|
|
-e NODE_ENV=production \
|
|
"$IMAGE_NAME:latest" || {
|
|
error "Failed to start container"
|
|
exit 1
|
|
}
|
|
|
|
# Wait for container to be ready
|
|
log "⏳ Waiting for container to be ready..."
|
|
sleep 10
|
|
|
|
# Health check
|
|
log "🏥 Performing health check..."
|
|
HEALTH_CHECK_TIMEOUT=60
|
|
HEALTH_CHECK_INTERVAL=2
|
|
ELAPSED=0
|
|
|
|
while [ $ELAPSED -lt $HEALTH_CHECK_TIMEOUT ]; do
|
|
if curl -f "http://localhost:$DEPLOY_PORT/api/health" > /dev/null 2>&1; then
|
|
success "✅ Application is healthy!"
|
|
break
|
|
fi
|
|
|
|
sleep $HEALTH_CHECK_INTERVAL
|
|
ELAPSED=$((ELAPSED + HEALTH_CHECK_INTERVAL))
|
|
echo -n "."
|
|
done
|
|
|
|
if [ $ELAPSED -ge $HEALTH_CHECK_TIMEOUT ]; then
|
|
error "Health check timeout. Application may not be running properly."
|
|
log "Container logs:"
|
|
docker logs "$CONTAINER_NAME" --tail=50
|
|
exit 1
|
|
fi
|
|
|
|
# Step 5: Verification
|
|
log "✅ Step 5: Verifying deployment..."
|
|
|
|
# Test main page
|
|
if curl -f "http://localhost:$DEPLOY_PORT/" > /dev/null 2>&1; then
|
|
success "✅ Main page is accessible"
|
|
else
|
|
error "❌ Main page is not accessible"
|
|
exit 1
|
|
fi
|
|
|
|
# Show container status
|
|
log "📊 Container status:"
|
|
sudo docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
|
|
|
# Show resource usage
|
|
log "📈 Resource usage:"
|
|
sudo docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" "$CONTAINER_NAME"
|
|
|
|
# Step 6: Cleanup
|
|
log "🧹 Step 6: Cleaning up old images..."
|
|
|
|
# Remove old images (keep last 3 versions)
|
|
sudo docker images "$IMAGE_NAME" --format "table {{.Tag}}\t{{.ID}}" | tail -n +2 | head -n -3 | awk '{print $2}' | xargs -r sudo docker rmi || {
|
|
warning "No old images to remove"
|
|
}
|
|
|
|
# Clean up unused Docker resources
|
|
sudo docker system prune -f --volumes || {
|
|
warning "Failed to clean up Docker resources"
|
|
}
|
|
|
|
# Final success message
|
|
success "🎉 Deployment completed successfully!"
|
|
log "🌐 Application is available at: http://localhost:$DEPLOY_PORT"
|
|
log "🏥 Health check endpoint: http://localhost:$DEPLOY_PORT/api/health"
|
|
log "📊 Container name: $CONTAINER_NAME"
|
|
log "📝 Logs: sudo docker logs $CONTAINER_NAME"
|
|
|
|
# Update deployment log
|
|
echo "$(date): Deployment successful - Port: $DEPLOY_PORT - Image: $IMAGE_NAME:$TIMESTAMP" >> "$LOG_FILE"
|
|
|
|
exit 0
|