diff --git a/.env.example b/.env.example index a7f2870..52a6b91 100644 --- a/.env.example +++ b/.env.example @@ -20,7 +20,8 @@ JWT_REFRESH_EXPIRES_IN=7d POSTGRES_USER=sso POSTGRES_PASSWORD=sso_secret POSTGRES_DB=sso_db -DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB} +POSTGRES_PORT=5432 +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB} # ────────────────────────────────────────────── # Redis @@ -35,6 +36,7 @@ RABBITMQ_USER=sso RABBITMQ_PASSWORD=sso_secret RABBITMQ_HOST=localhost RABBITMQ_PORT=5672 +RABBITMQ_UI_PORT=15672 RABBITMQ_URL=amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@${RABBITMQ_HOST}:${RABBITMQ_PORT} # ────────────────────────────────────────────── diff --git a/docker-compose.yml b/docker-compose.yml index 60fb00e..f71d731 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} ports: - - "5432:5432" + - "${POSTGRES_PORT:-5432}:5432" volumes: - pgdata:/var/lib/postgresql/data healthcheck: @@ -21,7 +21,7 @@ services: image: redis:7-alpine restart: unless-stopped ports: - - "6379:6379" + - "${REDIS_PORT:-6379}:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s @@ -36,8 +36,8 @@ services: RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} ports: - - "5672:5672" - - "15672:15672" + - "${RABBITMQ_PORT:-5672}:5672" + - "${RABBITMQ_UI_PORT:-15672}:15672" healthcheck: test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"] interval: 10s diff --git a/install.sh b/install.sh index a93adfb..de41aae 100644 --- a/install.sh +++ b/install.sh @@ -18,6 +18,31 @@ step() { echo -e "\n${CYAN}━━━ $1 ━━━${NC}"; } mark_done() { echo "$1" >> "$PROGRESS_FILE"; } is_done() { grep -qx "$1" "$PROGRESS_FILE" 2>/dev/null; } +# ─── Find free port (check + increment until free) ────────────── +find_free_port() { + local port=$1 max=$2 + max="${max:-65535}" + while [ "$port" -le "$max" ]; do + if ! ss -tlnp "sport = :$port" 2>/dev/null | grep -q .; then + echo "$port" + return 0 + fi + port=$((port + 1)) + done + echo "$1" + return 1 +} + +# ─── Update or add a variable in .env ──────────────────────────── +set_env() { + local key=$1 val=$2 file="${INSTALL_DIR}/.env" + if grep -q "^${key}=" "$file" 2>/dev/null; then + sed -i "s|^${key}=.*|${key}=${val}|" "$file" + else + echo "${key}=${val}" >> "$file" + fi +} + echo -e "${CYAN}" echo " ╔══════════════════════════════════════════════╗" echo " ║ SSO Service — Auto Installer ║" @@ -180,13 +205,40 @@ set -a; source .env; set +a # ─── 5. Docker infrastructure ──────────────────────────────────── step "5/8 Starting infrastructure (PostgreSQL, Redis, RabbitMQ)" -# Проверка занятости портов -for port in 5432 6379 5672 15672; do - if ss -tlnp "sport = :$port" 2>/dev/null | grep -q .; then - warn "Port $port is already in use — service may conflict with existing postgres/redis/rabbitmq" +# Проверка и переназначение занятых портов +PORT_MAP="" +for pair in "POSTGRES_PORT:5432" "REDIS_PORT:6379" "RABBITMQ_PORT:5672" "RABBITMQ_UI_PORT:15672"; do + var="${pair%%:*}" + default="${pair#*:}" + current=$(grep "^${var}=" "$INSTALL_DIR/.env" 2>/dev/null | cut -d= -f2) || true + current="${current:-$default}" + + if ss -tlnp "sport = :$current" 2>/dev/null | grep -q .; then + warn "Port $current ($var) is busy — finding free port..." + new_port=$(find_free_port "$((current + 1))" 2>/dev/null) || new_port=$((current + 100)) + set_env "$var" "$new_port" + info " $var changed: $current → $new_port" + PORT_MAP="$PORT_MAP $var=$new_port" + else + info " $var → $current" fi done +# Если порты изменились — перечитать .env +if [ -n "$PORT_MAP" ]; then + set -a; source "$INSTALL_DIR/.env"; set +a + info "Ports adjusted — re-sourced .env" +fi + +# Обновить DATABASE_URL если POSTGRES_PORT изменился +POSTGRES_PORT_CUR=$(grep "^POSTGRES_PORT=" "$INSTALL_DIR/.env" 2>/dev/null | cut -d= -f2) +PG_USER=$(grep "^POSTGRES_USER=" "$INSTALL_DIR/.env" 2>/dev/null | cut -d= -f2) +PG_PASS=$(grep "^POSTGRES_PASSWORD=" "$INSTALL_DIR/.env" 2>/dev/null | cut -d= -f2) +PG_DB=$(grep "^POSTGRES_DB=" "$INSTALL_DIR/.env" 2>/dev/null | cut -d= -f2) +NEW_URL="postgresql://${PG_USER}:${PG_PASS}@localhost:${POSTGRES_PORT_CUR}/${PG_DB}" +set_env "DATABASE_URL" "$NEW_URL" +export DATABASE_URL="$NEW_URL" + # Остановить предыдущие контейнеры (если есть), потом запустить заново $SUDO docker compose down --remove-orphans 2>/dev/null || true