Ejecuta Rails en el entorno de Cloud Run

Aprende a implementar una aplicación de Rails de muestra en Cloud Run y a integrar bases de datos administradas, almacenamiento de objetos, secretos encriptados y canalizaciones de compilación con procesamiento sin servidores.

La implementación de aplicaciones de Rails implica la integración de varios servicios para formar un proyecto cohesivo. En este instructivo, se da por sentado que tienes conocimientos de desarrollo web con Rails.

Para este instructivo, debes tener Ruby 3.0 o posterior y Rails 8 o posterior.

Diagrama que muestra la arquitectura de la implementación.
El sitio de Rails se entrega desde Cloud Run, que usa varios servicios de respaldo para almacenar diferentes tipos de datos (información de la base de datos relacional, recursos multimedia, secretos de configuración y imágenes de contenedores). Cloud Build actualiza los servicios de backend como parte de una tarea de compilación y migración.

Objetivos

  • Crea y conecta una base de datos de Cloud SQL a Active Record
  • Crea y usa Secret Manager para almacenar y acceder de forma segura a una clave maestra de Rails
  • Aloja archivos y contenido multimedia subidos por el usuario en Cloud Storage desde Active Storage
  • Usa Cloud Build para automatizar las migraciones de compilación y base de datos
  • Implementa una app de Rails en Cloud Run

Costos

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. Instala Google Cloud CLI.

  6. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

  7. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  9. Verify that billing is enabled for your Google Cloud project.

  10. Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  11. Instala Google Cloud CLI.

  12. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

  13. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  14. Asegúrate de otorgarle los permisos suficientes a la cuenta que se usa en este instructivo.

Prepara el entorno

En este instructivo, se usan varios servicios de Google Cloud para proporcionar la base de datos, el almacenamiento de medios y el almacenamiento de secretos que admiten la aplicación de Rails implementada. Prepara tu entorno configurando una región en la que implementar los servicios y clonando la app de Rails.

Configura el proyecto y la región predeterminados

  1. Establece la configuración de proyecto predeterminada para gcloud CLI ejecutando el siguiente comando:

    gcloud config set project PROJECT_ID
    

    Reemplaza PROJECT_ID por el ID del proyecto de Google Cloud.

  2. Configura tu región:

    export REGION=REGION
    

    Reemplaza REGION por una ubicación adecuada. Para lograr eficiencia entre los servicios, todos deben implementarse en la misma región. Para obtener más información sobre la región más cercana a ti, consulta Productos disponibles por ubicación.

Clona la app de Rails

El código de la app de muestra de Rails está en el repositorio GoogleCloudPlatform/ruby-docs-samples en GitHub.

  1. Clona el repositorio:

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git
    
  2. Ve al directorio que contiene el código de muestra y ejecuta los siguientes comandos para asegurarte de que la aplicación esté configurada correctamente con las gemas y las dependencias requeridas:

    Linux/macOS

    cd ruby-docs-samples/run/rails
    bundle install
    

    Windows

    cd ruby-docs-samples\run\rails
    bundle install
    

Prepara los servicios de respaldo

En este instructivo, se usan varios servicios de Google Cloud para proporcionar la base de datos, el almacenamiento de medios y el almacenamiento de secretos que admiten el proyecto de Rails implementado. Estos servicios se implementan en una región específica. Para lograr eficiencia entre los servicios, lo mejor es que todos se implementen en la misma región. Para obtener más información sobre la región más cercana a ti, consulta Productos disponibles por ubicación.

Configura una instancia de Cloud SQL para PostgreSQL

Rails admite varias bases de datos relacionales, incluidas varias que ofrece Cloud SQL. En este instructivo, se usa PostgreSQL, una base de datos de código abierto que suelen usar las apps de Rails.

En las siguientes secciones, se describe la creación de una instancia, una base de datos y un usuario de base de datos de PostgreSQL para tu app de Rails.

Crear una instancia de PostgreSQL

Console

  1. En la consola de Google Cloud , ve a la página Instancias de Cloud SQL.

    Ir a la página Instancias de Cloud SQL

  2. Haga clic en Crear instancia.

  3. Haz clic en Elegir PostgreSQL.

  4. En el campo ID de instancia, ingresa un nombre para la instancia (INSTANCE_NAME).

  5. En el campo Contraseña, ingresa una contraseña para el usuario de postgres.

  6. Usa los valores predeterminados en los otros campos.

  7. Haga clic en Crear instancia.

