#!/bin/bash set -e echo "๐Ÿš€ VoxBlog Deployment Script" echo "==============================" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color fetch_env_from_infisical() { if [ -z "${INFISICAL_TOKEN:-}" ]; then echo -e "${RED}โŒ INFISICAL_TOKEN is not set${NC}" echo "Provide an Infisical service token or create a .env file for local use." exit 1 fi echo -e "${YELLOW}๐Ÿ” Retrieving secrets from Infisical...${NC}" local tmp_env tmp_env=$(mktemp) local cli_image cli_image="${INFISICAL_CLI_IMAGE:-infisical/cli:latest}" # shellcheck disable=SC2206 local docker_cmd=(docker run --rm -e INFISICAL_TOKEN="${INFISICAL_TOKEN}") if [ -n "${INFISICAL_SITE_URL:-}" ]; then docker_cmd+=(-e INFISICAL_SITE_URL="${INFISICAL_SITE_URL}") fi if [ -n "${INFISICAL_API_URL:-}" ]; then docker_cmd+=(-e INFISICAL_API_URL="${INFISICAL_API_URL}") elif [ -n "${INFISICAL_SITE_URL:-}" ]; then local api_url api_url="${INFISICAL_SITE_URL%/}/api" docker_cmd+=(-e INFISICAL_API_URL="${api_url}") fi docker_cmd+=("${cli_image}" export --format=dotenv) if ! "${docker_cmd[@]}" >"${tmp_env}"; then echo -e "${RED}โŒ Failed to export secrets from Infisical${NC}" rm -f "${tmp_env}" exit 1 fi set -o allexport # shellcheck source=/dev/null source "${tmp_env}" set +o allexport rm -f "${tmp_env}" } load_environment() { if [ -n "${INFISICAL_TOKEN:-}" ]; then fetch_env_from_infisical elif [ -f .env ]; then echo -e "${YELLOW}โš ๏ธ Using local .env file (not recommended for production)...${NC}" set -o allexport # shellcheck source=/dev/null source .env set +o allexport else echo -e "${RED}โŒ No environment configuration found${NC}" echo "Provide INFISICAL_TOKEN (preferred) or create a local .env for testing." exit 1 fi } load_environment # Pull latest code echo -e "${YELLOW}๐Ÿ“ฅ Pulling latest code...${NC}" git pull origin main # Stop existing containers echo -e "${YELLOW}๐Ÿ›‘ Stopping existing containers...${NC}" docker-compose down # Build new images echo -e "${YELLOW}๐Ÿ”จ Building new images...${NC}" docker-compose build --no-cache # Start containers echo -e "${YELLOW}โ–ถ๏ธ Starting containers...${NC}" docker-compose up -d # Wait for services to be ready echo -e "${YELLOW}โณ Waiting for services to start...${NC}" sleep 15 # Run database migrations echo -e "${YELLOW}๐Ÿ—„๏ธ Running database migrations...${NC}" docker-compose exec -T api pnpm run drizzle:migrate || echo "Migration skipped or failed" # Health check echo -e "${YELLOW}๐Ÿฅ Performing health checks...${NC}" API_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3301/api/health || echo "000") if [ "$API_HEALTH" = "200" ]; then echo -e "${GREEN}โœ… API is healthy${NC}" else echo -e "${RED}โŒ API health check failed (HTTP $API_HEALTH)${NC}" echo "Checking API logs:" docker-compose logs --tail=50 api exit 1 fi ADMIN_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3300 || echo "000") if [ "$ADMIN_HEALTH" = "200" ]; then echo -e "${GREEN}โœ… Admin is healthy${NC}" else echo -e "${RED}โŒ Admin health check failed (HTTP $ADMIN_HEALTH)${NC}" echo "Checking Admin logs:" docker-compose logs --tail=50 admin exit 1 fi # Clean up old images echo -e "${YELLOW}๐Ÿงน Cleaning up old Docker images...${NC}" docker image prune -af --filter "until=24h" echo "" echo -e "${GREEN}โœ… Deployment complete!${NC}" echo "" echo "Services running:" echo " - API: http://localhost:3301" echo " - Admin: http://localhost:3300" echo "" echo "To view logs: docker-compose logs -f" echo "To stop: docker-compose down"