gwift-book/source/part-2-deployment/heroku.adoc

11 KiB
Raw Blame History

Déploiement sur Heroku

Heroku est une Plateform As A Service , où vous choisissez le service dont vous avez besoin (une base de données, un service de cache, un service applicatif, …​), vous lui envoyer les paramètres nécessaires et le tout démarre gentiment sans que vous ne deviez superviser lhôte. Ce mode démarrage ressemble énormément aux 12 facteurs dont nous avons déjà parlé plus tôt - raison de plus pour que notre application soit directement prête à y être déployée, dautant plus quil ne sera pas possible de modifier un fichier une fois quelle aura démarré: si vous souhaitez modifier un paramètre, cela reviendra à couper lactuelle et envoyer de nouveaux paramètres et recommencer le déploiement depuis le début.

heroku
Figure 1. Invest in apps, not ops. Heroku handles the hard stuff — patching and upgrading, 24/7 ops and security, build systems, failovers, and more — so your developers can stay focused on building great apps.

Pour un projet de type "hobby" et pour lexemple de déploiement ci-dessous, il est tout à fait possible de sen sortir sans dépenser un kopek, afin de tester nos quelques idées ou mettre rapidement un Most Valuable Product en place. La seule contrainte consistera à pouvoir héberger des fichiers envoyés par vos utilisateurs - ceci pourra être fait en configurant un bucket compatible S3, par exemple chez Amazon, Scaleway ou OVH.

Le fonctionnement est relativement simple: pour chaque application, Heroku crée un dépôt Git qui lui est associé. Il suffit donc denvoyer les sources de votre application vers ce dépôt pour quHeroku les interprête comme étant une nouvelle version, déploie les nouvelles fonctionnalités - sous réserve que tous les tests passent correctement - et les mettent à disposition. Dans un fonctionnement plutôt manuel, chaque déploiement est initialisé par le développeur ou par un membre de léquipe. Dans une version plus automatisée, chacun de ces déploiements peut être placé en fin de pipeline, lorsque tous les tests unitaires et dintégration auront été réalisés.

Au travers de la commande heroku create, vous associez donc une nouvelle référence à votre code source, comme le montre le contenu du fichier .git/config ci-dessous:

$ heroku create
Creating app... done, ⬢ young-temple-86098
https://young-temple-86098.herokuapp.com/ | https://git.heroku.com/young-temple-86098.git

