Consentement d'utilisation des Cookies

J'accepte Notre site sauvegarde des traceurs textes (cookies) sur votre appareil afin de vous garantir de meilleurs contenus et à des fins de collectes statistiques.Vous pouvez désactiver l'usage des cookies en changeant les paramètres de votre navigateur. En poursuivant votre navigation sur notre site sans changer vos paramètres de navigateur vous nous accordez la permission de conserver des informations sur votre appareil.

Déploiement d'une application Django docker





N'oubliez pas si vous avez besoin d'aide pour mettre votre application en production ou vous voulez qu'on le fasse pour vous ? Ouvrez un ticket !

Dans ce tutoriel nous allons voir comment packager notre application Django avec Gunicorn dans une image docker.

Le principal avantage d'utiliser docker plutôt qu'une VM est que nous ne devrons pas installer toutes les dépendances "à la main". Nous pourrons également déployer le nombre d'instances que nous voulons sans devoir tout réinstaller, et si nous faisons une mise à jour il faut simplement mettre à jour la version de l'image.

Tout d'abord les prérequis:

    - un compte docker sur le docker hub ( https://hub.docker.com/register/ )

    - je suppose que vous avez déjà une application django, donc ce tutoriel ne parlera pas de commander développer avec django

    - docker installé sur la machine de travail ( j'utilise une machine CentOS 7 ) et pour info les commandes sur CentOS sont:

yum install -y epel-release &&  yum install -y python-pip docker && service docker start

        

1) Je vais créer une application django basique pour ce tutoriel: 

Je vais appeler mon projet "tutorial" veillez à remplacer ce nom par celui de votre projet.  Pour le créer : 

django-admin startproject tutorial

 

2) Vérifier son fichier requierments.txt:

Comme tout bon fan de django je crée mon fichier requierements.txt qui contiendra les dépendances de mon application, le mien est assez simple :)

$ cat requirements.txt 
django
gunicorn

   La structure de mon projet ressemble à cela maintenant:

.
├── tutorial
│   ├── tutorial
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── manage.py
└── requirements.txt

Bon on s'emballe pas j'ai que l'admin d'activé dans mon projet rien de plus !

 

3) On crée le fichier qui va démarrer gunicorn:

Je l'appelle start.sh:

#!/bin/bash

# Start Gunicorn processes
echo Demarrage de Gunicorn ...
exec gunicorn tutorial.wsgi:application \
    --bind 0.0.0.0:8000 \
    --workers 3

Petite précision concernant le nombre de workers, ils dépendent du nombre de cpu core disponible et on les calculs suivant la formule :

(2 x nombre_de_core) + 1

Attention de changer le nom "tutorial' par le nom de votre projet. Je rends également le fichier exécutable :

chmod +x start.sh

Et je le lance pour afin d'être sur que cela fonctionne:

[hebus@hebus tutorial]# ./start.sh 
Starting Gunicorn.
[2016-10-07 09:46:42 +0000] [2984] [INFO] Starting gunicorn 19.6.0
[2016-10-07 09:46:42 +0000] [2984] [INFO] Listening at: http://0.0.0.0:8000 (2984)
[2016-10-07 09:46:42 +0000] [2984] [INFO] Using worker: sync
[2016-10-07 09:46:42 +0000] [2989] [INFO] Booting worker with pid: 2989
[2016-10-07 09:46:42 +0000] [2990] [INFO] Booting worker with pid: 2990
[2016-10-07 09:46:42 +0000] [2991] [INFO] Booting worker with pid: 2991

 

Tout semble ok, mon application est accessible via l'adresse IP locale et sur le port 8000.

 

 

4) Maintenant, on va créer notre image Docker:

 

Avant de créer une image docker il faut écrire un fichier Dockerfile afin de lui dire quoi mettre dans mon image. Nous appellerons ce fichier "Dockerfile" que nous allons créer dans le root de notre projet.

#Dockerfile

FROM python:2-onbuild

Ici rien de spécial juste qu'on met python dans notre Dockerfile car django c'est du python, et cette image va automatiquement copier notre projet dans le répertoire /usr/src/app de notre image Docker et exécuter pour nous "pip install -r requierements.txt" pur installer nos dépendances.

Maintenant nous allons ajouter notre script ./start.sh à notre image pour démarrer gunicorn:

COPY start.sh /start.sh

Et comme on veut faire tourner notre app sur le port 8000 on le précise dans notre Dockerfile afin d'exposer le port:

EXPOSE 8000

Voilà tout est en place, sauf que notre script on ne l'a pas exécuté, pour ce faire on en donne l'instruction dans la Dockerfile:

CMD ["/start.sh"]

Cela parait long, mais en fait c'est rapide une fois qu'on a compris, et si on regarde il y a presque moins de commande que pour préparer notre machine de dev. Maintenant que notre Dockerfile est complétée, elle ressemble à ceci :

