Cache no GitHub Actions: npm, pip e Docker

    Sem cache, cada workflow reinstala todas as dependências do zero — um npm ci simples pode demorar 60-90 segundos. Com cache configurado corretamente, esse tempo cai para 5-10 segundos. GitHub Actions oferece 10 GB de cache por repositório e a actions/cache gerencia invalidação automática por hash de arquivo.

    Cache de dependências Node.js

    actions/setup-node tem cache integrado — a forma mais simples de cachear npm:

    yaml
    # Forma 1: cache integrado no setup-node (recomendado)
          - uses: actions/setup-node@v4
            with:
              node-version: '22'
              cache: 'npm'         # ou 'yarn' ou 'pnpm'
              # Chave automática baseada no hash de package-lock.json
    
          - run: npm ci            # usa cache se disponível (~5s vs ~60s)
    
    # Forma 2: cache manual com actions/cache (mais controle)
          - name: Cache node_modules
            uses: actions/cache@v4
            id: npm-cache
            with:
              path: ~/.npm
              key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
              restore-keys: |
                npm-${{ runner.os }}-
    
          - run: npm ci
    
    # pnpm (mais eficiente que npm):
          - uses: pnpm/action-setup@v4
            with:
              version: 9
          - uses: actions/setup-node@v4
            with:
              node-version: '22'
              cache: 'pnpm'
          - run: pnpm install --frozen-lockfile
    Dica
    hashFiles("**/package-lock.json") gera um hash do lock file — quando qualquer dependência muda, o hash muda e o cache é invalidado. restore-keys fornece fallback para o cache mais recente mesmo com hash diferente.

    Cache de dependências Python

    Cache de pip para projetos Python:

    yaml
    # Forma 1: cache integrado no setup-python
          - uses: actions/setup-python@v5
            with:
              python-version: '3.12'
              cache: 'pip'
              cache-dependency-path: 'requirements*.txt'
    
          - run: pip install -r requirements.txt -r requirements-dev.txt
    
    # Forma 2: cache manual (mais controle)
          - name: Cache pip
            uses: actions/cache@v4
            with:
              path: ~/.cache/pip
              key: pip-${{ runner.os }}-${{ hashFiles('requirements*.txt') }}
              restore-keys: |
                pip-${{ runner.os }}-
    
    # Poetry — cache do virtualenv:
          - uses: actions/setup-python@v5
            with:
              python-version: '3.12'
          - uses: snok/install-poetry@v1
          - name: Cache Poetry venv
            uses: actions/cache@v4
            with:
              path: ~/.cache/pypoetry
              key: poetry-${{ runner.os }}-${{ hashFiles('poetry.lock') }}
          - run: poetry install

    Cache de layers Docker

    Cache de build Docker com GitHub Actions Cache para acelerar builds:

    yaml
          - name: Configurar Buildx com cache
            uses: docker/setup-buildx-action@v3
    
          - name: Build com cache GHA
            uses: docker/build-push-action@v6
            with:
              context: .
              push: true
              tags: ghcr.io/usuario/app:latest
              # Cache type=gha usa GitHub Actions Cache automaticamente
              cache-from: type=gha
              cache-to: type=gha,mode=max
    
    # mode=max: cacheia todas as camadas (incluindo intermediárias)
    # mode=min: cacheia apenas a camada final (menor cache, menos eficiente)
    
    # Para repos com muitos builds simultâneos — scope por branch:
              cache-from: type=gha,scope=${{ github.ref_name }}
              cache-to: type=gha,mode=max,scope=${{ github.ref_name }}

    Cache de build TypeScript/turbo

    Cache para monorepos com Turborepo ou NX:

    yaml
    # Turborepo — cache remoto no GitHub Actions:
          - name: Cache Turbo
            uses: actions/cache@v4
            with:
              path: .turbo
              key: turbo-${{ runner.os }}-${{ github.sha }}
              restore-keys: |
                turbo-${{ runner.os }}-
    
          - name: Build e test (apenas módulos afetados)
            run: npx turbo run build test --cache-dir=.turbo
    
    # NX — cache remoto:
          - name: Cache NX
            uses: actions/cache@v4
            with:
              path: .nx/cache
              key: nx-${{ runner.os }}-${{ hashFiles('nx.json', '**/project.json') }}
              restore-keys: |
                nx-${{ runner.os }}-
    
          - run: npx nx affected --target=build,test

    Estratégia de chaves de cache

    A chave correta garante cache útil sem stale data:

    yaml
    # Estrutura de chave recomendada:
    # {runtime}-{os}-{hash-dos-lockfiles}
    
    # Node.js:
    key: node-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
    
    # Python:
    key: python-3.12-${{ runner.os }}-${{ hashFiles('**/requirements*.txt', '**/pyproject.toml') }}
    
    # Docker (por branch para isolamento):
    key: docker-${{ runner.os }}-${{ github.ref_name }}-${{ hashFiles('Dockerfile', '.dockerignore') }}
    
    # restore-keys: lista de prefixos para fallback progressivo
    restore-keys: |
      docker-${{ runner.os }}-${{ github.ref_name }}-
      docker-${{ runner.os }}-
      docker-
    
    # Verificar hit/miss de cache:
          - name: Cache deps
            id: cache-deps
            uses: actions/cache@v4
            with: ...
    
          - name: Instalar deps (apenas se cache miss)
            if: steps.cache-deps.outputs.cache-hit != 'true'
            run: npm ci

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes