staging deploy
All checks were successful
Build & Deploy KLZ Cables / build-and-deploy (push) Successful in 3m54s
All checks were successful
Build & Deploy KLZ Cables / build-and-deploy (push) Successful in 3m54s
This commit is contained in:
@@ -2,7 +2,7 @@ name: Build & Deploy KLZ Cables
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, staging]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
@@ -15,6 +15,7 @@ jobs:
|
|||||||
- name: 📋 Log Workflow Start
|
- name: 📋 Log Workflow Start
|
||||||
run: |
|
run: |
|
||||||
echo "🚀 Starting deployment for ${{ github.repository }} (${{ github.ref }})"
|
echo "🚀 Starting deployment for ${{ github.repository }} (${{ github.ref }})"
|
||||||
|
echo " • Branch: ${{ github.ref_name }}"
|
||||||
echo " • Commit: ${{ github.sha }}"
|
echo " • Commit: ${{ github.sha }}"
|
||||||
echo " • Timestamp: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
|
echo " • Timestamp: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
|
||||||
|
|
||||||
@@ -33,23 +34,48 @@ jobs:
|
|||||||
# LOGGING: Build Phase
|
# LOGGING: Build Phase
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
- name: 🏗️ Build Docker image
|
- name: 🏗️ Build Docker image
|
||||||
|
env:
|
||||||
|
NEXT_PUBLIC_BASE_URL: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_BASE_URL || (secrets.STAGING_NEXT_PUBLIC_BASE_URL || secrets.NEXT_PUBLIC_BASE_URL) }}
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID || (secrets.STAGING_NEXT_PUBLIC_UMAMI_WEBSITE_ID || secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID) }}
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL || (secrets.STAGING_NEXT_PUBLIC_UMAMI_SCRIPT_URL || secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL) }}
|
||||||
run: |
|
run: |
|
||||||
echo "🏗️ Building Docker image (linux/arm64)..."
|
echo "🏗️ Building Docker image (linux/arm64) for branch ${{ github.ref_name }}..."
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--pull \
|
--pull \
|
||||||
--platform linux/arm64 \
|
--platform linux/arm64 \
|
||||||
--build-arg NEXT_PUBLIC_BASE_URL="${{ secrets.NEXT_PUBLIC_BASE_URL }}" \
|
--build-arg NEXT_PUBLIC_BASE_URL="$NEXT_PUBLIC_BASE_URL" \
|
||||||
--build-arg NEXT_PUBLIC_UMAMI_WEBSITE_ID="${{ secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID }}" \
|
--build-arg NEXT_PUBLIC_UMAMI_WEBSITE_ID="$NEXT_PUBLIC_UMAMI_WEBSITE_ID" \
|
||||||
--build-arg NEXT_PUBLIC_UMAMI_SCRIPT_URL="${{ secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL }}" \
|
--build-arg NEXT_PUBLIC_UMAMI_SCRIPT_URL="$NEXT_PUBLIC_UMAMI_SCRIPT_URL" \
|
||||||
|
-t registry.infra.mintel.me/mintel/klz-cables.com:${{ github.sha }} \
|
||||||
-t registry.infra.mintel.me/mintel/klz-cables.com:latest \
|
-t registry.infra.mintel.me/mintel/klz-cables.com:latest \
|
||||||
--push .
|
--push .
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# LOGGING: Deployment Phase
|
# LOGGING: Deployment Phase
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
- name: 🚀 Deploy to production server
|
- name: 🚀 Deploy to server
|
||||||
|
env:
|
||||||
|
NEXT_PUBLIC_BASE_URL: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_BASE_URL || (secrets.STAGING_NEXT_PUBLIC_BASE_URL || secrets.NEXT_PUBLIC_BASE_URL) }}
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID || (secrets.STAGING_NEXT_PUBLIC_UMAMI_WEBSITE_ID || secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID) }}
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${{ github.ref_name == 'main' && secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL || (secrets.STAGING_NEXT_PUBLIC_UMAMI_SCRIPT_URL || secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL) }}
|
||||||
|
SENTRY_DSN: ${{ github.ref_name == 'main' && secrets.SENTRY_DSN || (secrets.STAGING_SENTRY_DSN || secrets.SENTRY_DSN) }}
|
||||||
|
MAIL_HOST: ${{ github.ref_name == 'main' && secrets.MAIL_HOST || (secrets.STAGING_MAIL_HOST || secrets.MAIL_HOST) }}
|
||||||
|
MAIL_PORT: ${{ github.ref_name == 'main' && secrets.MAIL_PORT || (secrets.STAGING_MAIL_PORT || secrets.MAIL_PORT) }}
|
||||||
|
MAIL_USERNAME: ${{ github.ref_name == 'main' && secrets.MAIL_USERNAME || (secrets.STAGING_MAIL_USERNAME || secrets.MAIL_USERNAME) }}
|
||||||
|
MAIL_PASSWORD: ${{ github.ref_name == 'main' && secrets.MAIL_PASSWORD || (secrets.STAGING_MAIL_PASSWORD || secrets.MAIL_PASSWORD) }}
|
||||||
|
MAIL_FROM: ${{ github.ref_name == 'main' && secrets.MAIL_FROM || (secrets.STAGING_MAIL_FROM || secrets.MAIL_FROM) }}
|
||||||
|
MAIL_RECIPIENTS: ${{ github.ref_name == 'main' && secrets.MAIL_RECIPIENTS || (secrets.STAGING_MAIL_RECIPIENTS || secrets.MAIL_RECIPIENTS) }}
|
||||||
run: |
|
run: |
|
||||||
echo "🚀 Deploying to alpha.mintel.me..."
|
BRANCH=${{ github.ref_name }}
|
||||||
|
if [ "$BRANCH" = "main" ]; then
|
||||||
|
ENV_FILE=.env.prod
|
||||||
|
TRAEFIK_HOST="klz-cables.com, www.klz-cables.com"
|
||||||
|
else
|
||||||
|
ENV_FILE=.env.staging
|
||||||
|
TRAEFIK_HOST="staging.klz-cables.com"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚀 Deploying branch $BRANCH to $ENV_FILE..."
|
||||||
|
|
||||||
# Setup SSH
|
# Setup SSH
|
||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
@@ -60,60 +86,61 @@ jobs:
|
|||||||
# Create .env file content
|
# Create .env file content
|
||||||
cat > /tmp/klz-cables.env << EOF
|
cat > /tmp/klz-cables.env << EOF
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# KLZ Cables - Production Environment Configuration
|
# KLZ Cables - Environment Configuration ($BRANCH)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Auto-generated by CI/CD workflow
|
# Auto-generated by CI/CD workflow
|
||||||
# DO NOT EDIT MANUALLY - Changes will be overwritten on next deployment
|
# DO NOT EDIT MANUALLY - Changes will be overwritten on next deployment
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
# Application
|
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
NEXT_PUBLIC_BASE_URL=${{ secrets.NEXT_PUBLIC_BASE_URL }}
|
NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID=$NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
||||||
# Analytics (Umami)
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL=$NEXT_PUBLIC_UMAMI_SCRIPT_URL
|
||||||
NEXT_PUBLIC_UMAMI_WEBSITE_ID=${{ secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID }}
|
SENTRY_DSN=$SENTRY_DSN
|
||||||
NEXT_PUBLIC_UMAMI_SCRIPT_URL=${{ secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL }}
|
MAIL_HOST=$MAIL_HOST
|
||||||
|
MAIL_PORT=$MAIL_PORT
|
||||||
# Error Tracking (GlitchTip/Sentry)
|
MAIL_USERNAME=$MAIL_USERNAME
|
||||||
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
|
MAIL_PASSWORD=$MAIL_PASSWORD
|
||||||
|
MAIL_FROM=$MAIL_FROM
|
||||||
# Email Configuration (Mailgun)
|
MAIL_RECIPIENTS=$MAIL_RECIPIENTS
|
||||||
MAIL_HOST=${{ secrets.MAIL_HOST }}
|
|
||||||
MAIL_PORT=${{ secrets.MAIL_PORT }}
|
|
||||||
MAIL_USERNAME=${{ secrets.MAIL_USERNAME }}
|
|
||||||
MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }}
|
|
||||||
MAIL_FROM=${{ secrets.MAIL_FROM }}
|
|
||||||
MAIL_RECIPIENTS=${{ secrets.MAIL_RECIPIENTS }}
|
|
||||||
|
|
||||||
|
# Deployment variables for docker-compose
|
||||||
|
IMAGE_TAG=${{ github.sha }}
|
||||||
|
TRAEFIK_HOST=$TRAEFIK_HOST
|
||||||
|
ENV_FILE=$ENV_FILE
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Upload .env and deploy
|
# Upload .env and docker-compose.yml
|
||||||
scp -o StrictHostKeyChecking=accept-new /tmp/klz-cables.env root@alpha.mintel.me:/home/deploy/sites/klz-cables.com/.env
|
scp -o StrictHostKeyChecking=accept-new /tmp/klz-cables.env root@alpha.mintel.me:/home/deploy/sites/klz-cables.com/$ENV_FILE
|
||||||
|
scp -o StrictHostKeyChecking=accept-new docker-compose.yml root@alpha.mintel.me:/home/deploy/sites/klz-cables.com/docker-compose.yml
|
||||||
|
|
||||||
ssh -o StrictHostKeyChecking=accept-new root@alpha.mintel.me bash << EOF
|
ssh -o StrictHostKeyChecking=accept-new root@alpha.mintel.me bash << EOF
|
||||||
set -e
|
set -e
|
||||||
cd /home/deploy/sites/klz-cables.com
|
cd /home/deploy/sites/klz-cables.com
|
||||||
|
|
||||||
chmod 600 .env
|
chmod 600 $ENV_FILE
|
||||||
chown deploy:deploy .env
|
chown deploy:deploy $ENV_FILE
|
||||||
|
|
||||||
echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||||
docker pull registry.infra.mintel.me/mintel/klz-cables.com:latest
|
|
||||||
|
|
||||||
docker-compose down
|
echo "📥 Pulling images..."
|
||||||
|
IMAGE_TAG=${{ github.sha }} ENV_FILE=$ENV_FILE TRAEFIK_HOST="$TRAEFIK_HOST" docker compose --env-file $ENV_FILE pull
|
||||||
|
|
||||||
echo "🚀 Starting containers..."
|
echo "🚀 Starting containers..."
|
||||||
docker-compose up -d
|
IMAGE_TAG=${{ github.sha }} ENV_FILE=$ENV_FILE TRAEFIK_HOST="$TRAEFIK_HOST" docker compose --env-file $ENV_FILE up -d
|
||||||
|
|
||||||
|
echo "🧹 Cleaning up old images..."
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
echo "⏳ Giving the app a few seconds to warm up..."
|
echo "⏳ Giving the app a few seconds to warm up..."
|
||||||
sleep 10
|
sleep 10
|
||||||
|
|
||||||
echo "🔍 Checking container status..."
|
echo "🔍 Checking container status..."
|
||||||
docker-compose ps
|
docker compose --env-file $ENV_FILE ps
|
||||||
|
|
||||||
if ! docker-compose ps | grep -q "Up"; then
|
if ! docker compose --env-file $ENV_FILE ps | grep -q "Up"; then
|
||||||
echo "❌ Container failed to start"
|
echo "❌ Container failed to start"
|
||||||
docker-compose logs --tail=100
|
docker compose --env-file $ENV_FILE logs --tail=100
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -130,6 +157,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "📊 Status: ${{ job.status }}"
|
echo "📊 Status: ${{ job.status }}"
|
||||||
echo "🎯 Target: alpha.mintel.me"
|
echo "🎯 Target: alpha.mintel.me"
|
||||||
|
echo "🌿 Branch: ${{ github.ref_name }}"
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# NOTIFICATION: Gotify
|
# NOTIFICATION: Gotify
|
||||||
@@ -140,7 +168,7 @@ jobs:
|
|||||||
echo "Sending success notification to Gotify..."
|
echo "Sending success notification to Gotify..."
|
||||||
RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \
|
RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \
|
||||||
-F "title=✅ Deployment Success: ${{ github.repository }}" \
|
-F "title=✅ Deployment Success: ${{ github.repository }}" \
|
||||||
-F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref }}) was successful.
|
-F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref_name }}) was successful.
|
||||||
|
|
||||||
Commit: ${{ github.sha }}
|
Commit: ${{ github.sha }}
|
||||||
Actor: ${{ github.actor }}
|
Actor: ${{ github.actor }}
|
||||||
@@ -164,7 +192,7 @@ jobs:
|
|||||||
echo "Sending failure notification to Gotify..."
|
echo "Sending failure notification to Gotify..."
|
||||||
RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \
|
RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \
|
||||||
-F "title=❌ Deployment Failed: ${{ github.repository }}" \
|
-F "title=❌ Deployment Failed: ${{ github.repository }}" \
|
||||||
-F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref }}) failed!
|
-F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref_name }}) failed!
|
||||||
|
|
||||||
Commit: ${{ github.sha }}
|
Commit: ${{ github.sha }}
|
||||||
Actor: ${{ github.actor }}
|
Actor: ${{ github.actor }}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: registry.infra.mintel.me/mintel/klz-cables.com:latest
|
image: registry.infra.mintel.me/mintel/klz-cables.com:${IMAGE_TAG:-latest}
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- infra
|
- infra
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- ${ENV_FILE:-.env}
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# HTTP ⇒ HTTPS redirect
|
# HTTP ⇒ HTTPS redirect
|
||||||
- "traefik.http.routers.klz-cables-web.rule=(Host(`klz-cables.com`) || Host(`www.klz-cables.com`) || Host(`staging.klz-cables.com`)) && !PathPrefix(`/.well-known/acme-challenge/`)"
|
- "traefik.http.routers.klz-cables-web.rule=Host(`${TRAEFIK_HOST}`) && !PathPrefix(`/.well-known/acme-challenge/`)"
|
||||||
- "traefik.http.routers.klz-cables-web.entrypoints=web"
|
- "traefik.http.routers.klz-cables-web.entrypoints=web"
|
||||||
- "traefik.http.routers.klz-cables-web.middlewares=redirect-https"
|
- "traefik.http.routers.klz-cables-web.middlewares=redirect-https"
|
||||||
# HTTPS router
|
# HTTPS router
|
||||||
- "traefik.http.routers.klz-cables.rule=Host(`klz-cables.com`) || Host(`www.klz-cables.com`) || Host(`staging.klz-cables.com`)"
|
- "traefik.http.routers.klz-cables.rule=Host(`${TRAEFIK_HOST}`)"
|
||||||
- "traefik.http.routers.klz-cables.entrypoints=websecure"
|
- "traefik.http.routers.klz-cables.entrypoints=websecure"
|
||||||
- "traefik.http.routers.klz-cables.tls.certresolver=le"
|
- "traefik.http.routers.klz-cables.tls.certresolver=le"
|
||||||
- "traefik.http.routers.klz-cables.tls=true"
|
- "traefik.http.routers.klz-cables.tls=true"
|
||||||
|
|||||||
Reference in New Issue
Block a user