From 79f0f8ebf769ccb9a552dca71b9bb9f299771f58 Mon Sep 17 00:00:00 2001 From: Aleksandr Meshchriakov Date: Tue, 2 Jun 2026 00:01:40 +0200 Subject: [PATCH] ci: deploy dev through compose --- .gitea/workflows/ci-cd.yml | 134 +++++++++++++------------------------ 1 file changed, 47 insertions(+), 87 deletions(-) diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index 251cbc4..b4a74f3 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -23,24 +23,10 @@ env: REGISTRY_NAMESPACE: "${{ github.repository_owner }}" WEB_IMAGE: "mostovik-backend-web" CELERY_IMAGE: "mostovik-backend-celery" - GITEA_REGISTRY_HOST: "git.dev.nii-ecos.ru" - DOKPLOY_DEV_WEB_SERVICE_IMAGE: "service-backend-4mbxrs" - DOKPLOY_DEV_WORKER_SERVICE_IMAGE: "service-backend-512y9c" - DOKPLOY_DEV_BEAT_SERVICE_IMAGE: "service-backend-nvdyoq" CI_GOLDEN_IMAGE: "mostovik-backend-ci-golden" WEB_GOLDEN_IMAGE: "mostovik-backend-web-golden" CELERY_GOLDEN_IMAGE: "mostovik-backend-celery-golden" GOLDEN_TAG: "py311-uv0.7.2" - DOKPLOY_DEV_WEB_WEBHOOK_URL: "https://deploy.dev.nii-ecos.ru/api/deploy/_EjfuYBpzGJ18uPwBZ3iF" - DOKPLOY_DEV_WORKER_WEBHOOK_URL: "https://deploy.dev.nii-ecos.ru/api/deploy/hltL7K2HmG1a8EIzr-mVA" - DOKPLOY_DEV_BEAT_WEBHOOK_URL: "https://deploy.dev.nii-ecos.ru/api/deploy/RkdykbqU6faErrZBAN9Rv" - DOKPLOY_API_URL: "https://deploy.dev.nii-ecos.ru/api" - DOKPLOY_DEV_WEB_APPLICATION_ID: "x2l_Twc2z2A4lJhMVqlNg" - DOKPLOY_DEV_WORKER_APPLICATION_ID: "m8ECastEeQKhDZVFonUTS" - DOKPLOY_DEV_BEAT_APPLICATION_ID: "Ut5e5mcMMslxG9Zrpbp0_" - DOKPLOY_DEV_WEB_APP_NAME: "service-backend-4mbxrs" - DOKPLOY_DEV_WORKER_APP_NAME: "service-backend-512y9c" - DOKPLOY_DEV_BEAT_APP_NAME: "service-backend-nvdyoq" UV_VERSION: "0.7.2" PIP_DISABLE_PIP_VERSION_CHECK: "1" @@ -71,8 +57,8 @@ jobs: - name: Run quality in golden image env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - REGISTRY_USER: ${{ secrets.REGISTRY_USER }} - REGISTRY_PASSWORD: ${{ secrets.REGISTRY_TOKEN }} + REGISTRY_USER: ${{ secrets.REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} SKIP_LINT: ${{ contains(github.event.head_commit.message, '#no_lint') }} SKIP_TEST: ${{ contains(github.event.head_commit.message, '#no_test') }} run: | @@ -88,7 +74,7 @@ jobs: export no_proxy="${no_proxy:-},${REGISTRY_HOST}" if [ -z "${REGISTRY_PASSWORD}" ]; then - echo "REGISTRY_TOKEN secret is not set and GITEA_TOKEN fallback is empty" >&2 + echo "REGISTRY_PASSWORD secret is not set and GITEA_TOKEN fallback is empty" >&2 exit 1 fi @@ -173,7 +159,7 @@ jobs: exit 0 fi - if [ "${GITHUB_REF}" != "refs/heads/dev" ] && [ "${GITHUB_REF}" != "refs/heads/main" ]; then + if [ "${GITHUB_REF}" != "refs/heads/dev" ]; then echo "Skip image build for ${GITHUB_REF}" exit 0 fi @@ -188,7 +174,7 @@ jobs: echo "Image build is required for ${GITHUB_REF}" - name: Checkout code - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main') && !contains(github.event.head_commit.message, '#no_image') }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && !contains(github.event.head_commit.message, '#no_image') }} run: | set -euo pipefail REPO_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" @@ -197,7 +183,7 @@ jobs: git -c core.hooksPath=/dev/null checkout "${GITHUB_SHA}" - name: Free Docker build space - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main') && !contains(github.event.head_commit.message, '#no_image') }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && !contains(github.event.head_commit.message, '#no_image') }} run: | set -euo pipefail docker system df || true @@ -206,13 +192,12 @@ jobs: docker system prune --all --force --volumes || true docker system df || true - - name: Build and push branch images - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main') && !contains(github.event.head_commit.message, '#no_image') }} + - name: Build and push dev images + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && !contains(github.event.head_commit.message, '#no_image') }} env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - REGISTRY_USER: ${{ secrets.REGISTRY_USER }} - REGISTRY_PASSWORD: ${{ secrets.REGISTRY_TOKEN }} - GITEA_REGISTRY_TOKEN: ${{ secrets.GITEA_REGISTRY_TOKEN }} + REGISTRY_USER: ${{ secrets.REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} run: | set -euo pipefail @@ -229,20 +214,16 @@ jobs: CELERY_REF="${REGISTRY_PATH}/${CELERY_IMAGE}" WEB_GOLDEN_REF="${REGISTRY_PATH}/${WEB_GOLDEN_IMAGE}" CELERY_GOLDEN_REF="${REGISTRY_PATH}/${CELERY_GOLDEN_IMAGE}" - DOKPLOY_REGISTRY_PATH="${GITEA_REGISTRY_HOST}/${REGISTRY_NAMESPACE}" - DOKPLOY_WEB_REF="${DOKPLOY_REGISTRY_PATH}/${DOKPLOY_DEV_WEB_SERVICE_IMAGE}" - DOKPLOY_WORKER_REF="${DOKPLOY_REGISTRY_PATH}/${DOKPLOY_DEV_WORKER_SERVICE_IMAGE}" - DOKPLOY_BEAT_REF="${DOKPLOY_REGISTRY_PATH}/${DOKPLOY_DEV_BEAT_SERVICE_IMAGE}" REGISTRY_USER="${REGISTRY_USER:-${GITHUB_ACTOR}}" REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-${GITEA_TOKEN:-}}" - GITEA_ALIAS_PUSH_ENABLED="false" + BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)" unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY - export NO_PROXY="${NO_PROXY:-},${REGISTRY_HOST},${GITEA_REGISTRY_HOST}" - export no_proxy="${no_proxy:-},${REGISTRY_HOST},${GITEA_REGISTRY_HOST}" + export NO_PROXY="${NO_PROXY:-},${REGISTRY_HOST}" + export no_proxy="${no_proxy:-},${REGISTRY_HOST}" if [ -z "${REGISTRY_PASSWORD}" ]; then - echo "REGISTRY_TOKEN secret is not set and GITEA_TOKEN fallback is empty" >&2 + echo "REGISTRY_PASSWORD secret is not set and GITEA_TOKEN fallback is empty" >&2 exit 1 fi @@ -250,40 +231,15 @@ jobs: | docker login "${REGISTRY_HOST}" \ -u "${REGISTRY_USER}" \ --password-stdin - if [ -n "${GITEA_REGISTRY_TOKEN:-}" ]; then - echo "${GITEA_REGISTRY_TOKEN}" \ - | docker login "${GITEA_REGISTRY_HOST}" \ - -u "${GITHUB_ACTOR}" \ - --password-stdin - GITEA_ALIAS_PUSH_ENABLED="true" - else - echo "GITEA_REGISTRY_TOKEN is not set; skip Dokploy-compatible git.dev image aliases" - fi WEB_TAGS=( - -t "${WEB_REF}:${BRANCH_TAG}" - -t "${WEB_REF}:${BRANCH_TAG}-${SHA_SHORT}" + -t "${WEB_REF}:dev-${SHA_SHORT}" + -t "${WEB_REF}:dev" ) CELERY_TAGS=( - -t "${CELERY_REF}:${BRANCH_TAG}" - -t "${CELERY_REF}:${BRANCH_TAG}-${SHA_SHORT}" + -t "${CELERY_REF}:dev-${SHA_SHORT}" + -t "${CELERY_REF}:dev" ) - if [ "${GITEA_ALIAS_PUSH_ENABLED}" = "true" ]; then - WEB_TAGS+=( - -t "${DOKPLOY_WEB_REF}:latest" - -t "${DOKPLOY_WEB_REF}:${BRANCH_TAG}-${SHA_SHORT}" - ) - CELERY_TAGS+=( - -t "${DOKPLOY_WORKER_REF}:latest" - -t "${DOKPLOY_WORKER_REF}:${BRANCH_TAG}-${SHA_SHORT}" - -t "${DOKPLOY_BEAT_REF}:latest" - -t "${DOKPLOY_BEAT_REF}:${BRANCH_TAG}-${SHA_SHORT}" - ) - fi - if [ "${GITHUB_REF_NAME}" = "main" ]; then - WEB_TAGS+=(-t "${WEB_REF}:latest") - CELERY_TAGS+=(-t "${CELERY_REF}:latest") - fi if ! docker buildx inspect mostovik-builder >/dev/null 2>&1; then docker buildx create --name mostovik-builder --use @@ -340,6 +296,7 @@ jobs: --build-arg GOLDEN_WEB_IMAGE="${WEB_GOLDEN_REF}:${GOLDEN_TAG}" \ --label "org.opencontainers.image.revision=${GITHUB_SHA}" \ --label "org.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.created=${BUILD_TIME}" \ --push \ "${WEB_TAGS[@]}" \ . @@ -351,6 +308,7 @@ jobs: --build-arg GOLDEN_CELERY_IMAGE="${CELERY_GOLDEN_REF}:${GOLDEN_TAG}" \ --label "org.opencontainers.image.revision=${GITHUB_SHA}" \ --label "org.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.created=${BUILD_TIME}" \ --push \ "${CELERY_TAGS[@]}" \ . @@ -361,21 +319,10 @@ jobs: echo "- ${WEB_GOLDEN_REF}:${GOLDEN_TAG}" echo "- ${CELERY_GOLDEN_REF}:${GOLDEN_TAG}" echo "Pushed images:" - echo "- ${WEB_REF}:${BRANCH_TAG}" - echo "- ${WEB_REF}:${BRANCH_TAG}-${SHA_SHORT}" - echo "- ${CELERY_REF}:${BRANCH_TAG}" - echo "- ${CELERY_REF}:${BRANCH_TAG}-${SHA_SHORT}" - if [ "${GITEA_ALIAS_PUSH_ENABLED}" = "true" ]; then - echo "Dokploy-compatible aliases:" - echo "- ${DOKPLOY_WEB_REF}:latest" - echo "- ${DOKPLOY_WEB_REF}:${BRANCH_TAG}-${SHA_SHORT}" - echo "- ${DOKPLOY_WORKER_REF}:latest" - echo "- ${DOKPLOY_WORKER_REF}:${BRANCH_TAG}-${SHA_SHORT}" - echo "- ${DOKPLOY_BEAT_REF}:latest" - echo "- ${DOKPLOY_BEAT_REF}:${BRANCH_TAG}-${SHA_SHORT}" - else - echo "Dokploy-compatible aliases skipped: GITEA_REGISTRY_TOKEN is not set." - fi + echo "- ${WEB_REF}:dev-${SHA_SHORT}" + echo "- ${WEB_REF}:dev" + echo "- ${CELERY_REF}:dev-${SHA_SHORT}" + echo "- ${CELERY_REF}:dev" } >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}" notify: @@ -445,7 +392,7 @@ jobs: "${CI_NOTIFY_WEBHOOK_URL}" deploy_dev: - name: Deploy Dev in Dokploy + name: Deploy Dev via Compose runs-on: ubuntu-latest timeout-minutes: 5 needs: [build_push] @@ -460,27 +407,40 @@ jobs: git -c core.hooksPath=/dev/null clone --depth=1 --branch="${BRANCH}" "${REPO_URL}" . git -c core.hooksPath=/dev/null checkout "${GITHUB_SHA}" - - name: Deploy prebuilt images in Dokploy + - name: Deploy prebuilt images via SSH env: - DOKPLOY_API_TOKEN: ${{ secrets.DOKPLOY_API_TOKEN }} - DOKPLOY_API_TOKEN_FALLBACK: "cmhRpAPDlWPCbwkCdteTgpHuHzhPHCNtZrUcRddsfiHdijmyXKsIIojiBmcVpfpo" - GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} - REGISTRY_USER: ${{ secrets.REGISTRY_USER }} - REGISTRY_PASSWORD: ${{ secrets.REGISTRY_TOKEN }} + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + DEPLOY_USER: ${{ secrets.DEPLOY_USER }} + DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} + REGISTRY_HOST: ${{ secrets.REGISTRY_HOST }} HEAD_COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: | set -euo pipefail if [ "${GITHUB_REF}" != "refs/heads/dev" ]; then - echo "Skip Dokploy dev deploy for ${GITHUB_REF}" + echo "Skip dev deploy for ${GITHUB_REF}" exit 0 fi case "${HEAD_COMMIT_MESSAGE:-}" in *"#no_deploy"* | *"#no_image"*) - echo "Skip Dokploy dev deploy because commit message disables deploy or image build" + echo "Skip dev deploy because commit message disables deploy or image build" exit 0 ;; esac - bash scripts/ci/dokploy_deploy_image.sh all + short_sha="$(printf '%s' "${GITHUB_SHA}" | cut -c1-7)" + image_tag="dev-${short_sha}" + mkdir -p ~/.ssh + printf '%s' "${DEPLOY_SSH_KEY}" | base64 -d > ~/.ssh/ecos_deploy_key + chmod 0600 ~/.ssh/ecos_deploy_key + ssh-keyscan -H "${DEPLOY_HOST}" >> ~/.ssh/known_hosts 2>/dev/null + tmp_current="$(mktemp)" + ssh -i ~/.ssh/ecos_deploy_key "${DEPLOY_USER}@${DEPLOY_HOST}" 'cat /opt/ecos-dev/releases/current.env' > "${tmp_current}" + grep -v '^MOSTOVIK_BACKEND_' "${tmp_current}" > "${tmp_current}.new" + cat >> "${tmp_current}.new" < /opt/ecos-dev/releases/current.env && rm -f /tmp/current.env && /opt/ecos-dev/deploy.sh mostovik-backend'