Compila, prueba y aloja aplicaciones de Python en contenedores

En esta página, se describe cómo configurar Cloud Build para compilar, probar, implementar y alojar aplicaciones de Python en contenedores.

Cloud Build te permite usar cualquier imagen de contenedor disponible públicamente para ejecutar tus tareas de desarrollo, como compilar, probar, crear contenedores, subir a Artifact Registry, implementar y guardar tus registros de compilación. La imagen python de Docker Hub pública viene preinstalada con las herramientas de python y pip. Puedes configurar Cloud Build para usar estas herramientas a fin de instalar dependencias, compilar y ejecutar pruebas de unidades con estas herramientas.

Antes de comenzar

En las instrucciones de esta página, suponemos que estás familiarizado con Python. Además, tenga en cuenta lo siguiente:

  • Habilita las API de Cloud Build, Cloud Run, Cloud Storage and Artifact Registry.

    Habilita las API

  • Para ejecutar los comandos de gcloud en esta página, instala Google Cloud CLI.
  • Ten el proyecto de Python a mano, incluido el archivo requirements.txt. Necesitas un Dockerfile junto con tu código fuente.
  • Si deseas almacenar el contenedor compilado en Artifact Registry, crea un repositorio de Docker en Artifact Registry.
  • Si deseas almacenar registros de prueba en Cloud Storage, crea un bucket en Cloud Storage.

Permisos de IAM obligatorios

Para obtener instrucciones sobre cómo otorgar estos roles, consulta Otorga una función con la página IAM.

Configura compilaciones de Python

En esta sección, se explica un ejemplo de archivo de configuración de compilación para una app de Python. Tiene pasos de compilación para instalar requisitos, agregar pruebas de unidades y, luego de pasar las pruebas, compilar e implementar la app.

  1. En el directorio raíz del proyecto, crea un archivo de configuración de compilación llamado cloudbuild.yaml.

  2. Requisitos de instalación: La imagen python de Docker Hub viene preinstalada con pip. Para instalar dependencias desde pip, agrega un paso de compilación con los siguientes campos:

    • name: Configura el valor de este campo en python a fin de usar la imagen de Python desde Docker Hub para esta tarea.
    • entrypoint: Si configuras este campo, se anula el punto de entrada predeterminado de la imagen a la que se hace referencia en name. Configura el valor de este campo como pip para invocar a pip como el punto de entrada del paso de compilación y ejecuta los comandos de pip.
    • args: En el campo args de un paso de compilación, se toma una lista de argumentos y se los pasa a la imagen a la que se hace referencia en el campo name. Pasa los argumentos para ejecutar el comando pip install en este campo. La marca --user en el comando pip install garantiza que los pasos de compilación posteriores puedan acceder a los módulos instalados en este paso de compilación.

    En el siguiente paso de compilación, se agregan argumentos a fin de instalar los requisitos del archivo requirements.txt:

    steps:
      # Install dependencies
      - name: python
        entrypoint: pip
        args: ["install", "-r", "requirements.txt", "--user"]
  3. Agrega pruebas de unidades: Si definiste pruebas de unidades en tu aplicación con un framework de pruebas, como pytest, puedes configurar Cloud Build a fin de ejecutar las pruebas. Para ello, agrega los siguientes campos en un paso de compilación:

    • name: Configura el valor de este campo como python para usar la imagen de Python de Docker Hub en tu tarea.
    • entrypoint: Configura el valor de este campo como python para ejecutar los comandos de python.
    • args: Agrega los argumentos para ejecutar el comando python pytest.

    En el siguiente paso de compilación, se guarda el resultado del registro pytest en un archivo XML JUNIT. El nombre de este archivo se construye con la versión corta del ID de confirmación asociado con tu compilación. Los pasos de compilación posteriores guardarán los registros de este archivo en Cloud Storage.

    # Run unit tests
    - name: python
      entrypoint: python
      args: ["-m", "pytest", "--junitxml=${SHORT_SHA}_test_log.xml"] 
  4. Crea contenedores en la app: Después de agregar el paso de compilación a fin de garantizar que las pruebas se hayan aprobado, puedes compilar la aplicación. Cloud Build proporciona una imagen de Docker compilada con anterioridad que puedes usar para organizar tu aplicación de Python en contenedores. Para organizar tu app en contenedores, agrega los siguientes campos en un paso de compilación:

    • name: Establece el valor de este campo en gcr.io/cloud-builders/docker para usar la imagen de Docker compilada previamente para la tarea.
    • args: Agrega los argumentos para el comando docker build como valores para este campo.

    En el siguiente paso de compilación, se compila la imagen myimage y se etiqueta con la versión corta de tu ID de confirmación. En el paso de compilación, se usan las sustituciones predeterminadas para el ID del proyecto, el nombre del repositorio y los valores cortos de SHA, por lo que estos valores se sustituyen de forma automática durante la compilación.

    # 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. Envía el contenedor a Artifact Registry: Puedes almacenar el contenedor compilado en Artifact Registry, que es un servicio de Google Cloud que puedes usar para almacenar, administrar y proteger artefactos de compilación. Para hacer esto, deberás tener un repositorio de Docker existente en Artifact Registry. Para configurar Cloud Build a fin de almacenar la imagen en un repositorio de Docker de Artifact Registry, agrega un paso de compilación con los siguientes campos:

    • name: Establece el valor de este campo en gcr.io/cloud-builders/docker para usar la imagen oficial del compilador docker de Container Registry en tu tarea.
    • args: Agrega los argumentos para el comando docker push como valores de este campo. Para la URL de destino, ingresa el repositorio de Docker de Artifact Registry en el que deseas almacenar la imagen.

    En el siguiente paso de compilación, se envía la imagen que compilaste en el paso anterior a 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: Si quieres que Cloud Build genere información de origen de compilación, usa el campo images en tu paso de compilación en lugar de usar un paso de compilación de Docker push independiente. Si usas compilaciones regionales, también debes agregar el campo requestedVerifyOption y establecer el valor en VERIFIED para habilitar la generación de orígenes.

  6. Implementa el contenedor en Cloud Run: Para implementar la imagen en Cloud Run, agrega un paso de compilación con los siguientes campos:

    • name: Establece el valor de este campo en google/cloud-sdk para usar la imagen de gcloud CLI a fin de invocar el comando gcloud para implementar la imagen en Cloud Run.
    • args: Agrega los argumentos para el comando gcloud run deploy como los valores de este campo.

    En el siguiente paso de compilación, se implementa la imagen compilada con anterioridad en 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. Guardar registros de prueba en Cloud Storage: Puedes configurar Cloud Build para almacenar cualquier registro de prueba en Cloud Storage si especificas una ubicación de bucket existente y una ruta de acceso a los registros de prueba. En el siguiente paso de compilación, se almacenan los registros de prueba que guardaste en el archivo XML JUNIT en un bucket de Cloud Storage:

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

    En el siguiente fragmento, se muestra el archivo de configuración de compilación completo para todos los pasos descritos antes:

    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. Inicia tu compilación: manualmente o con activadores de compilación.

    Cuando se complete la compilación, podrás ver los detalles del repositorio en Artifact Registry.

    También puedes ver los metadatos de origen de compilación y validar la procedencia para proteger tu cadena de suministro de software.

¿Qué sigue?