Noelia  Graham

Noelia Graham

1660764420

Comment Déployer Une Application Django Sur AWS EC2 Avec Docker

Dans ce didacticiel, nous allons déployer une application Django sur AWS EC2 avec Docker. L'application s'exécutera derrière un proxy HTTPS Nginx qui utilise les certificats SSL Let's Encrypt. Nous utiliserons AWS RDS pour servir notre base de données Postgres avec AWS ECR pour stocker et gérer nos images Docker.

Objectifs

À la fin de ce didacticiel, vous serez en mesure de :

  1. Configurer une nouvelle instance EC2
  2. Installer Docker sur une instance EC2
  3. Configurer et utiliser une adresse IP Elastic
  4. Configurer un rôle IAM
  5. Utiliser le registre d'images Amazon Elastic Container Registry (ECR) pour stocker les images créées
  6. Configurer AWS RDS pour la persistance des données
  7. Configurer un groupe de sécurité AWS
  8. Déployer Django sur AWS EC2 avec Docker
  9. Exécutez l'application Django derrière un proxy HTTPS Nginx avec les certificats SSL Let's Encrypt

Conditions préalables

Cet article s'appuie sur Dockerizing Django avec Postgres, Gunicorn et Nginx et Securing a Containerized Django Application with Let's Encrypt posts.

Cela suppose que vous pouvez :

  1. Conteneurisez une application Django avec Postgres, Nginx et Gunicorn.
  2. Sécurisez une application Django conteneurisée s'exécutant derrière un proxy HTTPS Nginx avec les certificats SSL Let's Encrypt .
  3. Utilisez SSH pour vous connecter à un serveur distant et SCP pour copier des fichiers sur le serveur.

AWS EC2

Tout d'abord, créez un compte AWS si vous n'en avez pas déjà un.

Ensuite, accédez à la console EC2 et cliquez sur Launch instance :

Accueil EC2

Utilisez Ubuntu Server 18.04 LTS (HVM) pour l'image du serveur (AMI) :

Sélectionnez AMI

In the next step, stick with the t2.micro instance. Click on Next: Configure Instance Details:

Type d'instance EC2

At the Configure Instance Details step, leave everything as it is to keep things simple. Then click Next a few times until you're at the Configure Security Group step.

With Create a new security group selected, set the name and description to django-ec2 and add two rules:

  • HTTP -> Anywhere
  • HTTPS -> Anywhere

EC2 configure les groupes de sécurité

These rules are needed to issue certificates and to access the app.

Security group inbound rules are used to limit access to your instance from the internet. Unless you have some additional security requirements, you'll probably want to allow HTTP and HTTPS traffic from anywhere for instances hosting web apps. SSH must be allowed for you to connect to the instance for set up and deployment.

Click Review and Launch. On the next screen, click Launch.

You'll be prompted to select a key pair. You need it for SSH connection to your instance. Select Create a new key pair and name it djangoletsencrypt. Then click Download key pair. After the key pair is downloaded, click on Launch Instances:

EC2 Ajouter une paire de clés

It will take a few minutes for the instance to spin up.

Configure EC2 Instance

In this section, we'll install Docker on the instance, add an Elastic IP, and configure an IAM role.

Install Docker

Navigate back to the EC2 console, select the newly created instance, and grab the public IP address:

IP publique EC2

Connect to your EC2 instance using the .pem key that we downloaded in the "AWS EC2" step.

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance

Your .pem was probably downloaded into path like ~/Downloads/djangoletsencrypt.pem. If you're not sure where to store it, move it into the ~/.ssh directory. You may have to also change the permissions -- i.e., chmod 400 -i /path/to/your/djangoletsencrypt.pem.

Start by installing the latest version of Docker and version 1.29.2 of Docker Compose:

$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt update
$ sudo apt install docker-ce
$ sudo usermod -aG docker ${USER}
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

$ docker -v
Docker version 20.10.8, build 3967b7d

$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

Install AWS CLI

First, install unzip:

$ sudo apt install unzip

Download AWS CLI ZIP:

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

Unzip its content:

$ unzip awscliv2.zip

Install AWS CLI:

$ sudo ./aws/install

Verify installation:

$ aws --version

IP élastique

Par défaut, les instances reçoivent une nouvelle adresse IP publique à chaque démarrage et redémarrage.

Elastic IP vous permet d'allouer des adresses IP statiques pour vos instances EC2, de sorte que l'adresse IP reste la même tout le temps et peut être réassociée entre les instances. Il est recommandé d'en utiliser un pour votre configuration de production.

Accédez à Elastic IPs et cliquez sur Allocate Elastic IP address :

IP élastique

Ensuite, cliquez sur Allouer :

Allocation IP élastique

Cliquez sur Associer cette adresse IP Elastic :

Associé IP élastique

Sélectionnez votre instance et cliquez sur Associer :

Instance de sélection d'adresse IP élastique

Rôle IAM

We'll be using AWS ECR to pull images from AWS ECR to our EC2 instance during deployment. Since we won't be allowing public access to the Docker image on ECR, you'll need to create an IAM role with permissions to pull Docker images from ECR and attach it to your EC2 instance.

Navigate to the IAM console.

Click Roles in the left sidebar and then Create role:

Rôles IAM

Select AWS Service and EC2, then click on Next: Permissions:

Sélectionnez un cas d'utilisation IAM

Enter container in the search box, select the AmazonEC2ContainerRegistryPowerUser policy, and click Next: Tags:

Stratégie de rôle IAM

Cliquez sur Suivant : Réviser . Utilisez django-ec2pour le nom, et cliquez sur Créer un rôle :

Examen du rôle IAM

Vous devez maintenant attacher le nouveau rôle à votre instance EC2.

De retour dans la console EC2 , cliquez sur Instances , puis sélectionnez votre instance. Cliquez sur le menu déroulant Actions -> Paramètres de l'instance -> Attacher/Remplacer le rôle IAM :

Rôle IAM d'attachement EC2

Sélectionnez le rôle django-ec2 , puis cliquez sur Appliquer .

EC2 Sélectionnez le rôle IAM

Cliquez sur Fermer .

Ajouter un enregistrement DNS

Ajoutez un enregistrement A à votre DNS, pour le domaine que vous utilisez, pour pointer vers l'adresse IP publique de votre instance EC2.

Il s'agit de l'adresse IP Elastic que vous avez associée à votre instance.

AWS ECR

Amazon Elastic Container Registry (ECR) is a fully-managed Docker image registry that makes it easy for developers to store and manage images. For private images, access is managed via IAM users and roles.

Navigate to the ECR console. Click Repositories in the sidebar and then on Create repository:

Référentiels ECR

Set the name to django-ec2 and click on Create repository:

ECR Créer un référentiel

AWS RDS

Now we can configure an RDS Postgres database.

While you can run your own Postgres database in a container, since databases are critical services, adding additional layers, such us Docker, adds unnecessary risk in production. To simplify tasks such as minor version updates, regular backups, and scaling, it's recommended to use a managed service. So, we'll use RDS.

Navigate to the RDS console. Click on Create database:

Accueil RDS

Select the latest version of Postgres with the Free tier template:

RDS Créer une base de données

Under Settings, set:

  • DB Instance identifier: djangoec2
  • Master username: webapp
  • Select Auto generate a password

Stick with default settings for:

  • DB instance size
  • Storage
  • Availability & durability

Passez à la section Connectivité et définissez les éléments suivants :

  • Cloud privé virtuel (VPC) : par défaut
  • Groupe de sous-réseau : par défaut
  • Accessible au public : Non
  • Groupe de sécurité VPC :django-ec2
  • Port de la base de données : 5432

RDS Créer une connectivité de base de données

Laissez l' authentification de la base de données telle quelle.

Ouvrez la configuration supplémentaire et remplacez le nom de la base de données initiale par djangoec2:

RDS Créer le nom de base de données initial de la base de données

Laissez les autres paramètres tels quels.

Enfin, cliquez sur Créer une base de données .

