Intégration continue de Collabora (docker)

Infrastructure as code

Pour ceux qui l’ignorent, Collabora/Code est la version web de Libre-Office. Elle est notamment disponible avec Nextcloud. Une solution plébiscitée par de nombreuses entreprises et notamment chez mes clients.
Dans ses tutoriels d’installation en mode docker, la ligne de commande pour lancer votre container est souvent (voire tout le temps…) celle-ci :

sudo docker run -t -d -p 127.0.0.1:9980:9980 -e "domain=cloud\\.example\\.com" --restart always --cap-add MKNOD collabora/code

Mais qu’en est-il à chaque mise à jour ? La méthode peut être fastidieuse pour puller la dernière image, détruire notre container actuel et en redémarrer un nouveau basé sur la dernière image… Plusieurs options s’offrent à nous.

Première option  (méthode à la papa ) : écrire un script bash en guise de wrapper :


#!/usr/bin/env bash
if docker pull collabora/code | grep -q "Downloaded newer image"; then
	docker rm -f collabora 2>/dev/null
	docker run -t -d -p 127.0.0.1:9980:9980 -e "domain=cloud\\.example\\.com" --name collabora --restart always --cap-add MKNOD collabora/code
fi

Deuxième option : même si ce n’est pas sa raison d’être, passer par un fichier docker-compose.yml (avec un seul service…) qui ne nécessite pas d’installation d’un programme supplémentaire et qu’on pourra mettre à jour automatiquement avec :

docker-compose pull && docker-compose up -d

Je vous en propose donc un qui reprend les mêmes options que la ligne de commande :


version: '3'

services:
  collabora:
    image: collabora/code
    restart: always
    ports:
      - "127.0.0.1:9980:9980"
    environment:
      - domain=cloud.example.com
    cap_add:
      - MKNOD

Troisième option : passer par un playbook ansible, dont la vocation est justement l’automatisation des tâches. Ma solution préférée…


---
- hosts: localhost
  connection: local
  tasks:
    - name: collabora docker
      docker_container:
        name: collabora
        image: collabora/code
        pull: true
        restart_policy: "always"
        ports:
          - "127.0.0.1:9980:9980"
        env:
          domain: cloud.example.com
        capabilities:
          - MKNOD

Dernière option : passer par un script OpenTofu (fork libre de Terraform) qui est également ce qu’on peut faire de mieux en guise d’infrastructure as code.

Je vous livre mon main.tf

N.B. Il faudra préalablement détruire le container le cas échéant


terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "3.0.2"
    }
  }
}

provider "docker" {
  host = "unix:///var/run/docker.sock"
}

data "docker_registry_image" "collabora" {
  name = "collabora/code:latest"
}

resource "docker_image" "collabora" {
  name          = data.docker_registry_image.collabora.name
  pull_triggers = [data.docker_registry_image.collabora.sha256_digest]
}

resource "docker_container" "collabora" {
  image   = docker_image.collabora.name
  name    = "collabora"
  restart = "always"
  ports {
    internal = 9980
    external = 9980
    ip       = "127.0.0.1/32"
  }
  env = ["domain=cloud.example.com"]
  capabilities {
    add = ["MKNOD"]
  }
}

Et voilà, autant de possibilités de faire de l’automatisation et de l’infrastructure as code sans même parfois le savoir… A chacun de choisir la solution qui lui convient !