Ejecuta Django en el entorno de Cloud Run

Implementar aplicaciones con estado en Cloud Run, como Django, implica integrar servicios para que interactúen entre sí y formen un proyecto cohesivo.

En este instructivo, se da por sentado que tienes conocimientos de desarrollo web con Django. Si es la primera vez que desarrollas con Django, es recomendable que escribas tu primera app de Django antes de continuar.

Si bien en este instructivo se muestra Django de forma específica, puedes usar este proceso de implementación con otros marcos de trabajo basados en Django, como Wagtail y el Django CMS.

En este instructivo, se usa Django 5, que requiere al menos Python 3.10.

Objetivos

En este instructivo, podrás:

  • Crear y conectar una base de datos de Cloud SQL
  • Crea y usa valores de secretos de Secret Manager.
  • Implementar una app de Django en Cloud Run

  • Aloja archivos estáticos en Cloud Storage.

  • Usa Cloud Build para automatizar la implementación.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios nuevos de Google Cloud cumplan con los requisitos para acceder a una prueba gratuita.

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, Artifact Registry, 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 la CLI de gcloud.

  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, Artifact Registry, 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 la CLI de gcloud.

  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

Clona una app de ejemplo

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

  1. Puedes descargar la muestra como un archivo ZIP y extraerla o clonar el repositorio en tu máquina local:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. Ve al directorio que contiene el código de muestra:

    Linux/macOS

    cd python-docs-samples/run/django
    

    Windows

    cd python-docs-samples\run\django
    

Confirma tu configuración de Python

En este instructivo, se usa Python para ejecutar la aplicación de ejemplo en tu máquina. El código de ejemplo también requiere la instalación de dependencias.

Para obtener más detalles, consulta la guía del entorno de desarrollo de Python.

  1. Confirma que tu versión de Python sea al menos la 3.10.

     python -V
    

    Deberías ver Python 3.10.0 o una versión posterior.

  2. Crea un entorno virtual de Python y, luego, instala las dependencias:

    Linux/macOS

    python -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

    Windows

    python -m venv venv
    venv\scripts\activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

Descarga el proxy de Cloud SQL Auth para conectarte a Cloud SQL desde tu máquina local

Cuando se implementa, tu app usa el proxy de autenticación de Cloud SQL integrado en el entorno de Cloud Run para comunicarse con tu instancia de Cloud SQL. Sin embargo, para probar tu aplicación de manera local, debes instalar y usar una copia local del proxy en tu entorno de desarrollo. Para obtener más detalles, consulta la guía del proxy de Cloud SQL Auth.

