Docs/ Déploiement/ Docker Compose

Docker Compose

Déployez un docker-compose.yml comme une seule application sh0 : chaque service devient un conteneur sur un réseau privé, avec des volumes nommés et une seule adresse publique.

Vue d'ensemble

sh0 importe un fichier Compose comme une seule application. Chaque service devient un conteneur démarré depuis son image, dans l'ordre donné par depends_on. Les services ne peuvent pas être construits : un service qui déclare build: est refusé ; construisez son image ailleurs ou déployez-le comme une application distincte depuis son dépôt Git.

Déployer une pile

Dans le tableau de bord, ouvrez une pile, cliquez sur Ajouter une app, choisissez Docker Compose, nommez l'application, collez le fichier dans docker-compose.yml et cliquez sur Déployer. En ligne de commande, sh0 compose validate vérifie un fichier et sh0 compose deploy le déploie. Exemple avec un service web et un cache Redis :

docker-compose.yml
services:
  web:
    image: traefik/whoami:v1.10
    ports:
      - "8080:80"
    environment:
      REDIS_URL: redis://cache:6379
    depends_on:
      - cache
    deploy:
      resources:
        limits:
          memory: 64M
          cpus: "0.25"
    healthcheck:
      test: ["CMD", "true"]
  cache:
    image: redis:7-alpine
    mem_limit: 128m
    cpus: 0.5
    volumes:
      - cache-data:/data
volumes:
  cache-data:
Terminal
$ sh0 compose validate docker-compose.yml
[ok] Compose file is valid
  Services: web, cache

$ sh0 compose deploy --app-name my-stack --wait docker-compose.yml
[*] Deploying compose file 'docker-compose.yml' as 'my-stack'...
[ok] Compose stack 'my-stack' deployed (app ID: 79389ae4-4a59-42a5-b8f6-37a018c95ddc, status: deploying)
[*] Waiting for deployment to complete...
[ok] Deployment completed successfully

--var CLÉ=VALEUR (répétable) remplace la valeur de la variable d'environnement CLÉ dans chaque service qui la définit.

Ce que vérifie la validation

Un fichier est refusé s'il ne contient aucun service, si un service n'a pas d'image, déclare build:, a un port invalide ou une commande illisible, ou monte un chemin de l'hôte (/srv/data:/data, ./data:/data) : seuls les volumes nommés sont admis. Les clés que sh0 ne lit pas ne sont pas signalées : l'exemple ci-dessus passe la validation alors que ses blocs deploy et healthcheck sont ignorés.

Clés Compose

Clés lues par sh0 :

  • image : obligatoire, tirée de Docker Hub ou de tout registre.
  • ports : seul le port du conteneur est utilisé. Le premier service, dans l'ordre du fichier, qui déclare un port reçoit l'adresse publique de l'application via le proxy inverse. Le port hôte que vous écrivez n'est pas ouvert sur le serveur.
  • environment : sous forme de dictionnaire ou de liste.
  • volumes : volumes nommés uniquement. Un volume cache-data de l'application my-stack est créé sous le nom sh0-my-stack-cache-data et persiste d'un redémarrage à l'autre.
  • depends_on : ordre de démarrage, forme liste ou forme étendue.
  • command : chaîne ou liste.
  • mem_limit et cpus : limites de mémoire et de processeur du service. Ce sont les seules clés de ressources que sh0 lit.

Clés ignorées

deploy (y compris deploy.resources), healthcheck, entrypoint, restart, labels et networks sont acceptées et ignorées. Chaque conteneur reçoit la politique de redémarrage unless-stopped, et un service sans mem_limit ni cpus reçoit les limites par défaut. Sur la pile d'exemple, la limite de 64 Mo écrite sous deploy.resources ne s'est pas appliquée, alors que mem_limit: 128m s'est appliquée :

Terminal
$ docker inspect -f "{{.Name}} mem={{.HostConfig.Memory}} nanocpus={{.HostConfig.NanoCpus}} restart={{.HostConfig.RestartPolicy.Name}}" \
    sh0-17b83e1c-my-stack-web sh0-17b83e1c-my-stack-cache
/sh0-17b83e1c-my-stack-web mem=536870912 nanocpus=1000000000 restart=unless-stopped
/sh0-17b83e1c-my-stack-cache mem=134217728 nanocpus=500000000 restart=unless-stopped

Réseau

Les services d'une pile partagent un réseau privé et se joignent par leur nom de service : dans l'exemple, le conteneur cache obtient une réponse de http://web:80. Seul le service qui porte l'adresse publique est joignable depuis l'extérieur.

Gérer les services

La pile apparaît comme une seule application dans sh0 apps et dans le tableau de bord. Ses services sont listés par GET /api/v1/apps/<app-id>/services et peuvent être redémarrés, arrêtés ou démarrés un par un avec POST /api/v1/apps/<app-id>/services/<service-id>/restart (ou /stop, /start).

Modifier une pile déployée

La version 1.10.2 ne permet pas d'appliquer une nouvelle version du fichier Compose à une pile existante. Redéployer le fichier sous le même nom est refusé, et redéployer l'application échoue parce qu'elle n'a pas de dépôt :

Terminal
$ sh0 compose deploy --app-name my-stack docker-compose.yml
[*] Deploying compose file 'docker-compose.yml' as 'my-stack'...
Error: An app with name 'my-stack' already exists (VALIDATION_ERROR)

$ sh0 deploy my-stack --wait
[*] Deploying my-stack...
  Deployment ID: 34f99c19-adda-4a30-a1dc-4e670a3ff505
  Status:        queued
[*] Waiting for deployment to complete...
error: Deployment failed.

# Build log of that deployment:
[STEP 1/6] Cloning repository
[ERROR] App has no repository URL configured

Les services en marche ne sont pas affectés par ces échecs. Pour modifier la pile, déployez le nouveau fichier sous un nouveau nom, déplacez le trafic et les données, puis supprimez l'ancienne application ; sh0 delete supprime une application et ses ressources.

Warning
Ne versionnez pas de vrais secrets dans un fichier Compose. Gardez une valeur provisoire dans environment et fixez la vraie au déploiement avec --var.