Cliquez sur Afficher les détails des informations d'identification pour voir le mot de passe généré pour l' utilisateur de l' application Web :

Informations d'identification de la vue RDS

Conservez ce mot de passe dans un endroit sûr. Vous devrez le fournir à l'application Django ici sous peu.

It will take a few of minutes for the instance to spin up. Once up, click on the DB Identifier of the newly created database to see its details. Take note of the database endpoint; you'll need to set it in your Django app.

Détails de la base de données RDS

AWS Security Group

Within the EC2 console, click Security Groups in the sidebar. Find and click the ID of the django-ec2 group to edit its details.

Click on Edit inbound rules:

Détails du groupe de sécurité EC2

Add an inbound rule that will allow Postgres connections to instances inside that Security Group. To do that:

  • click on Add rule
  • select PostgreSQL for the rule type
  • select Custom for the rule source
  • click into the search field and select the django-ec2 Security Group
  • click on Save rules

To limit access to your database, only connections from instances inside the same Security Group are allowed. Our application can connect because we set the same Security Group, django-ec2, for both the RDS and EC2 instances. Instances inside other Security Groups are therefore not allowed to connect.

EC2 Modifier les règles entrantes

Project Config

With the AWS infrastructure set up, we now need to configure our Django project locally before deploying it.

First, clone down the contents from the GitHub project repo:

$ git clone https://github.com/testdrivenio/django-on-docker-letsencrypt django-on-docker-letsencrypt-aws
$ cd django-on-docker-letsencrypt-aws

This repository contains everything that you need to deploy a Dockerized Django with Let's Encrypt HTTPS certificates.

Docker Compose

Lorsque l'application est déployée pour la première fois, vous devez suivre ces deux étapes pour éviter les problèmes avec les certificats :

  1. Commencez par émettre les certificats à partir de l'environnement de staging de Let's Encrypt
  2. Ensuite, lorsque tout fonctionne comme prévu, passez à l'environnement de production de Let's Encrypt

Vous pouvez en savoir plus sur les limitations de Let's Encrypt sur les environnements de production dans la section Let's Encrypt de l'article précédent, Sécuriser une application Django conteneurisée avec Let's Encrypt .

Pour les tests, mettez à jour le fichier docker-compose.staging.yml. fichier comme ceci:

version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.staging
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.staging.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

Pour les services webet , mettez à jour les propriétés pour utiliser les images d'ECR (que nous ajouterons sous peu).nginx-proxyimage

Exemples:

image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web

image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy

Les valeurs se composent de l'URL du référentiel ( 123456789.dkr.ecr.us-east-1.amazonaws.com) ainsi que du nom de l'image ( django-ec2) et des balises ( webet nginx-proxy).

Pour simplifier les choses, nous utilisons un seul registre pour stocker les deux images. Nous avons utilisé les webet nginx-proxypour différencier les deux. Idéalement, vous devriez utiliser deux registres : un pour webet un pour nginx-proxy. Mettez-le à jour par vous-même si vous le souhaitez.

Outre les imagepropriétés, nous avons également supprimé le dbservice (et le volume associé) puisque nous utilisons RDS plutôt que de gérer Postgres dans un conteneur.

Environnements

Il est temps de configurer les fichiers d'environnement pour les conteneurs webet nginx-proxy-letsencrypt.

Commencez par ajouter un fichier .env.staging pour le webconteneur :

DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=djangoec2
SQL_USER=webapp
SQL_PASSWORD=<PASSWORD-FROM-AWS-RDS>
SQL_HOST=<DATABASE-ENDPOINT-FROM-AWS-RDS>
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>

Remarques:

  1. Passez <YOUR_DOMAIN.COM>à votre domaine actuel.
  2. Modifiez SQL_PASSWORDet SQL_HOSTpour qu'ils correspondent à ceux créés dans la section RDS.
  3. Passez SECRET_KEYà une longue chaîne aléatoire.
  4. Les VIRTUAL_HOSTet VIRTUAL_PORTsont nécessaires au nginx-proxyconteneur pour créer automatiquement la configuration du proxy inverse.
  5. LETSENCRYPT_HOSTest là pour qu'il nginx-proxy-companionpuisse émettre un certificat Let's Encrypt pour votre domaine.

À des fins de test/débogage, vous souhaiterez peut-être utiliser un *pour DJANGO_ALLOWED_HOSTSla première fois que vous déployez pour simplifier les choses. N'oubliez pas de limiter les hôtes autorisés une fois les tests terminés.

Deuxièmement, ajoutez un fichier .env.staging.proxy-companion , en veillant à mettre à jour la DEFAULT_EMAILvaleur :

DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy

Créer et envoyer des images Docker

Nous sommes maintenant prêts à créer les images Docker :

$ docker-compose -f docker-compose.staging.yml build

La construction peut prendre quelques minutes. Une fois cela fait, nous sommes prêts à pousser les images jusqu'à ECR.

Tout d'abord, en supposant que vous avez installé awscli et que vous avez défini vos informations d' identification AWS , connectez-vous au référentiel ECR Docker :

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com

Tu devrais voir:

Login Succeeded

Poussez ensuite les images vers ECR :

$ docker-compose -f docker-compose.staging.yml push

Ouvrez votre dépôt ECR django-ec2 pour voir les images poussées :

Images ECR

Exécution des conteneurs

Tout est prêt pour le déploiement.

Il est temps de passer à votre instance EC2.

En supposant que vous ayez un répertoire de projet créé sur votre instance, comme /home/ubuntu/django-on-docker , copiez les fichiers et dossiers avec SCP :

$ scp -i /path/to/your/djangoletsencrypt.pem \
      -r $(pwd)/{app,nginx,.env.staging,.env.staging.proxy-companion,docker-compose.staging.yml} \
      ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker

Ensuite, connectez-vous à votre instance via SSH et déplacez-vous dans le répertoire du projet :

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker

Connectez-vous au référentiel ECR Docker.

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com

Tirez les images :

$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy

Avec cela, vous êtes prêt à faire tourner les conteneurs :

$ docker-compose -f docker-compose.staging.yml up -d

Une fois les conteneurs opérationnels, accédez à votre domaine dans votre navigateur. Vous devriez voir quelque chose comme :

Certificat HTTPS non sécurisé

C'est prévu. Cet écran s'affiche car le certificat a été émis à partir d'un environnement intermédiaire .

Comment savoir si tout fonctionne ?

Cliquez sur "Avancé" puis sur "Continuer". Vous devriez maintenant voir votre application. Téléchargez une image, puis assurez-vous que vous pouvez afficher l'image sur https://yourdomain.com/media/IMAGE_FILE_NAME.

Délivrer le certificat de production

Maintenant que tout fonctionne comme prévu, nous pouvons passer à l'environnement de production de Let's Encrypt.

Arrêtez les conteneurs existants et quittez votre instance :

$ docker-compose -f docker-compose.staging.yml down -v
$ exit

De retour sur votre ordinateur local, ouvrez docker-compose.prod.yml et apportez les mêmes modifications que pour la version intermédiaire :

  1. Mettez à jour les ìmagepropriétés pour qu'elles correspondent à vos URL AWS ECR pour les services ẁebetnginx-proxy
  2. Supprimer le dbservice ainsi que le volume associé
version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.prod
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.prod.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

Créez ensuite un fichier .env.prod en dupliquant le fichier .env.staging . Vous n'avez pas besoin d'y apporter de modifications.

Enfin, ajoutez un fichier .env.prod.proxy-companion :

DEFAULT_EMAIL=youremail@yourdomain.com
NGINX_PROXY_CONTAINER=nginx-proxy

Construisez et transférez à nouveau des images :

$ docker-compose -f docker-compose.prod.yml build
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
$ docker-compose -f docker-compose.prod.yml push

Copiez les nouveaux fichiers et dossiers sur votre instance avec SCP :

$ scp -i /path/to/your/djangoletsencrypt.pem \
      $(pwd)/{.env.prod,.env.prod.proxy-companion,docker-compose.prod.yml} \
      ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker

