Compare commits

...

2 Commits

Author SHA1 Message Date
5b43349205 fix: prevent backtick expansion in env generation and fix traefik rules
All checks were successful
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 7s
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Successful in 1m34s
Build & Deploy KLZ Cables / 🏗️ Build App (push) Successful in 4m53s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Successful in 32s
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Successful in 4m13s
Build & Deploy KLZ Cables / 🔔 Notifications (push) Successful in 2s
2026-02-07 00:49:36 +01:00
96b296da12 fix: traefik routing rules and define missing compress middleware
Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 10s
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Successful in 1m37s
Build & Deploy KLZ Cables / 🏗️ Build App (push) Successful in 4m36s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Successful in 32s
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Failing after 1m44s
Build & Deploy KLZ Cables / 🔔 Notifications (push) Successful in 2s
2026-02-06 23:57:37 +01:00
2 changed files with 38 additions and 16 deletions

View File

@@ -29,6 +29,8 @@ jobs:
image_tag: ${{ steps.determine.outputs.image_tag }}
env_file: ${{ steps.determine.outputs.env_file }}
traefik_host: ${{ steps.determine.outputs.traefik_host }}
traefik_host_rule: ${{ steps.determine.outputs.traefik_host_rule }}
primary_host: ${{ steps.determine.outputs.primary_host }}
next_public_base_url: ${{ steps.determine.outputs.next_public_base_url }}
directus_url: ${{ steps.determine.outputs.directus_url }}
directus_host: ${{ steps.determine.outputs.directus_host }}
@@ -115,11 +117,23 @@ jobs:
TARGET="skip"
fi
if [[ "$TRAEFIK_HOST" == *","* ]]; then
# Multi-domain: Host(`a.com`) || Host(`b.com`)
TRAEFIK_HOST_RULE=$(echo "$TRAEFIK_HOST" | sed 's/,/ /g' | awk '{for(i=1;i<=NF;i++) printf "Host(`%s`)%s", $i, (i==NF?"":" || ")}')
PRIMARY_HOST=$(echo "$TRAEFIK_HOST" | cut -d',' -f1 | sed 's/ //g')
else
# Single domain: Host(`domain.com`)
TRAEFIK_HOST_RULE="Host(\`$TRAEFIK_HOST\`)"
PRIMARY_HOST="$TRAEFIK_HOST"
fi
{
echo "target=$TARGET"
echo "image_tag=$IMAGE_TAG"
echo "env_file=$ENV_FILE"
echo "traefik_host=$TRAEFIK_HOST"
echo "traefik_host_rule=$TRAEFIK_HOST_RULE"
echo "primary_host=$PRIMARY_HOST"
echo "next_public_base_url=$NEXT_PUBLIC_BASE_URL"
echo "directus_url=$DIRECTUS_URL"
echo "directus_host=$DIRECTUS_HOST"
@@ -229,7 +243,7 @@ jobs:
TARGET: ${{ needs.prepare.outputs.target }}
IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }}
ENV_FILE: ${{ needs.prepare.outputs.env_file }}
TRAEFIK_HOST: ${{ needs.prepare.outputs.traefik_host }}
TRAEFIK_HOST: ${{ needs.prepare.outputs.primary_host }}
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_base_url }}
NEXT_PUBLIC_UMAMI_WEBSITE_ID: ${{ needs.prepare.outputs.target == 'production' && secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID || (needs.prepare.outputs.target == 'staging' && secrets.STAGING_NEXT_PUBLIC_UMAMI_WEBSITE_ID || secrets.TESTING_NEXT_PUBLIC_UMAMI_WEBSITE_ID || secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID) }}
UMAMI_API_ENDPOINT: ${{ needs.prepare.outputs.target == 'production' && secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL || (needs.prepare.outputs.target == 'staging' && secrets.STAGING_NEXT_PUBLIC_UMAMI_SCRIPT_URL || secrets.TESTING_NEXT_PUBLIC_UMAMI_SCRIPT_URL || secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL) }}
@@ -268,15 +282,19 @@ jobs:
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H alpha.mintel.me >> ~/.ssh/known_hosts 2>/dev/null
# Generated by CI - $TARGET - $(date -u)
# Determine dynamic values before writing the file
LOG_LEVEL=$( [[ "$TARGET" == "testing" || "$TARGET" == "development" ]] && echo "debug" || echo "info" )
COOKIE_DOMAIN=.$(echo $NEXT_PUBLIC_BASE_URL | sed 's|https://||')
cat > /tmp/klz-cables.env << EOF
# Generated by CI - $TARGET - $(date -u)
NODE_ENV=production
IMAGE_TAG=$IMAGE_TAG
NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL
NEXT_PUBLIC_TARGET=$TARGET
NEXT_PUBLIC_UMAMI_WEBSITE_ID=$NEXT_PUBLIC_UMAMI_WEBSITE_ID
UMAMI_API_ENDPOINT=$UMAMI_API_ENDPOINT
SENTRY_DSN=$SENTRY_DSN
LOG_LEVEL=$( [[ "$TARGET" == "testing" || "$TARGET" == "development" ]] && echo "debug" || echo "info" )
LOG_LEVEL=$LOG_LEVEL
MAIL_HOST=$MAIL_HOST
MAIL_PORT=$MAIL_PORT
MAIL_USERNAME=$MAIL_USERNAME
@@ -300,14 +318,15 @@ jobs:
TARGET=$TARGET
SENTRY_ENVIRONMENT=$TARGET
IMAGE_TAG=$IMAGE_TAG
TRAEFIK_HOST=$TRAEFIK_HOST
ENV_FILE=$ENV_FILE
AUTH_MIDDLEWARE=$( [[ "$TARGET" == "production" ]] && echo "compress" || echo "${PROJECT_NAME}-auth,compress" )
PROJECT_NAME=$PROJECT_NAME
COOKIE_DOMAIN=.$(echo $NEXT_PUBLIC_BASE_URL | sed 's|https://||')
COOKIE_DOMAIN=$COOKIE_DOMAIN
TRAEFIK_HOST=$TRAEFIK_HOST
EOF
# Append complex variables that contain backticks using printf to avoid shell expansion hits
printf "AUTH_MIDDLEWARE=%s\n" "$( [[ "$TARGET" == "production" ]] && echo "${PROJECT_NAME}-compress" || echo "${PROJECT_NAME}-auth,${PROJECT_NAME}-compress" )" >> /tmp/klz-cables.env
printf "TRAEFIK_HOST_RULE='%s'\n" '${{ needs.prepare.outputs.traefik_host_rule }}' >> /tmp/klz-cables.env
# 1. Cleanup and Create Directories on server BEFORE SCP
ssh -o StrictHostKeyChecking=accept-new root@alpha.mintel.me bash << 'EOF'
set -e

