From 3684e64d7f8453e70ef485fb689fb1bb873c0625 Mon Sep 17 00:00:00 2001 From: JuruSysadmin Date: Wed, 7 Jan 2026 14:04:13 -0300 Subject: [PATCH] feat: add Gitea CI/CD workflows for Docker and direct Next.js deployment, Renovate, Dockerfile, docker-compose, and .dockerignore. --- .dockerignore | 52 ++++++++++++++ .gitea/workflows/deploy-docker.yaml | 50 +++++++++++++ .gitea/workflows/deploy.yaml | 58 +++++++++++++++ .gitea/{Workflow => workflows}/renovate.yaml | 12 +--- Dockerfile | 75 ++++++++++++++++++++ docker-compose.yml | 31 ++++++++ 6 files changed, 269 insertions(+), 9 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/deploy-docker.yaml create mode 100644 .gitea/workflows/deploy.yaml rename .gitea/{Workflow => workflows}/renovate.yaml (58%) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..86246de --- /dev/null +++ b/.dockerignore @@ -0,0 +1,52 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Next.js +.next +out +dist + +# Testing +coverage +.nyc_output + +# Misc +.DS_Store +*.pem + +# Debug +*.log + +# Local env files +.env*.local +.env + +# Vercel +.vercel + +# Git +.git +.gitignore +.gitattributes + +# IDE +.vscode +.idea +*.swp +*.swo +*~ + +# CI/CD +.github +.gitea + +# Documentation +README.md +*.md + +# Config files +renovate.json +config.js diff --git a/.gitea/workflows/deploy-docker.yaml b/.gitea/workflows/deploy-docker.yaml new file mode 100644 index 0000000..8accfb8 --- /dev/null +++ b/.gitea/workflows/deploy-docker.yaml @@ -0,0 +1,50 @@ +name: Deploy Next.js with Docker +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ secrets.REGISTRY_URL }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.production + push: true + tags: | + ${{ secrets.REGISTRY_URL }}/portal-dias-rota:latest + ${{ secrets.REGISTRY_URL }}/portal-dias-rota:${{ github.sha }} + cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/portal-dias-rota:buildcache + cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/portal-dias-rota:buildcache,mode=max + + - name: Deploy to server + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.DEPLOY_HOST }} + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_SSH_KEY }} + port: ${{ secrets.DEPLOY_PORT || 22 }} + script: | + cd ${{ secrets.DEPLOY_PATH }} + docker pull ${{ secrets.REGISTRY_URL }}/portal-dias-rota:latest + docker-compose down + docker-compose up -d + docker image prune -f diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..a1c6380 --- /dev/null +++ b/.gitea/workflows/deploy.yaml @@ -0,0 +1,58 @@ +name: Deploy Next.js Application +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build Next.js application + run: npm run build + env: + ORACLE_USER: ${{ secrets.ORACLE_USER }} + ORACLE_PASSWORD: ${{ secrets.ORACLE_PASSWORD }} + ORACLE_CONNECTION_STRING: ${{ secrets.ORACLE_CONNECTION_STRING }} + ORACLE_POOL_MIN: ${{ secrets.ORACLE_POOL_MIN }} + ORACLE_POOL_MAX: ${{ secrets.ORACLE_POOL_MAX }} + ORACLE_POOL_INCREMENT: ${{ secrets.ORACLE_POOL_INCREMENT }} + ORACLE_QUEUE_TIMEOUT: ${{ secrets.ORACLE_QUEUE_TIMEOUT }} + ORACLE_INACTIVITY_TIMEOUT: ${{ secrets.ORACLE_INACTIVITY_TIMEOUT }} + + - name: Deploy to production server + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.DEPLOY_HOST }} + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_SSH_KEY }} + port: ${{ secrets.DEPLOY_PORT || 22 }} + source: ".next,package.json,package-lock.json,public,src,.env.production" + target: ${{ secrets.DEPLOY_PATH }} + strip_components: 0 + + - name: Restart application + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.DEPLOY_HOST }} + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_SSH_KEY }} + port: ${{ secrets.DEPLOY_PORT || 22 }} + script: | + cd ${{ secrets.DEPLOY_PATH }} + npm ci --production + pm2 restart portal-dias-rota || pm2 start npm --name "portal-dias-rota" -- start diff --git a/.gitea/Workflow/renovate.yaml b/.gitea/workflows/renovate.yaml similarity index 58% rename from .gitea/Workflow/renovate.yaml rename to .gitea/workflows/renovate.yaml index 6d2b4fa..c6e1263 100644 --- a/.gitea/Workflow/renovate.yaml +++ b/.gitea/workflows/renovate.yaml @@ -1,21 +1,15 @@ -name: Renovate Bot +name: Renovate Manual on: - schedule: - - cron: '0 6 * * *' - workflow_dispatch: + workflow_dispatch: jobs: renovate: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Self-hosted Renovate uses: docker://renovate/renovate:latest env: RENOVATE_PLATFORM: 'gitea' RENOVATE_ENDPOINT: 'http://git.jurunense.com/api/v1' RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} - RENOVATE_AUTODISCOVER: 'true' - RENOVATE_REQUIRE_CONFIG: 'required' \ No newline at end of file + RENOVATE_AUTODISCOVER: 'true' \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..edc4271 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,75 @@ +# Etapa 1: Build +FROM node:20-alpine AS builder + +WORKDIR /app + +# Instalar dependências necessárias para Oracle Instant Client +RUN apk add --no-cache libaio libnsl libc6-compat curl unzip + +# Baixar e instalar Oracle Instant Client +RUN mkdir -p /opt/oracle && \ + cd /opt/oracle && \ + curl -o instantclient-basiclite.zip https://download.oracle.com/otn_software/linux/instantclient/2340000/instantclient-basiclite-linux.x64-23.4.0.24.05.zip && \ + unzip instantclient-basiclite.zip && \ + rm -f instantclient-basiclite.zip && \ + cd instantclient_23_4 && \ + rm -f *jdbc* *occi* *mysql* *jar uidrvci genezi adrci && \ + echo /opt/oracle/instantclient_23_4 > /etc/ld.so.conf.d/oracle-instantclient.conf && \ + ldconfig + +# Configurar variáveis de ambiente do Oracle +ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_23_4:$LD_LIBRARY_PATH + +# Copiar arquivos de dependências +COPY package*.json ./ + +# Instalar dependências +RUN npm ci + +# Copiar código fonte +COPY . . + +# Build da aplicação Next.js +RUN npm run build + +# Etapa 2: Runtime +FROM node:20-alpine AS runner + +WORKDIR /app + +# Instalar dependências necessárias para Oracle Instant Client +RUN apk add --no-cache libaio libnsl libc6-compat + +# Copiar Oracle Instant Client do builder +COPY --from=builder /opt/oracle/instantclient_23_4 /opt/oracle/instantclient_23_4 + +# Configurar LD_LIBRARY_PATH +RUN echo /opt/oracle/instantclient_23_4 > /etc/ld.so.conf.d/oracle-instantclient.conf && \ + ldconfig + +ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_23_4:$LD_LIBRARY_PATH + +# Criar usuário não-root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Copiar arquivos necessários do builder +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static + +# Definir permissões +RUN chown -R nextjs:nodejs /app + +# Mudar para usuário não-root +USER nextjs + +# Expor porta +EXPOSE 3003 + +# Variáveis de ambiente +ENV NODE_ENV=production +ENV PORT=3003 + +# Comando de inicialização +CMD ["node", "server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2c1f3ee --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3.8' + +services: + portal-dias-rota: + image: ${REGISTRY_URL}/portal-dias-rota:latest + container_name: portal-dias-rota + restart: unless-stopped + ports: + - "3003:3003" + environment: + - NODE_ENV=production + - ORACLE_USER=${ORACLE_USER} + - ORACLE_PASSWORD=${ORACLE_PASSWORD} + - ORACLE_CONNECTION_STRING=${ORACLE_CONNECTION_STRING} + - ORACLE_POOL_MIN=${ORACLE_POOL_MIN:-1} + - ORACLE_POOL_MAX=${ORACLE_POOL_MAX:-30} + - ORACLE_POOL_INCREMENT=${ORACLE_POOL_INCREMENT:-1} + - ORACLE_QUEUE_TIMEOUT=${ORACLE_QUEUE_TIMEOUT:-60000} + - ORACLE_INACTIVITY_TIMEOUT=${ORACLE_INACTIVITY_TIMEOUT:-20000} + networks: + - portal-network + healthcheck: + test: [ "CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3003" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + +networks: + portal-network: + driver: bridge