diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a28f3f4..70bd87a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,7 +6,7 @@ on: jobs: build-and-push: - runs-on: ubuntu-latest + runs-on: self-hosted permissions: contents: read packages: write @@ -15,10 +15,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - # Adiciona suporte a QEMU para conseguir buildar ARM64 em runners AMD64 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -34,8 +30,8 @@ jobs: with: context: ./manager push: true - # Constrói para as duas arquiteturas - platforms: linux/amd64,linux/arm64 + # Constrói nativamente apenas para ARM64 na Oracle + platforms: linux/arm64 tags: ghcr.io/${{ github.repository }}/edumanager:latest - name: Build and push Portal @@ -43,6 +39,14 @@ jobs: with: context: ./portal push: true - # Constrói para as duas arquiteturas - platforms: linux/amd64,linux/arm64 + # Constrói nativamente apenas para ARM64 na Oracle + platforms: linux/arm64 tags: ghcr.io/${{ github.repository }}/portalaluno:latest + + - name: Atualizar Containers em Produção (Watchtower) + run: | + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ~/.docker/config.json:/config.json \ + containrrr/watchtower \ + --run-once --cleanup diff --git a/.github/workflows/deploy_backup.yml b/.github/workflows/deploy_backup.yml new file mode 100644 index 0000000..395d778 --- /dev/null +++ b/.github/workflows/deploy_backup.yml @@ -0,0 +1,48 @@ +name: Build and Deploy + +on: + push: + branches: [ main ] + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # Adiciona suporte a QEMU para conseguir buildar ARM64 em runners AMD64 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Manager + uses: docker/build-push-action@v5 + with: + context: ./manager + push: true + # Constrói para as duas arquiteturas + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/${{ github.repository }}/edumanager:latest + + - name: Build and push Portal + uses: docker/build-push-action@v5 + with: + context: ./portal + push: true + # Constrói para as duas arquiteturas + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/${{ github.repository }}/portalaluno:latest \ No newline at end of file diff --git a/GEMINI.md b/GEMINI.md index 9c29009..5a9e4d3 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -9,7 +9,7 @@ - **Storage Architecture**: 100% Self-Hosted (MinIO) - Decoupled from Supabase Cloud. - **Image Serving**: All images are served via a backend proxy route (`/storage/:bucket/:key`) to ensure cross-origin compatibility and security. - **Synchronization**: High-performance local API for bank reconciliation (Asaas). -- **Orquestração:** Portainer (Docker) +- **Orquestração e CI/CD:** Portainer (Docker) com GitHub Actions via Self-Hosted Runner (Oracle ARM64 nativo) e Watchtower. - **Production Entry Point**: All production deployments MUST use `server.selfhosted.js` renamed/copied as `server.js` in the Docker containers to ensure full local feature availability. ## ⚠️ Regras de Negócio Críticas (MANDATÓRIO) @@ -24,5 +24,5 @@ 2. **Segurança:** Todas as rotas sensíveis devem validar o token JWT local (via secrets do ambiente). Proibido usar Supabase SDK para lógica de autenticação ou sincronização no frontend. 3. **Resiliência:** Tratamento rigoroso de erros em chamadas de API de terceiros (Asaas, Evolution API). 4. **Upload de Arquivos:** Proibido o uso de Base64 para envio de novos arquivos ao servidor. Use obrigatoriamente `FormData` e envie o objeto `File/Blob` para as rotas de API que integram com o MinIO. -5. **Build Stability**: Dockerfiles MUST include `ENV NODE_OPTIONS="--max-old-space-size=4096"` before `npm run build` to prevent Vite/Rolldown crashes during ARM64 cross-compilation. +5. **Build & Deploy Stability:** O pipeline de deploy deve obrigatoriamente utilizar `runs-on: self-hosted` e compilar apenas a plataforma `linux/arm64` (sem emulação QEMU). A atualização da stack em produção deve ser automatizada via container transiente do Watchtower. 6. **Express Compatibility**: Avoid using raw `/*` wildcards in Express 5 routes; use Regex paths (`/^\/route\/(.+)$/`) for compatibility with `path-to-regexp` v8. diff --git a/MEMORY.md b/MEMORY.md index d7100b0..529c381 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -8,7 +8,10 @@ - [x] Vacina de cache global: Injeção de `normalizePhotoUrl` nos módulos de Boletim, Turmas e Frequência. - [x] Estabilização do Build ARM64: Injeção de `max_old_space_size=4096` nos Dockerfiles para evitar crashes do Vite no Github Actions. - [x] Correção de Rota Express 5: Migração de curingas `*` para Regex para evitar falhas de inicialização no servidor. -- [ ] Próximo Passo: Validar o tempo de build no Github Actions e confirmar o carregamento das fotos na VPS Oracle. +- [x] Correção do Crash 404 no Portal: Injeção da pasta `src/services` no container de produção para permitir o import do `storage.js`. +- [x] Correção das Imagens de Prova: Normalização das URLs nas questões de avaliações (Portal e Manager). +- [x] Estabilização de CI/CD: Transição para `runs-on: self-hosted` (ARM64 nativo) eliminando lentidão e crashes do QEMU. +- [ ] Próximo Passo: Verificar se o Watchtower sincronizou as imagens corretamente na produção. ### 💳 Módulo Financeiro (Portal do Aluno) - **Funcionalidades Implementadas:** @@ -40,8 +43,8 @@ - [x] **Telemetria do Sistema (Settings):** Cards reais de monitoramento de disco (Postgres) e objetos (MinIO). ### 🚀 Infraestrutura e Deploy -- **Estado Atual:** O pipeline do GitHub Actions está configurado para gerar imagens Docker para `amd64` e `arm64`. -- **Desafio:** O build de `arm64` via QEMU é extremamente lento (>15 min). Tentativas de otimização causaram quebras e foram revertidas para manter a estabilidade. +- **Estado Atual:** Pipeline 100% estabilizado no GitHub Actions usando `self-hosted` runner (Oracle ARM64 nativo). +- **Melhoria:** O build agora ocorre diretamente na arquitetura de destino, sem emulação QEMU, garantindo velocidade e estabilidade total. ## 📋 Próximos Passos Pendentes diff --git a/manager/components/Exams.tsx b/manager/components/Exams.tsx index a17493d..5c3e9ac 100644 --- a/manager/components/Exams.tsx +++ b/manager/components/Exams.tsx @@ -14,6 +14,16 @@ const Exams: React.FC = ({ data, updateData }) => { const [editingExam, setEditingExam] = useState(null); const [isUploading, setIsUploading] = useState(false); + const normalizePhotoUrl = (url?: string) => { + if (!url) return ''; + if (url.startsWith('data:image') || url.startsWith('/storage')) return url; + try { + const match = url.match(/^https?:\/\/[^\/]+\/(.+)$/); + if (match) return `/storage/${match[1]}`; + } catch(e) {} + return url; + }; + const exams = data.exams || []; const filteredExams = exams.filter(exam => @@ -272,7 +282,7 @@ const Exams: React.FC = ({ data, updateData }) => { {question.imageUrl ? (
- Apoio + Apoio
Imagem de apoio window.open(question.imageUrl, '_blank')} + onClick={() => window.open(normalizePhotoUrl(question.imageUrl), '_blank')} /> )}