Crie, teste e conteinerize aplicativos Python

Nesta página, descrevemos como configurar o Cloud Build para criar, testar, conteinerizar e implantar aplicativos Python.

O Cloud Build permite usar qualquer imagem de contêiner disponível publicamente para executar suas tarefas de desenvolvimento, incluindo criação, teste, conteinerização, upload para o Artifact Registry, implantação e salvamento de registros de build. A imagem pública python do Docker Hub vem com as ferramentas python e pip pré-instaladas. É possível configurar o Cloud Build para usar essas ferramentas para instalar dependências, criar e executar testes de unidade usando essas ferramentas.

Antes de começar

Nas instruções desta página, pressupomos que você está familiarizado com o Python. Além disso:

  • Ative as APIs Cloud Build, Cloud Run, Cloud Storage and Artifact Registry.

    Ative as APIs

  • Para executar os comandos gcloud desta página, instale a Google Cloud CLI.
  • Tenha seu projeto Python em mãos, incluindo o arquivo requirements.txt. Você precisa de um Dockerfile com seu código-fonte.
  • Se você quiser armazenar o contêiner criado no Artifact Registry, crie um repositório do Docker no Artifact Registry.
  • Para armazenar registros de teste no Cloud Storage, crie um bucket no Cloud Storage.

Permissões do IAM obrigatórias

Para instruções sobre como conceder esses papéis, consulte Como conceder um papel usando a página do IAM.

Como configurar builds do Python