gcloud

  • Crea la instancia de PostgreSQL:

    gcloud sql instances create INSTANCE_NAME \
        --database-version POSTGRES_12 \
        --tier db-f1-micro \
        --region REGION
    

    Reemplaza lo siguiente:

    • INSTANCE_NAME: Es el nombre de la nueva instancia de Cloud SQL.

    • REGION: La región deGoogle Cloud

    La instancia demora unos minutos en crearse y estar lista para su uso.

Crea una base de datos

Console

  1. En la consola de Google Cloud , ve a la página Instancias de Cloud SQL.

    Ir a la página Instancias de Cloud SQL

  2. Selecciona la instancia INSTANCE_NAME.

  3. Ve a la pestaña Bases de datos.

  4. Haga clic en Create database.

  5. En el cuadro de diálogo Nombre de la base de datos, ingresa DATABASE_NAME.

  6. Haga clic en Crear.

gcloud

  • Crea la base de datos en la instancia creada recientemente:

    gcloud sql databases create DATABASE_NAME \
        --instance INSTANCE_NAME
    

    Reemplaza DATABASE_NAME por un nombre para la base de datos dentro de la instancia.

Crea un usuario

Genera una contraseña aleatoria para el usuario de la base de datos y escríbela en un archivo llamado dbpassword:

cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1 > dbpassword

Console

  1. En la consola de Google Cloud , ve a la página Instancias de Cloud SQL.

    Ir a la página Instancias de Cloud SQL

  2. Selecciona la instancia INSTANCE_NAME.

  3. Ve a la pestaña Usuarios.

  4. Haz clic en Agregar cuenta de usuario.

  5. En el diálogo Built-in Authentication, haz lo siguiente:

    1. Ingresa el nombre de usuario DATABASE_USERNAME.
    2. Ingresa el contenido del archivo dbpassword como la contraseña PASSWORD.
  6. Haga clic en Agregar.

gcloud

  • Crea el usuario en la instancia creada recientemente y establece su contraseña como el contenido de dbpassword:

    gcloud sql users create DATABASE_USERNAME \
       --instance=INSTANCE_NAME --password=$(cat dbpassword)
    

    Reemplaza DATABASE_USERNAME por un nombre para el usuario dentro de la instancia.

Configura un repositorio de Artifact Registry

Usa Artifact Registry para crear un repositorio en el que almacenar tu imagen de contenedor.

Console

  1. En la consola de Google Cloud , ve a la página Artifact Registry.

    Ve a Artifact Registry

  2. Haz clic en Crear repositorio.

  3. Ingresa lo siguiente:

    • En Nombre, ingresa "cloud-run-source-deploy".
    • En Formato, selecciona "Docker".
    • En Región, selecciona REGION.
  4. Mantén los valores predeterminados en los otros campos.

  5. Haz clic en Crear.

gcloud

  • Crea un repositorio de Artifact Registry:

    gcloud artifacts repositories create cloud-run-source-deploy \
        --repository-format docker \
        --location REGION
    

Configure un bucket de Cloud Storage

Puedes alojar elementos estáticos de Rails y medios subidos por el usuario en el almacenamiento de objetos con alta disponibilidad a través de Cloud Storage.