Comme précédemment, connectez-vous à votre instance via SSH et déplacez-vous dans le répertoire du projet :

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker

Connectez-vous à nouveau à votre référentiel Docker ECR :

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com

Tirez les images :

$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy

Et enfin faites tourner les conteneurs :

$ docker-compose -f docker-compose.prod.yml up -d

Accédez à nouveau à votre domaine. Vous ne devriez plus voir d'avertissement.

Félicitations! Vous utilisez maintenant un certificat de production Let's Encrypt pour votre application Django exécutée sur AWS EC2.

Vous voulez voir le processus de création de certificat en action, consultez les journaux :

$ docker-compose -f docker-compose.prod.yml logs nginx-proxy-letsencrypt

Conclusion

Dans ce didacticiel, vous avez déployé une application Django conteneurisée sur EC2. L'application s'exécute derrière un proxy HTTPS Nginx avec des certificats SSL Let's Encrypt. Vous avez également utilisé une instance RDS Postgres et stocké des images Docker sur ECR.

Source :  https://testdrive.io

#django #aws #docker 

What is GEEK

Buddha Community

Comment Déployer Une Application Django Sur AWS EC2 Avec Docker
Noelia  Graham

Noelia Graham

1660764420

Comment Déployer Une Application Django Sur AWS EC2 Avec Docker

Dans ce didacticiel, nous allons déployer une application Django sur AWS EC2 avec Docker. L'application s'exécutera derrière un proxy HTTPS Nginx qui utilise les certificats SSL Let's Encrypt. Nous utiliserons AWS RDS pour servir notre base de données Postgres avec AWS ECR pour stocker et gérer nos images Docker.

Objectifs

À la fin de ce didacticiel, vous serez en mesure de :

  1. Configurer une nouvelle instance EC2
  2. Installer Docker sur une instance EC2
  3. Configurer et utiliser une adresse IP Elastic
  4. Configurer un rôle IAM
  5. Utiliser le registre d'images Amazon Elastic Container Registry (ECR) pour stocker les images créées
  6. Configurer AWS RDS pour la persistance des données
  7. Configurer un groupe de sécurité AWS
  8. Déployer Django sur AWS EC2 avec Docker
  9. Exécutez l'application Django derrière un proxy HTTPS Nginx avec les certificats SSL Let's Encrypt

Conditions préalables

Cet article s'appuie sur Dockerizing Django avec Postgres, Gunicorn et Nginx et Securing a Containerized Django Application with Let's Encrypt posts.

Cela suppose que vous pouvez :

  1. Conteneurisez une application Django avec Postgres, Nginx et Gunicorn.
  2. Sécurisez une application Django conteneurisée s'exécutant derrière un proxy HTTPS Nginx avec les certificats SSL Let's Encrypt .
  3. Utilisez SSH pour vous connecter à un serveur distant et SCP pour copier des fichiers sur le serveur.

AWS EC2

Tout d'abord, créez un compte AWS si vous n'en avez pas déjà un.

Ensuite, accédez à la console EC2 et cliquez sur Launch instance :

Accueil EC2

Utilisez Ubuntu Server 18.04 LTS (HVM) pour l'image du serveur (AMI) :

Sélectionnez AMI

In the next step, stick with the t2.micro instance. Click on Next: Configure Instance Details:

Type d'instance EC2

At the Configure Instance Details step, leave everything as it is to keep things simple. Then click Next a few times until you're at the Configure Security Group step.

With Create a new security group selected, set the name and description to django-ec2 and add two rules:

  • HTTP -> Anywhere
  • HTTPS -> Anywhere

EC2 configure les groupes de sécurité

These rules are needed to issue certificates and to access the app.

Security group inbound rules are used to limit access to your instance from the internet. Unless you have some additional security requirements, you'll probably want to allow HTTP and HTTPS traffic from anywhere for instances hosting web apps. SSH must be allowed for you to connect to the instance for set up and deployment.

Click Review and Launch. On the next screen, click Launch.

You'll be prompted to select a key pair. You need it for SSH connection to your instance. Select Create a new key pair and name it djangoletsencrypt. Then click Download key pair. After the key pair is downloaded, click on Launch Instances:

EC2 Ajouter une paire de clés

It will take a few minutes for the instance to spin up.

Configure EC2 Instance

In this section, we'll install Docker on the instance, add an Elastic IP, and configure an IAM role.

Install Docker

Navigate back to the EC2 console, select the newly created instance, and grab the public IP address:

IP publique EC2

Connect to your EC2 instance using the .pem key that we downloaded in the "AWS EC2" step.

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance

Your .pem was probably downloaded into path like ~/Downloads/djangoletsencrypt.pem. If you're not sure where to store it, move it into the ~/.ssh directory. You may have to also change the permissions -- i.e., chmod 400 -i /path/to/your/djangoletsencrypt.pem.

Start by installing the latest version of Docker and version 1.29.2 of Docker Compose:

$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt update
$ sudo apt install docker-ce
$ sudo usermod -aG docker ${USER}
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

$ docker -v
Docker version 20.10.8, build 3967b7d

$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

Install AWS CLI

First, install unzip:

$ sudo apt install unzip

Download AWS CLI ZIP:

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

Unzip its content:

$ unzip awscliv2.zip

Install AWS CLI:

$ sudo ./aws/install

Verify installation:

$ aws --version

IP élastique

Par défaut, les instances reçoivent une nouvelle adresse IP publique à chaque démarrage et redémarrage.

Elastic IP vous permet d'allouer des adresses IP statiques pour vos instances EC2, de sorte que l'adresse IP reste la même tout le temps et peut être réassociée entre les instances. Il est recommandé d'en utiliser un pour votre configuration de production.

Accédez à Elastic IPs et cliquez sur Allocate Elastic IP address :

IP élastique

Ensuite, cliquez sur Allouer :

Allocation IP élastique

Cliquez sur Associer cette adresse IP Elastic :

Associé IP élastique

Sélectionnez votre instance et cliquez sur Associer :

Instance de sélection d'adresse IP élastique

Rôle IAM

We'll be using AWS ECR to pull images from AWS ECR to our EC2 instance during deployment. Since we won't be allowing public access to the Docker image on ECR, you'll need to create an IAM role with permissions to pull Docker images from ECR and attach it to your EC2 instance.

Navigate to the IAM console.

Click Roles in the left sidebar and then Create role:

Rôles IAM

Select AWS Service and EC2, then click on Next: Permissions:

Sélectionnez un cas d'utilisation IAM

Enter container in the search box, select the AmazonEC2ContainerRegistryPowerUser policy, and click Next: Tags:

Stratégie de rôle IAM

Cliquez sur Suivant : Réviser . Utilisez django-ec2pour le nom, et cliquez sur Créer un rôle :

Examen du rôle IAM

Vous devez maintenant attacher le nouveau rôle à votre instance EC2.

De retour dans la console EC2 , cliquez sur Instances , puis sélectionnez votre instance. Cliquez sur le menu déroulant Actions -> Paramètres de l'instance -> Attacher/Remplacer le rôle IAM :

Rôle IAM d'attachement EC2

Sélectionnez le rôle django-ec2 , puis cliquez sur Appliquer .

EC2 Sélectionnez le rôle IAM

Cliquez sur Fermer .

Ajouter un enregistrement DNS

Ajoutez un enregistrement A à votre DNS, pour le domaine que vous utilisez, pour pointer vers l'adresse IP publique de votre instance EC2.

Il s'agit de l'adresse IP Elastic que vous avez associée à votre instance.

AWS ECR

Amazon Elastic Container Registry (ECR) is a fully-managed Docker image registry that makes it easy for developers to store and manage images. For private images, access is managed via IAM users and roles.

Navigate to the ECR console. Click Repositories in the sidebar and then on Create repository:

Référentiels ECR

Set the name to django-ec2 and click on Create repository:

ECR Créer un référentiel

AWS RDS

Now we can configure an RDS Postgres database.

