Création d’une application Django avec déploiement sur Google Cloud Platform :

ÉTAPE 4 Fichiers statiques et Bucket Cloud Storage

Nous abordons dans ce tutoriel la mise en place du système de stockage appelé ‘Bucket’ qui va contenir les différents fichiers nécessaires à la création d’une application web Django

Les principales étapes sont :

Cela nécessite aussi les prérequis suivants :

Bucket “PUBLIC” : configuration du Stockage Cloud sur la console GCP

Accédez à la console Google Cloud : https://console.cloud.google.com/ :

Dans le panneau de navigation, accédez à Stockage / Stockage Cloud :

Cliquez sur Créer un bucket :

Choisissez un nom unique pour votre bucket, et suivez les étapes pour configurer les options nécessaires (région de stockage par exemple).

Nom du bucket :
  public_static_file_bucket
  
  Region :
  europe-west1 (Belgique)

Suivre les instructions et cliquez sur CREER .

Sélectionné le bucket créé puis cliquez sur AUTORISATIONS

Cliquez sur AJOUTER UN COMPTE PRINCIPAL puis entrer allusers et choississez CLoud storage / Lecteur des objets Storage

Le bucket est maintenant publique.

C’est dans ce bucket que nous allons placer les différents dossiers et fichiers dont notre application web Django a besoin comme par exemple le dossier admin qui contient les sous-dossiers css , img et js pour la mise en forme de la page admin.

Bucket “PRIVE” : configuration du Stockage Cloud sur la console GCP

Il s’agit de la même opération sauf que nous allons garder l’accès restreint de ce bucket pour un usage privé et sécurisé.

Accédez à la console Google Cloud : https://console.cloud.google.com/

Dans le panneau de navigation, accédez à Stockage / Stockage Cloud :

Cliquez sur Créer un bucket :

Choisissez un nom unique pour votre bucket, et suivez les étapes pour configurer les options nécessaires (par exemple, région de stockage).

Nom du bucket :
  private_static_file_bucket
  
  Region :
  europe-west1 (Belgique)

Suivre les instructions et cliquez sur CREER . Le bucket privé est créé. L’accès a ce bucket nécessite des règles d’authentification que l’on va voir maintenant.

Configuration IAM

Cette étape consiste à créer un compte de service qui sera lié à notre application afin d’avoir accès à certaine partie de GCP comme la base de données ou les buckets.

Dans le panneau de navigation, accédez à IAM et administration / Comptes de service:

Créez un nouveau compte de service, attribuez-lui un rôle avec des autorisations nécessaires pour accéder à votre bucket.

Nom du compte de service :
  django
  
  ID du compte de service :
  test-deploy-django-service-acc
  
  Adresse e-mail:
  django@deploy-project-django.iam.gserviceaccount.com

Ajouter les rôles suivants : Administrateur Cloud Run, Administrateur de Cloud SQL, Administrateur Storage et Créateur de jetons du compte de service :

Description de l'image

Téléchargez la clé JSON associée à ce compte de service. Si vous êtes sous Linux comme moi, cette clef va dans le répertoire home/utilisateur/.config/gcloud/

Il faut ensuite ajouter dans le fichier .zshrc la ligne :

export GOOGLE_SA_CREDENTIALS=/home/utilisateur/.config/gcloud/nom_de_votre_clef.json

Relancer le terminal. Votre machine a maintenant les droits (”credentials”) pour accéder à ce projet GCP à distance. La configuration des buckets est terminée du côté GCP.

Configuration du projet Django

Nous pouvons configurer notre projet Django pour accéder aux buckets GCP que l’on vient de créer.
Ajouter ce code au fichier
settings.py :