Console

  1. En la consola de Google Cloud , ve a la página Buckets de Cloud Storage.

    Ir a Buckets

  2. Haz clic en Crear.
  3. En la página Crear un bucket, ingresa la información de tu bucket. Para ir al paso siguiente, haz clic en Continuar.
    1. En la sección Primeros pasos, haz lo siguiente:
      • Ingresa un nombre único a nivel global que cumpla con los requisitos de nombre de los buckets.
      • Para agregar una etiqueta de bucket, expande la sección Etiquetas (), haz clic en Agregar etiqueta y especifica una key y un value para tu etiqueta.
    2. En Ubicación, selecciona lo siguiente: us-central1
    3. En la sección Elige cómo almacenar tus datos, haz lo siguiente:
      1. En la sección Establecer una clase predeterminada, selecciona lo siguiente: Estándar.
      2. Para habilitar el espacio de nombres jerárquico, en la sección Optimizar el almacenamiento para cargas de trabajo con uso intensivo de datos, selecciona Habilitar el espacio de nombres jerárquico en este bucket.
    4. En la sección Elige cómo controlar el acceso a los objetos, selecciona si tu bucket aplica o no la prevención del acceso público y elige un método de control de acceso para los objetos del bucket.
    5. En la sección Elige cómo proteger los datos de objetos, haz lo siguiente:
      • Selecciona cualquiera de las opciones de Protección de datos que desees configurar para tu bucket.
        • Para habilitar la eliminación no definitiva, haz clic en la casilla de verificación Política de eliminación no definitiva (para la recuperación de datos) y especifica la cantidad de días que deseas conservar los objetos después de la eliminación.
        • Para configurar el control de versiones de objetos, haz clic en la casilla de verificación Control de versiones de objetos (para el control de versión) y especifica la cantidad máxima de versiones por objeto y la cantidad de días después de los cuales vencen las versiones no actuales.
        • Para habilitar la política de retención en objetos y buckets, haz clic en la casilla de verificación Retención (para cumplimiento) y, luego, haz lo siguiente:
          • Para habilitar el bloqueo de retención de objetos, haz clic en la casilla de verificación Habilitar la retención de objetos.
          • Para habilitar el Bloqueo del bucket, haz clic en la casilla de verificación Establecer política de retención del bucket y elige una unidad de tiempo y una duración para tu período de retención.
      • Para elegir cómo se encriptarán los datos de tus objetos, expande la sección Encriptación de datos () y selecciona un método de encriptación de datos.
  4. Haz clic en Crear.

gcloud

  • Crear un bucket de Cloud Storage Para crear un nombre de bucket de Cloud Storage único, usa PROJECT_ID y un sufijo de tu elección, MEDIA_BUCKET_SUFFIX. En Cloud Storage, los nombres de bucket deben ser únicos a nivel global.

    gcloud storage buckets create gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \
        --location=REGION
    

Después de crear un bucket, haz públicas las imágenes subidas y cambia los permisos de los objetos de imagen para que todos puedan leerlos.

Console

  1. En la consola de Google Cloud , ve a la página Buckets de Cloud Storage.

    Ir a Buckets

  2. En la lista de buckets, haz clic en el nombre del bucket que deseas hacer público.

  3. Selecciona la pestaña Permisos cerca de la parte superior de la página.

  4. Haz clic en el botón Agregar miembros.

    Aparecerá el diálogo Agregar miembros.

  5. En el campo Miembros nuevos, ingresa allUsers.

  6. En el menú desplegable Seleccionar una función, selecciona el submenú Cloud Storage y haz clic en la opción Visualizador de objetos de almacenamiento.

  7. Haz clic en Guardar.

Una vez que se comparte de forma pública, aparece un ícono de vínculo para cada objeto en la columna de acceso público. Puedes hacer clic en este ícono a fin de obtener la URL del objeto.

Para obtener información sobre cómo ver detalles de errores acerca de operaciones fallidas de Ruby en la consola de Google Cloud , consulta Solución de problemas.

gcloud

  • Usa el comando gcloud storage buckets add-iam-policy-binding para hacer públicos todos los objetos. Usa el valor de MEDIA_BUCKET_SUFFIX que usaste cuando creaste el bucket.

    gcloud storage buckets add-iam-policy-binding gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \
        --member=allUsers --role=roles/storage.objectViewer
    

Almacena valores secretos en el Secret Manager

Ahora que los servicios de respaldo están configurados, Rails necesita información segura, como contraseñas, para acceder a estos servicios. En lugar de colocar estos valores directamente en el código fuente de Rails, este instructivo usa credenciales de Rails y Secret Manager para almacenar esta información de forma segura.

Crea un archivo de credenciales encriptadas y almacena la clave como un secreto de Secret Manager

Rails almacena los secretos en un archivo encriptado llamado “config/credentials.yml.enc”. El archivo se puede desencriptar con el config/master.key local o la variable de entorno ENV["RAILS_MASTER_KEY"]. En el archivo de credenciales, puedes almacenar la contraseña de la base de datos de la instancia de Cloud SQL y otras claves de acceso para las APIs externas.

Puedes almacenar esta clave de forma segura en Secret Manager. Luego, puedes otorgar acceso a Cloud Run y Cloud Build a la clave otorgando acceso a sus respectivas cuentas de servicio. Las cuentas de servicio se identifican con una dirección de correo electrónico que contiene el número de proyecto.

  1. Genera el archivo config/credentials.yml.enc con el siguiente comando:

    bin/rails credentials:edit
    

    El comando creará un archivo config/master.key si no se define una clave maestra y creará un archivo config/credentials.yml.enc si el archivo no existe. Se abrirá un archivo temporal en tu $EDITOR predeterminado con el contenido desencriptado de los secretos que se agregarán.

  2. Copia y pega la contraseña de la base de datos de la instancia de PostgreSQL recién creada del archivo dbpassword al archivo de credenciales:

    secret_key_base: GENERATED_VALUE
    gcp:
        db_password: PASSWORD
    

    Se puede acceder a los Secrets con Rails.application.credentials. Por ejemplo, Rails.application.credentials.secret_key_base debería devolver la base de la clave secreta de la aplicación y Rails.application.credentials.gcp[:db_password] debería devolver la contraseña de la base de datos.

  3. El config/credentials/yml.enc se almacena de forma encriptada, pero el config/master.key se puede almacenar en Secret Manager.

    Console

    1. En la consola de Google Cloud , ve a la página de Secret Manager.

      Ir a la página de Secret Manager

    2. Haz clic en Crear Secreto.

    3. En el campo Nombre, ingresa un nombre para el secreto RAILS_SECRET_NAME.

    4. En el cuadro de diálogo Valor del secreto, pega el valor mater.key en el cuadro.

    5. Haz clic en Crear secreto.

    6. En la página de detalles de Secret de tu secreto, toma nota del número del proyecto:

      projects/PROJECTNUM/secrets/RAILS_SECRET_NAME

    7. En la pestaña Permisos, haz clic en Agregar miembro.

    8. En el campo Miembros nuevos, ingresa PROJECTNUM-compute@developer.gserviceaccount.com y, luego, presiona Enter.

    9. En el campo Miembros nuevos, ingresa PROJECTNUM@cloudbuild.gserviceaccount.com y, luego, presiona Enter.

    10. En el menú desplegable Función, selecciona Descriptor de acceso a secretos de Secret Manager.

    11. Haz clic en Guardar.

    gcloud

    1. Crea un secreto nuevo con el valor de config/master.key:

      gcloud secrets create RAILS_SECRET_NAME --data-file config/master.key
      

      Reemplaza RAILS_SECRET_NAME por un nombre para el secreto nuevo.

    2. Para confirmar la creación del secreto, verifícalo:

      gcloud secrets describe RAILS_SECRET_NAME
      
      gcloud secrets versions access latest --secret RAILS_SECRET_NAME
      
    3. Obtén el valor del número de proyecto:

      gcloud projects describe PROJECT_ID --format='value(projectNumber)'
      
    4. Otorga acceso al secreto a la cuenta de servicio de Cloud Run:

      gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \
          --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \
          --role roles/secretmanager.secretAccessor
      

      Reemplaza PROJECTNUM por el valor del número de proyecto.

    5. Otorga acceso al secreto a la cuenta de servicio de Cloud Build:

      gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \
          --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \
          --role roles/secretmanager.secretAccessor
      

      En el resultado, confirma que bindings enumera las dos cuentas de servicio como miembros.

Conecta la app de Rails a la base de datos de producción y al almacenamiento