View File

@@ -25,31 +25,34 @@ services:
labels:
- "traefik.enable=true"
# HTTP ⇒ HTTPS redirect
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.rule=Host(`${TRAEFIK_HOST}`) && !PathPrefix(`/.well-known/acme-challenge/`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.rule=${TRAEFIK_HOST_RULE:-Host(`klz-cables.com`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.entrypoints=web"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-web.middlewares=redirect-https"
# HTTPS router (Protected)
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.rule=Host(`${TRAEFIK_HOST}`) && !PathPrefix(`/stats`, `/errors`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.rule=${TRAEFIK_HOST_RULE:-Host(`klz-cables.com`)}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.entrypoints=websecure"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.tls.certresolver=le"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.tls=true"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.service=${PROJECT_NAME:-klz-cables}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.middlewares=${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,${AUTH_MIDDLEWARE:-compress}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}.middlewares=${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,${AUTH_MIDDLEWARE:-${PROJECT_NAME:-klz-cables}-compress}"
# HTTPS router (Unprotected - for Analytics & Errors)
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.rule=Host(`${TRAEFIK_HOST}`) && PathPrefix(`/stats`, `/errors`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.rule=${TRAEFIK_HOST_RULE:-Host(`klz-cables.com`)} && PathPrefix(`/stats`, `/errors`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.entrypoints=websecure"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.tls.certresolver=le"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.tls=true"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.service=${PROJECT_NAME:-klz-cables}"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.middlewares=${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,compress"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-unprotected.middlewares=${PROJECT_NAME:-klz-cables}-ratelimit,${PROJECT_NAME:-klz-cables}-forward,${PROJECT_NAME:-klz-cables}-compress"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}.loadbalancer.server.port=80"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}.loadbalancer.server.scheme=http"
- "traefik.docker.network=infra"
# Middleware Definitions
- "traefik.http.middlewares.${PROJECT_NAME:-klz-cables}-compress.compress=true"
# Gatekeeper Router (to show the login page)
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.rule=Host(`gatekeeper.${TRAEFIK_HOST}`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.rule=Host(`gatekeeper.${TRAEFIK_HOST:-klz-cables.com}`)"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.entrypoints=websecure"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.tls.certresolver=le"
- "traefik.http.routers.${PROJECT_NAME:-klz-cables}-gatekeeper.tls=true"
@@ -79,7 +82,7 @@ services:
PORT: 3000
COOKIE_DOMAIN: ${COOKIE_DOMAIN}
AUTH_COOKIE_NAME: klz_gatekeeper_session
NEXT_PUBLIC_BASE_URL: https://gatekeeper.${TRAEFIK_HOST}
NEXT_PUBLIC_BASE_URL: https://gatekeeper.${TRAEFIK_HOST:-klz-cables.com}
GATEKEEPER_PASSWORD: ${GATEKEEPER_PASSWORD:-klz2026}
labels:
- "traefik.enable=true"