Statamic Peak

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 :

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.