# Dockerfile

FROM python:2.7-onbuild

COPY start.sh /start.sh

EXPOSE 8000

CMD ["/start.sh"]

Bon c'est bien beau mais mise à part un fichier texte me direz vous on a rien d'autre, bougez pas l'image est presque la.

Attention on vérifie qu'on est bien dans le root de notre projet django et on lance notre commande pour construire notre container :

docker build -t hebus/django-tutorial .

et ça donne après le téléchargement de la dépendance par docker de notre image "python:2-onbuild" : 

Sending build context to Docker daemon 20.48 kB
Step 1 : FROM python:2.7-onbuild
# Executing 3 build triggers...
Step 1 : COPY requirements.txt /usr/src/app/
 ---> Using cache
Step 1 : RUN pip install --no-cache-dir -r requirements.txt
 ---> Running in 5ab77f8a3286
Collecting django==1.10 (from -r requirements.txt (line 1))
  Downloading Django-1.10-py2.py3-none-any.whl (6.8MB)
Collecting gunicorn==19.6.0 (from -r requirements.txt (line 2))
  Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB)
Installing collected packages: django, gunicorn
Successfully installed django-1.10 gunicorn-19.6.0
Step 1 : COPY . /usr/src/app
 ---> a0ec5736a5f1
Removing intermediate container 5ab77f8a3286
Removing intermediate container 59f02577e9f4
Step 2 : COPY start.sh /start.sh
 ---> acfd9b5d2992
Removing intermediate container d89002950ae4
Step 3 : EXPOSE 8000
 ---> Running in 6c3fe86134b6
 ---> 6914909a31d6
Removing intermediate container 6c3fe86134b6
Step 4 : CMD /start.sh
 ---> Running in ce396ed25ff6
 ---> e86a6ec23b71
Removing intermediate container ce396ed25ff6
Successfully built e86a6ec23b71

Voila notre image docker est prête, nous allons maintenant la publier sur le Docker hub afin de pouvoir la récupérer sur notre serveur de production :

on s'assure d'abord d'être connecté au dockerhub en faisant

docker login

et ensuite on publie:

docker push hebus/django-tutorial 

et ce qui donne comme résultat:

The push refers to a repository [docker.io/hebus/django-tutorial]
bc9f1af55455: Pushed 
f3bef6e0fbd2: Pushed 
d81abf869dbb: Pushed 
f01b3d92255a: Pushed 
9d56c7adb2fa: Mounted from library/python 
24ab1022ada9: Mounted from library/python 
6a269e827c98: Mounted from library/python 
2c2153fbd032: Mounted from library/python 
d9a069c1d0fc: Mounted from library/python 
a5eb0fc1decb: Mounted from library/python 
b2ac5371e0f2: Mounted from library/python 
142a601d9793: Mounted from library/python 
latest: digest: sha256:0a75e281f6ea82f8554a149942a5b519b782c23047be89e465e298e0b49e38d7 size: 2818

Voila notre image est disponnible pour la production !

 

5) Déploiement dans le cloud:

J'utiliserais le cloud hebus pour le déploiement de mon image avec une instance "tiny" ( à adapter selon vos besoins) sans stockage étant donné que je n’ai pas de base de données ( mise à part une sqlite mais qui ne me sert pas étant donné que c'est un tutorial ), dans la partie 2 de cet article nous verrons comment déployer PostgreSQL avec et sans clusteur de réplication.

mon fichier de déploiement est le suivant:

{
      "name": "django", 
      "spec": {
            "template": {
                  "spec": {
                        "containers": [
                              {
                                    "name": "django", 
                                    "image": "hebus/django-tutorial", 
                                    "volumeMounts": [], 
                                    "env": [], 
                                    "imagePullPolicy": "Always", 
                                    "ports": [
                                          {
                                                "containerPort": 8000, 
                                                "name": "django"
                                          }
                                    ], 
                                    "resources": {
                                          "limits": {
                                                "cpu": "0.9", 
                                                "memory": "0.9Gi"
                                          }
                                    }
                              }
                        ], 
                        "volumes": []
                  }
            }, 
            "replicas": 1
      }
}

 

Veiller à bien renseigner le nom de votre image pour moi c'est "hebus/django-tutorial".

Et la dernière étape, la création de mon LoadBalancer pour accéder à mon App :

 

 

Et maintenant je vérifie que mon site est bien accessible dans le cloud en mettant l'adresse renseignée soit tutorial-django.apps.hebus.io

 

 

 

Et voilà vous avez déployé votre application simplement dans le cloud Hebus à l'aide de docker et kubernetes ( sans le savoir :) ).

Dans un prochain article, nous verrons comment ajouter du stockage persistant à notre application et la connecter à une base de données PostgreSQL. Également vous découvrirez la fonctionnalité de répliquas, alors stay tuned !