$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "heroku"]
        url = https://git.heroku.com/still-thicket-66406.git
        fetch = +refs/heads/*:refs/remotes/heroku/*

IMPORTANT:

Pour définir de quel type d'application il s'agit, Heroku nécessite un minimum de configuration.
Celle-ci se limite aux deux fichiers suivants:

* Déclarer un fichier `Procfile` qui va simplement décrire le fichier à passer au protocole WSGI
* Déclarer un fichier `requirements.txt` (qui va éventuellement chercher ses propres dépendances dans un sous-répertoire, avec l'option `-r`)

Après ce paramétrage, il suffit de pousser les changements vers ce nouveau dépôt grâce à la commande git push heroku master.

Warning
Heroku propose des espaces de déploiements, mais pas despace de stockage. Il est possible dy envoyer des fichiers utilisateurs (typiquement, des media personnalisés), mais ceux-ci seront perdus lors du redémarrage du container. Il est donc primordial de configurer correctement lhébergement des fichiers média, de préférences sur un stockage compatible S3.

Prêt à vous lancer ? Commencez par créer un compte: https://signup.heroku.com/python.

Configuration du compte Heroku

+ Récupération des valeurs denvironnement pour les réutiliser ci-dessous.

Vous aurez peut-être besoin dun coup de pouce pour démarrer votre première application; heureusement, la documentation est super bien faite:

heroku new app
Figure 2. Heroku: Commencer à travailler avec un langage

Installez ensuite la CLI (Command Line Interface) en suivant la documentation suivante.

Au besoin, cette CLI existe pour:

  1. macOS, via `brew `

  2. Windows, grâce à un binaire x64 (la version 32 bits existe aussi, mais il est peu probable que vous en ayez besoin)

  3. GNU/Linux, via un script Shell curl https://cli-assets.heroku.com/install.sh | sh ou sur SnapCraft.

Une fois installée, connectez-vous:

$ heroku login

Et créer votre application:

$ heroku create
Creating app... done, ⬢ young-temple-86098
https://young-temple-86098.herokuapp.com/ | https://git.heroku.com/young-temple-86098.git
heroku app created
Figure 3. Notre application est à présent configurée!

Ajoutons lui une base de données, que nous sauvegarderons à intervalle régulier:

$ heroku addons:create heroku-postgresql:hobby-dev
Creating heroku-postgresql:hobby-dev on ⬢ still-thicket-66406... free
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-clear-39693 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation

$ heroku pg:backups schedule --at '14:00 Europe/Brussels' DATABASE_URL
Scheduling automatic daily backups of postgresql-clear-39693 at 14:00 Europe/Brussels... done

TODO: voir comment récupérer le backup de la db :-p

# Copié/collé de https://cookiecutter-django.readthedocs.io/en/latest/deployment-on-heroku.html
heroku create --buildpack https://github.com/heroku/heroku-buildpack-python

heroku addons:create heroku-redis:hobby-dev

heroku addons:create mailgun:starter

heroku config:set PYTHONHASHSEED=random

heroku config:set WEB_CONCURRENCY=4

heroku config:set DJANGO_DEBUG=False
heroku config:set DJANGO_SETTINGS_MODULE=config.settings.production
heroku config:set DJANGO_SECRET_KEY="$(openssl rand -base64 64)"

# Generating a 32 character-long random string without any of the visually similar characters "IOl01":
heroku config:set DJANGO_ADMIN_URL="$(openssl rand -base64 4096 | tr -dc 'A-HJ-NP-Za-km-z2-9' | head -c 32)/"

# Set this to your Heroku app url, e.g. 'bionic-beaver-28392.herokuapp.com'
heroku config:set DJANGO_ALLOWED_HOSTS=

# Assign with AWS_ACCESS_KEY_ID
heroku config:set DJANGO_AWS_ACCESS_KEY_ID=

# Assign with AWS_SECRET_ACCESS_KEY
heroku config:set DJANGO_AWS_SECRET_ACCESS_KEY=

# Assign with AWS_STORAGE_BUCKET_NAME
heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME=

git push heroku master

heroku run python manage.py createsuperuser

heroku run python manage.py check --deploy

heroku open

Configuration

Pour quHeroku comprenne le type dapplication à démarrer, ainsi que les commandes à exécuter pour que tout fonctionne correctement. Pour un projet Django, cela comprend, à placer à la racine de votre projet:

  1. Un fichier requirements.txt (qui peut éventuellement faire appel à un autre fichier, via largument -r)

  2. Un fichier Procfile ([sans extension](https://devcenter.heroku.com/articles/procfile)!), qui expliquera la commande pour le protocole WSGI.

Dans notre exemple:

# requirements.txt
django==3.2.8
gunicorn
boto3
django-storages
# Procfile
release: python3 manage.py migrate
web: gunicorn gwift.wsgi

Hébergement S3

Pour cette partie, nous allons nous baser sur lObject Storage de Scaleway. Ils offrent 75GB de stockage et de transfert par mois, ce qui va nous laisser suffisament despace pour jouer un peu 😉.

scaleway object storage bucket

Lidée est quau moment de la construction des fichiers statiques, Django aille simplement les héberger sur un espace de stockage compatible S3. La complexité va être de configurer correctement les différents points de terminaison. Pour héberger nos fichiers sur notre bucket S3, il va falloir suivre et appliquer quelques étapes dans lordre:

  1. Configurer un bucket compatible S3 - je parlais de Scaleway, mais il y en a - littéralement - des dizaines.

  2. Ajouter la librairie boto3, qui soccupera de "parler" avec ce type de protocole

  3. Ajouter la librairie django-storage, qui va elle soccuper de faire le câblage entre le fournisseur (via boto3) et Django, qui sattend à ce quon lui donne un moteur de gestion via la clé [DJANGO_STATICFILES_STORAGE](https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-STATICFILES_STORAGE).

La première étape consiste à se rendre dans [la console Scaleway](https://console.scaleway.com/project/credentials), pour gérer ses identifiants et créer un jeton.

scaleway api key

Selon la documentation de django-storages, de boto3 et de Scaleway, vous aurez besoin des clés suivantes au niveau du fichier settings.py:

AWS_ACCESS_KEY_ID = os.getenv('ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME')

AWS_DEFAULT_ACL = 'public-read'
AWS_LOCATION = 'static'
AWS_S3_SIGNATURE_VERSION = 's3v4'

AWS_S3_HOST = 's3.%s.scw.cloud' % (AWS_S3_REGION_NAME,)
AWS_S3_ENDPOINT_URL = 'https://%s' % (AWS_S3_HOST, )

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3ManifestStaticStorage'

STATIC_URL = '%s/%s/' % (AWS_S3_ENDPOINT_URL, AWS_LOCATION)

# General optimization for faster delivery
AWS_IS_GZIPPED = True
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

Configurez-les dans la console dadministration dHeroku:

heroku vars reveal

Lors de la publication, vous devriez à présent avoir la sortie suivante, qui sera confirmée par le bucket:

remote: -----> $ python manage.py collectstatic --noinput
remote:        128 static files copied, 156 post-processed.

gwift cloud s3

Sources complémentaires: