Python: Usages avancés

Aller plus loin avec vos déploiements Python

👋 Bienvenue sur la documentation de Stackhero !

Stackhero propose une solution Python cloud prête à l'emploi qui offre de nombreux avantages, notamment :

  • Déployez votre application en quelques secondes avec un simple git push.
  • Utilisez votre propre nom de domaine et profitez de la configuration automatique des certificats HTTPS pour une sécurité renforcée.
  • Bénéficiez de sauvegardes automatiques, de mises à jour en un clic, ainsi que d'une tarification simple, transparente et prévisible.
  • Profitez d'une performance optimale et d'une sécurité renforcée grâce à une VM privée et dédiée.

Gagnez du temps et simplifiez-vous la vie : il suffit de 5 minutes pour essayer la solution d'hébergement Python cloud de Stackhero !

Jusqu'à présent, nous avons utilisé la commande git push stackhero main pour déployer la branche main en production.

Si vous souhaitez déployer une autre branche, utilisez cette commande où <BRANCH> correspond au nom de la branche à déployer :

git push stackhero <BRANCH>:main

Par exemple, pour déployer la branche production, il suffit d'exécuter :

git push stackhero production:main

Vous pouvez choisir de déployer un tag plutôt qu'une branche. Pour déployer un tag spécifique, remplacez <TAG> par le tag souhaité dans la commande suivante :

git push stackhero '<TAG>^{}:main'

Par exemple, pour déployer le tag v1.0.0, exécutez :

git push stackhero 'v1.0.0^{}:main'

La syntaxe ^{} garantit que vous poussez le commit référencé par le tag, et non la référence du tag elle-même.

En plus de déployer des branches ou des tags, vous pouvez également déployer un commit précis en utilisant son hash. Remplacez <COMMIT_HASH> par le hash du commit à déployer :

git push -f stackhero <COMMIT_HASH>:main

Par exemple, pour déployer le commit dont le hash est abcde, lancez :

git push -f stackhero abcde:main

Si un déploiement récent a introduit des problèmes, vous pouvez revenir à un commit antérieur en déployant ce commit. Commencez par identifier le hash du commit en exécutant :

git log

Cette commande affiche la date, le hash et la description de chaque commit.

Par exemple, le résultat peut ressembler à ceci :

git log

commit cccc8b3ebdccb9abc1926ef49ee589dae5c5fe06 (HEAD -> main, stackhero/main)
Author: Developer
Date:   Fri Apr 28 09:36:18 +0000

    Break the code

commit bbbb622301772072c3d82f3cc0d91e29e6e84901
Author: Developer
Date:   Wed Apr 26 12:49:28 +0000

    Update the code

commit aaaa1d8b06535b413e0df8298ccf52339dfef3ff
Author: Developer
Date:   Wed Apr 26 12:44:50 +0000

    Improve the code

Si le déploiement actuel en production correspond au commit "Break the code" (hash commençant par cccc), et que vous souhaitez revenir au commit précédent "Update the code" (hash commençant par bbbb), exécutez :

git push -f stackhero bbbb622301772072c3d82f3cc0d91e29e6e84901:main

Pour éviter de déployer du code défectueux et renforcer la stabilité de votre production, il est fortement conseillé de mettre en place un environnement de "staging".

Placé entre le développement et la production, l'environnement de staging offre une réplique quasi identique de la production. Il vous permet de tester votre code en profondeur avant un déploiement en production.

Utiliser un environnement de staging augmente votre confiance dans le bon fonctionnement et les performances de votre code, ce qui conduit à des déploiements plus robustes.

Ce type d'environnement sera abordé plus en détail dans la suite de la documentation.

L'utilisation d'un environnement de staging est une bonne pratique à adopter en complément des environnements de développement et de production. Il reproduit l'environnement de production afin de tester vos mises à jour et modifications avant leur mise en ligne, ce qui réduit les risques d'incidents en production.

Un environnement de staging doit être aussi proche que possible de la production.

Cependant, il doit utiliser une copie de votre base de données de production ou des services connectés, et non la base de données de production en direct.

Si votre service Python dépend de bases de données ou d'autres services, recréez-les dans une nouvelle stack <Project> - Staging.

Suivez ces étapes pour configurer un environnement de staging avec Stackhero :

  1. Sur le tableau de bord Stackhero, renommez votre stack existante de <Project> en <Project> - Production. Par exemple, si votre projet s'appelle Chat Bot, la stack devient Chat Bot - Production.
  2. Créez une nouvelle stack nommée <Project> - Staging. Pour le projet Chat Bot, la stack devient Chat Bot - Staging.
  3. Lancez un service Python dans la stack de staging.
  4. Récupérez la commande git remote et suivez les instructions de la documentation Déployer sur l'environnement de staging.

Cette configuration vous garantit un environnement de staging pleinement opérationnel pour tester vos mises à jour avant leur déploiement en production.

Il est fortement recommandé de maintenir des environnements de staging et de production séparés. Pour gérer plusieurs environnements, commencez par renommer le dépôt distant actuel. Par exemple, renommez le remote stackhero en stackhero-production avec :

git remote rename stackhero stackhero-production

Ensuite, créez un nouveau service Python pour votre environnement de staging. Récupérez la commande git remote add et modifiez-la en remplaçant <XXXXXX> par le domaine de votre service :

  • Commande d'origine :

    git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    
  • Commande modifiée :

    git remote add stackhero-staging ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    

Vous pouvez ensuite déployer sur l'environnement souhaité avec les commandes suivantes :

  • Déployer sur le staging :

    git push stackhero-staging main
    
  • Déployer sur la production :

    git push stackhero-production main
    

Pour améliorer le processus de déploiement, nous vous recommandons d'utiliser la version améliorée du Makefile.

Avec ce Makefile amélioré, déployer en production ou en staging se fait simplement avec make deploy-production ou make deploy-staging.

Voici un Makefile amélioré qui prend en charge plusieurs règles :

  • make dev (ou simplement make) : Démarre l'application en mode développement.
  • make deploy : Déploie l'application sur le remote nommé stackhero. Idéal si vous n'avez qu'une seule instance Stackhero.
  • make deploy-production : Déploie l'application sur le remote nommé stackhero-production.
  • make deploy-staging : Déploie l'application sur le remote nommé stackhero-staging.

Ce Makefile est conçu pour éviter l'erreur "Everything up-to-date" lorsque le code n'a pas changé.

Copiez-collez le contenu suivant comme nouveau Makefile :

# Règle exécutée par défaut lors de l'appel à "make" sans argument
.DEFAULT_GOAL := dev


# Stackhero for Python exécutera la règle "run" sur votre instance.
# C'est la commande à lancer en production et en staging.
run:
  ENV=production gunicorn app:app \
    --error-logfile - \
    -b 0.0.0.0:8080


# Commande à utiliser en environnement de développement
dev:
  python app.py


# Règle "deploy" pour déployer sur l'instance "stackhero".
# Adaptée si vous n'avez qu'une seule instance.
deploy:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero DEPLOY_BRANCH=main


# Les règles "deploy-*" déploient sur une instance nommée "stackhero-*".
# Par exemple, "make deploy-production" déploie sur "stackhero-production",
# ou "make deploy-staging" déploie sur "stackhero-staging".
deploy-%:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero-$* DEPLOY_BRANCH=main


# Règle interne de déploiement. Ne pas modifier.
deploy-script:
  @echo "Déploiement de la branche \"${DEPLOY_BRANCH}\" sur \"${DEPLOY_REMOTE}\"..."
  @echo

  @if [ -n "$$(git status --porcelain)" ]; then \
    echo "Impossible de déployer car des modifications ne sont pas commitées :"; \
    echo "\e[0m"; \
    git status -s; \
    echo ""; \
    echo "\e[0;31m"; \
    echo "Vous pouvez utiliser cette commande pour valider les modifications :"; \
    echo "git add -A . && git commit -m \"Votre message\""; \
    echo "\e[0m"; \
    exit 1; \
  fi

  @git push --dry-run ${DEPLOY_REMOTE} ${DEPLOY_BRANCH} 2>&1 | grep -q -F "Everything up-to-date"; \
  EXIT_CODE=$$?; \
  if [ $$EXIT_CODE -eq 0 ]; then \
    echo -n "Rien de nouveau à déployer... Forcer le déploiement (cela créera un nouveau commit) ? (y/N) "; \
    read answer && \
    case $$answer in \
      y|Y|yes|YES) \
      git commit --allow-empty -m "Force update for deploy purpose to \"${DEPLOY_REMOTE}\"" ; \
      ;; \
    *) \
      echo "Rien à déployer !"; \
      exit 1; \
      ;; \
    esac \
  fi

  git push ${DEPLOY_REMOTE} ${DEPLOY_BRANCH}

À un moment donné, vous aurez besoin de stocker des secrets comme des tokens ou des mots de passe pour des bases de données ou des services tiers. Il est essentiel de les stocker de façon sécurisée. Évitez de les inclure directement dans votre dépôt ou votre code, cela représente un risque de sécurité important.

