Module 8 - Déploiement avancé et maintenance
Maîtrisez le déploiement professionnel de WikiJS en production avec haute disponibilité et maintenance optimale
Module 8Introduction au déploiement en production
Ce module final vous guide dans le déploiement professionnel de WikiJS, de l'architecture scalable au monitoring avancé. Apprenez à maintenir une plateforme robuste, performante et hautement disponible.
Objectifs de production
Étapes du déploiement professionnel
- Architecture : Choix de l'infrastructure adaptée
- Containerisation : Docker et orchestration
- Automatisation : CI/CD et déploiement continu
- Monitoring : Observabilité et alerting
- Sauvegardes : Stratégies de récupération
- Performance : Optimisation et mise à l'échelle
- Sécurité : Durcissement et conformité
- Maintenance : Opérations et support
Architectures de déploiement
Sélectionnez l'architecture qui correspond à vos besoins de charge, budget et exigences de disponibilité.
Avantages
- Configuration simple
- Coût minimal
- Maintenance aisée
- Démarrage rapide
Inconvénients
- Point unique de défaillance
- Scalabilité limitée
- Downtime pour maintenance
Avantages
- Haute disponibilité
- Distribution de charge
- Récupération automatique
- Scalabilité horizontale
Inconvénients
- Configuration complexe
- Coût plus élevé
- Synchronisation des sessions
Avantages
- Auto-scaling
- Services managés
- Résilience maximale
- Multi-régions
Inconvénients
- Complexité importante
- Vendor lock-in
- Coûts variables
# docker-compose.yml - Architecture load balanced
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/ssl/certs
depends_on:
- wikijs-1
- wikijs-2
restart: unless-stopped
wikijs-1:
image: requarks/wiki:2
environment:
DB_TYPE: postgres
DB_HOST: postgres
DB_PORT: 5432
DB_USER: wikijs
DB_PASS: ${DB_PASSWORD}
DB_NAME: wiki
depends_on:
- postgres
- redis
volumes:
- wikijs_data_1:/wiki/data
restart: unless-stopped
wikijs-2:
image: requarks/wiki:2
environment:
DB_TYPE: postgres
DB_HOST: postgres
DB_PORT: 5432
DB_USER: wikijs
DB_PASS: ${DB_PASSWORD}
DB_NAME: wiki
depends_on:
- postgres
- redis
volumes:
- wikijs_data_2:/wiki/data
restart: unless-stopped
postgres:
image: postgres:15
environment:
POSTGRES_DB: wiki
POSTGRES_USER: wikijs
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
restart: unless-stopped
backup:
image: postgres:15
environment:
PGPASSWORD: ${DB_PASSWORD}
volumes:
- ./backups:/backups
- postgres_data:/var/lib/postgresql/data
command: |
sh -c '
while true; do
pg_dump -h postgres -U wikijs wiki > /backups/backup-$(date +%Y%m%d-%H%M%S).sql
find /backups -name "backup-*.sql" -mtime +7 -delete
sleep 86400
done
'
depends_on:
- postgres
volumes:
postgres_data:
redis_data:
wikijs_data_1:
wikijs_data_2:
# nginx.conf
events {
worker_connections 1024;
}
http {
upstream wikijs_backend {
server wikijs-1:3000;
server wikijs-2:3000;
# Health checks
keepalive 32;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
# SSL Configuration
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/certs/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml+rss
image/svg+xml;
server {
listen 80;
server_name wiki.mondomaine.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name wiki.mondomaine.com;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Rate limiting
location /login {
limit_req zone=login burst=10 nodelay;
proxy_pass http://wikijs_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
limit_req zone=api burst=50 nodelay;
proxy_pass http://wikijs_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://wikijs_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Static assets caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
proxy_pass http://wikijs_backend;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
Containerisation avancée avec Docker
Créez des images Docker optimisées, sécurisées et prêtes pour la production avec des pratiques avancées de containerisation.
Dockerfile production-ready pour WikiJS
# Build stage
FROM node:18-alpine AS builder
# Métadonnées
LABEL maintainer="votre-email@domain.com"
LABEL description="WikiJS Production Build"
LABEL version="2.5.0"
# Arguments de build
ARG NODE_ENV=production
ARG BUILD_DATE
ARG VCS_REF
# Environnement de build
ENV NODE_ENV=$NODE_ENV
ENV NPM_CONFIG_CACHE=/tmp/.npm
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
# Sécurité : utilisateur non-root
RUN addgroup -g 1000 wikijs && \
adduser -D -s /bin/sh -u 1000 -G wikijs wikijs
# Répertoire de travail
WORKDIR /wiki
# Installation des dépendances système
RUN apk add --no-cache \
bash \
curl \
git \
python3 \
make \
g++ \
sqlite
# Copie des fichiers de dépendances
COPY package*.json ./
COPY --chown=wikijs:wikijs . .
# Installation des dépendances avec optimisations
RUN npm ci --only=production --ignore-scripts && \
npm cache clean --force && \
rm -rf /tmp/.npm
# Build de l'application
RUN npm run build
# Production stage
FROM node:18-alpine AS production
# Installation des dépendances runtime minimales
RUN apk add --no-cache \
bash \
curl \
sqlite \
&& rm -rf /var/cache/apk/*
# Utilisateur non-root
RUN addgroup -g 1000 wikijs && \
adduser -D -s /bin/sh -u 1000 -G wikijs wikijs
# Répertoire de travail
WORKDIR /wiki
# Copie des fichiers depuis le stage de build
COPY --from=builder --chown=wikijs:wikijs /wiki .
# Création des répertoires nécessaires
RUN mkdir -p /wiki/data /wiki/logs && \
chown -R wikijs:wikijs /wiki
# Configuration des volumes
VOLUME ["/wiki/data", "/wiki/logs"]
# Port exposé
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/healthz || exit 1
# Passage à l'utilisateur non-root
USER wikijs
# Point d'entrée
ENTRYPOINT ["/wiki/wiki", "start"]
Build multi-stage pour optimisation
Avantages du multi-stage build
- Taille réduite : Image finale sans outils de build
- Sécurité : Pas d'outils de développement en production
- Performance : Layers optimisés et cachés
- Reproductibilité : Build déterministe
# Stage 1: Dependencies
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production --ignore-scripts
# Stage 2: Build
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && \
npm prune --production
# Stage 3: Runtime
FROM node:18-alpine AS runtime
# Sécurité hardening
RUN apk add --no-cache dumb-init && \
addgroup -g 1001 -S nodejs && \
adduser -S wikijs -u 1001
# Copie sélective des artefacts
WORKDIR /app
COPY --from=dependencies --chown=wikijs:nodejs /app/node_modules ./node_modules
COPY --from=build --chown=wikijs:nodejs /app/dist ./dist
COPY --from=build --chown=wikijs:nodejs /app/public ./public
COPY --chown=wikijs:nodejs package*.json ./
USER wikijs
# Point d'entrée sécurisé
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]
Sécurisation des conteneurs
Bonnes pratiques de sécurité
- Utilisateur non-root : Toujours utiliser un utilisateur dédié
- Images de base : Préférer les images Alpine ou distroless
- Secrets : Ne jamais inclure de secrets dans l'image
- Scans : Scanner les vulnérabilités régulièrement
# .dockerignore
.git
.github
.gitignore
README.md
Dockerfile
.dockerignore
node_modules
npm-debug.log
coverage
.nyc_output
.env*
*.log
.DS_Store
Thumbs.db
# Fichiers sensibles
config/local*
logs/
data/
backups/
certificates/
*.key
*.pem
*.p12
# Fichiers de développement
.vscode
.idea
*.swp
*.swo
*~
# Tests
test/
tests/
spec/
cypress/
__tests__/
*.test.js
*.spec.js
# Documentation
docs/
*.md
#!/bin/bash
# security-scan.sh - Scanner les vulnérabilités
# Couleurs pour les logs
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
IMAGE_NAME="wikijs:latest"
echo -e "${GREEN}🔍 Scanning $IMAGE_NAME for vulnerabilities...${NC}"
# 1. Scan avec Trivy
echo -e "\n${YELLOW}📊 Running Trivy scan...${NC}"
if command -v trivy &> /dev/null; then
trivy image --severity HIGH,CRITICAL $IMAGE_NAME
else
echo -e "${RED}❌ Trivy not installed${NC}"
fi
# 2. Scan avec Docker Scout (si disponible)
echo -e "\n${YELLOW}🔍 Running Docker Scout...${NC}"
if command -v docker &> /dev/null && docker scout version &> /dev/null; then
docker scout cves $IMAGE_NAME
else
echo -e "${YELLOW}⚠️ Docker Scout not available${NC}"
fi
# 3. Vérification des bonnes pratiques
echo -e "\n${YELLOW}✅ Checking Docker best practices...${NC}"
# Vérifier si l'image utilise un utilisateur non-root
USER_CHECK=$(docker run --rm $IMAGE_NAME whoami 2>/dev/null)
if [ "$USER_CHECK" = "root" ]; then
echo -e "${RED}❌ Image running as root user${NC}"
else
echo -e "${GREEN}✅ Image running as non-root user: $USER_CHECK${NC}"
fi
# Vérifier la taille de l'image
IMAGE_SIZE=$(docker images $IMAGE_NAME --format "{{.Size}}")
echo -e "${GREEN}📊 Image size: $IMAGE_SIZE${NC}"
# Vérifier les ports exposés
EXPOSED_PORTS=$(docker inspect $IMAGE_NAME --format='{{range $p, $conf := .Config.ExposedPorts}}{{$p}} {{end}}')
echo -e "${GREEN}🔌 Exposed ports: $EXPOSED_PORTS${NC}"
echo -e "\n${GREEN}🎉 Security scan completed!${NC}"
Optimisation des performances
Métriques d'optimisation
- Taille image : <200MB (vs >800MB sans optimisation)
- Temps de build : <3min avec cache Docker layers
- Temps de démarrage : <10s pour un conteneur
- Utilisation mémoire : <512MB RAM par instance
#!/bin/bash
# optimize-image.sh
IMAGE_NAME="wikijs"
TAG="latest"
FULL_NAME="$IMAGE_NAME:$TAG"
echo "🔧 Optimizing Docker image: $FULL_NAME"
# 1. Build avec buildkit pour cache avancé
echo "📦 Building with BuildKit..."
DOCKER_BUILDKIT=1 docker build \
--target production \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from $FULL_NAME \
-t $FULL_NAME .
# 2. Analyser les layers
echo "📊 Analyzing layers..."
docker history $FULL_NAME --human
# 3. Optimiser avec dive si disponible
if command -v dive &> /dev/null; then
echo "🔍 Running dive analysis..."
dive $FULL_NAME --ci
fi
# 4. Compresser l'image
echo "🗜️ Compressing image..."
docker save $FULL_NAME | gzip > "${IMAGE_NAME}-${TAG}.tar.gz"
# 5. Statistiques finales
echo "📈 Final statistics:"
echo "Size: $(docker images $FULL_NAME --format '{{.Size}}')"
echo "Created: $(docker images $FULL_NAME --format '{{.CreatedAt}}')"
# 6. Test de démarrage rapide
echo "⚡ Testing startup time..."
time docker run --rm $FULL_NAME echo "Container started successfully"
echo "✅ Optimization complete!"
Votre parcours accompli
Découverte de WikiJS, concepts de base et comparaison avec les alternatives du marché.
Installation complète avec Node.js, bases de données et configuration initiale.
Intégration OAuth, LDAP, SAML et OpenID Connect pour l'authentification unique.
MFA, JWT, API Keys et authentification sans mot de passe pour une sécurité maximale.
Gestion avancée des utilisateurs, RBAC et politiques de sécurité entreprise.
Création de thèmes sur mesure, CSS avancé et branding professionnel.
Stratégies business, intégration paiements et création de revenus récurrents.
Architecture scalable, containerisation, CI/CD et monitoring en production.
Prochaines étapes
Mise en pratique
- Déployez votre première instance WikiJS
- Configurez le SSO avec votre fournisseur
- Créez votre thème personnalisé
- Implémentez votre stratégie de monétisation
Communauté et support
- Rejoignez la communauté WikiJS
- Partagez vos réalisations
- Contribuez aux projets open source
- Continuez à apprendre et innover