El proxy de autenticación de Cloud SQL usa la API de Cloud SQL para interactuar con tu instancia de SQL. Para ello, se requiere la autenticación de la aplicación a través de gcloud CLI.

  1. Autentica y adquiere credenciales para la API:

    gcloud auth application-default login
    
  2. Descarga e instala el proxy de Cloud SQL Auth en tu máquina local.

    Linux de 64 bits

    1. Descarga el proxy de autenticación de Cloud SQL:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.linux.amd64
    2. Haz que el proxy de autenticación de Cloud SQL sea ejecutable:
      chmod +x cloud-sql-proxy

    Linux de 32 bits

    1. Descarga el proxy de autenticación de Cloud SQL:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.linux.386
    2. Si no se encuentra el comando curl, ejecuta sudo apt install curl y repite el comando de descarga.
    3. Haz que el proxy de autenticación de Cloud SQL sea ejecutable:
      chmod +x cloud-sql-proxy

    macOS de 64 bits

    1. Descarga el proxy de autenticación de Cloud SQL:
      curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.darwin.amd64
    2. Haz que el proxy de autenticación de Cloud SQL sea ejecutable:
      chmod +x cloud-sql-proxy

    Mac M1

    1. Descarga el proxy de autenticación de Cloud SQL:
        curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.darwin.arm64
        
    2. Haz que el proxy de autenticación de Cloud SQL sea ejecutable:
        chmod +x cloud-sql-proxy
        

    Windows de 64 bits

    Haz clic con el botón derecho en https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.x64.exe y selecciona Guardar vínculo como para descargar el proxy de autenticación de Cloud SQL. Cambia el nombre del archivo por cloud-sql-proxy.exe.

    Windows de 32 bits

    Haz clic con el botón derecho en https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.21.1/cloud-sql-proxy.x86.exe y selecciona Guardar vínculo como para descargar el proxy de autenticación de Cloud SQL. Cambia el nombre del archivo por cloud-sql-proxy.exe.

    Imagen de Docker del proxy de Cloud SQL 

    El proxy de autenticación de Cloud SQL tiene diferentes imágenes de contenedor, como distroless, alpine y buster. La imagen de contenedor del proxy de autenticación de Cloud SQL predeterminada usa distroless, que no contiene shell. Si necesitas una shell o herramientas relacionadas, descarga una imagen basada en alpine o buster. Para obtener más información, consulta Imágenes de contenedor del proxy de autenticación de Cloud SQL.

    Puedes extraer la última imagen a tu máquina local con Docker a través del siguiente comando:

    docker pull gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.21.1
    

    Otro SO

    Para otros sistemas operativos que no se incluyen aquí, puedes compilar el proxy de autenticación de Cloud SQL desde la fuente.

    Puedes mover la descarga a un lugar común, como una ubicación en tu PATH o tu directorio principal. Si decides hacerlo, cuando inicies el proxy de autenticación de Cloud SQL más adelante en el instructivo, recuerda hacer referencia a la ubicación que elegiste cuando uses los comandos cloud-sql-proxy.

Crea servicios de respaldo

En este instructivo, se usan varios Google Cloud servicios para proporcionar la base de datos, el almacenamiento de medios y el almacenamiento de secretos que admiten el proyecto de Django implementado. Estos servicios se implementan en una región específica. 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 región.

En este instructivo, se usan los mecanismos integrados de alojamiento de recursos estáticos en Cloud Run.

Configura una instancia de Cloud SQL para PostgreSQL

Django admite oficialmente varias bases de datos relacionales, pero ofrece la mayor compatibilidad con PostgreSQL. Cloud SQL admite PostgreSQL, por lo que en este instructivo se elige usar ese tipo de base de datos.

En la siguiente sección, se describe la creación de una instancia, una base de datos y un usuario de base de datos de PostgreSQL para la app.

  1. Crea la 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 SQL Edition, elige "Enterprise".

    5. En Ajuste predeterminado de edición, elige "Zona de pruebas".

    6. En el campo ID de instancia, ingresa INSTANCE_NAME.

    7. Ingresa una contraseña para el usuario de postgres.

    8. Mantén los valores predeterminados en los otros campos.

    9. Haz clic en Crear instancia.

    La instancia tarda unos minutos en estar lista para su uso.

    gcloud

    • Crea la instancia de PostgreSQL:

      gcloud sql instances create INSTANCE_NAME \
          --project PROJECT_ID \
          --database-version POSTGRES_16 \
          --tier db-n1-standard-2 \
          --region REGION
      

    Reemplaza lo siguiente:

    • INSTANCE_NAME: El nombre de la instancia de Cloud SQL
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REGION: La región deGoogle Cloud

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

  2. Dentro de la instancia creada, crea una base de datos:

    Console

    1. En la página de tu instancia, ve a la pestaña Bases de datos.
    2. Haz clic en Crear base de datos.
    3. En el diálogo Database Name, ingresa DATABASE_NAME.
    4. Haz 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.

  3. Crea un usuario de base de datos:

    Console

    1. En la página de tu instancia, ve a la pestaña Usuarios.
    2. Haz clic en Agregar cuenta de usuario.
    3. En el diálogo Elige la forma de autenticación, en "Autenticación integrada", haz lo siguiente:
    4. Ingresa el nombre de usuario DATABASE_USERNAME.
    5. Ingresa la contraseña DATABASE_PASSWORD
    6. Haga clic en Agregar.

    gcloud

    • Crea el usuario en la instancia creada recientemente:

      gcloud sql users create DATABASE_USERNAME \
          --instance INSTANCE_NAME \
          --password DATABASE_PASSWORD
      

      Reemplaza PASSWORD por una contraseña segura.

