Créez un registre docker privé et un docker hub proxy avec Nexus
Au lieu de stocker nos images Docker privées générées lors des builds sur un registry public tel que Docker Hub, nous allons mettre en place un registry privé avec Nexus (docker hosted). Nous allons également en profiter pour créer un proxy vers le Docker Hub public (docker proxy). Un dépôt proxy Docker dans Nexus agit comme un intermédiaire entre notre environnement de développement (ou CI/CD) et Docker Hub. Nexus stocke localement les images Docker provenant de Docker Hub, réduisant ainsi le temps de téléchargement en cas de demandes répétées et permet aux développeurs d'accéder plus rapidement aux dépendances nécessaires à leurs projets.
Nous mettons donc en place deux registres avec Nexus :
- Un registre d'images Docker privé
- Un registre Docker public pour accélérer les pulls
Voici le principe de fonctionnement expliqué avec le diagramme ci-dessous :
Installez Nexus Repository Manager
Nous allons installer Nexus dans un conteneur Docker avec Docker compose
dans la VM masterserver
Le Docker Compose est un fichier YAML, contrairement au Dockerfile. Il permet de décrire l'ensemble de la configuration de l'application, les relations entre les images Docker, ainsi que l'ordre de démarrage de ces dernières.
Créez un fichier docker-compose.yaml dans votre espace de travail sur la machine hôte ou directement sur masterserver
. Si vous souhaitez créer le fichier sur votre machine hôte, tout comme avec Docker CLI, installez Docker Compose.
Sur Windows, vous pouvez l'installer avec Chocolatey
choco install docker-compose
Voici le contenu du fichier Docker Compose :
version: "3.7"
services:
nexus:
image: sonatype/nexus3
expose:
- 8081
- 8082
- 8083
restart: always
volumes:
- "nexus-work:/sonatype-work"
ports:
- "5001:8081"
- "5002:8082"
- "5003:8083"
volumes:
nexus-work: {}
Les ports exposés sont les suivants :
- 8081 : le port par défaut de Nexus pour accéder à son interface graphique.
- 8082 : le port que nous allons choisir pour le registre public.
- 8083 : le port que nous allons choisir pour le registre privé.
Ces ports du conteneur (8081, 8082 et 8083) sont mappés sur les ports 5001, 5002 et 5003 de la machine hôte (masterserver
), respectivement. Vous êtes libre de choisir d'autres ports en fonction de leur disponibilité et de vos préférences !
Le volume "nexus-work" est monté sur le chemin "/sonatype-work" à l'intérieur du conteneur. Cela permet de persister les données générées par Nexus, comme les artefacts et la configuration.
Placez-vous à la racine du dossier où vous avez créé votre fichier Docker Compose et exécutez la commande suivante :
docker compose up -d
Faites un docker ps
pour vérifier que le conteneur est en cours d'exécution et que les ports sont correctement mappés :
E:\workspace\dockerize\sonatype-nexus
λ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
bbe83eb3d218 sonatype/nexus3 "/opt/sonatype/nexus…" 6 days ago Up 5 days 0.0.0.0:5001->8081/tcp, :::5001->8081/tcp, 0.0.0.0:5002->8082/tcp, :::5002->8082/tcp, 0.0.0.0:5003->8083/tcp, :::5003->8083/tcp sonatype-nexus-nexus-1
Accédez à l'interface web de Nexus depuis votre navigateur via l'adresse prod.local:5001
.
Cliquez sur "Sign in" pour vous authentifier. Le compte administrateur est créé automatiquement. Le nom d'utilisateur est admin
et le mot de passe se trouve dans le fichier /nexus-data/admin.password
.
Pour l'afficher tapez cette commande dans masterserver
qui permet d'exécuter la commande cat à l'intérieur du conteneur nexus:
docker exec -i sonatype-nexus-nexus-1 cat /nexus-data/admin.password
Configurez docker pour accepter les registres non sécurisés
Par défaut, Docker n'accepte pas la communication avec des registres non sécurisés, c'est-à-dire via HTTP. Cependant, notre domaine local prod.local
utilise uniquement le protocole HTTP. Par conséquent, nous devons configurer Docker pour lui permettre de communiquer avec des registres non sécurisés.
Nous allons créer deux registres : le registre public, qui utilise le port 5002
de notre machine hôte, et le registre privé, qui utilise le port 5003
.
Vous allez donc ajouter l'adresse de ces deux registres à la liste des "insecure-registries" dans la configuration de Docker. Cela informe Docker qu'il peut se connecter à ces registres sans utiliser HTTPS.
La liste des registres non sécurisés peut être ajoutée sous format JSON dans le fichier /etc/docker/daemon.json
:
root@masterserver:/# cat /etc/docker/daemon.json
{
"insecure-registries" : ["http://prod.local:5002","http://prod.local:5003"]
}
Enregistrez le fichier et redémarrez le service docker
sudo systemctl daemon-reload
sudo systemctl restart docker
Petite information : pour vos propres serveurs et si vous avez un vrai nom de domaine enregistré, vous pouvez utiliser "Let's Encrypt" pour obtenir des certificat SSL/TLS gratuit !
Créez un docker hub proxy
Créez un stockage blob pour le registre public
Le stockage blob permet de stocker les images docker.
-
Cliquez sur l'icône de configuration (engrenage).
-
Accédez à "Blob Stores".
-
Créez un nouveau Blob Store de type "File".
-
Vous pouvez lui donner le nom de votre choix, mais un bon choix est "docker-hub".
-
Cliquez sur "Save".
Activez "Docker Bearer Token Relam"
Docker Bearer Token Realm
est une mesure de sécurité nécessaire pour gérer l'authentification des pulls anonymes.
-
Cliquez sur "Security > Realms".
-
Ajoutez le "Docker Bearer Token Realm".
-
Cliquez sur "Save".
Créez un registre docker hub proxy
- Cliquez sur "Repositories".
- Cliquez sur "Create Repository" et sélectionnez "docker (proxy)".
- Donnez-lui un nom, exemple "docker-hub"
- Cochez "HTTP" et attribuez-lui le port 8082 (c'est le port que nous avons choisi pour le registre public).
- Cochez "Allow anonymous docker pull".
- Sous Proxy > Remote Storage, saisissez cette URL : https://registry-1.docker.io
- Sous Docker Index, sélectionnez "Use Docker Hub".
- Sous Storage > Blob Store, choisissez le Blob Store que vous avez créé précédemment ("docker-hub").
- Cliquez sur "Create Repository".
Voilà, vous avez créé un registre docker hub de type proxy !
Maintenant, il est temps de tester tout cela. Vous allez donc tester un pull d'une image docker depuis le docker hub proxy :
Avec Docker Hub, si vous souhaitez récupérer une image du serveur nginx
, par exemple, vous pouvez le faire avec la commande docker pull nginx
. Maintenant, pour passer par le proxy Docker Hub que vous avez créé, lancez la commande docker pull prod.local:5002/nginx
dans votre terminal :
root@masterserver:/home/mossaabfr# docker pull prod.local:5002/nginx
Using default tag: latest
latest: Pulling from nginx
af107e978371: Pull complete
336ba1f05c3e: Pull complete
8c37d2ff6efa: Pull complete
51d6357098de: Pull complete
782f1ecce57d: Pull complete
5e99d351b073: Pull complete
7b73345df136: Pull complete
Digest: sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026
Status: Downloaded newer image for prod.local:5002/nginx:latest
prod.local:5002/nginx:latest
Petit rappel : le port 5002
est celui qui a été mappé avec le port 8082
sur lequel nous avons configuré le registre public.
Depuis le bouton "Browse", vous pouvez accéder à votre proxy Docker Hub, et vous constaterez que l'image nginx a bien été enregistrée par Nexus. La prochaine fois que vous effectuerez un pull depuis Nexus, il fournira directement l'image depuis le cache, sans avoir besoin de faire appel au Docker Hub public.
Créez un registre docker privé
Créez un stockage blob pour le registre privé
De la même manière que pour le registre public, vous savez maintenant comment faire. Créez un stockage blob, nommé par exemple "docker-private", que vous allez utiliser pour stocker les images privées.
Créez un registre privé (docker-hosted)
- Cliquez sur "Repositories".
- Cliquez sur "Create Repository" et sélectionnez "docker (hosted)".
- Donnez-lui un nom, exemple "docker-private"
- Cochez "HTTP" et attribuez-lui le port 8083 (c'est le port que nous avons choisi pour le registre privé).
- Sous Docker Index, sélectionnez "Use Docker Hub".
- Sous Storage > Blob Store, choisissez le Blob Store que vous avez créé précédemment ("docker-private").
- Cliquez sur "Create Repository".
Voilà, vous avez maintenant créé votre registre docker privé !
Pour tester notre registre Docker privé, nous allons créer une image de notre application Spring Boot et la pousser vers le registre privé.
Vous avez créé un proxy Docker Hub, profitez-en ! Modifiez votre Dockerfile pour effectuer le pull depuis le registre Nexus. Ajoutez son URL prod.local:5002/
devant le nom de l'image, de la même manière que pour la commande docker pull
FROM prod.local:5002/amazoncorretto:17-alpine
COPY target/*.jar /opt/app/devops-project-samples.jar
EXPOSE 7070
ENTRYPOINT ["java","-jar","/opt/app/devops-project-samples.jar"]
Quand vous construisez une image Docker et que vous voulez la pousser vers un registre privé, son nom doit être préfixé par l'URL de ce dernier.
Depuis la racine de votre projet, exécuter la commande suivante pour faire le build de l'image :
docker build -t prod.local:5003/devops-project-samples:latest .
Vérifiez que votre image a bien été créée :
PS E:\workspace\maven-projects\devops-project-samples> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
prod.local:5003/devops-project-samples latest 9b8294df572b 2 minutes ago 309MB
Pour effectuer un push de l'image, similaire à Docker Hub, vous devez vous authentifier. Vous pouvez utiliser le compte admin pour tester, mais en production, il est recommandé de créer des utilisateurs avec des rôles spécifiques plutôt que d'utiliser directement le compte admin.
Commencez alors par exécuter la commande docker login
pour vous connecter au registre privé :
PS E:\workspace\maven-projects\devops-project-samples> docker login prod.local:5003
Username: admin
Password:
Login Succeeded
Poussez l'image docker de votre application avec la commande docker push
:
PS E:\workspace\maven-projects\devops-project-samples> docker push prod.local:5003/devops-project-samples:latest
The push refers to repository [prod.local:5003/devops-project-samples]
8a716a5d01c6: Pushed
7e661cbcb912: Layer already exists
9fe9a137fd00: Layer already exists
latest: digest: sha256:2bcea3be4dc37856bfd0d90ad643c947bcf8c55c5ea3530ecdb12c75789cfea8 size: 953
Vérifiez dans "Browse" > "docker-private" que votre image a bien été enregistrée !