En este instructivo, se usa una instancia de PostgreSQL como base de datos de producción y Cloud Storage como backend de almacenamiento. Para que Rails se conecte a la base de datos y al bucket de almacenamiento recién creados, debes especificar toda la información necesaria para acceder a ellos en el archivo .env. El archivo .env contiene la configuración de las variables de entorno de la aplicación. La aplicación leerá este archivo con la gema dotenv. Dado que los secretos se almacenan en credentials.yml.enc y Secret Manager, el .env no tiene que encriptarse porque no contiene credenciales sensibles.

  1. Para configurar la app de Rails para que se conecte con la base de datos y el bucket de almacenamiento, abre el archivo .env.
  2. Modifica la configuración del archivo .env de la siguiente manera. Usa el valor de MEDIA_BUCKET_SUFFIX que usaste cuando creaste el bucket.

    PRODUCTION_DB_NAME: DATABASE_NAME
    PRODUCTION_DB_USERNAME: DATABASE_USERNAME
    CLOUD_SQL_CONNECTION_NAME: PROJECT_ID:REGION:INSTANCE_NAME
    GOOGLE_PROJECT_ID: PROJECT_ID
    STORAGE_BUCKET_NAME: PROJECT_ID-MEDIA_BUCKET_SUFFIX
    

    Ahora, la app de Rails está configurada para usar Cloud SQL y Cloud Storage cuando se implemente en Cloud Run.

Implementa la app en Cloud Run

Con los servicios de respaldo configurados, ahora puedes implementar la app como un servicio de Cloud Run.

  1. Con el cloudbuild.yaml proporcionado, usa Cloud Build para compilar la imagen, ejecutar las migraciones de la base de datos y propagar los recursos estáticos:

    gcloud builds submit --config cloudbuild.yaml \
        --substitutions _SERVICE_NAME=SERVICE_NAME,_INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION,_SECRET_NAME=RAILS_SECRET_NAME
    

    Reemplaza SERVICE_NAME por el nombre del servicio. La primera compilación tarda unos minutos en completarse. Si se agotó el tiempo de espera de la compilación, aumenta la duración del tiempo de espera insertando --timeout=2000s en el comando de compilación.

  2. Cuando la compilación se realice correctamente, implementa el servicio de Cloud Run por primera vez y configura la región del servicio, la imagen base y la instancia de Cloud SQL conectada:

    gcloud run deploy SERVICE_NAME \
            --region REGION \
            --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/SERVICE_NAME \
            --add-cloudsql-instances PROJECT_ID:REGION:INSTANCE_NAME \
            --allow-unauthenticated
    

    Deberías ver un resultado que muestre que la implementación se realizó correctamente, con una URL de servicio.

  3. Para ver el servicio implementado, ve a la URL del servicio.

    Página de destino del álbum de gatos.
    Si la URL del servicio muestra Álbum de fotos de gatos, estás en la página principal de la app.

  4. Intenta subir una foto nueva. Si la foto se sube correctamente, significa que la aplicación de Rails se implementó correctamente.

    Ejemplo de elemento de álbum de gatos
    Si la URL del servicio muestra Álbum de fotos de gatos, estás en la página principal de la app.

Actualiza la aplicación

Si bien los pasos iniciales de aprovisionamiento y la implementación fueron complejos, realizar actualizaciones es un proceso más sencillo:

  1. Ejecuta la compilación de Cloud Build y la secuencia de comandos de migración:

    gcloud builds submit --config cloudbuild.yaml \
            --substitutions _SERVICE_NAME=SERVICE_NAME,_INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION,_SECRET_NAME=RAILS_SECRET_NAME
    
  2. Implementa el servicio y especifica solo la región y la imagen:

    gcloud run deploy SERVICE_NAME \
            --region REGION \
            --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/SERVICE_NAME
    

Examina el código

La app de muestra de Rails se creó con comandos estándar de Rails. Los siguientes comandos crean la app cat_album y usan el comando scaffold para generar un modelo, un controlador y vistas para el recurso Photo:

rails new cat_album
rails generate scaffold Photo caption:text

Conexión a base de datos

El archivo config/database.yml contiene la configuración necesaria para acceder a tus bases de datos en diferentes entornos (desarrollo, prueba y producción). Por ejemplo, la base de datos de producción está configurada para ejecutarse en Cloud SQL para PostgreSQL. El nombre de la base de datos y el nombre de usuario se configuran a través de variables de entorno en el archivo .env, mientras que la contraseña de la base de datos se almacena dentro del archivo config/credentials.yml.enc, que requiere la RAILS_MASTER_KEY para descifrar.

