Article
Utiliser Docker Compose avec Phoenix Framework
Docker Compose permet de démarrer ensemble des services au sein d'un projet. Comment l'utiliser avec Phoenix Framework ? C'est ce qu'on va voir ensemble !
Vous avez une image Docker avec votre application Elixir et vous voulez utiliser Docker Compose pour gérer les services associés (PostgreSQL par exemple). Si ce n'est pas le cas, mes précédents articles sur le sujet sont un bon point de départ.
Cet article fait parti d'une série sur la release et le déploiement d'une application Phoenix Framework. Si vous voulez accéder aux autres articles :
Comment utiliser Docker Compose pour notre application Phoenix Framework ?
Comment automatiser la release Mix et la publication de l'image dans une pipeline de CI/CD ?
Utiliser Docker Compose en local
L'intérêt de Docker est de partager un même environnement entre vos postes. C'est utile en production mais aussi en développement local. Pour ce premier cas, je vous propose d'utiliser Docker Compose pour démarrer les services associés à votre projet sans mettre votre application Phoenix Framework dans un conteneur.
Pourquoi ? Parce que votre application locale (mix
) n'est pas la même que celle de production (release
), parce que l'expérience développeur est meilleure avec asdf
, parce qu'aucun tuto en ligne ne va vous rappeler de vous connecter à votre conteneur avant d'exécuter les commandes qu'ils vous donnent et pour vous évitez de devoir modifier votre Dockerfile de développement pour ajouter des dépendances.
On va créer un fichier compose.local.yml
.
services:
db:
image: postgres:14
restart: always
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
ports:
- 5432:5432
volumes:
- db:/var/lib/postgresql/data
volumes:
db:
driver: local
Assez simplement, on va lui demander de démarrer un service postgres, avec l'utilisateur et le mot de passe fournis, accessible via le port 5432
et un stockage des données persistant.
Pour le démarrer, on va utiliser la commande docker compose
. Par défaut, le fichier recherché est compose.yml
, mais nous allons l'utiliser pour notre image de production.
docker compose -f compose.local.yml up
Si vous préférez, vous pouvez appeler ce fichier compose.yml
et celui de votre production compose.prod.yml
.
Utiliser Docker Compose en production
Pour utiliser Docker Compose en production, on va principalement devoir ajouter notre serveur Phoenix Framework comme service.
services:
phoenix:
image: MON_REGISTRY/MON_NAMESPACE/MON_PROJET
env_file:
- .env
ports:
- '4000:4000'
depends_on:
- db
volumes:
- files:/uploads
db:
image: postgres:14
env_file:
- .env
environment:
PGDATA: /var/lib/postgresql/data/pgdata
restart: always
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
files:
pgdata:
En plus de notre serveur, j'ai remplacé les variables d'environnement par un `env_file`. Cela évite de référencer en clair des mots de passe dans un fichier qui sera dans notre dépôt sur Github ou Sourcehut. C'est un fichier qui doit être présent sur note hôte au moment du lancement de la commande docker compose et dont le contenu est transformé en variables d'environnement dans nos conteneurs.
Il existe d'autres méthodes pour s'occuper des secrets avec Docker. Dans le cas de l'image postgres, il est possible d'utiliser Docker secrets
avec les variables POSTGRES_PASSWORD_FILE
, POSTGRES_USER_FILE
et POSTGRES_DB_FILE
. Si l'on veut faire la même chose pour notre serveur Phoenix, il faut modifier notre fichier config/runtime.exs
pour aller lire les valeurs dans un fichier plutôt qu'une variable d'environnement.
Edit : J'ai ajouté un exemple de volume vers un dossier /uploads
pour les fichiers uploadés (téléversés) vers le serveur. On peut l'appeler comme on veut, le nom n'est pas choisi par Phoenix. Cela ne fonctionnera pas avec le dossier priv
comme son emplacement change à chaque nouvelle version de votre application. Le plus simple est donc de choisir un chemin arbitraire.