Configura Artifact Registry

Usa Artifact Registry para crear un registro en el que se almacene tu imagen de contenedor.

Console

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

    Ir a la página de 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 Artifact Registry:
gcloud artifacts repositories create cloud-run-source-deploy \
    --repository-format docker \
    --location REGION

Configure un bucket de Cloud Storage

Puedes almacenar los recursos estáticos incluidos de Django, así como los medios subidos por el usuario, en el almacenamiento de objetos con alta disponibilidad a través de Cloud Storage. El paquete django-storages[google] controla la interacción de Django con este backend de almacenamiento.

Console

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

    Ve a la página de Cloud Storage

  2. Haga clic en Crear bucket.

  3. Ingresa lo siguiente (haz clic en "Continuar" cuando sea necesario):

    • En Nombre, ingresa "PROJECT_ID_MEDIA_BUCKET".
    • En Región, selecciona REGION.
    • En Clase de almacenamiento, mantén los valores predeterminados.
    • En Impedir el acceso público, desmarca “Aplicar la prevención de acceso público”.
    • En Control de acceso, selecciona "Preciso".
  4. Mantén los valores predeterminados en los otros campos.

  5. Haz clic en Crear.

gcloud

  • Crea un bucket de Cloud Storage:

    gcloud storage buckets create gs://PROJECT_ID_MEDIA_BUCKET --location=REGION
    

    Reemplaza MEDIA_BUCKET por un sufijo para el bucket de medios. Combinado con el ID del proyecto, esto crea un nombre de bucket único.

Almacena valores secretos en el Secret Manager

Ahora que los servicios de respaldo están configurados, Django necesita información sobre ellos. En lugar de colocar estos valores directamente en el código fuente de Django, este instructivo usa Secret Manager para almacenar esta información de forma segura.

Cree un archivo de entorno de Django como un secreto del Secret Manager

Almacenas la configuración necesaria para iniciar Django en un archivo .env seguro. La app de muestra usa la API de Secret Manager para recuperar el valor del secreto y el paquete django-environ para cargar los valores en el entorno de Django. El secreto está configurado para que Cloud Run y Cloud Build puedan acceder a él.

  1. Crea un archivo llamado .env, en el que se definan la cadena de conexión de la base de datos, el nombre del bucket de medios y un nuevo valor de SECRET_KEY:

    echo DATABASE_URL=postgres://DATABASE_USERNAME:DATABASE_PASSWORD@//cloudsql/PROJECT_ID:REGION:INSTANCE_NAME/DATABASE_NAME > .env
    echo GS_BUCKET_NAME=PROJECT_ID_MEDIA_BUCKET >> .env
    echo SECRET_KEY=$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1) >> .env
    
  2. Almacena el secreto 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 django_settings.

    4. En el diálogo Valor del secreto, pega el contenido de tu archivo .env.

    5. Haz clic en Crear secreto.

    6. Borra el archivo local para evitar las invalidaciones de la configuración local.

    gcloud

    1. Crea un nuevo secreto, django_settings, con el valor del archivo .env:

      gcloud secrets create django_settings --data-file .env
      
    2. Borra el archivo local para evitar las invalidaciones de la configuración local:

      rm .env
      
  3. Configura el acceso al secreto:

    Console

    1. En Secret: django_settings, toma nota del número del proyecto:

      projects/PROJECTNUM/secrets/django_settings
      
    2. Haz clic en la pestaña Permisos.

    3. Haz clic en Otorgar acceso.

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

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

    6. Haz clic en Guardar.

    gcloud

    1. Obtén el valor del número de proyecto (PROJECTNUM):

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

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

    En el resultado, confirma que bindings enumera la nueva cuenta de servicio.

