دليل Docker Compose: إدارة تطبيقات متعددة الحاويات
تعريف وإدارة التطبيقات متعددة الحاويات باستخدام Docker Compose: تبعيات الخدمات، متغيرات البيئة، فحوصات الصحة، التوسع والنشر في بيئة الإنتاج. دليل شامل.
تثبيت Traefik، اكتشاف الخدمات التلقائي مع Docker provider، SSL من Let's Encrypt، تكوين middleware، dashboard، Kubernetes Ingress Controller وموازنة التحميل.
Traefik موجّه حافة وبروكسي عكسي حديث مصمم لمعماريات الخدمات المصغرة. بفضل تكامله العميق مع Docker وKubernetes، يكتشف الخدمات ويوجّهها تلقائياً.
الميزات الرئيسية لـ Traefik:
يوفر Traefik v3 أداءً أفضل وميزات جديدة مقارنة بـ v2. يركز هذا الدليل على Traefik v3.
# docker-compose.yml
services:
traefik:
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard (أغلق في الإنتاج)
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./config:/etc/traefik/config:ro
- traefik_certs:/certs
networks:
- traefik-net
labels:
- "traefik.enable=true"
# Dashboard
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hash"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
volumes:
traefik_certs:
networks:
traefik-net:
external: true
# traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
api:
dashboard: true
insecure: false # false في الإنتاج
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
http3:
advertisedPort: 443
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /certs/acme.json
httpChallenge:
entryPoint: web
# DNS challenge (لـ wildcard)
# dnsChallenge:
# provider: cloudflare
# resolvers:
# - "1.1.1.1:53"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-net
file:
directory: /etc/traefik/config
watch: true
log:
level: INFO
filePath: /var/log/traefik/traefik.log
accessLog:
filePath: /var/log/traefik/access.log
bufferingSize: 100
سجّل الخدمات تلقائياً في Traefik باستخدام علامات Docker:
# مثال تطبيق
services:
webapp:
image: nginx:alpine
networks:
- traefik-net
labels:
# تفعيل Traefik
- "traefik.enable=true"
# HTTP router
- "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.webapp.entrypoints=websecure"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
# منفذ الخدمة
- "traefik.http.services.webapp.loadbalancer.server.port=80"
# تطبيق middleware
- "traefik.http.routers.webapp.middlewares=security-headers,rate-limit"
networks:
traefik-net:
external: true
services:
api:
image: myapi:latest
networks:
- traefik-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=3000"
# فحص الصحة
- "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.api.loadbalancer.healthcheck.interval=30s"
frontend:
image: myfrontend:latest
networks:
- traefik-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`example.com`) || Host(`www.example.com`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
- "traefik.http.services.frontend.loadbalancer.server.port=80"
networks:
traefik-net:
external: true
# config/middlewares.yml
http:
middlewares:
# ترويسات الأمان
security-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
contentTypeNosniff: true
frameDeny: true
referrerPolicy: "strict-origin-when-cross-origin"
customResponseHeaders:
X-Powered-By: ""
Server: ""
# تحديد المعدل
rate-limit:
rateLimit:
average: 100
burst: 50
period: 1m
sourceCriterion:
ipStrategy:
depth: 1
# Basic auth
basic-auth:
basicAuth:
users:
- "admin:$apr1$xyz$hashedpassword"
removeHeader: true
# قائمة IP المسموح بها
ip-whitelist:
ipAllowList:
sourceRange:
- "192.168.1.0/24"
- "10.0.0.0/8"
# إعادة توجيه www إلى non-www
www-redirect:
redirectRegex:
regex: "^https://www\\.(.*)"
replacement: "https://${1}"
permanent: true
# تكوين dashboard آمن
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik-dashboard.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$xyz$$hash"
إنشاء كلمة مرور basic auth:
# إنشاء كلمة مرور مع htpasswd
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g
# أو مع openssl
echo "admin:$(openssl passwd -apr1 'كلمتك_السرية')" | sed -e 's/\$/\$\$/g'
# إضافة مستودع Traefik Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
# تثبيت Traefik
helm install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
--set deployment.replicas=2 \
--set ports.web.redirectTo.port=websecure \
--set ingressRoute.dashboard.enabled=true
# ingressroute.yml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: webapp-ingress
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: webapp-service
port: 80
middlewares:
- name: security-headers
tls:
certResolver: letsencrypt
# middleware.yml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: security-headers
namespace: default
spec:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
contentTypeNosniff: true
frameDeny: true
# traefik.yml - نقطة دخول TCP
entryPoints:
mysql:
address: ":3306"
redis:
address: ":6379"
# config/tcp.yml
tcp:
routers:
mysql-router:
entryPoints:
- mysql
rule: "HostSNI(`*`)"
service: mysql-service
services:
mysql-service:
loadBalancer:
servers:
- address: "mysql:3306"
# موازنة التحميل مع نسخ متعددة
services:
api:
image: myapi:latest
deploy:
replicas: 3
networks:
- traefik-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.services.api.loadbalancer.server.port=3000"
# Sticky sessions
- "traefik.http.services.api.loadbalancer.sticky.cookie=true"
- "traefik.http.services.api.loadbalancer.sticky.cookie.name=traefik_session"
- "traefik.http.services.api.loadbalancer.sticky.cookie.secure=true"
# فحص الصحة
- "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
- "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"
Traefik حل بروكسي عكسي وموازن تحميل قوي للبنى التحتية الحديثة للخدمات المصغرة. بتكامله العميق مع Docker وKubernetes وإدارة SSL التلقائية ونظام middleware الغني، إنه خيار موثوق لبيئات الإنتاج. يتيح تكوينه المبني على العلامات لكل خدمة تعريف قواعد التوجيه الخاصة بها.
يمتلك Traefik تكاملاً عميقاً مع Docker/Kubernetes ويكتشف الخدمات تلقائياً. يتطلب Nginx تكويناً ثابتاً وإعادة تحميل عند كل تغيير. يدعم Traefik التكوين الديناميكي ويتحدث بدون توقف. Nginx أكثر نضجاً وقد يؤدي أداءً أفضل تحت حركة مرور عالية جداً. يُفضَّل Traefik لبيئات الخدمات المصغرة، وNginx لخوادم الويب التقليدية.
لا تفتح أبداً dashboard في الوضع غير الآمن (المنفذ 8080) في الإنتاج. احمِ dashboard بـ HTTPS وbasic auth بإضافة علامات إلى حاوية Traefik. قيّد الوصول بعناوين IP محددة باستخدام middleware قائمة IP. بديلاً، يمكنك تعطيل dashboard بالكامل واستخدام Prometheus/Grafana للمراقبة.
عيّن مزود dnsChallenge تحت certificatesResolvers في traefik.yml. لـ Cloudflare، يلزم 'provider: cloudflare' ومتغير البيئة 'CF_DNS_API_TOKEN'. عرّف مفاتيح API ذات الصلة كمتغيرات بيئة لمزودي DNS الآخرين. DNS challenge أكثر أماناً من HTTP challenge ويتيح إصدار شهادات wildcard.
نعم، تُطبَّق middlewares بالترتيب الذي عُرِّفت به. الترتيب الموصى به عموماً: قائمة IP → تحديد المعدل → المصادقة → الترويسات. الترتيب الخاطئ قد يؤدي إلى سلوك غير متوقع. مثلاً، إذا وضعت middleware المصادقة قبل تحديد المعدل، ستُحسب الطلبات غير المصادق عليها أيضاً ضمن الحد.
استخدم rolling updates في Docker Swarm أو Kubernetes. يوجّه Traefik حركة المرور تلقائياً عندما تكون الحاويات الجديدة جاهزة. تكوين فحص الصحة أمر بالغ الأهمية: لا يُرسَل حركة مرور إلى الحاويات غير الصحية. عرّف endpoint فحص الصحة بالعلامة 'traefik.http.services.myapp.loadbalancer.healthcheck.path=/health'.
يحصل Traefik على شهادات منفصلة لكل نطاق. لنطاقات متعددة، استخدم 'Host(`a.com`) || Host(`b.com`)' في قاعدة الموجّه. تُصدَر شهادات منفصلة تلقائياً لكل نطاق. DNS challenge مطلوب لشهادات wildcard. قد يلزم التكوين اليدوي أو استخدام شهادات خارجية لشهادات SAN.
تعريف وإدارة التطبيقات متعددة الحاويات باستخدام Docker Compose: تبعيات الخدمات، متغيرات البيئة، فحوصات الصحة، التوسع والنشر في بيئة الإنتاج. دليل شامل.
إنشاء CI/CD pipelines مع GitHub Actions: بناء ونشر Docker، النشر على الخادم عبر SSH، أتمتة الاختبارات، إدارة الأسرار وتحسين سير العمل.
تثبيت Ansible، ملف الجرد، كتابة playbook، هيكل الأدوار، المتغيرات، vault المشفر، أوامر ad-hoc وأتمتة تكوين الخادم. دليل خطوة بخطوة.