While you can run your own Postgres database in a container, since databases are critical services, adding additional layers, such us Docker, adds unnecessary risk in production. To simplify tasks such as minor version updates, regular backups, and scaling, it's recommended to use a managed service. So, we'll use RDS.

Navigate to the RDS console. Click on Create database:

Accueil RDS

Select the latest version of Postgres with the Free tier template:

RDS Créer une base de données

Under Settings, set:

  • DB Instance identifier: djangoec2
  • Master username: webapp
  • Select Auto generate a password

Stick with default settings for:

  • DB instance size
  • Storage
  • Availability & durability

Passez à la section Connectivité et définissez les éléments suivants :

  • Cloud privé virtuel (VPC) : par défaut
  • Groupe de sous-réseau : par défaut
  • Accessible au public : Non
  • Groupe de sécurité VPC :django-ec2
  • Port de la base de données : 5432

RDS Créer une connectivité de base de données

Laissez l' authentification de la base de données telle quelle.

Ouvrez la configuration supplémentaire et remplacez le nom de la base de données initiale par djangoec2:

RDS Créer le nom de base de données initial de la base de données

Laissez les autres paramètres tels quels.

Enfin, cliquez sur Créer une base de données .

Cliquez sur Afficher les détails des informations d'identification pour voir le mot de passe généré pour l' utilisateur de l' application Web :

Informations d'identification de la vue RDS

Conservez ce mot de passe dans un endroit sûr. Vous devrez le fournir à l'application Django ici sous peu.

It will take a few of minutes for the instance to spin up. Once up, click on the DB Identifier of the newly created database to see its details. Take note of the database endpoint; you'll need to set it in your Django app.

Détails de la base de données RDS

AWS Security Group

Within the EC2 console, click Security Groups in the sidebar. Find and click the ID of the django-ec2 group to edit its details.

Click on Edit inbound rules:

Détails du groupe de sécurité EC2

Add an inbound rule that will allow Postgres connections to instances inside that Security Group. To do that:

  • click on Add rule
  • select PostgreSQL for the rule type
  • select Custom for the rule source
  • click into the search field and select the django-ec2 Security Group
  • click on Save rules

To limit access to your database, only connections from instances inside the same Security Group are allowed. Our application can connect because we set the same Security Group, django-ec2, for both the RDS and EC2 instances. Instances inside other Security Groups are therefore not allowed to connect.

EC2 Modifier les règles entrantes

Project Config

With the AWS infrastructure set up, we now need to configure our Django project locally before deploying it.

First, clone down the contents from the GitHub project repo:

$ git clone https://github.com/testdrivenio/django-on-docker-letsencrypt django-on-docker-letsencrypt-aws
$ cd django-on-docker-letsencrypt-aws

This repository contains everything that you need to deploy a Dockerized Django with Let's Encrypt HTTPS certificates.

Docker Compose

Lorsque l'application est déployée pour la première fois, vous devez suivre ces deux étapes pour éviter les problèmes avec les certificats :

  1. Commencez par émettre les certificats à partir de l'environnement de staging de Let's Encrypt
  2. Ensuite, lorsque tout fonctionne comme prévu, passez à l'environnement de production de Let's Encrypt

Vous pouvez en savoir plus sur les limitations de Let's Encrypt sur les environnements de production dans la section Let's Encrypt de l'article précédent, Sécuriser une application Django conteneurisée avec Let's Encrypt .

Pour les tests, mettez à jour le fichier docker-compose.staging.yml. fichier comme ceci:

version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.staging
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.staging.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

Pour les services webet , mettez à jour les propriétés pour utiliser les images d'ECR (que nous ajouterons sous peu).nginx-proxyimage

Exemples:

image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web

image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy

Les valeurs se composent de l'URL du référentiel ( 123456789.dkr.ecr.us-east-1.amazonaws.com) ainsi que du nom de l'image ( django-ec2) et des balises ( webet nginx-proxy).

Pour simplifier les choses, nous utilisons un seul registre pour stocker les deux images. Nous avons utilisé les webet nginx-proxypour différencier les deux. Idéalement, vous devriez utiliser deux registres : un pour webet un pour nginx-proxy. Mettez-le à jour par vous-même si vous le souhaitez.

Outre les imagepropriétés, nous avons également supprimé le dbservice (et le volume associé) puisque nous utilisons RDS plutôt que de gérer Postgres dans un conteneur.

Environnements

Il est temps de configurer les fichiers d'environnement pour les conteneurs webet nginx-proxy-letsencrypt.

Commencez par ajouter un fichier .env.staging pour le webconteneur :

DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=djangoec2
SQL_USER=webapp
SQL_PASSWORD=<PASSWORD-FROM-AWS-RDS>
SQL_HOST=<DATABASE-ENDPOINT-FROM-AWS-RDS>
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>

Remarques:

  1. Passez <YOUR_DOMAIN.COM>à votre domaine actuel.
  2. Modifiez SQL_PASSWORDet SQL_HOSTpour qu'ils correspondent à ceux créés dans la section RDS.
  3. Passez SECRET_KEYà une longue chaîne aléatoire.
  4. Les VIRTUAL_HOSTet VIRTUAL_PORTsont nécessaires au nginx-proxyconteneur pour créer automatiquement la configuration du proxy inverse.
  5. LETSENCRYPT_HOSTest là pour qu'il nginx-proxy-companionpuisse émettre un certificat Let's Encrypt pour votre domaine.

À des fins de test/débogage, vous souhaiterez peut-être utiliser un *pour DJANGO_ALLOWED_HOSTSla première fois que vous déployez pour simplifier les choses. N'oubliez pas de limiter les hôtes autorisés une fois les tests terminés.

Deuxièmement, ajoutez un fichier .env.staging.proxy-companion , en veillant à mettre à jour la DEFAULT_EMAILvaleur :

DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy

Créer et envoyer des images Docker

Nous sommes maintenant prêts à créer les images Docker :

$ docker-compose -f docker-compose.staging.yml build

La construction peut prendre quelques minutes. Une fois cela fait, nous sommes prêts à pousser les images jusqu'à ECR.

Tout d'abord, en supposant que vous avez installé awscli et que vous avez défini vos informations d' identification AWS , connectez-vous au référentiel ECR Docker :

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com

Tu devrais voir:

Login Succeeded

Poussez ensuite les images vers ECR :

$ docker-compose -f docker-compose.staging.yml push

Ouvrez votre dépôt ECR django-ec2 pour voir les images poussées :

Images ECR

Exécution des conteneurs

Tout est prêt pour le déploiement.

Il est temps de passer à votre instance EC2.

En supposant que vous ayez un répertoire de projet créé sur votre instance, comme /home/ubuntu/django-on-docker , copiez les fichiers et dossiers avec SCP :

$ scp -i /path/to/your/djangoletsencrypt.pem \
      -r $(pwd)/{app,nginx,.env.staging,.env.staging.proxy-companion,docker-compose.staging.yml} \
      ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker

Ensuite, connectez-vous à votre instance via SSH et déplacez-vous dans le répertoire du projet :

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker

Connectez-vous au référentiel ECR Docker.

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com

Tirez les images :

$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy

Avec cela, vous êtes prêt à faire tourner les conteneurs :

$ docker-compose -f docker-compose.staging.yml up -d

Une fois les conteneurs opérationnels, accédez à votre domaine dans votre navigateur. Vous devriez voir quelque chose comme :

Certificat HTTPS non sécurisé

C'est prévu. Cet écran s'affiche car le certificat a été émis à partir d'un environnement intermédiaire .

Comment savoir si tout fonctionne ?

Cliquez sur "Avancé" puis sur "Continuer". Vous devriez maintenant voir votre application. Téléchargez une image, puis assurez-vous que vous pouvez afficher l'image sur https://yourdomain.com/media/IMAGE_FILE_NAME.

Délivrer le certificat de production

Maintenant que tout fonctionne comme prévu, nous pouvons passer à l'environnement de production de Let's Encrypt.

