#!/usr/bin/env bash # Обновление кода на сервере: pull ветки, сборка образа с версией коммита, перезапуск app. # Использование: ./scripts/deploy.sh [ветка] (по умолчанию master либо $DEPLOY_BRANCH) set -euo pipefail cd "$(dirname "$0")/.." BRANCH="${1:-${DEPLOY_BRANCH:-master}}" if docker compose version >/dev/null 2>&1; then DC="docker compose" else DC="docker-compose" fi echo ">> Рабочая копия" if [ -n "$(git status --porcelain --untracked-files=no -- . ':(exclude)public/version.json')" ]; then git status --short echo "Есть незакоммиченные изменения. Задайте DEPLOY_ALLOW_DIRTY=1, чтобы продолжить." [ "${DEPLOY_ALLOW_DIRTY:-0}" = "1" ] || exit 1 fi echo ">> Обновление ветки $BRANCH" git fetch origin --prune git checkout "$BRANCH" git pull --ff-only origin "$BRANCH" GIT_COMMIT="$(git rev-parse HEAD)" GIT_COMMIT_DATE="$(git log -1 --format=%cI)" export GIT_COMMIT GIT_COMMIT_DATE echo ">> Сборка: $GIT_COMMIT ($GIT_COMMIT_DATE)" $DC build --build-arg "GIT_COMMIT=$GIT_COMMIT" --build-arg "GIT_COMMIT_DATE=$GIT_COMMIT_DATE" app $DC up -d app echo ">> Проверка" $DC exec -T app cat /app/public/version.json HOST_MD5="$(md5sum server.js | cut -d' ' -f1)" APP_MD5="$($DC exec -T app md5sum /app/server.js | tr -d '\r' | cut -d' ' -f1)" if [ "$HOST_MD5" = "$APP_MD5" ]; then echo "server.js в контейнере совпадает с рабочей копией: $APP_MD5" else echo "ВНИМАНИЕ: server.js в контейнере ($APP_MD5) не совпадает с рабочей копией ($HOST_MD5)" fi if command -v curl >/dev/null 2>&1; then echo ">> /version.json" for _ in $(seq 1 20); do curl -skf --max-time 3 https://127.0.0.1:3443/version.json >/dev/null 2>&1 && break sleep 1 done curl -sk --max-time 5 https://127.0.0.1:3443/version.json || echo "Не удалось получить /version.json (приложение ещё поднимается или образ собран без аргументов версии)" echo fi $DC ps