L'utilisation de variables d'environnement présente deux avantages majeurs :

  1. Vos secrets ne sont jamais stockés dans votre dépôt Git, ce qui limite les risques d'accès non autorisé.
  2. Vous pouvez utiliser des identifiants différents selon l'environnement, par exemple une base de données de production en production et une base de développement en local.

En développement, créez un fichier .env à la racine de votre projet. Ce fichier doit être exclu de Git pour ne jamais être commité.

Pour lire automatiquement le fichier .env, vous pouvez utiliser le module python-dotenv :

pip install python-dotenv
pip freeze > requirements.txt

Ensuite, créez un fichier .env à la racine du projet et ajoutez vos variables :

ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"
# ...

Enfin, assurez-vous que le fichier .env est bien exclu de Git en l'ajoutant à votre .gitignore :

echo ".env" >> .gitignore

Le fichier .env n'est pas suffisamment sécurisé pour les environnements de staging et de production. Stackhero vous permet de stocker vos variables d'environnement de manière sécurisée directement dans la configuration de votre service Python.

Vous pouvez définir ces variables depuis le tableau de bord Stackhero en sélectionnant votre service Python puis en cliquant sur le bouton "Configurer".

Variables d'environnement Python sur StackheroVariables d'environnement Python sur Stackhero

L'accès aux variables d'environnement en Python est très simple. Utilisez simplement os.environ.get() comme ci-dessous :

import os

print(os.environ.get('ENV'))

Par exemple, pour se connecter à un serveur Redis via une variable d'environnement :

import os
import redis

r = redis.from_url(os.environ.get("REDIS_URL"))

En développement, définissez la variable REDIS_URL dans votre fichier .env :

REDIS_URL="redis://localhost:6379"

Pour la production et le staging, définissez REDIS_URL sur le tableau de bord Stackhero dans la configuration du service Python :

REDIS_URL="rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:6380"

Il est recommandé de gérer les packages Python via un fichier requirements.txt. Ce fichier liste tous les packages nécessaires et leurs versions pour garantir le bon fonctionnement de votre code.

Le maintenir à jour permet de :

  1. S'assurer que tous les packages requis sont installés.
  2. Utiliser uniquement des versions compatibles.

Lors du déploiement sur votre instance Stackhero, les packages listés dans requirements.txt sont installés automatiquement.

Pour générer ou mettre à jour le fichier requirements.txt, exécutez la commande suivante après l'installation de nouveaux packages :

pip freeze > requirements.txt

La plupart des applications Python utilisent les ports HTTP 80 (HTTP) et 443 (HTTPS).

Si votre application doit ouvrir d'autres ports ou utiliser d'autres protocoles (TCP ou UDP), vous pouvez ajuster le paramètre "Ports Redirections" dans votre service Python sur le tableau de bord Stackhero.

Pour chaque port supplémentaire, indiquez le port d'entrée (côté public), le port de destination (utilisé par votre application Python) et le protocole (TCP ou UDP).

Redirections de ports dans le tableau de bord StackheroRedirections de ports dans le tableau de bord Stackhero

Pour stocker des fichiers comme des photos d'utilisateurs ou des documents, il est généralement préférable d'utiliser une solution d'object storage.

L'object storage permet de partager des fichiers entre plusieurs services ou instances et sépare le stockage du code, conformément aux bonnes pratiques.

Nous recommandons MinIO, une solution rapide et puissante compatible avec le protocole Amazon S3.

Si vous préférez un stockage local, vous pouvez utiliser le stockage persistant fourni avec votre instance Python, situé dans /persistent/storage/. Cependant, cette approche est déconseillée dans la plupart des cas.

ATTENTION : Ne stockez jamais de données en dehors du dossier /persistent/storage/ !

Stocker des données ailleurs peut entraîner leur perte lors d'un redémarrage, d'une mise à jour de l'instance ou lors d'un nouveau push de code.

Sur macOS, il peut être contraignant de saisir le mot de passe de votre clé SSH privée à chaque push de code. Pour plus de confort, vous pouvez enregistrer ce mot de passe de façon sécurisée dans le trousseau Apple, plutôt que de le supprimer de votre clé.

Pour enregistrer le mot de passe d'une clé nommée id_ed25519, exécutez :

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Après cela, le mot de passe de votre clé ne vous sera plus demandé, ce qui vous fera gagner du temps.

Si vous utilisez une clé RSA, remplacez id_ed25519 par id_rsa dans la commande :

ssh-add --apple-use-keychain ~/.ssh/id_rsa