Mise à jour d’image Docker

Posted on Thu 22 August 2019 in Hosting

Ça a prit du temps mais ça y est, je me suis mis à docker. Ça faisait un moment que je regardais de loin, que j’avais tenté des trucs, lancé quelques containers… Par exemple, sur mon instance Gitlab, les graphs sont rendu à travers un service PlantUML installé dans un Docker. Pareil, sur mon instance Nextcloud, j’ai activé l’application Collabora Online (qui permet d’éditer des documents directement depuis le navigateur) et le service est rendu à travers un container Docker. Le problème, c’est que je les avais lancé il y a bien longtemps et que les images ont évolués depuis. Et moi, j’aime pas bien avoir des choses pas trop à jour.

Il me fallait donc un moyen de mettre à jour mes containers Docker avec l’interruption de service la plus courte, en nettoyant les vielles images plus utilisées. J’ai donc concoctée une petite fonction Bash qui fait ça très bien pour moi:

update_docker()
{
    local image_name
    local container_name
    local new_image_sha
    local current_image_sha

    image_name="$1"
    shift
    container_name="$1"
    shift

    echo "Update ${container_name}"

    docker pull "${image_name}" > /dev/null
    new_image_sha=$(docker images "${image_name}" --no-trunc -q)
    current_image_sha=$(docker inspect "${container_name}" 2> /dev/null | jq -r ".[0].Image")
    if [[ "${new_image_sha}" != "${current_image_sha}" ]]; then
        if [[ "${current_image_sha}" != "null" ]]; then
            echo "Stop previous container"
            docker stop "${container_name}"
            docker rm "${container_name}"
        fi
        echo "Start new container"
        docker run -d "--name=${container_name}" --restart=always "$@" "${image_name}"
        if [[ "${current_image_sha}" != "null" ]]; then
            docker rmi "${current_image_sha}"
        fi
    else
        echo "Do nothing, ${container_name} already at latest version"
    fi
}

Cette fonction nécessite Docker évidemment et le petit utilitaire jq qui permet de faire des requêtes et d’extraire des informations directement depuis un Json.

À l’utilisation, rien de plus simple, la fonction a besoin du nom de l’image (registry:latest), du nom du container (myregistry) suivi des options supplémentaires à rajouter lors du lancement du container. L’option --restart=always est, quant à elle systématiquement ajoutée.

Pour créer ou mettre à jour un container, la commande suivante est donc suffisante :

update_docker registry:latest myregistry -p 5000:5000

Et voilà !

Note : je ne sais faire et n’utilise pour le moment que des services qui n’ont pas de donnée persistante donc je ne sais pas à quel point ça fonctionne dans le cas général ! Pour mon utilisation, ça à l’air tout bon !