Compilar, probar y contenerizar aplicaciones Python

En esta página se describe cómo configurar Cloud Build para compilar, probar, contenerizar y desplegar aplicaciones Python.

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

Antes de empezar

En las instrucciones de esta página se presupone que tienes conocimientos de Python. Además, también ocurre lo siguiente:

  • Enable the Cloud Build, Cloud Run, Cloud Storage and Artifact Registry APIs.

    Enable the APIs

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

Permisos de gestión de identidades y accesos necesarios

Para obtener instrucciones sobre cómo conceder estos roles, consulta el artículo Conceder un rol mediante la página IAM.

Configurar compilaciones de Python

En esta sección se explica un archivo de configuración de compilación de ejemplo para una aplicación de Python. Incluye pasos de compilación para instalar requisitos, añadir pruebas unitarias y, una vez superadas las pruebas, compilar y desplegar la aplicación.

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

  2. Instala los requisitos: la imagen python de Docker Hub viene con pip preinstalado. Para instalar las dependencias de pip, añade un paso de compilación con los siguientes campos:

    • name: asigna el valor python a este campo para usar la imagen de Python de Docker Hub en esta tarea.
    • entrypoint: al definir este campo, se anula el punto de entrada predeterminado de la imagen a la que se hace referencia en name. Asigna el valor pip a este campo para invocar pip como punto de entrada del paso de compilación y ejecuta los comandos pip.
    • args: el campo args de un paso de compilación toma una lista de argumentos y los transfiere a la imagen a la que hace referencia el campo name. Introduce los argumentos para ejecutar el comando pip install en este campo. La marca --user del comando pip install asegura que los pasos de compilación posteriores puedan acceder a los módulos instalados en este paso de compilación.

    El siguiente paso de compilación añade argumentos para instalar los requisitos del archivo requirements.txt:

    steps:
      # Install dependencies
      - name: python
        entrypoint: pip
        args: ["install", "-r", "requirements.txt", "--user"]
  3. Añadir pruebas unitarias: si has definido pruebas unitarias en tu aplicación mediante un framework de pruebas como pytest, puedes configurar Cloud Build para que ejecute las pruebas añadiendo los siguientes campos en un paso de compilación:

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

    El siguiente paso de compilación guarda la salida del registro pytest en un archivo XML de JUNIT. El nombre de este archivo se crea a partir de la versión corta del ID de la confirmación asociada a tu compilación. En un paso de compilación posterior, se 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. Conteneriza la aplicación: después de añadir el paso de compilación para asegurarte de que se han superado las pruebas, puedes compilar la aplicación. Cloud Build proporciona una imagen Docker prediseñada que puedes usar para contenerizar tu aplicación Python. Para contenedorizar tu aplicación, añade los siguientes campos en un paso de compilación:

    • name: asigna el valor gcr.io/cloud-builders/docker a este campo para usar la imagen de Docker precompilada en tu tarea.
    • args: añade los argumentos del comando docker build como valores de este campo.

    El siguiente paso de compilación crea la imagen myimage y la etiqueta con la versión corta del ID de confirmación. El paso de compilación usa las sustituciones predeterminadas para el ID del proyecto, el nombre del repositorio y los valores SHA cortos, por lo que estos valores se sustituyen automáticamente en el momento de 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 creado en Artifact Registry, que es un Google Cloud servicio que puedes usar para almacenar, gestionar y proteger artefactos de compilación. Para ello, debe tener un repositorio de Docker en Artifact Registry. Para configurar Cloud Build de forma que almacene la imagen en un repositorio de Docker de Artifact Registry, añade un paso de compilación con los siguientes campos:

    • name: asigna el valor gcr.io/cloud-builders/docker a este campo para usar la imagen oficial del compilador docker en tu tarea.
    • args: añade los argumentos del comando docker push como valores de este campo. En la URL de destino, introduce el repositorio Docker de Artifact Registry en el que quieras almacenar la imagen.

    El siguiente paso de compilación envía la imagen que has compilado 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 procedencia de compilación de niveles de la cadena de suministro para artefactos de software (SLSA), haz lo siguiente:

  6. Despliega el contenedor en Cloud Run: para desplegar la imagen en Cloud Run, añade un paso de compilación con los siguientes campos:

    • name: asigna el valor google/cloud-sdk a este campo para usar la imagen de la CLI de gcloud para invocar el comando gcloud y desplegar la imagen en Cloud Run.
    • args: añade los argumentos del comando gcloud run deploy como valores de este campo.

    El siguiente paso de compilación despliega la imagen compilada anteriormente 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 pruebas en Cloud Storage: puedes configurar Cloud Build para que almacene los registros de pruebas en Cloud Storage. Para ello, especifica la ubicación de un segmento y la ruta de los registros de pruebas. El siguiente paso de compilación almacena los registros de prueba que has guardado en el archivo XML de JUNIT en un segmento 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 con todos los pasos descritos anteriormente:

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

    Una vez que se haya completado la compilación, puedes ver los detalles del repositorio en Artifact Registry.

    También puedes ver los metadatos de procedencia de la compilación y validar la procedencia.

Siguientes pasos