add rebuild docker install sh

This commit is contained in:
lendry
2026-06-25 09:19:47 +03:00
parent 933f7fb9e1
commit d8f97ee232

View File

@@ -10,7 +10,7 @@
set -euo pipefail set -euo pipefail
SCRIPT_VERSION="2.2.3" SCRIPT_VERSION="2.2.4"
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT_DIR" cd "$ROOT_DIR"
@@ -31,6 +31,8 @@ INSTALL_LOCAL=0
INSTALL_INTRANET=0 INSTALL_INTRANET=0
OFFLINE="${OFFLINE:-0}" OFFLINE="${OFFLINE:-0}"
NGINX_MODE="${NGINX_MODE:-auto}" NGINX_MODE="${NGINX_MODE:-auto}"
SKIP_DOCKER_PRUNE="${SKIP_DOCKER_PRUNE:-0}"
DOCKER_PRUNE_AGGRESSIVE="${DOCKER_PRUNE_AGGRESSIVE:-0}"
CLI_DOMAIN_API="" CLI_DOMAIN_API=""
CLI_DOMAIN_FRONTEND="" CLI_DOMAIN_FRONTEND=""
@@ -64,6 +66,7 @@ ${BOLD}Lendry ID v${SCRIPT_VERSION}${NC} — установка и управл
./install.sh --configure-domains Изменить домены / Nginx / SSL ./install.sh --configure-domains Изменить домены / Nginx / SSL
./install.sh --renew-ssl Обновить сертификаты Let's Encrypt ./install.sh --renew-ssl Обновить сертификаты Let's Encrypt
./install.sh --restart Перезапуск контейнеров ./install.sh --restart Перезапуск контейнеров
./install.sh --docker-prune Только очистка Docker (без пересборки)
./install.sh --fix-proxy Исправить 502: host Nginx + порты 3000/3002/3003 ./install.sh --fix-proxy Исправить 502: host Nginx + порты 3000/3002/3003
./install.sh --status Статус сервисов ./install.sh --status Статус сервисов
./install.sh --reset-db Сброс PostgreSQL (новый пароль из .env, данные удалятся) ./install.sh --reset-db Сброс PostgreSQL (новый пароль из .env, данные удалятся)
@@ -93,6 +96,9 @@ ${BOLD}Прочие опции:${NC}
${BOLD}Переменные окружения:${NC} ${BOLD}Переменные окружения:${NC}
FORCE_ENV=1 Новые JWT-секреты (пароли БД/MinIO/RabbitMQ сохраняются если volume уже есть) FORCE_ENV=1 Новые JWT-секреты (пароли БД/MinIO/RabbitMQ сохраняются если volume уже есть)
OFFLINE=1 То же, что --offline OFFLINE=1 То же, что --offline
SKIP_DOCKER_PRUNE=1 Не очищать образы/кеш перед пересборкой
DOCKER_PRUNE_AGGRESSIVE=1 Глубже чистить неиспользуемые образы проекта
COMPOSE_PARALLEL_LIMIT=4 Параллельная сборка сервисов (по умолчанию 4)
${BOLD}Примеры:${NC} ${BOLD}Примеры:${NC}
./install.sh --intranet --install --yes \\ ./install.sh --intranet --install --yes \\
@@ -122,6 +128,9 @@ parse_args() {
--configure-domains) ACTION="configure-domains"; shift ;; --configure-domains) ACTION="configure-domains"; shift ;;
--renew-ssl) ACTION="renew-ssl"; shift ;; --renew-ssl) ACTION="renew-ssl"; shift ;;
--restart) ACTION="restart"; shift ;; --restart) ACTION="restart"; shift ;;
--docker-prune) ACTION="docker-prune"; shift ;;
--skip-docker-prune) SKIP_DOCKER_PRUNE=1; shift ;;
--docker-prune-aggressive) DOCKER_PRUNE_AGGRESSIVE=1; shift ;;
--fix-proxy) ACTION="fix-proxy"; shift ;; --fix-proxy) ACTION="fix-proxy"; shift ;;
--status) ACTION="status"; shift ;; --status) ACTION="status"; shift ;;
--reset-db) ACTION="reset-db"; shift ;; --reset-db) ACTION="reset-db"; shift ;;
@@ -407,6 +416,134 @@ docker_cmd() {
fi fi
} }
configure_docker_build_env() {
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
export BUILDKIT_PROGRESS="${BUILDKIT_PROGRESS:-auto}"
export COMPOSE_PARALLEL_LIMIT="${COMPOSE_PARALLEL_LIMIT:-4}"
}
docker_disk_usage_brief() {
docker_cmd system df 2>/dev/null | sed 's/^/ /' || true
}
docker_remove_stopped_project_containers() {
local project cid
project="$(compose_project_name)"
while IFS= read -r cid; do
[[ -z "$cid" ]] && continue
docker_cmd rm -f "$cid" 2>/dev/null || true
done < <(docker_cmd ps -aq --filter "label=com.docker.compose.project=${project}" --filter "status=exited" 2>/dev/null || true)
}
docker_prune_stale_project_images() {
local project="$1"
local aggressive="${2:-0}"
local id repo
while IFS= read -r id; do
[[ -z "$id" ]] && continue
if docker_cmd ps -a --filter "ancestor=${id}" -q 2>/dev/null | grep -q .; then
continue
fi
docker_cmd rmi -f "$id" 2>/dev/null || true
done < <(docker_cmd images --filter "label=com.docker.compose.project=${project}" -q 2>/dev/null | sort -u || true)
if [[ "$aggressive" == "1" ]]; then
while IFS= read -r repo id; do
[[ -z "$id" || "$repo" == "<none>" ]] && continue
case "$repo" in
lendry-id-* | idservice-* | "${project}"-*)
if ! docker_cmd ps -a --filter "ancestor=${id}" -q 2>/dev/null | grep -q .; then
docker_cmd rmi -f "$id" 2>/dev/null || true
fi
;;
esac
done < <(docker_cmd images --format '{{.Repository}} {{.ID}}' 2>/dev/null || true)
fi
}
docker_prune_before_rebuild() {
local aggressive="${1:-0}"
log "Очистка Docker перед пересборкой (volumes данных не удаляются)..."
build_compose_stack_cmd
if [[ "$aggressive" == "1" ]]; then
log " Режим aggressive: остановка стека и удаление orphan-контейнеров..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" down --remove-orphans 2>/dev/null || true
else
log " Удаление остановленных контейнеров проекта..."
docker_remove_stopped_project_containers
docker_cmd container prune -f --filter "until=24h" 2>/dev/null || true
fi
log " Удаление dangling-образов и старого build cache..."
docker_cmd image prune -f 2>/dev/null || true
if docker_cmd builder prune --help 2>/dev/null | grep -q 'until='; then
docker_cmd builder prune -f --filter "until=168h" 2>/dev/null || \
docker_cmd builder prune -f 2>/dev/null || true
else
docker_cmd builder prune -f 2>/dev/null || true
fi
log " Удаление неиспользуемых образов проекта..."
docker_prune_stale_project_images "$(compose_project_name)" "$aggressive"
ok "Docker очищен перед сборкой"
docker_disk_usage_brief
}
docker_prune_after_rebuild() {
docker_cmd image prune -f 2>/dev/null || true
}
compose_build_parallel_flags() {
COMPOSE_BUILD_PARALLEL=()
if docker_cmd compose build --help 2>/dev/null | grep -q -- '--parallel'; then
COMPOSE_BUILD_PARALLEL=(--parallel)
fi
}
compose_build_and_up() {
local -a services=()
if [[ $# -gt 0 ]]; then
services=("$@")
fi
configure_docker_build_env
build_compose_stack_cmd
compose_build_parallel_flags
if [[ "${SKIP_DOCKER_PRUNE:-0}" -ne 1 ]]; then
docker_prune_before_rebuild "${DOCKER_PRUNE_AGGRESSIVE:-0}"
fi
if [[ ${#services[@]} -gt 0 ]]; then
log "Сборка сервисов: ${services[*]} (BuildKit, limit=${COMPOSE_PARALLEL_LIMIT})..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" build "${COMPOSE_BUILD_PARALLEL[@]}" "${services[@]}"
log "Запуск сервисов..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --remove-orphans "${services[@]}"
else
log "Сборка образов (BuildKit, параллельно, limit=${COMPOSE_PARALLEL_LIMIT})..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" build "${COMPOSE_BUILD_PARALLEL[@]}"
log "Запуск контейнеров..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --remove-orphans
fi
if [[ "${SKIP_DOCKER_PRUNE:-0}" -ne 1 ]]; then
docker_prune_after_rebuild
fi
}
action_docker_prune() {
load_env
prepare_compose_stack
SKIP_DOCKER_PRUNE=0
docker_prune_before_rebuild "${DOCKER_PRUNE_AGGRESSIVE:-1}"
ok "Очистка Docker завершена"
}
install_nginx_host() { install_nginx_host() {
if has_cmd nginx; then if has_cmd nginx; then
ok "Nginx уже установлен" ok "Nginx уже установлен"
@@ -1819,16 +1956,11 @@ wait_for_service() {
} }
deploy_stack() { deploy_stack() {
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
prepare_compose_stack prepare_compose_stack
verify_postgres_auth verify_postgres_auth
build_compose_stack_cmd
log "Сборка и запуск контейнеров (1020 минут при первом запуске)..." log "Сборка и запуск контейнеров (1020 минут при первом запуске)..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --build compose_build_and_up
recreate_host_port_services recreate_host_port_services
ensure_host_upstreams ensure_host_upstreams
@@ -1895,6 +2027,7 @@ print_summary() {
echo -e " ${BOLD}Управление:${NC} ./install.sh" echo -e " ${BOLD}Управление:${NC} ./install.sh"
echo -e " ${BOLD}Смена доменов:${NC} ./install.sh --configure-domains" echo -e " ${BOLD}Смена доменов:${NC} ./install.sh --configure-domains"
echo -e " ${BOLD}Логи:${NC} docker compose logs -f api-gateway nginx" echo -e " ${BOLD}Логи:${NC} docker compose logs -f api-gateway nginx"
echo -e " ${BOLD}Очистка Docker:${NC} ./install.sh --docker-prune"
echo "" echo ""
echo " Первый зарегистрированный пользователь станет супер-администратором." echo " Первый зарегистрированный пользователь станет супер-администратором."
echo " Секреты в .env — не коммитьте в git." echo " Секреты в .env — не коммитьте в git."
@@ -1964,6 +2097,9 @@ show_status() {
echo "" echo ""
docker_cmd compose ps 2>/dev/null || warn "Контейнеры не запущены" docker_cmd compose ps 2>/dev/null || warn "Контейнеры не запущены"
echo "" echo ""
echo -e " ${BOLD}Docker disk:${NC}"
docker_disk_usage_brief
echo ""
if docker_cmd ps -q -f name=lendry-id-nginx 2>/dev/null | grep -q .; then if docker_cmd ps -q -f name=lendry-id-nginx 2>/dev/null | grep -q .; then
if [[ "$(env_get NGINX_MODE docker)" == "host" ]]; then if [[ "$(env_get NGINX_MODE docker)" == "host" ]]; then
warn "КОНФЛИКТ: контейнер lendry-id-nginx запущен при NGINX_MODE=host — выполните: ./install.sh --fix-proxy" warn "КОНФЛИКТ: контейнер lendry-id-nginx запущен при NGINX_MODE=host — выполните: ./install.sh --fix-proxy"
@@ -2027,8 +2163,7 @@ apply_intranet_selfsigned_runtime() {
env_set INTERNAL_WS_URL "http://media-ws:8085" env_set INTERNAL_WS_URL "http://media-ws:8085"
log "Пересборка frontend (same-origin /idp-api)..." log "Пересборка frontend (same-origin /idp-api)..."
build_compose_stack_cmd compose_build_and_up frontend
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --build frontend
} }
action_renew_ssl() { action_renew_ssl() {
@@ -2071,8 +2206,7 @@ action_fix_host_proxy() {
write_compose_override write_compose_override
log "Шаг 3/4: пересоздание api-gateway, frontend, docs, media-ws..." log "Шаг 3/4: пересоздание api-gateway, frontend, docs, media-ws..."
build_compose_stack_cmd compose_build_and_up "${HOST_EDGE_SERVICES[@]}"
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --force-recreate "${HOST_EDGE_SERVICES[@]}"
ensure_host_upstreams ensure_host_upstreams
log "Шаг 4/4: конфиги системного Nginx..." log "Шаг 4/4: конфиги системного Nginx..."
@@ -2081,8 +2215,7 @@ action_fix_host_proxy() {
apply_intranet_selfsigned_runtime apply_intranet_selfsigned_runtime
log "Шаг 5/5: пересоздание ldap-auth и sso-core..." log "Шаг 5/5: пересоздание ldap-auth и sso-core..."
build_compose_stack_cmd compose_build_and_up ldap-auth sso-core
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --build --force-recreate ldap-auth sso-core
ok "Прокси исправлен — проверьте: curl -I http://127.0.0.1:3002" ok "Прокси исправлен — проверьте: curl -I http://127.0.0.1:3002"
show_status show_status
@@ -2092,8 +2225,8 @@ action_restart() {
load_env load_env
prepare_compose_stack prepare_compose_stack
refresh_host_nginx_configs refresh_host_nginx_configs
build_compose_stack_cmd log "Пересборка и перезапуск контейнеров..."
docker_cmd "${COMPOSE_STACK_CMD[@]}" up -d --build compose_build_and_up
recreate_host_port_services recreate_host_port_services
ensure_host_upstreams ensure_host_upstreams
ok "Контейнеры перезапущены" ok "Контейнеры перезапущены"
@@ -2111,15 +2244,16 @@ show_menu() {
echo " 1) Полная установка / переустановка стека" echo " 1) Полная установка / переустановка стека"
echo " 2) Настроить / изменить домены и Nginx + SSL" echo " 2) Настроить / изменить домены и Nginx + SSL"
echo " 3) Обновить SSL-сертификаты (selfsigned / Let's Encrypt)" echo " 3) Обновить SSL-сертификаты (selfsigned / Let's Encrypt)"
echo " 4) Перезапуск / пересборка контейнеров" echo " 4) Перезапуск / пересборка контейнеров (+ очистка Docker)"
echo " 5) Статус сервисов" echo " 5) Статус сервисов"
echo " 6) Удалить конфиги Nginx IdP" echo " 6) Удалить конфиги Nginx IdP"
echo " 7) Сброс PostgreSQL (если ошибка P1000 / пароль БД)" echo " 7) Сброс PostgreSQL (если ошибка P1000 / пароль БД)"
echo " 8) Очистить Docker (образы/кеш, без пересборки)"
echo " 0) Выход" echo " 0) Выход"
echo "" echo ""
local choice local choice
read -r -p "Выберите пункт [0-7]: " choice read -r -p "Выберите пункт [0-8]: " choice
case "$choice" in case "$choice" in
1) NON_INTERACTIVE=0; action_full_install ;; 1) NON_INTERACTIVE=0; action_full_install ;;
@@ -2129,6 +2263,7 @@ show_menu() {
5) show_status ;; 5) show_status ;;
6) remove_nginx_configs; ok "Готово" ;; 6) remove_nginx_configs; ok "Готово" ;;
7) action_reset_db; action_restart ;; 7) action_reset_db; action_restart ;;
8) action_docker_prune ;;
0) exit 0 ;; 0) exit 0 ;;
*) warn "Неверный пункт" ;; *) warn "Неверный пункт" ;;
esac esac
@@ -2148,6 +2283,7 @@ main() {
configure-domains) action_configure_domains ;; configure-domains) action_configure_domains ;;
renew-ssl) action_renew_ssl ;; renew-ssl) action_renew_ssl ;;
restart) action_restart ;; restart) action_restart ;;
docker-prune) action_docker_prune ;;
fix-proxy) action_fix_host_proxy ;; fix-proxy) action_fix_host_proxy ;;
status) show_status ;; status) show_status ;;
reset-db) action_reset_db ;; reset-db) action_reset_db ;;