mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
156 lines
4.4 KiB
YAML
156 lines
4.4 KiB
YAML
stages:
|
|
- build
|
|
- migrate
|
|
- deploy
|
|
- seed
|
|
|
|
default:
|
|
tags:
|
|
- self-hosted-prod
|
|
|
|
variables:
|
|
DOCKER_BUILDKIT: "1"
|
|
|
|
IMAGE_TAG: "production_${CI_COMMIT_SHORT_SHA}"
|
|
IMAGE_NAME: "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}"
|
|
IMAGE_LATEST: "${CI_REGISTRY_IMAGE}:production_latest"
|
|
|
|
DEPLOY_DIR: "/opt/deploy/lti"
|
|
COMPOSE_FILE: "docker-compose.yaml"
|
|
|
|
# =========================
|
|
# BUILD (AUTO)
|
|
# =========================
|
|
build_production:
|
|
stage: build
|
|
rules:
|
|
- if: '$CI_COMMIT_BRANCH == "production"'
|
|
when: on_success
|
|
- when: never
|
|
script: |
|
|
set -e
|
|
docker info
|
|
|
|
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
|
|
|
echo "✅ Build image: $IMAGE_NAME"
|
|
docker build -t "$IMAGE_NAME" -f Dockerfile .
|
|
|
|
echo "✅ Push image: $IMAGE_NAME"
|
|
docker push "$IMAGE_NAME"
|
|
|
|
echo "✅ Tag latest: $IMAGE_LATEST"
|
|
docker tag "$IMAGE_NAME" "$IMAGE_LATEST"
|
|
docker push "$IMAGE_LATEST"
|
|
|
|
# =========================
|
|
# MIGRATE (PRODUCTION)
|
|
# =========================
|
|
migrate_production:
|
|
stage: migrate
|
|
rules:
|
|
- if: '$CI_COMMIT_BRANCH == "production"'
|
|
when: on_success
|
|
- when: never
|
|
needs:
|
|
- job: build_production
|
|
artifacts: false
|
|
script: |
|
|
set -e
|
|
echo "✅ Running migrations (production) ..."
|
|
|
|
cd "$DEPLOY_DIR"
|
|
test -f "$COMPOSE_FILE" || (echo "❌ $COMPOSE_FILE not found in $DEPLOY_DIR" && exit 1)
|
|
test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1)
|
|
|
|
set -a
|
|
. ./.env
|
|
set +a
|
|
|
|
test -n "$DB_HOST" || (echo "❌ DB_HOST empty" && exit 1)
|
|
test -n "$DB_PORT" || (echo "❌ DB_PORT empty" && exit 1)
|
|
test -n "$DB_USER" || (echo "❌ DB_USER empty" && exit 1)
|
|
test -n "$DB_PASSWORD" || (echo "❌ DB_PASSWORD empty" && exit 1)
|
|
test -n "$DB_NAME" || (echo "❌ DB_NAME empty" && exit 1)
|
|
|
|
export DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE:-disable}"
|
|
echo "✅ DATABASE_URL=$DATABASE_URL"
|
|
|
|
# NOTE: pastikan nama servicenya benar untuk production (ini sebelumnya masih stg-*)
|
|
docker compose -f "$COMPOSE_FILE" up -d stg-postgres-lti stg-redis-lti || true
|
|
|
|
COMPOSE_NETWORK_KEY="$(docker compose -f "$COMPOSE_FILE" config | awk '/networks:/ {getline; print $1}' | tr -d ':')"
|
|
NETWORK_NAME="$(docker network ls --format '{{.Name}}' | grep "_${COMPOSE_NETWORK_KEY}$" | head -n 1)"
|
|
test -n "$NETWORK_NAME" || (echo "❌ Cannot find docker network for compose ($COMPOSE_NETWORK_KEY)" && exit 1)
|
|
|
|
echo "✅ Checking migrations from repo..."
|
|
ls -lah "$CI_PROJECT_DIR/internal/database/migrations"
|
|
|
|
echo "✅ Running migrations via migrate/migrate container"
|
|
set +e
|
|
out=$(docker run --rm \
|
|
--network "$NETWORK_NAME" \
|
|
-v "$CI_PROJECT_DIR/internal/database/migrations:/migrations:ro" \
|
|
migrate/migrate:v4.15.2 \
|
|
-path=/migrations -database "$DATABASE_URL" up 2>&1)
|
|
code=$?
|
|
set -e
|
|
|
|
echo "$out"
|
|
|
|
if echo "$out" | grep -qi "no change"; then
|
|
echo "✅ No change (already up to date)"
|
|
exit 0
|
|
fi
|
|
|
|
if [ $code -ne 0 ]; then
|
|
echo "❌ Migration failed with exit code $code"
|
|
exit $code
|
|
fi
|
|
|
|
echo "✅ Migration applied successfully"
|
|
|
|
# =========================
|
|
# DEPLOY (AUTO)
|
|
# =========================
|
|
deploy_production:
|
|
stage: deploy
|
|
rules:
|
|
- if: '$CI_COMMIT_BRANCH == "production"'
|
|
when: on_success
|
|
- when: never
|
|
needs:
|
|
- job: build_production
|
|
artifacts: false
|
|
script: |
|
|
set -e
|
|
docker info
|
|
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
|
|
|
cd "$DEPLOY_DIR"
|
|
test -f "$COMPOSE_FILE" || (echo "❌ $COMPOSE_FILE not found in $DEPLOY_DIR" && exit 1)
|
|
test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1)
|
|
|
|
docker compose -f "$COMPOSE_FILE" pull
|
|
docker compose -f "$COMPOSE_FILE" up -d --force-recreate
|
|
docker image prune -f
|
|
|
|
# =========================
|
|
# SEED (MANUAL)
|
|
# =========================
|
|
seed_production:
|
|
stage: seed
|
|
rules:
|
|
- if: '$CI_COMMIT_BRANCH == "production"'
|
|
when: manual
|
|
- when: never
|
|
script: |
|
|
set -e
|
|
cd "$DEPLOY_DIR"
|
|
test -f .env || (echo "❌ .env not found" && exit 1)
|
|
|
|
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
|
|
|
docker compose --env-file .env pull seed
|
|
docker compose --env-file .env run --rm seed
|