Crea un secreto para la contraseña de administrador de Django

Por lo general, el usuario administrador de Django se crea ejecutando el comando de administración interactivo createsuperuser.

En este instructivo, se usa una migración de datos para crear el usuario administrador y recuperar la contraseña de administrador de Secret Manager.

Console

  1. En la consola de Google Cloud , ve a la página de Secret Manager.
  2. Haz clic en Crear secreto.

  3. En el campo Nombre, ingresa superuser_password.

  4. En el campo Valor del secreto, ingresa una contraseña aleatoria y única.

  5. Haz clic en Crear secreto.

  6. En Detalles de superuser_password, anota el número del proyecto (projects/PROJECTNUM/secrets/superuser_password).

  7. Haz clic en la pestaña Permisos.

  8. Haz clic en Agregar.

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

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

  11. Haga clic en Guardar.

gcloud

  1. Crea un secreto nuevo, superuser_password, a partir de una contraseña generada de forma aleatoria:

    echo -n "$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 30 | head -n1)" | gcloud secrets create superuser_password --data-file -
    
  2. Otorga acceso al secreto a Cloud Build:

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

    En el resultado, confirma que bindings solo enumera Cloud Build como miembro.

Cómo ejecutar la app en una computadora local

Con los servicios de respaldo configurados, ahora puedes ejecutar la app en tu computadora. Esta configuración permite el desarrollo local y la aplicación de migraciones de bases de datos. Ten en cuenta que las migraciones de bases de datos también se aplican en Cloud Build, pero deberás tener esta configuración local para makemigrations.

  1. En una terminal independiente, inicia el proxy de Cloud SQL Auth:

    Linux/macOS

    ./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME
    

    Windows

    cloud-sql-proxy.exe PROJECT_ID:REGION:INSTANCE_NAME
    

    En este paso, se establece una conexión entre tu computadora local y tu instancia de Cloud SQL a fin de realizar pruebas locales. Mantén el proxy de autenticación de Cloud SQL en ejecución durante todo el tiempo que realices pruebas locales en tu app. Ejecutar este proceso en una terminal separada te permite seguir trabajando mientras se ejecuta.

  2. En la terminal original, establece el ID del proyecto de forma local (lo usa la API de Secret Manager):

    Linux/macOS

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    

    Windows

    set GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  3. Establece una variable de entorno para indicar que usas el proxy de autenticación de Cloud SQL (este valor se reconoce en el código):

    Linux/macOS

    export USE_CLOUD_SQL_AUTH_PROXY=true
    

    Windows

    set USE_CLOUD_SQL_AUTH_PROXY=true
    
  4. Ejecuta las migraciones de Django para configurar tus modelos y recursos:

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    python manage.py collectstatic
    
  5. Inicia el servidor web de Django:

    python manage.py runserver 8080
    
  6. En tu navegador, ve a http://localhost:8080.

    Si estás en Cloud Shell, haz clic en el botón Vista previa en la Web y selecciona Vista previa en el puerto 8080.

    En la página, se muestra el siguiente texto: “Hello, world. You're at the polls index”. El servidor web de Django que se ejecuta en tu computadora proporciona las páginas de la app de muestra.

  7. Presiona Ctrl/Cmd+C para detener el servidor web local.

Implementar la app en Cloud Run

