From e0d6077a6543ae4ebfe8883d398813888652b842 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Sun, 5 Jul 2026 04:06:41 +0700 Subject: [PATCH] refactor(ci): remove automated deploy, add manual deploy.sh CI now only builds + pushes images to GitLab Container Registry. Deploy is done manually via deploy.sh with specific SHA tag support. Usage: ./deploy.sh [sha] # default: latest --- .gitlab-ci.yml | 66 ++++-------------------------- deploy.sh | 106 ++++++++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 99 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 65ab5a3..e1bf2fa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,20 +1,16 @@ -# ─── BETE GitLab CI/CD Pipeline ─────────────────────────────────────────────── -# 1. Build 3 Docker images (backend, discord-gateway, proxy — proxy includes frontend WASM) -# 2. Push to GitLab Container Registry -# 3. Deploy to VPS — pull images, docker compose up +# ─── BETE GitLab CI Pipeline ─────────────────────────────────────────────────── +# Builds 3 Docker images (backend, discord-gateway, proxy) and pushes to +# GitLab Container Registry with both `:$CI_COMMIT_SHA` and `:latest` tags. # -# Required CI/CD Variables (set in GitLab → Settings → CI/CD → Variables): -# -# VPS_HOST - VPS IP/hostname -# VPS_USERNAME - SSH user -# VPS_SSH_KEY - SSH private key (type: file) -# ENV_FILE - Full .env file content (type: env_var) — optional if .env already on VPS +# Deploy manually from your dev machine: +# export VPS_HOST=... VPS_USER=... VPS_SSH_KEY=... GITLAB_TOKEN=... +# ./deploy.sh # deploy :latest +# ./deploy.sh # deploy specific commit # # ────────────────────────────────────────────────────────────────────────────── stages: - build - - deploy variables: # Submodules — discord.js-selfbot-v13 and discord-video-stream @@ -72,51 +68,3 @@ build-proxy: SERVICE_NAME: proxy only: - master - -# ── Deploy stage ────────────────────────────────────────────────────────────── -deploy-vps: - stage: deploy - image: debian:stable-slim - only: - - master - needs: - - build-backend - - build-discord-gateway - - build-proxy - before_script: - - apt-get update -qq && apt-get install -y -qq openssh-client - - mkdir -p ~/.ssh - - cp "$VPS_SSH_KEY" ~/.ssh/id_rsa - - chmod 600 ~/.ssh/id_rsa - - ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts 2>/dev/null - script: - # Login to GitLab Container Registry, pull images, update docker-compose, restart - - scp infra/docker/docker-compose.yml "$SSH_HOST:$APP_DIR/infra/docker/docker-compose.yml" - - | - ssh "$SSH_HOST" " - set -eu - - cd $APP_DIR - - echo '→ Logging in to GitLab Container Registry...' - echo '$CI_JOB_TOKEN' | docker login $CI_REGISTRY -u '$CI_REGISTRY_USER' --password-stdin - - echo '→ Pulling SHA-pinned images...' - IMAGE_TAG=$CI_COMMIT_SHA docker compose -f infra/docker/docker-compose.yml pull - - echo '→ Restarting containers (recreates if image changed)...' - IMAGE_TAG=$CI_COMMIT_SHA docker compose -f infra/docker/docker-compose.yml up -d --remove-orphans - - # Force restart proxy to pick up new upstream DNS IPs. - # Docker's DNS changes when backend containers are recreated, - # but nginx only resolves upstream hostnames at startup. Without this, - # nginx keeps pointing to stale container IPs → 502 Bad Gateway. - echo '→ Ensuring proxy container is restarted (nginx upstream DNS refresh)...' - IMAGE_TAG=$CI_COMMIT_SHA docker compose -f infra/docker/docker-compose.yml restart proxy - - echo '→ Cleaning up...' - docker image prune -f - echo '✓ Deploy complete' - " - after_script: - - rm -f ~/.ssh/id_rsa diff --git a/deploy.sh b/deploy.sh index 33676ec..50e8ca1 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,49 +1,75 @@ #!/bin/bash +# ─── Bete Manual Deploy Script ─────────────────────────────────────────────── +# Pulls Docker images from GitLab Container Registry and restarts containers. +# +# Usage: +# ./deploy.sh # deploy :latest +# ./deploy.sh # deploy specific commit SHA +# ./deploy.sh --help # show this help +# +# Required env: +# VPS_HOST — VPS IP/hostname +# VPS_USER — SSH user +# VPS_SSH_KEY — path to SSH private key +# GITLAB_TOKEN — GitLab Personal Access Token (for docker login) +# +# Optional env: +# APP_DIR — app directory on VPS (default: /opt/imphenbot) +# GITLAB_USER — GitLab username (default: gitlab-ci-token) +# REGISTRY — container registry (default: registry.gitlab.com) +# COMPOSE_FILE — path relative to APP_DIR (default: infra/docker/docker-compose.yml) +# ────────────────────────────────────────────────────────────────────────────── -# Configuration for CLI deployment -VPS_HOST="45.127.35.244" -VPS_USER="root" -# Find first available private key in ~/.ssh or use specific one if you want to hardcode -SSH_KEY_PATH=$(find ~/.ssh -name "id_rsa" -o -name "id_ed25519" | head -n 1) +set -eu -echo "🚀 Starting CLI deployment to $VPS_USER@$VPS_HOST..." - -if [ -z "$SSH_KEY_PATH" ]; then - echo "⚠️ No SSH key found in ~/.ssh. Falling back to default SSH behavior." - SSH_CMD="ssh -o StrictHostKeyChecking=no $VPS_USER@$VPS_HOST" - RSYNC_CMD="rsync -avz --exclude-from='.dockerignore' -e 'ssh -o StrictHostKeyChecking=no'" -else - echo "🔑 Using SSH key: $SSH_KEY_PATH" - SSH_CMD="ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no $VPS_USER@$VPS_HOST" - RSYNC_CMD="rsync -avz --exclude-from='.dockerignore' -e 'ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no'" +if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then + sed -n '2,/^$/ s/^# //p' "$0" + exit 0 fi -# Directory on the VPS where the app will be deployed -REMOTE_DIR="/opt/imphenbot" +# ── Config ──────────────────────────────────────────────────────────────────── +IMAGE_TAG="${1:-latest}" +APP_DIR="${APP_DIR:-/opt/imphenbot}" +COMPOSE_FILE="${COMPOSE_FILE:-infra/docker/docker-compose.yml}" +REGISTRY="${REGISTRY:-registry.gitlab.com}" +GITLAB_USER="${GITLAB_USER:-gitlab-ci-token}" -echo "📦 Syncing files to VPS..." -$SSH_CMD "mkdir -p $REMOTE_DIR" -eval "$RSYNC_CMD ./ $VPS_USER@$VPS_HOST:$REMOTE_DIR" +# ── Required vars ───────────────────────────────────────────────────────────── +: "${VPS_HOST:?Required: VPS_HOST}" +: "${VPS_USER:?Required: VPS_USER}" +: "${VPS_SSH_KEY:?Required: VPS_SSH_KEY}" +: "${GITLAB_TOKEN:?Required: GITLAB_TOKEN}" -if [ -f .env ]; then - echo "🔒 Copying local .env to VPS..." - if [ -z "$SSH_KEY_PATH" ]; then - scp -o StrictHostKeyChecking=no .env $VPS_USER@$VPS_HOST:$REMOTE_DIR/.env - else - scp -i $SSH_KEY_PATH -o StrictHostKeyChecking=no .env $VPS_USER@$VPS_HOST:$REMOTE_DIR/.env - fi -else - echo "⚠️ No local .env found to copy." -fi +SSH_DEST="${VPS_USER}@${VPS_HOST}" -echo "🔄 Rebuilding and restarting Docker containers..." -$SSH_CMD << EOF - cd $REMOTE_DIR - if command -v docker-compose &> /dev/null; then - docker-compose up -d --build - else - docker compose up -d --build - fi -EOF +# ── Helper: run command on VPS ──────────────────────────────────────────────── +vps() { + ssh -i "$VPS_SSH_KEY" -o StrictHostKeyChecking=accept-new "$SSH_DEST" "$@" +} -echo "✅ Deployment complete!" +# ── Steps ───────────────────────────────────────────────────────────────────── +echo "→ Deploying tag: ${IMAGE_TAG}" +echo "→ Target: ${SSH_DEST}:${APP_DIR}" +echo "" + +echo "→ Copying ${COMPOSE_FILE} to VPS..." +scp -i "$VPS_SSH_KEY" -o StrictHostKeyChecking=accept-new \ + "$COMPOSE_FILE" "${SSH_DEST}:${APP_DIR}/${COMPOSE_FILE}" + +echo "→ Logging in to GitLab Container Registry..." +vps "echo '${GITLAB_TOKEN}' | docker login ${REGISTRY} -u '${GITLAB_USER}' --password-stdin" + +echo "→ Pulling images (tag: ${IMAGE_TAG})..." +vps "cd ${APP_DIR} && IMAGE_TAG=${IMAGE_TAG} docker compose -f ${COMPOSE_FILE} pull" + +echo "→ Restarting containers..." +vps "cd ${APP_DIR} && IMAGE_TAG=${IMAGE_TAG} docker compose -f ${COMPOSE_FILE} up -d --remove-orphans" + +echo "→ Restarting proxy (nginx upstream DNS refresh)..." +vps "cd ${APP_DIR} && IMAGE_TAG=${IMAGE_TAG} docker compose -f ${COMPOSE_FILE} restart proxy" + +echo "→ Cleaning up old images..." +vps "docker image prune -f" + +echo "" +echo "✓ Deploy complete (tag: ${IMAGE_TAG})"