Padrão de DevOps: Docker & GitLab CI/CD
Status: Aprovado Área: Arquitetura / DevOps Domínio Relacionado: (N/A)
1. Visão Geral
Este documento define o padrão para empacotamento, publicação e implantação da documentação do CRM utilizando Docker, Docker Compose e pipelines automatizados do GitLab CI/CD.
A arquitetura do deploy baseia-se em build de dois estágios (multi-stage) e na disponibilização de um servidor web otimizado (Nginx) para servir o conteúdo estático produzido pelo Docusaurus.
2. Dockerfile (Build Multi-Stage)
O processo de compilação da imagem Docker isola as dependências de build e runtime.
# Stage 1: Build estático com Node.js
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Servidor estático com Nginx
FROM nginx:1.25-alpine AS runner
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
Regras do Dockerfile:
- Segurança: Utilização de imagens base
alpineleves e com superfície de ataque reduzida. - Performance: A instalação de dependências utiliza
npm cipara garantir reprodutibilidade baseando-se estritamente nopackage-lock.json. - Isolamento: Nenhum código-fonte ou ferramenta de compilação (como compiladores Node e TypeScript) é exposto na imagem final de runtime, que contém apenas o binário do Nginx e os arquivos estáticos compilados.
3. Configuração do Servidor Web (Nginx)
O arquivo nginx.conf é injetado no container de runtime e deve respeitar as seguintes diretrizes de performance e segurança:
- Compressão Gzip: Ativada para reduzir o consumo de banda de rede de arquivos texto, JS e CSS.
- Cache-Control: Headers de cache longo (30 dias) aplicados dinamicamente para arquivos estáticos (
.js,.css, imagens, fontes). - SPA/Docusaurus routing: Fallback com
try_filespara garantir roteamento limpo de páginas. - Segurança (Headers HTTP): Injeção obrigatória dos cabeçalhos:
X-Frame-Options: SAMEORIGIN(prevenção contra clickjacking)X-Content-Type-Options: nosniff(prevenção contra sniffing de mime-types)X-XSS-Protection: 1; mode=block(bloqueio de scripts cross-site)
4. Pipeline do GitLab CI/CD
A pipeline de CI/CD está documentada no arquivo .gitlab-ci.yml na raiz do projeto e segue as seguintes políticas de governança:
Estágios da Pipeline
build-and-publish: Job único responsável por realizar o build e fazer o push das imagens de forma otimizada.
Políticas de Tagging (Publicação de Imagens)
O sistema publica tags no GitLab Container Registry baseado na branch de origem:
- Branch Padrão (Produção): Commits na branch principal geram duas tags no registry:
:latest(aponta para a versão estável de produção mais recente).:sha-$CI_COMMIT_SHORT_SHA(identificador único imutável do commit de build).
- Outras Branches (Desenvolvimento): Commits em branches paralelas publicam tags com o padrão:
:branch-$CI_COMMIT_REF_SLUG(ex::branch-feature-dashboard).:sha-$CI_COMMIT_SHORT_SHA.
Mecanismo de Cache
O pipeline puxa a imagem :latest existente antes do build (docker pull ... || true) e a utiliza como parâmetro --cache-from no Docker build, acelerando a pipeline ao evitar reinstalação de dependências do Node que não sofreram alterações.
5. Docker Compose (Integração com Traefik Proxy)
Para subir o serviço na VPS junto com o proxy reverso e gerenciador de SSL (Traefik), utiliza-se a seguinte estrutura no docker-compose.yml:
services:
# Serviço do Traefik: Proxy Reverso e SSL Automático
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
environment:
- DOCKER_API_VERSION=1.40
command:
- "--global.checknewversion=false"
- "--global.sendanonymoususage=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=admin@guardiansystem.com.br"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
networks:
- traefik_proxy
# Serviço da Documentação do CRM
crm-docs:
image: "vulcano.guardiansystem.com.br/guardian-system/crm:latest"
container_name: crm-portal-docs
restart: unless-stopped
expose:
- "80"
networks:
- traefik_proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.crm-docs.rule=Host(`crm.oryon.api.br`)"
- "traefik.http.routers.crm-docs.entrypoints=websecure"
- "traefik.http.routers.crm-docs.tls=true"
- "traefik.http.routers.crm-docs.tls.certresolver=letsencrypt"
- "traefik.http.services.crm-docs.loadbalancer.server.port=80"
deploy:
resources:
limits:
cpus: '0.50'
memory: 256M
reservations:
cpus: '0.10'
memory: 64M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
traefik_proxy:
external: true
Diretrizes do Compose:
- Segurança de Rede: O container não publica portas diretamente na interface do host (
ports: ...omitido). A comunicação é feita exclusivamente via rede privada Docker virtualtraefik_proxy. - Orquestração e Descoberta: O Traefik faz a autodescoberta do container e mapeia o tráfego da porta
80interna do container para a rota HTTPS baseada nos labels injetados. - Limites de Recursos: Impõe limites rígidos de CPU (50% de um núcleo) e Memória (256MB) para garantir resiliência de infraestrutura em ambientes compartilhados.
- Rotação de Logs: Configuração obrigatória de limites de tamanho (
max-size: 10memax-file: 3) para evitar o esgotamento de espaço em disco no servidor.
6. Mecanismo de Busca Local (Offline Search)
Para garantir que a documentação possa ser lida e pesquisada em ambientes de VPS privados, redes locais ou VPNs sem depender de indexadores externos baseados na nuvem (como Algolia DocSearch), o projeto utiliza a busca local offline via plugin @easyops-cn/docusaurus-search-local.
Características da Configuração:
- Indexação Estática: O índice de palavras-chave é gerado de forma totalmente estática e otimizada durante a compilação do projeto (
npm run build). - Suporte a Idiomas: Configurado para indexar e realizar pesquisas eficientes em Português (pt) e Inglês (en).
- UX (User Experience): Habilita destaque visual de termos buscados ao abrir a página correspondente (
highlightSearchTermsOnTargetPage: true) e adiciona a trilha hierárquica nos resultados da pesquisa (explicitSearchResultPath: true).