nexus/setup.sh
2026-01-26 11:58:04 -05:00

248 lines
8.9 KiB
Bash
Executable File

#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SECRETS_DIR="${SCRIPT_DIR}/secrets"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
usage() {
echo "Usage: $0 <command>"
echo ""
echo "Commands:"
echo " init Initialize secrets directory with AppRole credentials"
echo " start Start the application (migrations run automatically)"
echo " stop Stop the application"
echo " restart Safe restart (down + up, preserves startup order)"
echo " logs View application logs"
echo " rebuild Rebuild and restart (migrations run automatically)"
echo " rebuild --no-cache Force full rebuild without Docker cache"
echo ""
echo "WARNING: Do not use 'docker compose restart <service>' directly!"
echo " This breaks service dependencies. Always use './setup.sh restart'"
echo ""
echo "Environment variables (for init):"
echo " VAULT_APP_ROLE_ID AppRole ID for nexus app runtime"
echo " VAULT_APP_SECRET_ID AppRole Secret ID for nexus app runtime"
echo " VAULT_MIGRATE_ROLE_ID AppRole ID for nexus migrations"
echo " VAULT_MIGRATE_SECRET_ID AppRole Secret ID for nexus migrations"
echo " VAULT_KRATOS_APP_ROLE_ID AppRole ID for kratos runtime"
echo " VAULT_KRATOS_APP_SECRET_ID AppRole Secret ID for kratos runtime"
echo " VAULT_KRATOS_MIGRATE_ROLE_ID AppRole ID for kratos migrations"
echo " VAULT_KRATOS_MIGRATE_SECRET_ID AppRole Secret ID for kratos migrations"
echo " VAULT_OATHKEEPER_ROLE_ID AppRole ID for oathkeeper runtime"
echo " VAULT_OATHKEEPER_SECRET_ID AppRole Secret ID for oathkeeper runtime"
}
init_secrets() {
log_info "Initializing secrets directory..."
# Create directories for all services
mkdir -p "${SECRETS_DIR}/app" "${SECRETS_DIR}/migrate"
mkdir -p "${SECRETS_DIR}/kratos-app" "${SECRETS_DIR}/kratos-migrate"
mkdir -p "${SECRETS_DIR}/oathkeeper"
mkdir -p "${SCRIPT_DIR}/run/app" "${SCRIPT_DIR}/run/migrate"
mkdir -p "${SCRIPT_DIR}/run/kratos" "${SCRIPT_DIR}/run/kratos-migrate"
mkdir -p "${SCRIPT_DIR}/run/oathkeeper"
# Check for required nexus environment variables
if [ -z "$VAULT_APP_ROLE_ID" ] || [ -z "$VAULT_APP_SECRET_ID" ]; then
log_error "VAULT_APP_ROLE_ID and VAULT_APP_SECRET_ID must be set"
exit 1
fi
if [ -z "$VAULT_MIGRATE_ROLE_ID" ] || [ -z "$VAULT_MIGRATE_SECRET_ID" ]; then
log_error "VAULT_MIGRATE_ROLE_ID and VAULT_MIGRATE_SECRET_ID must be set"
exit 1
fi
# Check for required kratos environment variables
if [ -z "$VAULT_KRATOS_APP_ROLE_ID" ] || [ -z "$VAULT_KRATOS_APP_SECRET_ID" ]; then
log_error "VAULT_KRATOS_APP_ROLE_ID and VAULT_KRATOS_APP_SECRET_ID must be set"
exit 1
fi
if [ -z "$VAULT_KRATOS_MIGRATE_ROLE_ID" ] || [ -z "$VAULT_KRATOS_MIGRATE_SECRET_ID" ]; then
log_error "VAULT_KRATOS_MIGRATE_ROLE_ID and VAULT_KRATOS_MIGRATE_SECRET_ID must be set"
exit 1
fi
# Check for required oathkeeper environment variables
if [ -z "$VAULT_OATHKEEPER_ROLE_ID" ] || [ -z "$VAULT_OATHKEEPER_SECRET_ID" ]; then
log_error "VAULT_OATHKEEPER_ROLE_ID and VAULT_OATHKEEPER_SECRET_ID must be set"
exit 1
fi
# Write nexus app credentials (644 for container read access)
echo -n "$VAULT_APP_ROLE_ID" > "${SECRETS_DIR}/app/role-id"
echo -n "$VAULT_APP_SECRET_ID" > "${SECRETS_DIR}/app/secret-id"
chmod 644 "${SECRETS_DIR}/app/role-id" "${SECRETS_DIR}/app/secret-id"
log_info "Nexus app credentials written to ${SECRETS_DIR}/app/"
# Write nexus migrate credentials (644 for container read access)
echo -n "$VAULT_MIGRATE_ROLE_ID" > "${SECRETS_DIR}/migrate/role-id"
echo -n "$VAULT_MIGRATE_SECRET_ID" > "${SECRETS_DIR}/migrate/secret-id"
chmod 644 "${SECRETS_DIR}/migrate/role-id" "${SECRETS_DIR}/migrate/secret-id"
log_info "Nexus migrate credentials written to ${SECRETS_DIR}/migrate/"
# Write kratos app credentials (644 for container read access)
echo -n "$VAULT_KRATOS_APP_ROLE_ID" > "${SECRETS_DIR}/kratos-app/role-id"
echo -n "$VAULT_KRATOS_APP_SECRET_ID" > "${SECRETS_DIR}/kratos-app/secret-id"
chmod 644 "${SECRETS_DIR}/kratos-app/role-id" "${SECRETS_DIR}/kratos-app/secret-id"
log_info "Kratos app credentials written to ${SECRETS_DIR}/kratos-app/"
# Write kratos migrate credentials (644 for container read access)
echo -n "$VAULT_KRATOS_MIGRATE_ROLE_ID" > "${SECRETS_DIR}/kratos-migrate/role-id"
echo -n "$VAULT_KRATOS_MIGRATE_SECRET_ID" > "${SECRETS_DIR}/kratos-migrate/secret-id"
chmod 644 "${SECRETS_DIR}/kratos-migrate/role-id" "${SECRETS_DIR}/kratos-migrate/secret-id"
log_info "Kratos migrate credentials written to ${SECRETS_DIR}/kratos-migrate/"
# Write oathkeeper credentials (644 for container read access)
echo -n "$VAULT_OATHKEEPER_ROLE_ID" > "${SECRETS_DIR}/oathkeeper/role-id"
echo -n "$VAULT_OATHKEEPER_SECRET_ID" > "${SECRETS_DIR}/oathkeeper/secret-id"
chmod 644 "${SECRETS_DIR}/oathkeeper/role-id" "${SECRETS_DIR}/oathkeeper/secret-id"
log_info "Oathkeeper credentials written to ${SECRETS_DIR}/oathkeeper/"
log_info "All secrets initialized successfully!"
}
start_app() {
log_info "Starting application..."
if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
log_error "Nexus secrets not initialized. Run '$0 init' first."
exit 1
fi
if [ ! -f "${SECRETS_DIR}/kratos-app/role-id" ]; then
log_error "Kratos secrets not initialized. Run '$0 init' first."
exit 1
fi
if [ ! -f "${SECRETS_DIR}/oathkeeper/role-id" ]; then
log_error "Oathkeeper secrets not initialized. Run '$0 init' first."
exit 1
fi
# Start all services (migrations run automatically before app)
docker compose up -d
log_info "Application started!"
log_info "Health checks:"
log_info " Nexus: curl http://localhost:5050/health/ready"
log_info " Kratos: curl http://localhost:6050/health/alive"
log_info " Oathkeeper: curl http://localhost:7250/health/alive"
log_info " Frontend: curl http://localhost:5000/"
}
stop_app() {
log_info "Stopping application..."
docker compose down
log_info "Application stopped!"
}
restart_app() {
log_info "Restarting application (safe restart)..."
if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
log_error "Nexus secrets not initialized. Run '$0 init' first."
exit 1
fi
# Safe restart: down then up preserves dependency order
docker compose down
docker compose up -d
log_info "Application restarted!"
log_info "Health checks:"
log_info " Nexus: curl http://localhost:5050/health/ready"
log_info " Kratos: curl http://localhost:6050/health/alive"
log_info " Oathkeeper: curl http://localhost:7250/health/alive"
log_info " Frontend: curl http://localhost:5000/"
}
rebuild_app() {
local no_cache="${1:-}"
if [ "$no_cache" = "--no-cache" ]; then
log_info "Rebuilding without cache and restarting application..."
else
log_info "Rebuilding and restarting application..."
fi
if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
log_error "Nexus secrets not initialized. Run '$0 init' first."
exit 1
fi
if [ ! -f "${SECRETS_DIR}/kratos-app/role-id" ]; then
log_error "Kratos secrets not initialized. Run '$0 init' first."
exit 1
fi
if [ ! -f "${SECRETS_DIR}/oathkeeper/role-id" ]; then
log_error "Oathkeeper secrets not initialized. Run '$0 init' first."
exit 1
fi
# Pull latest code
git pull
# Rebuild and restart (migrations run automatically)
if [ "$no_cache" = "--no-cache" ]; then
docker compose build --no-cache
docker compose up -d
else
docker compose up -d --build
fi
log_info "Application rebuilt and started!"
log_info "Health checks:"
log_info " Nexus: curl http://localhost:5050/health/ready"
log_info " Kratos: curl http://localhost:6050/health/alive"
log_info " Oathkeeper: curl http://localhost:7250/health/alive"
log_info " Frontend: curl http://localhost:5000/"
}
view_logs() {
local service="${1:-}"
if [ -z "$service" ]; then
docker compose logs -f nexus kratos oathkeeper frontend
else
docker compose logs -f "$service"
fi
}
# Main
case "${1:-}" in
init)
init_secrets
;;
start)
start_app
;;
stop)
stop_app
;;
restart)
restart_app
;;
rebuild)
rebuild_app "${2:-}"
;;
logs)
view_logs
;;
*)
usage
exit 1
;;
esac