Con los servicios de respaldo configurados, ahora puedes implementar el servicio de Cloud Run.

  1. Con el cloudmigrate.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 cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    

    La primera compilación tarda unos minutos en completarse.

  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 polls-service \
        --region REGION \
        --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/polls-service \
        --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:

    Service [polls-service] revision [polls-service-00001-tug] has been deployed
    and is serving 100 percent of traffic.
    Service URL: https://polls-service-PROJECT_ID.REGION.run.app
    
  3. Actualiza el servicio a las URLs de servicio como una variable de entorno.

    CLOUDRUN_SERVICE_URLS=$(gcloud run services describe polls-service \
        --region $REGION  \
        --format "value(metadata.annotations[\"run.googleapis.com/urls\"])" | tr -d '"[]')
    
    gcloud run services update polls-service \
        --region REGION \
        --update-env-vars "^##^CLOUDRUN_SERVICE_URLS=$CLOUDRUN_SERVICE_URLS"
    
  4. Para ver el servicio implementado, ve a la URL del servicio.

  5. Para acceder al administrador de Django, agrega /admin a la URL y accede con el nombre de usuario admin y la contraseña que estableciste anteriormente.

    Para recuperar la contraseña de superusuario de Secret Manager, haz lo siguiente:

    gcloud secrets versions access latest --secret superuser_password && echo ""
    

Actualizar 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 cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    
  2. Implementa el servicio y especifica solo la región y la imagen:

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

Configuración para producción

Ahora tienes una implementación de Django en funcionamiento, pero puedes seguir otros pasos para asegurarte de que tu aplicación esté lista para la producción.

Cómo inhabilitar la depuración

Confirma que la variable DEBUG en mysite/settings.py esté establecida en False. Esto evitará que se muestren páginas de error detalladas al usuario, lo que puede filtrar información sobre las configuraciones.

Limita los privilegios del usuario de la base de datos

Cualquier usuario que se cree con Cloud SQL tiene los privilegios asociados al rol cloudsqlsuperuser: CREATEROLE, CREATEDB y LOGIN.

Para evitar que el usuario de la base de datos de Django tenga estos permisos, crea el usuario de forma manual en PostgreSQL. Deberás tener instalado el terminal interactivo de psql o usar Cloud Shell, que tiene esta herramienta preinstalada.

Console

  1. En la consola de Google Cloud , activa Cloud Shell.

    Activa Cloud Shell

  2. En Cloud Shell, usa la terminal integrada para conectarte a tu instancia INSTANCE_NAME:

    gcloud sql connect INSTANCE_NAME --user postgres
    
  3. Ingresa la contraseña del usuario de postgres.

    Ahora estás usando psql. Deberías ver el mensaje de postgres=>.

  4. Crear un usuario

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    

    Reemplaza PASSWORD por una contraseña aleatoria y única.

  5. Otorga derechos completos sobre la base de datos nueva al usuario nuevo:

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  6. Salga de psql:

    \q
    

gcloud

  1. Inicia una conexión a la instancia de SQL:

    gcloud sql connect INSTANCE_NAME --user postgres
    

    Reemplaza INSTANCE_NAME por la instancia de Cloud SQL creada.

  2. Ingresa la contraseña del usuario de postgres.

    Ahora estás usando psql. Deberías ver el mensaje de postgres=>.

  3. Crear un usuario

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    
  4. Otorga derechos completos sobre la base de datos nueva al usuario nuevo:

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  5. Salga de psql:

    \q
    

Cómo configurar permisos mínimos

De forma predeterminada, este servicio se implementa con la cuenta de servicio de procesamiento predeterminada. Sin embargo, en algunos casos, usar la cuenta de servicio predeterminada puede otorgar demasiados permisos. Si deseas ser más restrictivo, debes crear tu propia cuenta de servicio y asignar solo los permisos que requiere tu servicio. Los permisos necesarios pueden variar de un servicio a otro, según los recursos que use un servicio en particular.

Los roles mínimos del proyecto que requiere este servicio son los siguientes:

  • Invocador de Cloud Run
  • Cliente de Cloud SQL
  • Administrador de almacenamiento en el bucket de medios
  • Usuario con acceso a Secret Manager en el secreto de configuración de Django (El servicio no requiere acceso a la clave secreta de administrador de Django).

