Exercices et projets
Objectifs
- Consolider vos connaissances Portainer
- Mettre en pratique les concepts appris
- Développer des compétences opérationnelles
Exercice 1 : Installation et configuration initiale
Objectif
Installer Portainer et effectuer la configuration de base.
Tâches
- Installez Portainer CE sur votre machine locale
- Créez un compte administrateur
- Explorez le dashboard
- Identifiez les ressources existantes (conteneurs, images, volumes)
Commandes de départ
# Créer le volume de données
docker volume create portainer_data
# Déployer Portainer
docker run -d \
-p 8000:8000 \
-p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Résultat attendu
- Portainer accessible sur https://localhost:9443
- Dashboard affichant les métriques de votre environnement
Exercice 2 : Gestion des conteneurs
Objectif
Maîtriser les opérations de base sur les conteneurs.
Tâches
-
Créez un conteneur nginx via l'interface
- Nom :
web-server - Image :
nginx:alpine - Port :
8080:80
- Nom :
-
Accédez aux logs du conteneur
-
Ouvrez une console et listez les fichiers de
/usr/share/nginx/html -
Surveillez les statistiques de ressources
-
Créez une copie du conteneur avec un port différent (8081)
Résultat attendu
- Deux conteneurs nginx fonctionnels
- Capacité à déboguer et monitorer
Exercice 3 : Déploiement d'une stack
Objectif
Déployer une application multi-conteneurs.
Tâches
-
Créez une nouvelle stack nommée
blog -
Utilisez le compose suivant :
version: "3.9"
services:
wordpress:
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress123
WORDPRESS_DB_NAME: wordpress
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress123
MYSQL_ROOT_PASSWORD: rootpassword
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
-
Déployez la stack
-
Vérifiez que les deux services sont actifs
-
Accédez à WordPress sur http://localhost:8000
Résultat attendu
- Stack WordPress fonctionnelle
- Volume persistant pour la base de données
Exercice 4 : Gestion des volumes
Objectif
Maîtriser la gestion du stockage.
Tâches
-
Créez un volume nommé
app-config -
Utilisez la fonction Browse pour :
- Créer un fichier
config.json - Y ajouter du contenu de configuration
- Créer un fichier
-
Créez un conteneur qui utilise ce volume :
services:
app:
image: alpine
command: sleep 3600
volumes:
- app-config:/config
volumes:
app-config:
external: true
- Vérifiez que le fichier est accessible dans le conteneur
Résultat attendu
- Volume avec fichier de configuration
- Données persistantes entre les redémarrages
Exercice 5 : Configuration réseau
Objectif
Configurer des réseaux personnalisés pour isoler les services.
Tâches
-
Créez deux réseaux :
frontend-net(172.20.0.0/16)backend-net(172.21.0.0/16)
-
Déployez une stack avec isolation :
version: "3.9"
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
networks:
- frontend-net
- backend-net
api:
image: nginx:alpine
networks:
- backend-net
database:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
networks:
- backend-net
networks:
frontend-net:
external: true
backend-net:
external: true
- Testez la connectivité :
- nginx peut atteindre api et database
- api peut atteindre database
- database ne peut pas atteindre l'extérieur
Résultat attendu
- Isolation réseau fonctionnelle
- Services connectés selon l'architecture
Exercice 6 : Gestion des utilisateurs
Objectif
Configurer le contrôle d'accès.
Tâches
-
Créez une équipe
developers -
Créez un utilisateur
dev1dans cette équipe -
Configurez l'accès à l'environnement :
developers: Operator (pas de suppression)
-
Testez en vous connectant avec
dev1:- Vérifiez les permissions disponibles
- Essayez de supprimer un conteneur (doit échouer)
Résultat attendu
- RBAC fonctionnel
- Permissions respectées
Projet 1 : Environnement de développement
Objectif
Créer un environnement de développement complet géré via Portainer.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Dev Environment │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Traefik │ │ App │ │ Postgres│ │ Redis │ │
│ │ :80 │──▶│ :3000 │──▶│ :5432 │ │ :6379 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │
│ ┌──────▼──────────────▼──────┐ │
│ │ adminer mailhog │ │
│ │ :8080 :8025 │ │
│ └────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Stack
version: "3.9"
services:
traefik:
image: traefik:v2.10
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)"
- "traefik.http.routers.dashboard.service=api@internal"
app:
image: node:18-alpine
command: sh -c "npm install && npm run dev"
working_dir: /app
volumes:
- ./app:/app
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.localhost`)"
- "traefik.http.services.app.loadbalancer.server.port=3000"
depends_on:
- postgres
- redis
postgres:
image: postgres:15
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: devpassword
POSTGRES_DB: app_dev
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
adminer:
image: adminer
labels:
- "traefik.enable=true"
- "traefik.http.routers.adminer.rule=Host(`db.localhost`)"
mailhog:
image: mailhog/mailhog
labels:
- "traefik.enable=true"
- "traefik.http.routers.mailhog.rule=Host(`mail.localhost`)"
- "traefik.http.services.mailhog.loadbalancer.server.port=8025"
volumes:
postgres_data:
Critères de réussite
- Tous les services accessibles via leurs sous-domaines
- Dashboard Traefik fonctionnel
- Base de données accessible via Adminer
- Emails interceptés par Mailhog
Projet 2 : Stack de monitoring
Objectif
Déployer une stack de monitoring complète.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Monitoring Stack │
├───────────────────────── ────────────────────────────────────────┤
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Prometheus│───▶│ Grafana │ │ Alertmgr │ │
│ │ :9090 │ │ :3000 │ │ :9093 │ │
│ └─────┬─────┘ └───────────┘ └───────────┘ │
│ │ │
│ ┌────┼────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │cAdvisor│ │ Node │ │ Pushgw │ │
│ │ :8080 │ │Exporter│ │ :9091 │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Stack
version: "3.9"
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana_data:/var/lib/grafana
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
alertmanager:
image: prom/alertmanager:latest
ports:
- "9093:9093"
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
volumes:
prometheus_data:
grafana_data:
Critères de réussite
- Prometheus collecte les métriques
- Grafana affiche les dashboards
- cAdvisor monitore les conteneurs
- Alertmanager configuré
Projet 3 : Environnement multi-équipes
Objectif
Configurer Portainer pour gérer plusieurs équipes avec isolation.
Tâches
-
Créer 3 équipes :
frontend-teambackend-teamdevops-team
-
Créer des utilisateurs pour chaque équipe
-
Créer des stacks dédiées :
frontend-app(accessible à frontend-team)backend-api(accessible à backend-team)infrastructure(accessible à devops-team)
-
Configurer les permissions :
- Chaque équipe n'accède qu'à ses ressources
- devops-team a un accès read-only à tout
Critères de réussite
- Isolation complète entre les équipes
- devops-team peut monitorer sans modifier
Quiz de validation
Questions
-
Quel port utilise Portainer pour HTTPS par défaut ?
- a) 8080
- b) 9000
- c) 9443
- d) 443
-
Comment accéder à la console d'un conteneur ?
- a) Via SSH
- b) Via l'onglet Console dans Portainer
- c) Via Telnet
- d) Ce n'est pas possible
-
Quelle est la différence entre Agent et Edge Agent ?
- a) Aucune
- b) Edge Agent initie la connexion sortante
- c) Agent est pour Kubernetes
- d) Edge Agent est plus rapide
-
Comment déployer une application multi-conteneurs ?
- a) Créer chaque conteneur un par un
- b) Utiliser une Stack
- c) Utiliser uniquement la CLI
- d) Ce n'est pas possible
-
Que permet la fonction Browse sur un volume ?
- a) Voir les logs
- b) Naviguer et modifier les fichiers
- c) Supprimer le volume
- d) Monter le volume
Réponses
- c) 9443 - Port HTTPS par défaut
- b) Via l'onglet Console - Exec dans le conteneur
- b) Edge Agent initie la connexion sortante - Pour les environnements derrière NAT
- b) Utiliser une Stack - Docker Compose dans Portainer
- b) Naviguer et modifier les fichiers - File browser intégré
Ressources supplémentaires
Documentation officielle
Communauté
Conclusion
Félicitations ! Vous avez terminé le cours Portainer.
Vous maîtrisez maintenant :
- Installation et configuration
- Gestion des conteneurs, images, volumes, réseaux
- Déploiement de stacks
- Gestion des utilisateurs et RBAC
- Bonnes pratiques de production
Portainer est un outil puissant qui simplifie considérablement la gestion des conteneurs. Continuez à pratiquer et explorer les fonctionnalités avancées !