Sous ce titre, l’idée est de présenter un workflow de construction d’une image docker, sa publication et son déploiement depuis un simple git push grâce à Drone. Pour cela je vais utiliser un vieux projet en php toujours en vie : phpsysinfo
Lorsqu’on souhaite utiliser Docker plusieurs étapes sont nécessaires avant d’arriver à la publication finale.
L’étape 1 peut être longue selon la complexité du projet, mais comme ce n’est pas le sujet ici j’ai pris un projet basique.
L’étape 2 peut être faite sur un PC/VM Linux sauf si l’architure cible n’est pas du x86. Dans ce cas il faudra construire l’image sur un raspberry PI (si la cible est de l’ARMv7) ou un serveur ARM64v8 chez scaleway.
L’étape 3 devra être faite depuis la machine où l’on a construit l’image.
L’étape 4 sur son serveur Docker ou un des managers du Docker swarm.
Faire tout ceci sur le serveur cible n’est pas vraiment dans les canons du devops. L’objectif est de présenter une solution qui permettra d’écrire le Dockerfile et le docker-compose sur son PC personnel, commiter les modifications et les pusher vers un serveur git qui déclenchera un webhook vers Drone qui exécutera toutes les étapes.
La première tâche est de créer un dépôt git (gitea, github, gitlab, …) et d’avoir configuré une application vers son serveur drone avec les tokens qui vont bien. Mon dépôt se trouve ici : dockerfile_phpsysinfo, on y trouve 3 fichiers nécessaire au workflow :
FROM arm64v8/php:7.3.5-apache
MAINTAINER Frederic Logier <fredix@protonmail.com>
ENV PHPSYSINFO_VERSION 3.2.10
RUN curl -SL https://github.com/phpsysinfo/phpsysinfo/archive/v${PHPSYSINFO_VERSION}.tar.gz | tar -xzC /tmp/ \
&& mv /tmp/phpsysinfo-${PHPSYSINFO_VERSION}/* /var/www/html/ \
&& rm -rf /tmp/phpsysinfo-${PHPSYSINFO_VERSION}
RUN cat /var/www/html/phpsysinfo.ini.new | sed 's/^LOAD_BAR=false/LOAD_BAR=true/' >/var/www/html/phpsysinfo.ini
La première ligne permet d’avoir une image avec Apache/PHP clé en main. La 3ème crée une variable qui sera utilisée ensuite pour télécharger le tarball de la version (pour l’exemple l’avant dernière). L’image lance automatiquement Apache qui va lire son répertoire par defaut /var/www/html dans lequel on y a décompressé le projet. Par défaut Apache écoutera sur le port 80 dans le conteneur. Si j’avais utilisé une image basique Debian/Ubuntu j’aurais du installer Apache et PHP dans le conteneur puis lancer Apache.
version: "3.7"
services:
phpsysinfo:
image: fredix/arm64v8-phpsysinfo:3.2.10
restart: always
ports:
- 80
networks:
- traefik-net
deploy:
replicas: 2
placement:
constraints:
# - node.labels.location == cloud-arm64
- node.role == manager
labels:
- "traefik.port=80"
- "traefik.docker.network=traefik-net"
- "traefik.frontend.rule=Host:phpsysinfo.fredix.xyz"
networks:
traefik-net:
external: true
Une des forces de drone est de proposer des plugins qui étendent ses possibilités (la liste complète se trouve sur le marketplace). J’utilise les plugins :
kind: pipeline
name: default
platform:
os: linux
arch: arm64
clone:
depth: 50
steps:
#- name: clone
# image: plugins/git:linux-arm64
- name: docker
image: plugins/docker:linux-arm64
settings:
repo: fredix/arm64v8-phpsysinfo
tags: 3.2.10
dockerfile: Dockerfile.arm64v8
username:
from_secret: docker_username
password:
from_secret: docker_password
- name: transfer-compose
image: fredix/arm64v8-alpine-drone-scp
volumes:
- name: key
path: /root/ssh/drone.key
settings:
host: 192.168.254.1
username: drone
key_path: /root/ssh/drone.key
target: /tmp/phpsysinfo/
source: phpsysinfo-arm64v8.yml
rm: true
when:
branch: [master]
event: [push]
- name: ssh
image: fredix/arm64v8-alpine-drone-ssh
volumes:
- name: key
path: /root/ssh/drone.key
settings:
host: 192.168.254.1
port: 22
username: drone
key_path: /root/ssh/drone.key
script:
- "sudo docker stack deploy --compose-file=/tmp/phpsysinfo/phpsysinfo-arm64v8.yml phpsysinfo-arm64"
when:
status: success
- name: telegram
image: fredix/arm64v8-alpine-drone-telegram
settings:
token:
from_secret: plugin_token
to:
from_secret: plugin_to
message: >
{{#success build.status}}
build {{build.number}} succeeded on {{repo.name}}. Good job {{build.author}} {{build.link}}
{{else}}
build {{build.number}} failed on {{repo.name}}. Fix me please {{build.author}} {{build.link}}
{{/success}}
when:
status: [ success, failure ]
volumes:
- name: key
host:
path: /docker_volumes/drone_agent/drone.key
Avant de pusher ces fichiers vers le serveur git, il faudra côté drone cliquer sur Sync pour voir ce nouveau dépôt. Ensuite l’activer puis le paramétrer en cochant Trusted (nécessaire pour le plugin drone-ssh) et créer les 4 secrets : docker_username docker_password (pour que drone puisse publier sur le hub docker), plugin_to plugin_token (pour que drone puis me notifier sur télégram via un bot, voir l’article telegram-plugin-drone)
Le dépôt est prêt, il suffit de commit et de pusher. Drone a créé le build 5 du pipeline visible ici : https://drone.fredix.xyz/fredix/dockerfile_phpsysinfo/5
J’ai bien reçu la notification telegram :
L’image docker a bien été publié : https://hub.docker.com/r/fredix/arm64v8-phpsysinfo/tags
Et le site accessible ici : https://phpsysinfo.fredix.xyz/index.php?disp=bootstrap
Maintenant passons à la dernière version 3.3.0. Pour cela on modifie les 3 fichiers :
On commit, push.
pipeline 6 créé : https://drone.fredix.xyz/fredix/dockerfile_phpsysinfo/6
image docker publiée
La nouvelle version est déployée
A noter que la directive replicas: 2 dans le fichier phpsysinfo-arm64v8.yml lance 2 instances de l’image ce qui empèche une interruption de service pendant la mise à jour.
Un exemple de configuration : using-drone-ci-to-build-a-jekyll-site-and-deploy-to-docker-swarm, mais le .drone.yml devra être mise à jour avec le nouveau format de drone.