Cuando la app se ejecuta en Cloud Run (completamente administrado), se conecta a la instancia de PostgreSQL con un socket proporcionado por el entorno de Cloud Run. Cuando la app se ejecuta en tu máquina local, se conecta a la instancia de PostgreSQL con el proxy de autenticación de Cloud SQL.

production:
  <<: *default
  database: <%= ENV["PRODUCTION_DB_NAME"] %>
  username: <%= ENV["PRODUCTION_DB_USERNAME"] %>
  password: <%= Rails.application.credentials.gcp[:db_password] %>
  host: "<%= ENV.fetch("DB_SOCKET_DIR") { '/cloudsql' } %>/<%= ENV["CLOUD_SQL_CONNECTION_NAME"] %>"

Contenido multimedia subido por el usuario y almacenado en la nube

Rails usa Active Storage para subir archivos a proveedores de almacenamiento. Los archivos config/storage.yml y config/environments/production.rb especifican Cloud Storage como el proveedor de servicios en el entorno de producción.

google:
  service: GCS
  project: <%= ENV["GOOGLE_PROJECT_ID"] %>
  bucket: <%= ENV["STORAGE_BUCKET_NAME"] %>
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :google

Automatización con Cloud Build

El archivo cloudbuild.yaml realiza no solo los pasos típicos de compilación de imágenes (crear la imagen del contenedor y enviarla a Artifact Registry), sino también las migraciones de la base de datos de Rails. Esta migración se realiza con trabajos de Cloud Run, en los que se usa un comando personalizado para que el contenedor realice la migración, en lugar del servidor web predeterminado.

steps:
  - id: "build image"
    name: "gcr.io/cloud-builders/docker"
    entrypoint: 'bash'
    args: ["-c", "docker build --build-arg MASTER_KEY=$$RAILS_KEY -t ${_IMAGE_NAME} . "]
    secretEnv: ["RAILS_KEY"]

  - id: "push image"
    name: "gcr.io/cloud-builders/docker"
    args: ["push", "${_IMAGE_NAME}"]

  - id: "apply migrations"
    name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: /bin/bash
    secretEnv: ["RAILS_KEY"]
    args:
      - "-c"
      - |
        gcloud run jobs create migrate-job \
          --region ${_REGION} \
          --image ${_IMAGE_NAME} \
          --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
          --set-env-vars RAILS_MASTER_KEY=$$RAILS_KEY \
          --command bundle \
          --args exec,rails,db:migrate \
          --execute-now --wait && \
          gcloud run jobs delete  migrate-job --region ${_REGION} -q

options:
  dynamicSubstitutions: true

substitutions:
  _REGION: us-central1
  _SERVICE_NAME: rails-cat-album
  _INSTANCE_NAME: cat-album
  _SECRET_NAME: rails-master-key
  _AR_REPO_NAME: cloud-run-source-deploy
  _IMAGE_NAME: ${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_AR_REPO_NAME}/${_SERVICE_NAME}
  _CLOUD_SQL_CONNECTION_NAME: ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}

availableSecrets:
  secretManager:
  - versionName: projects/${PROJECT_ID}/secrets/${_SECRET_NAME}/versions/latest
    env: RAILS_KEY

images:
  - "${_IMAGE_NAME}"

En esta configuración, se usan variables de sustitución. Si cambias los valores directamente en el archivo, significa que la marca --substitutions se puede quitar en el momento de la migración.

En esta configuración, solo se aplican las migraciones existentes en el directorio db/migrate. Para crear archivos de migración, consulta Active Record Migrations.

Para compilar la imagen y aplicar las migraciones, la configuración de Cloud Build necesita acceso al secreto RAILS_MASTER_KEY de Secret Manager. El campo availableSecrets establece la versión del secreto y las variables de entorno que se usarán para el secreto. El secreto de la clave maestra se pasa como argumento en el paso de la imagen de compilación y, luego, se establece como RAILS_MASTER_KEY en el Dockerfile cuando se compila la imagen.

ARG MASTER_KEY
ENV RAILS_MASTER_KEY=${MASTER_KEY}

Para extender la configuración de Cloud Build y que incluya la implementación en una sola configuración sin tener que ejecutar dos comandos, consulta Implementación continua desde Git con Cloud Build. Esto requiere cambios en IAM, como se describió.

Limpieza

  1. En la Google Cloud consola, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.