Otimizar a montagem e o cachê
(Secção Tecnologia e Infraestrutura)
Resumo curto
A velocidade do CI/CD no iGaming afeta diretamente a frequência dos lançamentos, o custo dos minutos e a resistência do p99 nas cargas de pico. A chave é o cachê certo (dependências, artefatos, camadas de contêineres, resultados intermediários de compilação), montagens incorporadas e determinação. A «boa» montagem é repetida rapidamente com a digitação inalterada, e a deficiência em dinheiro é previsível e controlável.
1) Mapa de cabos e o que nós escondemos
Dependências: pacotes NPM/pnpm, pip wheels/Poetry, Maven/Gradle, Go moda, Cargo crates, NuGet.
Os artefatos intermediários de compilação são '£/.cache/pip', '£/.m2', '.gradle', '£/.cargo/registry/',' $ GOMODCACHE ',' target/', 'build',' node _ modales/.pnpm-store '.
Camadas de contêiner: Docker layer cache (BuildKit/GHA cachê), cash registry-based, multi-estágio.
Ferramentas e SDK: toolchans/micromotivas (JDK, Node, Python, Rustup targets).
Mono/poliretro meta: dinheiro Nx/Turborepo/Bazel remote-cache para tarefas (lint/teste/build).
Dados de teste e ficsturas e2e snepshots BD compilados UI bandles.
ML/dados: datasets preparados, embeddings, motores compilados (TensorRT/ONNX).
2) Princípios de montagem rápida e previsível
1. Determinação: capture versões (lockfiles), pin imagens básicas, hermetic plugins → conclusão reproduzida.
2. Idempotidade, a mesma montagem → os mesmos artefactos e haches.
3. Multiplicidade: Reencontrando apenas o que mudou (DAG/needs/matrix/affected).
4. Local e «calor»: cachês ao lado dos runners/no registro, aquecido antes dos picos.
5. Deficiência explícita: chaves de cachê de lockfile/ficheiros de configuração e haste de conteúdo.
6. Higiene: TTL/' expire _ in ', limpeza automática, controle de tamanho e artefatos.
7. Segurança da cadeia de fornecimento: dinheiro ≠ lixo para segredos; SBOM/assinatura de artefatos permanecem obrigatórios.
3) Docker/OCI: imagens rápidas sem cruzadores
Pattern
Multi-stage (builder → runtime).
Runtime mínimo (distroless/ubi-micro, apenas so/ca-certs).
Ordem de camadas: Primeiro, raramente alterado (deps), depois código.
'.dockerignore': exclua '.git', testes/ficturas, cachês locais.
: 'cache-from/to' é um cachê compartilhado entre os paus e os ramos.
Exemplo de Dockerfile (Node + pnpm)
dockerfile syntax=docker/dockerfile:1. 7
FROM node:20-bookworm AS deps
WORKDIR /app
COPY pnpm-lock. yaml./
RUN corepack enable && pnpm fetch
FROM node:20-bookworm AS builder
WORKDIR /app
COPY --from=deps /root/.cache/pnpm /root/.cache/pnpm
COPY package. json pnpm-lock. yaml./
RUN corepack enable && pnpm install --offline
COPY..
RUN pnpm build
FROM gcr. io/distroless/nodejs20 AS runtime
WORKDIR /app
COPY --from=builder /app/dist./dist
USER 10001
CMD ["dist/server. js"]
BuildKit в CI (GitHub Actions)
yaml
- uses: docker/setup-buildx-action@v3
- uses: actions/cache@v4 with:
path: /tmp/.buildx-cache key: buildx-${{ github. ref }}-${{ github. sha }}
restore-keys: buildx-${{ github. ref }}-
- uses: docker/build-push-action@v6 with:
push: true tags: ${{ env. IMAGE }}
cache-from: type=gha cache-to: type=gha,mode=max
4) Ecossistemas de línguas: o que armazenar e como
Java/Kotlin (Maven/Gradle)
Remote cache Gradle, paralelismo, configuração-a-pedido.
A chave do cachê é hash 'build. gradle[.kts]` + lockfiles + `gradle-wrapper. properties`.
Publicar build cache node em armazenamento de objeto/HTTP.
Compilação aumentada e teste split por lotes.
yaml
GitLab CI cache:
key: gradle-${CI_COMMIT_REF_SLUG}
paths: [.gradle/caches,.gradle/wrapper ]
script:
-./gradlew --build-cache --parallel build
Node. js (npm/pnpm/yarn)
Cash store local ('£/.npm', '£/.cache/pnpm'), chave por lockfile.
Nx/Turborepo remote-cachê (S3/Redis) para tarefas (lint/teste/build).
'turbo run build --cache-dir = .turbo' e 'affected' - cortamos para o monorrepo.
Python (pip/Poetry)
Dinheiro wheels + virtualeng; chave por 'requiments. lock`/`poetry. lock`.
Montar wheels em estágio separado, reutilizar entre matrizes.
Para extensões C - 'pip wheel' + 'auditwheel' na imagem builder.
Go
Кэш `GOMODCACHE`, `GOCACHE`; fixe 'GOTOOLCHAIN '/versões.
Divida os passos: 'go moon download' → cópia do código → 'go build'.
Para grandes monorepes - Bazel/Bazelisk ou 'mage' com slot build'.
Rust
`~/.cargo/registry`, `~/.cargo/git`, `target/`; sccache (remoto/local).
Compartilhar o cachê entre os ramos por 'Cargo. lock`.
C/C++
ccache/sccache + chave sobre as bandeiras do compilador e as versões SDK.
Carregar toolchain para uma imagem básica separada.
5) Bazel/Nx/Turborepo: dinheiro de tarefas e grafo
Bazel remote cachê (HTTP/Cloud) - conteúdo adensável; Estantilidade rigorosa, barras de areia.
Nx/Turborepo - O dinheiro de saída de tarefas e «only-affected» são executados em monorrepo.
Deficiência: depende da entrada do passo (arquivos/bandeiras/variáveis).
6) Estratégias de deficiência em dinheiro
Chave = hash entradas: lockfiles, configs compiladores, manifestos.
Deficiência macia: 'restore-keys' (GHA )/prefixados (GLCI).
Deficiência severa: rotate namespace/chave em alterações críticas.
Divisão de camadas: deps vs surces - Altere o código sem tocar em dependências pesadas.
7) Bildes e matrizes incorporados
DAG/needs: execute o DAG em paralelo, não espere por sequências.
Paths-filter: apenas para componentes afetados.
Shard testes: por diretório/seed, aline a duração.
Warm-pool runners: imagens pré-aquecidas/cachês antes dos picos (torneios/campanhas).
8) Artefatos vs dinheiro: o que é diferente
Dinheiro: entradas reutilizadas/resultados intermediários, área suja, TTL curto/médio.
Artefactos: montagens finais (imagens, binários, charts), imutáveis, assinados, com SBOM.
As regras são que o dinheiro é limpo de forma agressiva, os artefatos são mantidos sob política de lançamento.
9) Observabilidade, KPI e FinOps
Métricas (por pipline/repo):- Hit-rate cachê (%), Warm-start vs Cold-start time, média/mediana duração de estágios.
- Costa per pipeline/job, tamanho cachê/artefatos, largura de banda (jobs/hour).
- Participação de «affected-runs» no monorrepo, cruzamento inalterado (waste).
- Queda de hit-rate abaixo do limite, aumento do tempo "build' imagem, inflação de artefatos, falhas de SLO.
10) Segurança em dinheiro e suply chain
Não há segredos em dinheiro/artefatos; mask vars, escaninhos de segredos.
Pin SHA ações externas/plugins, apenas runners confiáveis.
Assinatura de contêineres/binários (cosign), SBOM (CycloneDX/SPDX) e verificação em CD.
Isolamento: namespace separados do cachê para 'dave/estágio/prod', direitos de leitura somente para foreign branches.
11) Modelos práticos
GitHub Action - idioma + contêiner
yaml name: ci on: [push, pull_request]
concurrency: { group: ${{ github. ref }}, cancel-in-progress: true }
jobs:
build:
runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: { node-version: '20' }
- uses: actions/cache@v4 with:
path: ~/.cache/pnpm key: pnpm-${{ hashFiles('pnpm-lock. yaml') }}
- run: corepack enable && pnpm i --frozen-lockfile
- run: pnpm build
- uses: docker/build-push-action@v6 with:
tags: ${{ env. IMAGE }}
cache-from: type=gha cache-to: type=gha,mode=max
GitLab CI — Gradle remote cache
yaml variables:
GRADLE_USER_HOME: ".gradle"
cache:
key: gradle-${CI_COMMIT_REF_SLUG}
paths: [.gradle/wrapper,.gradle/caches ]
build:
stage: build script:
-./gradlew --build-cache --no-daemon build artifacts:
paths: [ "build/libs/.jar" ]
expire_in: 3 days
Jenkins — ccache/sccache
groovy pipeline {
agent { label 'cpp' }
environment { CCACHE_DIR = '/cache/ccache' }
stages {
stage('Build') {
steps {
sh 'ccache -M 10G'
sh 'cmake -B build -S. && cmake --build build -j$(nproc)'
}
}
}
post { always { sh 'ccache -s' } }
}
12) ML/dados: acelere as montagens pesadas
Dinheiro de modelos/embeddings/datasets em runners NVMe locais; versionagem por hash.
O pré-mercado TensorRT/ONNX os motores como artefatos de lançamento; reutilização na inferência.
Artefatos chunked (splits) para grandes modelos; TTL e limpeza adiada.
13) Folha de cheque de implementação
1. Fixe lockfiles e imagens básicas; Liguem a BuildKit.
2. Divida as camadas Docker: deps → código; adicione '.dockerignore'.
3. Levante remote cache (Gradle/Bazel/Nx/Turbo); estabeleça um dependency proxy.
4. Configure o dinheiro das dependências em CI por lockfile; ative as matrizes e 'paths-filter'.
5. Insira bilds e «affected only» no monorrepo.
6. Mede hit-rate, warm/cold time, custo; Mostrem os alertas.
7. Coloque o SBOM/assinatura, e proíba os segredos no cachê.
8. Aqueça os cachês antes dos lançamentos de pico; regule a TTL/retenção.
9. Documente a deficiência de dinheiro e runbooks em «dinheiro quebrado».
10. Limpe regularmente os cachês «eternos» e arquive os artefatos pesados.
14) Antipattern
Enorme Dockerfile com passos frequentemente alterados antes da instalação deps.
Um dinheiro «eterno» comum sem chaves/TTL → flocos e lixo.
Misturar artefatos e dinheiro; falta de assinatura/SBOM.
Versões inválidas das ferramentas → «O dinheiro existe, mas não se repete».
Matrizes a cada PR; Falta de concurrency. cancel`.
Runner único sem cachê quente e sem dependency proxy.
Resumo
A otimização da montagem é um trabalho de sistema com caixas, incorporatividade e determinação. A estrutura correta do Dockerfile, remote-cachê para bilds, dependency proxy e disciplina de deficiência fornecem linhas de montagem rápidas, baratas e reproduzíveis. Adicione a observabilidade e as regras de segurança - e seus lançamentos serão frequentes, estáveis e econômicos.