# Static files (CSS, JavaScript, Images)
  # https://docs.djangoproject.com/en/5.0/howto/static-files/
  
  GOOGLE_SA_CREDENTIALS = os.environ.get('GOOGLE_SA_CREDENTIALS', '/home/utilisateur/.config/gcloud/nom_de_votre_clef.json')
  
  STATIC_URL = '/static/'
  
  STATIC_ROOT = os.path.join(BASE_DIR, 'static')
  
  GS_BUCKET_NAME = 'public_static_file_bucket'
  
  GS_MEDIA_BUCKET_NAME = 'private_static_file_bucket'
  
  DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorageUniformBucket"
  
  STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
  
  GS_DEFAULT_ACL = "publicRead"
  
  GS_PROJECT_ID = 'deploy-project-django'

Utilisation des fichiers sur le bucket “PRIVE”

Pour utiliser les fichiers du bucket privé dans une vue django nous utilisons une fonction qui permet d’obtenir une URL temporaire avec un système de jeton. Voilà le code dans le fichier views.py pour afficher une image dans une vue hello_world:

from django.shortcuts import render
  from django.http import HttpResponse
  from django.conf import settings
  from google.cloud import storage
  from datetime import datetime, timedelta
  from google.auth.transport import requests
  import google.auth
  from google.oauth2 import service_account
  
  #=======================================================================================================================
  def sign_url(filename):
      # Vérifiez si vous êtes en local ou sur GCP
      if settings.DEBUG:
          # Environnement local
          credentials = service_account.Credentials.from_service_account_file(settings.GOOGLE_SA_CREDENTIALS,
              scopes=["https://www.googleapis.com/auth/cloud-platform"],
          )
      else:
          # Environnement GCP (production)
          credentials, project_id = google.auth.default()
  
      # Effectuez une demande de rafraîchissement pour obtenir le jeton d'accès des crédits actuels (sinon, il est None)
      r = requests.Request()
      credentials.refresh(r)
  
      client = storage.Client(credentials=credentials)
      bucket = client.get_bucket(settings.GS_MEDIA_BUCKET_NAME)
      blob = bucket.get_blob(f'media/{filename}')
      expires = datetime.datetime.now() + datetime.timedelta(seconds=86400)
  
      # Déterminez l'adresse e-mail du compte de service à utiliser
      service_account_email = "django@deploy-project-django.iam.gserviceaccount.com"
      if hasattr(credentials, "service_account_email"):
          service_account_email = credentials.service_account_email
  
      url = blob.generate_signed_url(expiration=expires, service_account_email=service_account_email, access_token=credentials.token)
      return url, 200
  
  #=======================================================================================================================
  def hello_world(request):
      image_url, _ = sign_url("nom_de_l_image.jpg")
  
      # Passer l'URL signée au modèle pour l'afficher dans le template
      context = {'image_url': image_url}
  
      return render(request, 'hello_world.html', context)
  
  #=======================================================================================================================

La template hello_world.html associée :

<!DOCTYPE html>
  <html>
  <head>
      <title>Hello, World!</title>
  </head>
  <body>
      <h1>Hello, World!</h1>
      <img src="" alt="Uploaded Image">
  </body>
  </html>

Et le fichier urls.py modifié :

from django.urls import path
  from .views import hello_world
  from django.conf import settings
  from django.conf.urls.static import static
  
  urlpatterns = [
      path('hello/', hello_world, name='hello_world'),
      # autres vues
  ]

Utilisation des fichiers sur le bucket PUBLIC

L’utilisation des fichiers nécessaires (fichiers js, css ou images) sur le bucket public est beaucoup plus simple. Voilà un exemple de template utilisant les fichiers static :

<!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Mon application</title>
      {% load static %}
      <link rel="shortcut icon" href={% static 'mon-icone.ico' %} />

Il suffit d’utiliser la ligne {% load static%} eu début de la template html et ensuite d’utiliser {% static 'nom_de_mon_fichier' %}

Déploiement sur GCP

On peut finalement rédéployer comme dans les tutoriels précédants en ajoutant le compte de service comme cela :

Description de l'image

Prochaine étape : Sécurité et gestion des données sensibles avec Secret Manager