#!/bin/bash # Deployment script for go-first / URPI # Usage: ./deploy.sh [production|staging] set -euo pipefail # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color ENVIRONMENT="${1:-staging}" PROJECT_NAME="go-first" DOCKER_IMAGE="ghcr.io/dnoulet/${PROJECT_NAME}" VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev") log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } check_requirements() { log_info "Checking requirements..." command -v docker >/dev/null 2>&1 || { log_error "docker is required but not installed."; exit 1; } command -v docker-compose >/dev/null 2>&1 || { log_error "docker-compose is required but not installed."; exit 1; } if [[ "$ENVIRONMENT" == "production" ]]; then command -v kubectl >/dev/null 2>&1 || log_warn "kubectl not found, using docker-compose" fi } build_and_push() { log_info "Building Docker image: ${DOCKER_IMAGE}:${VERSION}" docker build -t "${DOCKER_IMAGE}:${VERSION}" -t "${DOCKER_IMAGE}:latest" . log_info "Pushing Docker image..." docker push "${DOCKER_IMAGE}:${VERSION}" docker push "${DOCKER_IMAGE}:latest" } deploy_docker_compose() { log_info "Deploying with docker-compose (${ENVIRONMENT})..." ENV_FILE=".env.${ENVIRONMENT}" if [[ ! -f "$ENV_FILE" ]]; then log_error "Environment file ${ENV_FILE} not found!" exit 1 fi # Pull latest images docker-compose --env-file "$ENV_FILE" pull # Start services docker-compose --env-file "$ENV_FILE" up -d --remove-orphans # Wait for health checks log_info "Waiting for services to be healthy..." sleep 10 # Check health if docker-compose --env-file "$ENV_FILE" ps | grep -q "unhealthy"; then log_error "Some services are unhealthy!" docker-compose --env-file "$ENV_FILE" ps exit 1 fi log_info "Deployment successful!" } deploy_kubernetes() { log_info "Deploying to Kubernetes (${ENVIRONMENT})..." # Apply Kubernetes manifests kubectl apply -k "deploy/kubernetes/overlays/${ENVIRONMENT}" # Wait for rollout kubectl rollout status deployment/${PROJECT_NAME} -n ${PROJECT_NAME}-${ENVIRONMENT} --timeout=300s log_info "Kubernetes deployment successful!" } run_migrations() { log_info "Running database migrations..." if [[ "$ENVIRONMENT" == "production" ]]; then # Run migrations in production docker-compose --env-file ".env.${ENVIRONMENT}" exec -T app ./go-first migrate up else docker-compose --env-file ".env.${ENVIRONMENT}" exec -T app ./go-first migrate up fi } cleanup() { log_info "Cleaning up old Docker images..." docker image prune -f } main() { log_info "Starting deployment for ${ENVIRONMENT} (version: ${VERSION})" check_requirements if [[ "$ENVIRONMENT" != "production" && "$ENVIRONMENT" != "staging" ]]; then log_error "Invalid environment. Use 'production' or 'staging'" exit 1 fi build_and_push if command -v kubectl >/dev/null 2>&1 && [[ "$ENVIRONMENT" == "production" ]]; then deploy_kubernetes else deploy_docker_compose fi run_migrations cleanup log_info "Deployment completed successfully!" log_info "Application available at: https://www.urpi.be" } main "$@"