Nesta seção, você verá um exemplo de arquivo de configuração de versão para um aplicativo Python. Ele tem etapas de versão para instalar requisitos, adicionar testes de unidade e, após a aprovação, criar e implantar o aplicativo.

  1. No diretório raiz do projeto, crie um arquivo de configuração do Cloud Build chamado cloudbuild.yaml.

  2. Requisitos de instalação: a imagem python do Docker Hub vem pré-instalada com pip. Para instalar dependências de pip, adicione uma etapa de versão com os seguintes campos:

    • name: defina o valor desse campo como python para usar a imagem Python do Docker Hub nesta tarefa.
    • entrypoint: a definição desse campo substitui o ponto de entrada padrão da imagem referenciada em name. Defina o valor desse campo como pip para invocar pip como o entrypoint da etapa de versão e execute comandos pip.
    • args: o campo args de uma etapa de criação recebe uma lista de argumentos e os passa para a imagem referenciada pelo campo name. Transmita os argumentos para executar o comando pip install nesse campo. A sinalização --user no comando pip install garante que as etapas subsequentes de versão possam acessar os módulos instalados nesta etapa de versão.

    A etapa de criação a seguir adiciona argumentos para instalar requisitos do arquivo requirements.txt:

    steps:
      # Install dependencies
      - name: python
        entrypoint: pip
        args: ["install", "-r", "requirements.txt", "--user"]
  3. Adicionar testes de unidade: se você definiu testes de unidade no aplicativo usando um framework de teste, como pytest, configure o Cloud Build para executar os testes adicionando os campos a seguir em uma etapa do build:

    • name: defina o valor desse campo como python para usar a imagem Python do Docker Hub na tarefa.
    • entrypoint: defina o valor desse campo como python para executar comandos python.
    • args: adicione os argumentos para executar o comando python pytest.

    A etapa de criação a seguir salva a saída do registro pytest em um arquivo XML JUNIT. O nome desse arquivo é construído usando a versão curta do ID de confirmação associada ao seu build. Uma próxima etapa de versão salvará os registros nesse arquivo no Cloud Storage.

    # Run unit tests
    - name: python
      entrypoint: python
      args: ["-m", "pytest", "--junitxml=${SHORT_SHA}_test_log.xml"] 
  4. Crie o contêiner no app: depois de adicionar a etapa de versão para garantir que os testes passaram, você pode criar o aplicativo. O Cloud Build fornece uma imagem do Docker predefinida que pode ser usada para contentorizar o aplicativo Python. Para contentorizar o aplicativo, adicione os seguintes campos em uma etapa do build

    • name: define o valor desse campo como gcr.io/cloud-builders/docker para usar a imagem do Docker pré-criada para sua tarefa.
    • args: adicione os argumentos do comando docker build como valores para este campo.

    A etapa de criação a seguir cria a imagem myimage e a marca com a versão curta do seu ID de confirmação. A etapa de versão usa as substituições padrão para o ID do projeto, nome do repositório e valores SHA curtos. Portanto, esses valores são substituídos automaticamente no tempo de criação.

    # Docker Build
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t',
             'us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}', '.']
  5. Envie o contêiner para o Artifact Registry: é possível armazenar o contêiner criado no Artifact Registry, que é um serviço do Google Cloud que pode ser usado para armazenar, gerenciar e proteger artefatos de versão. Para isso, é necessário ter um repositório existente do Docker no Artifact Registry. Para configurar o Cloud Build para armazenar a imagem em um repositório do Artifact Registry no Docker, adicione uma etapa de versão com os seguintes campos:

    • name: defina o valor desse campo como gcr.io/cloud-builders/docker para usar a imagem oficial do builder docker do Container Registry para sua tarefa.
    • args: adicione os argumentos do comando docker push como valores deste campo. Para o URL de destino, insira o repositório Docker do Artifact Registry em que você quer armazenar a imagem.

    A etapa de criação a seguir envia a imagem que você criou na etapa anterior para o Artifact Registry:

    # Docker push to Google Artifact Registry
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}']

    Opcional: se você quiser que o Cloud Build gere informações de procedência do build, use o campo images na sua etapa de build em vez de usar um separado usando uma etapa de build Docker push. Se você estiver usando builds regionais, também precisará adicionar o campo requestedVerifyOption e definir o valor como VERIFIED para ativar a geração de procedência.

  6. Implantar o contêiner no Cloud Run: para implantar a imagem no Cloud Run, adicione uma etapa de versão com os seguintes campos:

    • name: defina o valor desse campo como google/cloud-sdk para usar a imagem da CLI gcloud para invocar o comando gcloud e implantar a imagem no Cloud Run.
    • args: adicione os argumentos do comando gcloud run deploy como os valores deste campo.

    A etapa de criação a seguir implanta a imagem criada anteriormente no Cloud Run:

    # Deploy to Cloud Run
    - name: google/cloud-sdk
      args: ['gcloud', 'run', 'deploy', 'helloworld-${SHORT_SHA}',
             '--image=us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}',
             '--region', 'us-central1', '--platform', 'managed',
             '--allow-unauthenticated']
  7. Salvar registros de teste no Cloud Storage: é possível configurar o Cloud Build para armazenar todos os registros de teste no Cloud Storage especificando um local e um caminho do bucket existente para os registros de teste. A etapa de criação a seguir armazena os registros de teste que você salvou no arquivo XML JUNIT em um bucket do Cloud Storage:

    # Save test logs to Google Cloud Storage
    artifacts:
      objects:
        location: gs://${_BUCKET_NAME}/
        paths:
          - ${SHORT_SHA}_test_log.xml

    O snippet a seguir mostra o arquivo de configuração da compilação completo para todas as etapas descritas acima:

    steps:
      # Install dependencies
      - name: python
        entrypoint: pip
        args: ["install", "-r", "requirements.txt", "--user"]
    
      # Run unit tests
      - name: python
        entrypoint: python
        args: ["-m", "pytest", "--junitxml=${SHORT_SHA}_test_log.xml"]
    
      # Docker Build
      - name: 'gcr.io/cloud-builders/docker'
        args: ['build', '-t',
               'us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}', '.']
    
      # Docker push to Google Artifact Registry
      - name: 'gcr.io/cloud-builders/docker'
        args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}']
    
      # Deploy to Cloud Run
      - name: google/cloud-sdk
        args: ['gcloud', 'run', 'deploy', 'helloworld-${SHORT_SHA}',
               '--image=us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}',
               '--region', 'us-central1', '--platform', 'managed',
               '--allow-unauthenticated']
    
    # Save test logs to Google Cloud Storage
    artifacts:
      objects:
        location: gs://${_BUCKET_NAME}/
        paths:
          - ${SHORT_SHA}_test_log.xml
    # Store images in Google Artifact Registry
    images:
      - us-central1-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY_REPO}/myimage:${SHORT_SHA}
  8. Inicie seu build: manualmente ou usando acionadores de build.

    Quando o build for concluído, você vai poder acessar os detalhes do repositório no Artifact Registry.

    Também é possível conferir os metadados de procedência do build e validar a procedência para ajudar a proteger sua cadeia de suprimentos de software.

A seguir