Arrêtez les conteneurs existants et quittez votre instance :

$ docker-compose -f docker-compose.staging.yml down -v
$ exit

De retour sur votre ordinateur local, ouvrez docker-compose.prod.yml et apportez les mêmes modifications que pour la version intermédiaire :

  1. Mettez à jour les ìmagepropriétés pour qu'elles correspondent à vos URL AWS ECR pour les services ẁebetnginx-proxy
  2. Supprimer le dbservice ainsi que le volume associé
version: '3.8'

services:
  web:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
    command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env.prod
  nginx-proxy:
    container_name: nginx-proxy
    build: nginx
    image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
    restart: always
    ports:
      - 443:443
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web
  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    env_file:
      - ./.env.prod.proxy-companion
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - acme:/etc/acme.sh
    depends_on:
      - nginx-proxy

volumes:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:
  acme:

Créez ensuite un fichier .env.prod en dupliquant le fichier .env.staging . Vous n'avez pas besoin d'y apporter de modifications.

Enfin, ajoutez un fichier .env.prod.proxy-companion :

DEFAULT_EMAIL=youremail@yourdomain.com
NGINX_PROXY_CONTAINER=nginx-proxy

Construisez et transférez à nouveau des images :

$ docker-compose -f docker-compose.prod.yml build
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
$ docker-compose -f docker-compose.prod.yml push

Copiez les nouveaux fichiers et dossiers sur votre instance avec SCP :

$ scp -i /path/to/your/djangoletsencrypt.pem \
      $(pwd)/{.env.prod,.env.prod.proxy-companion,docker-compose.prod.yml} \
      ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker

Comme précédemment, connectez-vous à votre instance via SSH et déplacez-vous dans le répertoire du projet :

$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker

Connectez-vous à nouveau à votre référentiel Docker ECR :

$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com

Tirez les images :

$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy

Et enfin faites tourner les conteneurs :

$ docker-compose -f docker-compose.prod.yml up -d

Accédez à nouveau à votre domaine. Vous ne devriez plus voir d'avertissement.

Félicitations! Vous utilisez maintenant un certificat de production Let's Encrypt pour votre application Django exécutée sur AWS EC2.

Vous voulez voir le processus de création de certificat en action, consultez les journaux :

$ docker-compose -f docker-compose.prod.yml logs nginx-proxy-letsencrypt

Conclusion

Dans ce didacticiel, vous avez déployé une application Django conteneurisée sur EC2. L'application s'exécute derrière un proxy HTTPS Nginx avec des certificats SSL Let's Encrypt. Vous avez également utilisé une instance RDS Postgres et stocké des images Docker sur ECR.

Source :  https://testdrive.io

#django #aws #docker 

Ahebwe  Oscar

Ahebwe Oscar

1620177818

Django admin full Customization step by step

Welcome to my blog , hey everyone in this article you learn how to customize the Django app and view in the article you will know how to register  and unregister  models from the admin view how to add filtering how to add a custom input field, and a button that triggers an action on all objects and even how to change the look of your app and page using the Django suit package let’s get started.

Database

Custom Titles of Django Admin

Exclude in Django Admin

Fields in Django Admin

#django #create super user django #customize django admin dashboard #django admin #django admin custom field display #django admin customization #django admin full customization #django admin interface #django admin register all models #django customization

Eladio  Rau

Eladio Rau

1660389180

Comment Déployer Une Application Django Sur Heroku Avec Docker

Cet article explique comment déployer une application Django sur Heroku avec Docker via Heroku Container Runtime.

Objectifs

À la fin de ce didacticiel, vous serez en mesure de :

  1. Expliquez pourquoi vous pouvez utiliser le Container Runtime de Heroku pour exécuter une application
  2. Dockeriser une application Django
  3. Déployer et exécuter une application Django dans un conteneur Docker sur Heroku
  4. Configurer GitLab CI pour déployer des images Docker sur Heroku
  5. Gérez les ressources statiques avec WhiteNoise
  6. Configurer Postgres pour qu'il s'exécute sur Heroku
  7. Créer un Dockerfile de production qui utilise des builds Docker en plusieurs étapes
  8. Utiliser le registre de conteneurs Heroku et le manifeste de construction pour déployer Docker sur Heroku

Exécution du conteneur Heroku

Outre les déploiements traditionnels du compilateur Git plus slug ( git push heroku master), Heroku prend également en charge les déploiements basés sur Docker, avec Heroku Container Runtime.

Déploiements basés sur Docker

Les déploiements basés sur Docker présentent de nombreux avantages par rapport à l'approche traditionnelle :

  1. Aucune limite de slug : Heroku autorise une taille de slug maximale de 500 Mo pour les déploiements traditionnels basés sur Git. Les déploiements basés sur Docker, en revanche, n'ont pas cette limite.
  2. Contrôle total sur le système d'exploitation : Plutôt que d'être limité par les packages installés par les buildpacks Heroku , vous avez un contrôle total sur le système d'exploitation et pouvez installer n'importe quel package que vous souhaitez avec Docker.
  3. Parité dev/prod plus forte : les builds basés sur Docker ont une parité plus forte entre le développement et la production puisque les environnements sous-jacents sont les mêmes.
  4. Moins de dépendance vis-à-vis d'un fournisseur : Enfin, Docker facilite grandement le passage à un autre fournisseur d'hébergement cloud tel qu'AWS ou GCP.

En général, les déploiements basés sur Docker vous offrent une plus grande flexibilité et un meilleur contrôle sur l'environnement de déploiement. Vous pouvez déployer les applications que vous souhaitez dans l'environnement de votre choix. Cela dit, vous êtes désormais responsable des mises à jour de sécurité. Avec les déploiements traditionnels basés sur Git, Heroku en est responsable. Ils appliquent les mises à jour de sécurité pertinentes à leurs Stacks et migrent votre application vers les nouvelles Stacks si nécessaire. Garde ça en tête.

Il existe actuellement deux façons de déployer des applications avec Docker sur Heroku :

  1. Container Registry : déployez des images Docker pré-construites sur Heroku
  2. Build Manifest : étant donné un Dockerfile, Heroku construit et déploie l'image Docker

La principale différence entre ces deux est qu'avec la dernière approche - par exemple, via le Build Manifest - vous avez accès aux fonctionnalités Pipelines , Review et Release . Ainsi, si vous convertissez une application d'un déploiement basé sur Git vers Docker et que vous utilisez l'une de ces fonctionnalités, vous devez utiliser l'approche Build Manifest.

Rassurez-vous, nous examinerons les deux approches dans cet article.

Dans les deux cas, vous aurez toujours accès à la CLI Heroku , à tous les puissants addons et au tableau de bord . En d'autres termes, toutes ces fonctionnalités fonctionnent avec le Container Runtime.

Type de déploiementMécanisme de déploiementMises à jour de sécurité (qui gère)Accès aux pipelines, examen, publicationAccès à la CLI, aux modules complémentaires et au tableau de bordLimites de taille des lingots
Compilateur Git + SlugPoussée GitHérokuOuiOuiOui
Docker + Exécution du conteneurPoussée DockerTuNonOuiNon
Docker + Build ManifestPoussée GitTuOuiOuiNon

Gardez à l'esprit que les déploiements basés sur Docker sont limités aux mêmes contraintes que les déploiements basés sur Git. Par exemple, les volumes persistants ne sont pas pris en charge car le système de fichiers est éphémère et les processus Web ne prennent en charge que les requêtes HTTP(S). Pour plus d'informations à ce sujet, consultez les commandes Dockerfile et le runtime .

Concepts Docker contre Heroku

DockerHéroku
Fichier DockerBuildPack
ImageLimace
RécipientDynamo

Configuration du projet

Créez un répertoire de projet, créez et activez un nouvel environnement virtuel et installez Django :

$ mkdir django-heroku-docker
$ cd django-heroku-docker

$ python3.10 -m venv env
$ source env/bin/activate

(env)$ pip install django==3.2.9

