- 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.
161 lines
4.0 KiB
Bash
Executable File
161 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Portfolio Deployment Script
|
|
# Usage: ./scripts/deploy.sh [environment]
|
|
|
|
set -e
|
|
|
|
# Configuration
|
|
ENVIRONMENT=${1:-production}
|
|
REGISTRY="ghcr.io"
|
|
IMAGE_NAME="dennis-konkol/my_portfolio"
|
|
CONTAINER_NAME="portfolio-app"
|
|
COMPOSE_FILE="docker-compose.zero-downtime.yml"
|
|
|
|
# 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"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
# 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 ! docker info > /dev/null 2>&1; then
|
|
error "Docker is not running. Please start Docker and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if docker compose is available
|
|
if ! docker compose version &> /dev/null; then
|
|
error "docker compose is not available. Please ensure Docker is installed and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if .env file exists
|
|
if [ ! -f .env ]; then
|
|
error ".env file not found. Please create it with the required environment variables."
|
|
exit 1
|
|
fi
|
|
|
|
log "Starting deployment for environment: $ENVIRONMENT"
|
|
|
|
# Set image tag based on environment
|
|
if [ "$ENVIRONMENT" = "production" ]; then
|
|
IMAGE_TAG="production"
|
|
else
|
|
IMAGE_TAG="main"
|
|
fi
|
|
|
|
FULL_IMAGE_NAME="$REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
|
|
|
|
log "Using image: $FULL_IMAGE_NAME"
|
|
|
|
# Login to registry (if needed)
|
|
log "Logging in to container registry..."
|
|
echo "$GITHUB_TOKEN" | docker login $REGISTRY -u $GITHUB_ACTOR --password-stdin || {
|
|
warning "Failed to login to registry. Make sure GITHUB_TOKEN and GITHUB_ACTOR are set."
|
|
}
|
|
|
|
# Build latest image locally
|
|
log "Building latest image locally..."
|
|
docker build -t portfolio-app:latest . || {
|
|
error "Failed to build image locally"
|
|
exit 1
|
|
}
|
|
|
|
# Stop and remove old containers
|
|
log "Stopping old containers..."
|
|
docker compose -f $COMPOSE_FILE down || {
|
|
warning "No old containers to stop"
|
|
}
|
|
|
|
# Remove old images (keep last 3 versions)
|
|
log "Cleaning up old images..."
|
|
docker images $REGISTRY/$IMAGE_NAME --format "table {{.Tag}}\t{{.ID}}" | tail -n +2 | head -n -3 | awk '{print $2}' | xargs -r docker rmi || {
|
|
warning "No old images to remove"
|
|
}
|
|
|
|
# Start new containers
|
|
log "Starting new containers..."
|
|
docker compose -f $COMPOSE_FILE up -d || {
|
|
error "Failed to start containers"
|
|
exit 1
|
|
}
|
|
|
|
# Wait for health check
|
|
log "Waiting for application to be healthy..."
|
|
HEALTH_CHECK_TIMEOUT=60
|
|
HEALTH_CHECK_INTERVAL=2
|
|
ELAPSED=0
|
|
|
|
while [ $ELAPSED -lt $HEALTH_CHECK_TIMEOUT ]; do
|
|
if curl -f http://localhost/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 compose -f $COMPOSE_FILE logs --tail=50
|
|
exit 1
|
|
fi
|
|
|
|
# Verify deployment
|
|
log "Verifying deployment..."
|
|
if curl -f http://localhost/api/health > /dev/null 2>&1; then
|
|
success "Deployment successful!"
|
|
|
|
# Show container status
|
|
log "Container status:"
|
|
docker compose -f $COMPOSE_FILE ps
|
|
|
|
# Show resource usage
|
|
log "Resource usage:"
|
|
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
|
|
|
|
else
|
|
error "Deployment verification failed!"
|
|
log "Container logs:"
|
|
docker compose -f $COMPOSE_FILE logs --tail=50
|
|
exit 1
|
|
fi
|
|
|
|
# Cleanup
|
|
log "Cleaning up unused Docker resources..."
|
|
docker system prune -f --volumes || {
|
|
warning "Failed to clean up Docker resources"
|
|
}
|
|
|
|
success "Deployment completed successfully!"
|
|
log "Application is available at: http://localhost/"
|
|
log "Health check endpoint: http://localhost/api/health"
|