Para crear una cuenta de servicio con los permisos necesarios y asignarla al servicio, ejecuta el siguiente comando:

  1. En gcloud CLI, crea una cuenta de servicio con los roles requeridos:

    gcloud iam service-accounts create polls-service-account
    SERVICE_ACCOUNT=polls-service-account@PROJECT_ID.iam.gserviceaccount.com
    
    # Cloud SQL Client
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/cloudsql.client
    
    # Storage Admin, on the media bucket
    gcloud storage buckets add-iam-policy-binding gs://MEDIA_BUCKET \
        --member=serviceAccount:${SERVICE_ACCOUNT} \
        --role=roles/storage.objectAdmin
    
    # Secret Accessor, on the Django settings secret.
    gcloud secrets add-iam-policy-binding django_settings \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/secretmanager.secretAccessor
    
    # Secret Accessor, on the Django super user password.
    gcloud secrets add-iam-policy-binding superuser_password \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/secretmanager.secretAccessor
    
  2. Implementa el servicio y asócialo a la nueva cuenta de servicio:

    gcloud run services update polls-service \
        --region REGION \
        --service-account ${SERVICE_ACCOUNT}
    
  3. Actualiza los trabajos de Cloud Run en cloudmigrate.yaml para que también tengan este parámetro de configuración de --service-account.

Examina el código

Aplicación de muestra

La app de muestra de Django se creó con las herramientas estándar de Django. Con los siguientes comandos, se crea el proyecto y la app de encuestas:

django-admin startproject mysite
python manage.py startapp polls

Las vistas, los modelos y las configuraciones de rutas base se copiaron de Escribir tu primera app de Django (Parte 1 y Parte 2).

Secretos del Secret Manager

El archivo settings.py contiene código que usa la API de Secret Manager en Python para recuperar la versión más reciente del secreto con nombre y extraerlo al entorno (con django-environ):

# SECURITY WARNING: don't run with debug turned on in production!
# Change this to "False" when you are ready for production
env = environ.Env(DEBUG=(bool, True))
env_file = os.path.join(BASE_DIR, ".env")

# Attempt to load the Project ID into the environment, safely failing on error.
try:
    _, os.environ["GOOGLE_CLOUD_PROJECT"] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
    pass

if os.path.isfile(env_file):
    # Use a local secret file, if provided

    env.read_env(env_file)
# ...
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
    # Pull secrets from Secret Manager
    project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")

    client = secretmanager.SecretManagerServiceClient()
    settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
    name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
    payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")

    env.read_env(io.StringIO(payload))
else:
    raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")

El secreto se usa para almacenar varios valores secretos y reducir la cantidad de secretos diferentes que se deben configurar.

Configuración de CSRF

Django tiene protección integrada contra la falsificación de solicitudes entre sitios (CSRF). A partir de Django 4.0, los cambios en la forma en que funciona esto significan que es importante indicarle a Django cuál es su URL alojada, de modo que pueda ofrecer las mejores protecciones para los usuarios que envían datos.

Proporcionas la URL de la app como una variable de entorno en el archivo settings.py. Este es el valor que Django usa para la configuración pertinente.

# SECURITY WARNING: It's recommended that you use this when
# running in production. The URLs will be known once you first deploy
# to Cloud Run. This code takes the URLs and converts it to both these settings formats.
CLOUDRUN_SERVICE_URLS = env("CLOUDRUN_SERVICE_URLS", default=None)
if CLOUDRUN_SERVICE_URLS:
    CSRF_TRUSTED_ORIGINS = env("CLOUDRUN_SERVICE_URLS").split(",")
    # Remove the scheme from URLs for ALLOWED_HOSTS
    ALLOWED_HOSTS = [urlparse(url).netloc for url in CSRF_TRUSTED_ORIGINS]

    SECURE_SSL_REDIRECT = True
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
else:
    ALLOWED_HOSTS = ["*"]

Anulaciones de secretos locales

Si se encuentra un archivo .env en el sistema de archivos local, se usa en lugar del valor de Secret Manager. Crear un archivo .env de forma local puede ayudar con las pruebas locales (p.ej., desarrollo local en una base de datos SQLite o cualquier otro parámetro de configuración local).