N'hésitez pas à échanger virtualenv et Pip contre Poetry ou Pipenv . Pour en savoir plus, consultez Environnements Python modernes .

Ensuite, créez un nouveau projet Django, appliquez les migrations et lancez le serveur :

(env)$ django-admin startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver

Accédez à http://localhost:8000/ pour afficher l'écran de bienvenue de Django. Tuez le serveur et quittez l'environnement virtuel une fois terminé.

Docker

Ajoutez un Dockerfile à la racine du projet :

# pull official base image
FROM python:3.10-alpine

# set work directory
WORKDIR /app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0

# install psycopg2
RUN apk update \
    && apk add --virtual build-essential gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2

# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .

# add and run as non-root user
RUN adduser -D myuser
USER myuser

# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Ici, nous avons commencé avec une image Docker basée sur Alpine pour Python 3.10. Nous définissons ensuite un répertoire de travail avec deux variables d'environnement :

  1. PYTHONDONTWRITEBYTECODE: Empêche Python d'écrire des fichiers pyc sur le disque
  2. PYTHONUNBUFFERED: Empêche Python de mettre en mémoire tampon stdout et stderr

Ensuite, nous avons installé des dépendances au niveau du système et des packages Python, copié les fichiers du projet, créé et basculé vers un utilisateur non root (ce qui est recommandé par Heroku ) et utilisé CMD pour exécuter Gunicorn lorsqu'un conteneur tourne au moment de l'exécution. Prenez note de la $PORTvariable. Essentiellement, tout serveur Web qui s'exécute sur le Container Runtime doit écouter le trafic HTTP au niveau de $PORTla variable d'environnement, qui est définie par Heroku au moment de l'exécution .

Créez un fichier requirements.txt :

Django==3.2.9
gunicorn==20.1.0

Ajoutez ensuite un fichier .dockerignore :

__pycache__
*.pyc
env/
db.sqlite3

Mettez à jour les variables SECRET_KEY, DEBUGet dans settings.py :ALLOWED_HOSTS

SECRET_KEY = os.environ.get('SECRET_KEY', default='foo')

DEBUG = int(os.environ.get('DEBUG', default=0))

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

N'oubliez pas l'importation :

import os

Pour tester localement, créez l'image et exécutez le conteneur, en veillant à transmettre les variables d'environnement appropriées :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest

Assurez-vous que l'application est en cours d'exécution sur http://localhost:8007/ dans votre navigateur. Arrêtez puis supprimez le conteneur en cours d'exécution une fois terminé :

$ docker stop django-heroku
$ docker rm django-heroku

Ajoutez un .gitignore :

__pycache__
*.pyc
env/
db.sqlite3

Ensuite, créons une vue Django rapide pour tester facilement l'application lorsque le mode débogage est désactivé.

Ajoutez un fichier views.py au répertoire "hello_django":

from django.http import JsonResponse


def ping(request):
    data = {'ping': 'pong!'}
    return JsonResponse(data)

Ensuite, mettez à jour urls.py :

from django.contrib import admin
from django.urls import path

from .views import ping


urlpatterns = [
    path('admin/', admin.site.urls),
    path('ping/', ping, name="ping"),
]

Testez ceci à nouveau avec le mode débogage désactivé :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=0" -p 8007:8765 web:latest

Vérifiez que http://localhost:8007/ping/ fonctionne comme prévu :

{
  "ping": "pong!"
}

Arrêtez puis supprimez le conteneur en cours d'exécution une fois terminé :

$ docker stop django-heroku
$ docker rm django-heroku

Bruit blanc

Si vous souhaitez utiliser WhiteNoise pour gérer vos actifs statiques, ajoutez d'abord le package au fichier requirements.txt :

Django==3.2.9
gunicorn==20.1.0
whitenoise==5.3.0

Mettez à jour le middleware dans settings.py comme ceci :

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # new
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Configurez ensuite la gestion de vos fichiers statiques avec STATIC_ROOT:

STATIC_ROOT = BASE_DIR / 'staticfiles'

Enfin, ajoutez la prise en charge de la compression et de la mise en cache :

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Ajoutez la collectstaticcommande au Dockerfile :

# pull official base image
FROM python:3.10-alpine

# set work directory
WORKDIR /app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0

# install psycopg2
RUN apk update \
    && apk add --virtual build-essential gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2

# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .

# collect static files
RUN python manage.py collectstatic --noinput

# add and run as non-root user
RUN adduser -D myuser
USER myuser

# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Pour tester, créez la nouvelle image et lancez un nouveau conteneur :

$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest

Vous devriez pouvoir afficher les fichiers statiques lorsque vous exécutez :

$ docker exec django-heroku ls /app/staticfiles
$ docker exec django-heroku ls /app/staticfiles/admin

Arrêtez puis supprimez à nouveau le conteneur en cours d'exécution :

$ docker stop django-heroku
$ docker rm django-heroku

postgres

Pour que Postgres soit opérationnel, nous utiliserons le package dj_database_url pour générer le dictionnaire de configuration de base de données approprié pour les paramètres de Django en fonction d'une DATABASE_URLvariable d'environnement.

Ajoutez la dépendance au fichier requirements :

Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

Ensuite, apportez les modifications suivantes aux paramètres pour mettre à jour la configuration de la base de données si le DATABASE_URLest présent :

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

DATABASE_URL = os.environ.get('DATABASE_URL')
db_from_env = dj_database_url.config(default=DATABASE_URL, conn_max_age=500, ssl_require=True)
DATABASES['default'].update(db_from_env)

Ainsi, si le DATABASE_URLn'est pas présent, SQLite sera toujours utilisé.

Ajoutez également l'importation en haut :

import dj_database_url

Nous testerons cela un peu après avoir créé une base de données Postgres sur Heroku.

Configuration Heroku

Créez un compte Heroku (si vous n'en avez pas déjà un), puis installez la CLI Heroku (si vous ne l'avez pas déjà fait).

Créez une nouvelle application :

$ heroku create
Creating app... done, ⬢ limitless-atoll-51647
https://limitless-atoll-51647.herokuapp.com/ | https://git.heroku.com/limitless-atoll-51647.git

Ajoutez la SECRET_KEYvariable d'environnement :

$ heroku config:set SECRET_KEY=SOME_SECRET_VALUE -a limitless-atoll-51647

Remplacez SOME_SECRET_VALUE-la par une chaîne générée aléatoirement d'au moins 50 caractères.

Ajoutez l'URL Heroku ci-dessus à la liste de ALLOWED_HOSTShello_django /settings.py comme suit :

ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'limitless-atoll-51647.herokuapp.com']

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Déploiement Heroku Docker

À ce stade, nous sommes prêts à commencer à déployer des images Docker sur Heroku. Avez-vous décidé de l'approche que vous souhaitez adopter ?

  1. Container Registry : déployez des images Docker pré-construites sur Heroku
  2. Build Manifest : étant donné un Dockerfile, Heroku construit et déploie l'image Docker

Incertain? Essayez-les tous les deux !

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

Encore une fois, avec cette approche, vous pouvez déployer des images Docker prédéfinies sur Heroku.

Connectez-vous au Heroku Container Registry , pour indiquer à Heroku que nous souhaitons utiliser le Container Runtime :

$ heroku container:login

Recréez l'image Docker et étiquetez-la au format suivant :

registry.heroku.com/<app>/<process-type>

Assurez-vous de remplacer <app>par le nom de l'application Heroku que vous venez de créer et <process-type>avec webpuisqu'il s'agira d'un processus Web .

Par exemple:

$ docker build -t registry.heroku.com/limitless-atoll-51647/web .

Poussez l'image vers le registre :

$ docker push registry.heroku.com/limitless-atoll-51647/web

Libérez l'image :

$ heroku container:release -a limitless-atoll-51647 web

Cela exécutera le conteneur. Vous devriez pouvoir voir l'application sur https://APP_NAME.herokuapp.com . Il devrait renvoyer un 404.

