1660764420
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.
À la fin de ce didacticiel, vous serez en mesure de :
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 :
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 :
Utilisez Ubuntu Server 18.04 LTS (HVM) pour l'image du serveur (AMI) :
In the next step, stick with the t2.micro instance. Click on Next: Configure Instance Details:
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:
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:
It will take a few minutes for the instance to spin up.
In this section, we'll install Docker on the instance, add an Elastic IP, and configure an IAM role.
Navigate back to the EC2 console, select the newly created instance, and grab the public IP address:
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
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
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 :
Ensuite, cliquez sur Allouer :
Cliquez sur Associer cette adresse IP Elastic :
Sélectionnez votre instance et cliquez sur Associer :
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:
Select AWS Service and EC2, then click on Next: Permissions:
Enter container
in the search box, select the AmazonEC2ContainerRegistryPowerUser policy, and click Next: Tags:
Cliquez sur Suivant : Réviser . Utilisez django-ec2
pour le nom, et cliquez sur Créer un rôle :
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 :
Sélectionnez le rôle django-ec2 , puis cliquez sur Appliquer .
Cliquez sur Fermer .
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.
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:
Set the name to django-ec2
and click on Create repository:
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:
Select the latest version of Postgres with the Free tier template:
Under Settings, set:
djangoec2
webapp
Stick with default settings for:
Passez à la section Connectivité et définissez les éléments suivants :
django-ec2
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
:
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 :
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.
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:
Add an inbound rule that will allow Postgres connections to instances inside that Security Group. To do that:
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.
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.
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 :
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 web
et , 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 ( web
et nginx-proxy
).
Pour simplifier les choses, nous utilisons un seul registre pour stocker les deux images. Nous avons utilisé les
web
etnginx-proxy
pour différencier les deux. Idéalement, vous devriez utiliser deux registres : un pourweb
et un pournginx-proxy
. Mettez-le à jour par vous-même si vous le souhaitez.
Outre les image
propriétés, nous avons également supprimé le db
service (et le volume associé) puisque nous utilisons RDS plutôt que de gérer Postgres dans un conteneur.
Il est temps de configurer les fichiers d'environnement pour les conteneurs web
et nginx-proxy-letsencrypt
.
Commencez par ajouter un fichier .env.staging pour le web
conteneur :
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:
<YOUR_DOMAIN.COM>
à votre domaine actuel.SQL_PASSWORD
et SQL_HOST
pour qu'ils correspondent à ceux créés dans la section RDS.SECRET_KEY
à une longue chaîne aléatoire.VIRTUAL_HOST
et VIRTUAL_PORT
sont nécessaires au nginx-proxy
conteneur pour créer automatiquement la configuration du proxy inverse.LETSENCRYPT_HOST
est là pour qu'il nginx-proxy-companion
puisse émettre un certificat Let's Encrypt pour votre domaine.À des fins de test/débogage, vous souhaiterez peut-être utiliser un
*
pourDJANGO_ALLOWED_HOSTS
la 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_EMAIL
valeur :
DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy
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 :
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 :
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
.
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 :
ìmage
propriétés pour qu'elles correspondent à vos URL AWS ECR pour les services ẁeb
etnginx-proxy
db
service 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
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
1660764420
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.
À la fin de ce didacticiel, vous serez en mesure de :
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 :
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 :
Utilisez Ubuntu Server 18.04 LTS (HVM) pour l'image du serveur (AMI) :
In the next step, stick with the t2.micro instance. Click on Next: Configure Instance Details:
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:
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:
It will take a few minutes for the instance to spin up.
In this section, we'll install Docker on the instance, add an Elastic IP, and configure an IAM role.
Navigate back to the EC2 console, select the newly created instance, and grab the public IP address:
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
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
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 :
Ensuite, cliquez sur Allouer :
Cliquez sur Associer cette adresse IP Elastic :
Sélectionnez votre instance et cliquez sur Associer :
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:
Select AWS Service and EC2, then click on Next: Permissions:
Enter container
in the search box, select the AmazonEC2ContainerRegistryPowerUser policy, and click Next: Tags:
Cliquez sur Suivant : Réviser . Utilisez django-ec2
pour le nom, et cliquez sur Créer un rôle :
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 :
Sélectionnez le rôle django-ec2 , puis cliquez sur Appliquer .
Cliquez sur Fermer .
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.
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:
Set the name to django-ec2
and click on Create repository:
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:
Select the latest version of Postgres with the Free tier template:
Under Settings, set:
djangoec2
webapp
Stick with default settings for:
Passez à la section Connectivité et définissez les éléments suivants :
django-ec2
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
:
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 :
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.
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:
Add an inbound rule that will allow Postgres connections to instances inside that Security Group. To do that:
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.
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.
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 :
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 web
et , 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 ( web
et nginx-proxy
).
Pour simplifier les choses, nous utilisons un seul registre pour stocker les deux images. Nous avons utilisé les
web
etnginx-proxy
pour différencier les deux. Idéalement, vous devriez utiliser deux registres : un pourweb
et un pournginx-proxy
. Mettez-le à jour par vous-même si vous le souhaitez.
Outre les image
propriétés, nous avons également supprimé le db
service (et le volume associé) puisque nous utilisons RDS plutôt que de gérer Postgres dans un conteneur.
Il est temps de configurer les fichiers d'environnement pour les conteneurs web
et nginx-proxy-letsencrypt
.
Commencez par ajouter un fichier .env.staging pour le web
conteneur :
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:
<YOUR_DOMAIN.COM>
à votre domaine actuel.SQL_PASSWORD
et SQL_HOST
pour qu'ils correspondent à ceux créés dans la section RDS.SECRET_KEY
à une longue chaîne aléatoire.VIRTUAL_HOST
et VIRTUAL_PORT
sont nécessaires au nginx-proxy
conteneur pour créer automatiquement la configuration du proxy inverse.LETSENCRYPT_HOST
est là pour qu'il nginx-proxy-companion
puisse émettre un certificat Let's Encrypt pour votre domaine.À des fins de test/débogage, vous souhaiterez peut-être utiliser un
*
pourDJANGO_ALLOWED_HOSTS
la 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_EMAIL
valeur :
DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy
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 :
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 :
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
.
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 :
ìmage
propriétés pour qu'elles correspondent à vos URL AWS ECR pour les services ẁeb
etnginx-proxy
db
service 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
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
1620177818
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.
#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
1660389180
Cet article explique comment déployer une application Django sur Heroku avec Docker via Heroku Container Runtime.
À la fin de ce didacticiel, vous serez en mesure de :
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.
Les déploiements basés sur Docker présentent de nombreux avantages par rapport à l'approche traditionnelle :
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 :
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éploiement | Mécanisme de déploiement | Mises à jour de sécurité (qui gère) | Accès aux pipelines, examen, publication | Accès à la CLI, aux modules complémentaires et au tableau de bord | Limites de taille des lingots |
---|---|---|---|---|---|
Compilateur Git + Slug | Poussée Git | Héroku | Oui | Oui | Oui |
Docker + Exécution du conteneur | Poussée Docker | Tu | Non | Oui | Non |
Docker + Build Manifest | Poussée Git | Tu | Oui | Oui | Non |
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 .
Docker | Héroku |
---|---|
Fichier Docker | BuildPack |
Image | Limace |
Récipient | Dynamo |
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é.
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 :
PYTHONDONTWRITEBYTECODE
: Empêche Python d'écrire des fichiers pyc sur le disquePYTHONUNBUFFERED
: Empêche Python de mettre en mémoire tampon stdout et stderrEnsuite, 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 $PORT
variable. Essentiellement, tout serveur Web qui s'exécute sur le Container Runtime doit écouter le trafic HTTP au niveau de $PORT
la 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
, DEBUG
et 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
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 collectstatic
commande 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
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_URL
variable 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_URL
est 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_URL
n'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.
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_KEY
variable 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_HOSTS
hello_django /settings.py comme suit :
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'limitless-atoll-51647.herokuapp.com']
Assurez-vous de remplacer
limitless-atoll-51647
chacune des commandes ci-dessus par le nom de votre application.
À 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 ?
Incertain? Essayez-les tous les deux !
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 web
puisqu'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-51647
pour 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-51647
chacune des commandes ci-dessus par le nom de votre application.
Accédez à la section "Test Postgres" une fois terminé.
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 :
setup
est utilisé pour définir les modules complémentaires Heroku et les variables de configuration à créer lors du provisionnement de l'application.release
est utilisé pour définir les tâches que vous souhaitez exécuter lors d'une release.run
est 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:$PORT
commande peut être supprimée du Dockerfile et ajoutée au fichier heroku.yml sous larun
scè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
release
scène. Pour en savoir plus, consultez cette question Stack Overflow .
Ensuite, installez le heroku-manifest
plug-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-51647
pour 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-51647
chacune des commandes ci-dessus par le nom de votre application.
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_URL
variable 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-51647
chacune des commandes ci-dessus par le nom de votre application Heroku.
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_TOKEN
dans les paramètres CI/CD de votre projet : Paramètres > CI/CD > Variables.
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.
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 :
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_deploy
scène comme un travail unique. Une fois terminée, une nouvelle version devrait être automatiquement créée sur Heroku.
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 :
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.
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.
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 :
Ensuite, dans l' test
étape, nous configurons Postgres , définissons la DATABASE_URL
variable 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 :
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.
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 :
Ensuite, dans l' test
étape, nous configurons Postgres , définissons la DATABASE_URL
variable 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 :
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.
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.
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 .
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 .
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:
Source : https://testdrive.io
1620185280
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:
Describe 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
1595298120
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