Conexión a base de datos

El archivo settings.py contiene la configuración de tu base de datos de SQL: Usa el asistente env.db() de django-environ para cargar la cadena de conexión establecida en DATABASE_URL en el parámetro de configuración DATABASES.

Cuando ejecutas la aplicación de forma local y usas el proxy de autenticación de Cloud SQL para acceder a la base de datos alojada, la marca USE_CLOUD_SQL_AUTH_PROXY ajusta la configuración de la base de datos para usar el proxy.

# Use django-environ to parse the connection string
DATABASES = {"default": env.db()}

# If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
    DATABASES["default"]["HOST"] = "127.0.0.1"
    DATABASES["default"]["PORT"] = 5432

Estático almacenado en la nube

El archivo settings.py también usa django-storages para integrar el bucket de medios de Cloud Storage directamente en el proyecto:

# Define static storage via django-storages[google]
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
STATIC_URL = "/static/"
STORAGES = {
    "default": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
    },
    "staticfiles": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
    },
}
GS_DEFAULT_ACL = "publicRead"

Automatización con Cloud Build

El cloudmigrate.yaml controla todos los pasos necesarios para crear una nueva imagen de contenedor y usarla para aplicar migraciones de bases de datos.

En este instructivo, se opta por usar paquetes de compilación para compilar la imagen del contenedor y puntos de entrada personalizados en Procfile para controlar los comandos de administración. Luego, los trabajos de Cloud Run pueden hacer referencia a estos para ejecutar los comandos.

steps:
  - id: "Build Container Image"
    name: gcr.io/k8s-skaffold/pack
    args: ["build", "${_IMAGE_NAME}", "--builder=gcr.io/buildpacks/builder"]

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

  - id: "Migrate database"
    name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: /bin/bash
    args:
      - "-c"
      - |
        gcloud run jobs create migrate-job \
          --region ${_REGION} \
          --image ${_IMAGE_NAME} \
          --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
          --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
          --command migrate \
          --execute-now

  - id: "Create superuser"
    name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: /bin/bash
    args:
      - "-c"
      - |
        gcloud run jobs create superuser-job \
          --region ${_REGION} \
          --image ${_IMAGE_NAME} \
          --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \
          --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \
          --set-env-vars DJANGO_SUPERUSER_EMAIL=${_ADMIN_EMAIL} \
          --set-secrets DJANGO_SUPERUSER_PASSWORD=${_ADMIN_PASSWORD_NAME}:latest \
          --command createsuperuser \
          --execute-now

options:
  dynamicSubstitutions: true

substitutions:
  _INSTANCE_NAME: django-instance
  _CLOUD_SQL_CONNECTION_NAME: ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}
  _REGION: us-central1
  _SERVICE_NAME: polls-service
  _SECRET_SETTINGS_NAME: django_settings
  _ARTIFACT_REGISTRY: cloud-run-source-deploy
  _IMAGE_NAME: ${_REGION}-docker.pkg.dev/${PROJECT_ID}/${_ARTIFACT_REGISTRY}/${_SERVICE_NAME}
  _ADMIN_EMAIL: example@example.com
  _ADMIN_PASSWORD_NAME: superuser_password

images:
  - "${_IMAGE_NAME}"

En esta configuración, se usan variables de sustitución.

Creación de superusuarios con trabajos de Cloud Run

El comando de administración de Django createsuperuser se puede ejecutar de forma no interactiva configurando DJANGO_SUPERUSER_EMAIL y DJANGO_SUPERUSER_PASSWORD.

En este instructivo, se opta por usar Cloud Run Jobs para ejecutar este comando. Para ello, se agrega una entrada personalizada a Procfile que ejecuta createsuperuser.

# Create superuser (requires DJANGO_SUPERUSER_PASSWORD and DJANGO_SUPERUSER_EMAIL envvars)
createsuperuser: python manage.py createsuperuser --username admin --noinput || echo "User already exists."

Realiza una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

  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.

¿Qué sigue?