Essayez d'exécuter heroku open -a limitless-atoll-51647pour ouvrir l'application dans votre navigateur par défaut.

Vérifiez que https://APP_NAME.herokuapp.com/ping fonctionne également :

{
  "ping": "pong!"
}

Vous devriez également pouvoir afficher les fichiers statiques :

$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Accédez à la section "Test Postgres" une fois terminé.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

Encore une fois, avec l' approche Build Manifest , vous pouvez demander à Heroku de créer et de déployer des images Docker basées sur un fichier manifeste heroku.yml .

Définissez la pile de votre application sur conteneur :

$ heroku stack:set container -a limitless-atoll-51647

Ajoutez un fichier heroku.yml à la racine du projet :

build:
  docker:
    web: Dockerfile

Ici, nous disons simplement à Heroku quel Dockerfile utiliser pour créer l'image.

Parallèlement à build, vous pouvez également définir les étapes suivantes :

  • setupest utilisé pour définir les modules complémentaires Heroku et les variables de configuration à créer lors du provisionnement de l'application.
  • releaseest utilisé pour définir les tâches que vous souhaitez exécuter lors d'une release.
  • runest utilisé pour définir les commandes à exécuter pour les processus Web et de travail.

Assurez-vous de consulter la documentation Heroku pour en savoir plus sur ces quatre étapes.

Il convient de noter que la gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORTcommande peut être supprimée du Dockerfile et ajoutée au fichier heroku.yml sous la runscène :

build:
  docker:
    web: Dockerfile
run:
  web: gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Assurez-vous également de placer la commande 'collectstatic' dans votre Dockerfile. Ne le déplacez pas sur releasescène. Pour en savoir plus, consultez cette question Stack Overflow .

Ensuite, installez le heroku-manifestplug-in à partir du canal CLI bêta :

$ heroku update beta
$ heroku plugins:install @heroku-cli/plugin-manifest

Avec cela, initialisez un référentiel Git et créez un commit.

Ensuite, ajoutez la télécommande Heroku :

$ heroku git:remote -a limitless-atoll-51647

Poussez le code jusqu'à Heroku pour créer l'image et exécuter le conteneur :

$ git push heroku master

Vous devriez pouvoir voir l'application sur https://APP_NAME.herokuapp.com . Il devrait renvoyer un 404.

Essayez d'exécuter heroku open -a limitless-atoll-51647pour ouvrir l'application dans votre navigateur par défaut.

Vérifiez que https://APP_NAME.herokuapp.com/ping fonctionne également :

{
  "ping": "pong!"
}

Vous devriez également pouvoir afficher les fichiers statiques :

$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647

Assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application.

Test Postgres

Créez la base de données :

$ heroku addons:create heroku-postgresql:hobby-dev -a limitless-atoll-51647

Cette commande définit automatiquement la DATABASE_URLvariable d'environnement pour le conteneur.

Une fois la base de données opérationnelle, exécutez les migrations :

$ heroku run python manage.py makemigrations -a limitless-atoll-51647
$ heroku run python manage.py migrate -a limitless-atoll-51647

Ensuite, sautez dans psql pour afficher les tables nouvellement créées :

$ heroku pg:psql -a limitless-atoll-51647

# \dt
                      List of relations
 Schema |            Name            | Type  |     Owner
--------+----------------------------+-------+----------------
 public | auth_group                 | table | siodzhzzcvnwwp
 public | auth_group_permissions     | table | siodzhzzcvnwwp
 public | auth_permission            | table | siodzhzzcvnwwp
 public | auth_user                  | table | siodzhzzcvnwwp
 public | auth_user_groups           | table | siodzhzzcvnwwp
 public | auth_user_user_permissions | table | siodzhzzcvnwwp
 public | django_admin_log           | table | siodzhzzcvnwwp
 public | django_content_type        | table | siodzhzzcvnwwp
 public | django_migrations          | table | siodzhzzcvnwwp
 public | django_session             | table | siodzhzzcvnwwp
(10 rows)

# \q

Encore une fois, assurez-vous de remplacer limitless-atoll-51647chacune des commandes ci-dessus par le nom de votre application Heroku.

CI GitLab

Créez un compte GitLab (si nécessaire), puis créez un nouveau projet (à nouveau, si nécessaire).

Récupérez votre jeton d'authentification Heroku :

$ heroku auth:token

Ensuite, enregistrez le jeton en tant que nouvelle variable appelée HEROKU_AUTH_TOKENdans les paramètres CI/CD de votre projet : Paramètres > CI/CD > Variables.

configuration gitlab

Ensuite, nous devons ajouter un fichier de configuration GitLab CI/CD appelé .gitlab-ci.yml à la racine du projet. Le contenu de ce fichier variera en fonction de l'approche utilisée.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

.gitlab-ci.yml :

image: docker:stable
services:
  - docker:dind

variables:
  DOCKER_DRIVER: overlay2
  HEROKU_APP_NAME: <APP_NAME>
  HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web

stages:
  - build_and_deploy

build_and_deploy:
  stage: build_and_deploy
  script:
    - apk add --no-cache curl
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker pull $HEROKU_REGISTRY_IMAGE || true
    - docker build
      --cache-from $HEROKU_REGISTRY_IMAGE
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

release.sh :

#!/bin/sh


IMAGE_ID=$(docker inspect ${HEROKU_REGISTRY_IMAGE} --format={{.Id}})
PAYLOAD='{"updates": [{"type": "web", "docker_image": "'"$IMAGE_ID"'"}]}'

curl -n -X PATCH https://api.heroku.com/apps/$HEROKU_APP_NAME/formation \
  -d "${PAYLOAD}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/vnd.heroku+json; version=3.docker-releases" \
  -H "Authorization: Bearer ${HEROKU_AUTH_TOKEN}"

Ici, nous avons défini une seule build_and_deploy étape où nous :

  1. Installer cURL
  2. Connectez-vous au registre de conteneurs Heroku
  3. Tirez l'image précédemment poussée (si elle existe)
  4. Construire et étiqueter la nouvelle image
  5. Poussez l'image jusqu'au registre
  6. Créez une nouvelle version via l' API Heroku en utilisant l'ID d'image dans le script release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Avec cela, initialisez un dépôt Git, validez, ajoutez la télécommande GitLab et poussez votre code jusqu'à GitLab pour déclencher un nouveau pipeline . Cela exécutera la build_and_deployscène comme un travail unique. Une fois terminée, une nouvelle version devrait être automatiquement créée sur Heroku.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

.gitlab-ci.yml :

variables:
  HEROKU_APP_NAME: <APP_NAME>

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Ici, nous avons défini une seule deploy étape où nous :

  1. Installez Ruby avec une gemme appelée dpl
  2. Déployer le code sur Heroku avec dpl

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Validez, ajoutez la télécommande GitLab et poussez votre code jusqu'à GitLab pour déclencher un nouveau pipeline . Cela exécutera l' deployétape comme un travail unique. Une fois terminé, le code doit être déployé sur Heroku.

IC avancée

Plutôt que de simplement créer l'image Docker et de créer une version sur GitLab CI, exécutons également les tests Django, Flake8 , Black et isort .

Encore une fois, cela variera en fonction de l'approche que vous avez utilisée.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

Mettez à jour .gitlab-ci.yml comme suit :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:latest || true
    - docker build
      --cache-from $IMAGE:latest
      --tag $IMAGE:latest
      --file ./Dockerfile
      "."
    - docker push $IMAGE:latest

test:
  stage: test
  image: $IMAGE:latest
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
    HEROKU_APP_NAME: <APP_NAME>
    HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
  script:
    - apk add --no-cache curl
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker pull $HEROKU_REGISTRY_IMAGE || true
    - docker build
      --cache-from $HEROKU_REGISTRY_IMAGE
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Donc, nous avons maintenant trois étapes : build, test, et deploy.

Dans l' buildétape, nous :

  1. Connectez-vous au registre de conteneurs GitLab
  2. Tirez l'image précédemment poussée (si elle existe)
  3. Construire et étiqueter la nouvelle image
  4. Poussez l'image vers le registre de conteneurs GitLab

