From 1058b7005f4c6062a95ce464e522ceaf841d8bb5 Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Sun, 28 Dec 2025 23:28:31 -0300 Subject: [PATCH] chore: update deploy workflow and frontend Dockerfile --- .forgejo/workflows/deploy.yaml | 151 +++++++++++++++++++++------------ frontend/Dockerfile | 38 +++------ 2 files changed, 111 insertions(+), 78 deletions(-) diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index 3a1c2cf..9bd63f9 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -9,6 +9,10 @@ on: - 'backoffice/**' - 'frontend/**' +env: + REGISTRY: rg.fr-par.scw.cloud + NAMESPACE: gohorsejobs + jobs: # Job 1: Testes do Backend (Padrão GoHorse) test-backend: @@ -35,14 +39,83 @@ jobs: go test -v ./internal/services/... go test -v ./internal/core/usecases/... - # Job 2: Deploy com Proteção de I/O e RAM - deploy-dev: + # Job 2: Build e Push das Imagens para Scaleway Registry + build-and-push: runs-on: docker needs: [test-backend] - # Executa se o teste passar OU se o teste foi pulado (mudança só no front/backoffice) if: always() && (needs.test-backend.result == 'success' || needs.test-backend.result == 'skipped') + outputs: + backend_updated: ${{ steps.check.outputs.backend }} + frontend_updated: ${{ steps.check.outputs.frontend }} + backoffice_updated: ${{ steps.check.outputs.backoffice }} steps: - - name: Executar Deploy via SSH na Apolo + - name: Checkout code + uses: https://github.com/actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Check changed files + id: check + run: | + if git diff --name-only HEAD~1 HEAD | grep -q "^backend/"; then + echo "backend=true" >> $GITHUB_OUTPUT + else + echo "backend=false" >> $GITHUB_OUTPUT + fi + if git diff --name-only HEAD~1 HEAD | grep -q "^frontend/"; then + echo "frontend=true" >> $GITHUB_OUTPUT + else + echo "frontend=false" >> $GITHUB_OUTPUT + fi + if git diff --name-only HEAD~1 HEAD | grep -q "^backoffice/"; then + echo "backoffice=true" >> $GITHUB_OUTPUT + else + echo "backoffice=false" >> $GITHUB_OUTPUT + fi + + - name: Login to Scaleway Registry + run: | + echo "${{ secrets.SCW_SECRET_KEY }}" | docker login ${{ env.REGISTRY }} -u nologin --password-stdin + + - name: Build and Push Backend + if: steps.check.outputs.backend == 'true' + run: | + docker build -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-${{ github.sha }} \ + -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-latest \ + ./backend + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-${{ github.sha }} + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-latest + + - name: Build and Push Frontend + if: steps.check.outputs.frontend == 'true' + run: | + docker build \ + --build-arg NODE_OPTIONS="--max-old-space-size=2048" \ + --build-arg NEXT_PUBLIC_API_URL="${{ secrets.API_URL }}" \ + --build-arg NEXT_PUBLIC_BACKOFFICE_URL="${{ secrets.BACKOFFICE_URL }}" \ + -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-${{ github.sha }} \ + -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-latest \ + ./frontend + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-${{ github.sha }} + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-latest + + - name: Build and Push Backoffice + if: steps.check.outputs.backoffice == 'true' + run: | + docker build \ + -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-${{ github.sha }} \ + -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-latest \ + ./backoffice + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-${{ github.sha }} + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-latest + + # Job 3: Deploy no Servidor (Pull das imagens do Scaleway) + deploy-dev: + runs-on: docker + needs: [build-and-push] + if: always() && needs.build-and-push.result == 'success' + steps: + - name: Deploy via SSH uses: https://github.com/appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.HOST }} @@ -50,59 +123,33 @@ jobs: key: ${{ secrets.SSH_KEY }} port: ${{ secrets.PORT || 22 }} script: | - cd /mnt/data/gohorsejobs - git fetch origin - git checkout dev - git pull origin dev - - # --- PREPARAÇÃO DO AMBIENTE --- - # 1. Cria diretório temporário na RAM para evitar escritas no SSD (vda3) - mkdir -p /tmp/podman-build - export TMPDIR=/tmp/podman-build - - # 2. Força o kernel a liberar cache e finalizar escritas pendentes para baixar o Load - sync; echo 3 | sudo tee /proc/sys/vm/drop_caches + # Login no Scaleway Registry + echo "${{ secrets.SCW_SECRET_KEY }}" | podman login ${{ env.REGISTRY }} -u nologin --password-stdin # --- DEPLOY DO BACKEND --- - if git diff --name-only HEAD@{1} HEAD | grep -q "^backend/"; then - echo "Iniciando Build Backend (CPU: 50%)..." - nice -n 19 ionice -c 3 podman build \ - --cpu-quota 50000 \ - --memory 1024m \ - -t localhost/gohorsejobs-backend-dev:latest ./backend + if [ "${{ needs.build-and-push.outputs.backend_updated }}" == "true" ]; then + echo "Pulling e reiniciando Backend..." + podman pull ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-latest + podman tag ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backend:dev-latest localhost/gohorsejobs-backend-dev:latest sudo systemctl restart gohorsejobs-backend-dev fi - # --- DEPLOY DO BACKOFFICE --- - if git diff --name-only HEAD@{1} HEAD | grep -q "^backoffice/"; then - echo "Iniciando Build Backoffice (CPU: 30%)..." - nice -n 19 ionice -c 3 podman build \ - --cpu-quota 30000 \ - --memory 2048m \ - -t localhost/gohorsejobs-backoffice-dev:latest ./backoffice - sudo systemctl restart gohorsejobs-backoffice-dev - fi - - # --- DEPLOY DO FRONTEND (Foco em sobrevivência do disco) --- - if git diff --name-only HEAD@{1} HEAD | grep -q "^frontend/"; then - echo "Iniciando Build Frontend (CPU: 20%, RAM: 3G)..." - # ionice -c 3 garante que o build não roube I/O do banco de dados - # NODE_OPTIONS aumenta a RAM disponível para o build não dar swap - # --no-cache garante que o Next.js rebuild com os novos valores de env - nice -n 19 ionice -c 3 podman build \ - --cpu-quota 20000 \ - --memory 3072m \ - --no-cache \ - --build-arg NODE_OPTIONS="--max-old-space-size=2048" \ - --build-arg NEXT_PUBLIC_API_URL="${{ secrets.API_URL || 'http://backend:8080' }}" \ - --build-arg NEXT_PUBLIC_BACKOFFICE_URL="${{ secrets.BACKOFFICE_URL || 'http://backoffice:3001' }}" \ - -t localhost/gohorsejobs-frontend-dev:latest ./frontend + # --- DEPLOY DO FRONTEND --- + if [ "${{ needs.build-and-push.outputs.frontend_updated }}" == "true" ]; then + echo "Pulling e reiniciando Frontend..." + podman pull ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-latest + podman tag ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/frontend:dev-latest localhost/gohorsejobs-frontend-dev:latest sudo systemctl restart gohorsejobs-frontend-dev fi - # --- LIMPEZA FINAL --- - echo "Limpando caches e sincronizando disco..." - rm -rf /tmp/podman-build/* - podman image prune -f - podman builder prune -f - sync \ No newline at end of file + # --- DEPLOY DO BACKOFFICE --- + if [ "${{ needs.build-and-push.outputs.backoffice_updated }}" == "true" ]; then + echo "Pulling e reiniciando Backoffice..." + podman pull ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-latest + podman tag ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/backoffice:dev-latest localhost/gohorsejobs-backoffice-dev:latest + sudo systemctl restart gohorsejobs-backoffice-dev + fi + + # --- LIMPEZA --- + echo "Limpando imagens antigas..." + podman image prune -f \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index a2b81df..c349b1c 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,6 +1,5 @@ # ============================================================================= -# GoHorse Jobs Frontend - Ultra-Optimized Dockerfile with pnpm -# Target: < 150MB final image, minimal disk usage during build +# GoHorse Jobs Frontend - Ultra-Optimized Dockerfile # ============================================================================= # syntax=docker/dockerfile:1 @@ -8,11 +7,7 @@ # Stage 1: Base with pnpm # ----------------------------------------------------------------------------- FROM mirror.gcr.io/library/node:20-alpine AS base - -# Enable corepack and activate pnpm (latest) RUN corepack enable && corepack prepare pnpm@latest --activate - -# Set pnpm store for caching ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" @@ -20,34 +15,27 @@ ENV PATH="$PNPM_HOME:$PATH" # Stage 2: Dependencies # ----------------------------------------------------------------------------- FROM base AS deps - WORKDIR /app - -# Copy package files (pnpm will use package-lock.json if no pnpm-lock.yaml) COPY package.json package-lock.json* pnpm-lock.yaml* ./ - -# Install deps with cache mount - dramatically reduces disk usage on rebuilds RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ pnpm import 2>/dev/null || true && \ pnpm install --frozen-lockfile || pnpm install # ----------------------------------------------------------------------------- -# Stage 3: Builder (memory-optimized) +# Stage 3: Builder (AQUI ESTAVA O PROBLEMA) # ----------------------------------------------------------------------------- FROM base AS builder - -# Reduce memory usage during build ENV NODE_OPTIONS="--max-old-space-size=512" - WORKDIR /app - -# Copy deps from previous stage COPY --from=deps /app/node_modules ./node_modules -# Copy source files (respects .dockerignore) -COPY package.json next.config.* tsconfig.json ./ +# CORREÇÃO: Copiando TODAS as configs e pastas necessárias +COPY package.json next.config.* tsconfig.json postcss.config.mjs ./ +# Se tiver outras configs como tailwind.config.ts, adicione aqui ou use COPY . . (com dockerignore bom) COPY public ./public COPY src ./src +# Adicionei a pasta messages que apareceu no seu ls +COPY messages ./messages # Build arguments ARG NEXT_PUBLIC_API_URL=http://localhost:8080 @@ -56,26 +44,24 @@ ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_BACKOFFICE_URL=$NEXT_PUBLIC_BACKOFFICE_URL ENV NEXT_TELEMETRY_DISABLED=1 -# Build and cleanup in same layer RUN pnpm build && \ rm -rf node_modules/.cache .next/cache # ----------------------------------------------------------------------------- -# Stage 4: Production Runner (minimal) +# Stage 4: Production Runner # ----------------------------------------------------------------------------- FROM mirror.gcr.io/library/node:20-alpine AS runner - WORKDIR /app -# Security: non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -u 1001 -S nextjs -G nodejs ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ - PORT=3000 + PORT=3000 \ + HOSTNAME="0.0.0.0" -# Copy ONLY standalone output (smallest possible) +# O Docker faz o "cp" que você fez na mão AQUI: COPY --from=builder --chown=nextjs:nodejs /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static @@ -84,4 +70,4 @@ USER nextjs EXPOSE 3000 -CMD ["node", "server.js"] +CMD ["node", "server.js"] \ No newline at end of file