Ensuite, dans l' testétape, nous configurons Postgres , définissons la DATABASE_URLvariable d'environnement, puis exécutons les tests Django, Flake8, Black et isort en utilisant l'image qui a été construite à l'étape précédente.

Dans l' deployétape, nous :

  1. Installer cURL
  2. Connectez-vous au registre de conteneurs Heroku
  3. Tirez l'image précédemment poussée (si elle existe)
  4. Construire et étiqueter la nouvelle image
  5. Poussez l'image jusqu'au registre
  6. Créez une nouvelle version via l' API Heroku en utilisant l'ID d'image dans le script release.sh

Ajoutez les nouvelles dépendances au fichier requirements :

# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1

Avant de passer à GitLab, exécutez les tests Django localement :

$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test

System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Assurez-vous que Flake8 réussit, puis mettez à jour le code source en fonction des recommandations Black et isort :

(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black

Validez et poussez votre code encore une fois. Assurez-vous que toutes les étapes passent.

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

Mettez à jour .gitlab-ci.yml comme suit :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:latest || true
    - docker build
      --cache-from $IMAGE:latest
      --tag $IMAGE:latest
      --file ./Dockerfile
      "."
    - docker push $IMAGE:latest

test:
  stage: test
  image: $IMAGE:latest
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  variables:
    HEROKU_APP_NAME: <APP_NAME>
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Donc, nous avons maintenant trois étapes : build, test, et deploy.

Dans l' buildétape, nous :

  1. Connectez-vous au registre de conteneurs GitLab
  2. Tirez l'image précédemment poussée (si elle existe)
  3. Construire et étiqueter la nouvelle image
  4. Poussez l'image vers le registre de conteneurs GitLab

Ensuite, dans l' testétape, nous configurons Postgres , définissons la DATABASE_URLvariable d'environnement, puis exécutons les tests Django, Flake8, Black et isort en utilisant l'image qui a été construite à l'étape précédente.

Dans l' deployétape, nous :

  1. Installez Ruby avec une gemme appelée dpl
  2. Déployer le code sur Heroku avec dpl

Ajoutez les nouvelles dépendances au fichier requirements :

# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0

# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1

Avant de passer à GitLab, exécutez les tests Django localement :

$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test

System check identified no issues (0 silenced).

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Assurez-vous que Flake8 réussit, puis mettez à jour le code source en fonction des recommandations Black et isort :

(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black

Validez et poussez votre code encore une fois. Assurez-vous que toutes les étapes passent.

Construction Docker en plusieurs étapes

Enfin, mettez à jour le Dockerfile comme ceci pour utiliser une construction en plusieurs étapes afin de réduire la taille finale de l'image :

FROM python:3.10-alpine AS build-python
RUN apk update && apk add --virtual build-essential gcc python3-dev musl-dev postgresql-dev
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY ./requirements.txt .
RUN pip install -r requirements.txt

FROM python:3.10-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0
ENV PATH="/opt/venv/bin:$PATH"
COPY --from=build-python /opt/venv /opt/venv
RUN apk update && apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev
RUN pip install psycopg2-binary
WORKDIR /app
COPY . .
RUN python manage.py collectstatic --noinput
RUN adduser -D myuser
USER myuser
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT

Ensuite, nous devons mettre à jour la configuration GitLab pour tirer parti de la mise en cache de la couche Docker.

Approche #1 : Registre des conteneurs

Ignorez cette section si vous utilisez l'approche Build Manifest.

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
  HEROKU_APP_NAME: <APP_NAME>
  HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production

test:
  stage: test
  image: $IMAGE:production
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - apk add --no-cache curl
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --tag $HEROKU_REGISTRY_IMAGE
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production
    - docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
    - docker push $HEROKU_REGISTRY_IMAGE
    - chmod +x ./release.sh
    - ./release.sh

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Examinez les modifications par vous-même. Ensuite, testez-le une dernière fois.

Pour en savoir plus sur ce modèle de mise en cache, consultez la section "Multi-stage" de l'article Faster CI Builds with Docker Cache .

Approche #2 : Construire un manifeste

Ignorez cette section si vous utilisez l'approche Container Registry.

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy

variables:
  IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
  HEROKU_APP_NAME: <APP_NAME>

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $IMAGE:build-python || true
    - docker pull $IMAGE:production || true
    - docker build
      --target build-python
      --cache-from $IMAGE:build-python
      --tag $IMAGE:build-python
      --file ./Dockerfile
      "."
    - docker build
      --cache-from $IMAGE:production
      --tag $IMAGE:production
      --file ./Dockerfile
      "."
    - docker push $IMAGE:build-python
    - docker push $IMAGE:production

test:
  stage: test
  image: $IMAGE:production
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: ""
    DATABASE_URL: postgresql://runner@postgres:5432/test
  script:
    - python manage.py test
    - flake8 hello_django --max-line-length=100
    - black hello_django --check
    - isort hello_django --check --profile black

deploy:
  stage: deploy
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN

Assurez-vous de remplacer <APP_NAME>par le nom de votre application Heroku.

Examinez les modifications par vous-même. Ensuite, testez-le une dernière fois.

Pour en savoir plus sur ce modèle de mise en cache, consultez la section "Multi-stage" de l'article Faster CI Builds with Docker Cache .

Conclusion

Dans cet article, nous avons parcouru deux approches pour déployer une application Django sur Heroku avec Docker : le registre de conteneurs et le manifeste de construction.

Alors, quand devriez-vous penser à utiliser Heroku Container Runtime plutôt que le compilateur Git et slug traditionnel pour les déploiements ?

Lorsque vous avez besoin de plus de contrôle sur l'environnement de déploiement de production.

Exemples:

  1. Votre application et vos dépendances dépassent la limite maximale de 500 Mo de slug.
  2. Votre application nécessite des packages non installés par les packs de construction Heroku habituels.
  3. Vous voulez une plus grande assurance que votre application se comportera de la même manière en développement qu'en production.
  4. Vous aimez vraiment, vraiment travailler avec Docker.

Source :  https://testdrive.io

#django #heroku #docker 

Ahebwe  Oscar

Ahebwe Oscar

1620185280

How model queries work in Django

How model queries work in Django

Welcome to my blog, hey everyone in this article we are going to be working with queries in Django so for any web app that you build your going to want to write a query so you can retrieve information from your database so in this article I’ll be showing you all the different ways that you can write queries and it should cover about 90% of the cases that you’ll have when you’re writing your code the other 10% depend on your specific use case you may have to get more complicated but for the most part what I cover in this article should be able to help you so let’s start with the model that I have I’ve already created it.

**Read More : **How to make Chatbot in Python.

Read More : Django Admin Full Customization step by step

let’s just get into this diagram that I made so in here:

django queries aboutDescribe each parameter in Django querset

we’re making a simple query for the myModel table so we want to pull out all the information in the database so we have this variable which is gonna hold a return value and we have our myModel models so this is simply the myModel model name so whatever you named your model just make sure you specify that and we’re gonna access the objects attribute once we get that object’s attribute we can simply use the all method and this will return all the information in the database so we’re gonna start with all and then we will go into getting single items filtering that data and go to our command prompt.

Here and we’ll actually start making our queries from here to do this let’s just go ahead and run** Python manage.py shell** and I am in my project file so make sure you’re in there when you start and what this does is it gives us an interactive shell to actually start working with our data so this is a lot like the Python shell but because we did manage.py it allows us to do things a Django way and actually query our database now open up the command prompt and let’s go ahead and start making our first queries.

#django #django model queries #django orm #django queries #django query #model django query #model query #query with django

Verda  Conroy

Verda Conroy

1595298120

Deploying a Django Application to AWS EC2 Instance With Docker

In AWS we have several ways to deploy Django (and not Django applications) with Docker. We can use ECS or EKS clusters.

#python #web dev #docker #aws #kubernetes #django