مقدمة
يتيح لك Docker Compose تعريف تطبيق متعدد الحاويات — تطبيق ويب، وقاعدة بياناته، وذاكرة تخزين مؤقت، ووكيل عكسي — في ملف تعريفي واحد، ثم تشغيل كل ذلك بأمر واحد. فبدلاً من تنفيذ أوامر docker run الطويلة يدويًا، تصف الحالة المطلوبة مرة واحدة ويتولى Compose مطابقتها نيابةً عنك.
في هذا الدرس ستنشر حزمة صغيرة لكن واقعية على خادم لينكس: تطبيق ويب، وقاعدة بيانات PostgreSQL، ووكيلًا عكسيًا Caddy يُنهي اتصال HTTPS تلقائيًا. وبنهاية الدرس سيكون لديك تطبيق يعمل ويمكن الوصول إليه عبر TLS على نطاقك الخاص.
سننشر على خادم Skyline Cloud الافتراضي. ولأن Skyline تشغّل بنية تحتية داخل المملكة العربية السعودية، تبقى بياناتك وبيانات عملائك خاضعة لولاية نظام حماية البيانات الشخصية (PDPL) والهيئة الوطنية للأمن السيبراني (NCA) والهيئة السعودية للبيانات والذكاء الاصطناعي (SDAIA) — وهو أمر مهم عند استضافة أعباء العمل لمنشآت في المملكة ودول الخليج. وإذا لم يكن لديك خادم بعد، أنشئ واحدًا في دقائق.
المتطلبات المسبقة
- خادم لينكس (Ubuntu 22.04/24.04 أو Debian 12) بعنوان IP عام. خادم افتراضي بمعالج 1–2 نواة وذاكرة 2 جيجابايت يكفي للبداية.
- مستخدم غير الجذر (non-root) يملك صلاحيات
sudo، مع إمكانية الوصول عبر SSH إلى الخادم. - اسم نطاق مع سجل A يشير إلى عنوان IP العام لخادمك. باستخدام نطاق .sa وإدارة DNS من Skyline، أنشئ سجلًا مثل
app.example.sa → 203.0.113.10.
الخطوة 1 — تثبيت محرك Docker وإضافة Compose
تأتي إصدارات Docker الحديثة بـ Compose كإضافة (docker compose وليس الأمر القديم docker-compose). يقوم سكربت التثبيت الرسمي بتثبيت المحرك والإضافة معًا:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
أضف مستخدمك إلى مجموعة docker حتى تتمكن من تشغيل Docker دون sudo، ثم أعد فتح جلستك:
sudo usermod -aG docker $USER
newgrp docker
تحقّق من المحرك وإضافة Compose:
docker --version
docker compose version
الخطوة 2 — تنظيم بنية المشروع
أنشئ مجلدًا لحزمتك وانتقل إليه:
mkdir -p ~/myapp && cd ~/myapp
سنحتفظ بثلاثة ملفات هنا: ملف Dockerfile لصورة التطبيق، وملف compose.yaml الذي يربط الخدمات معًا، وملف .env للأسرار والإعدادات.
الخطوة 3 — كتابة ملف Dockerfile للتطبيق
بالنسبة لتطبيق Node.js نموذجي، يبقي البناء متعدد المراحل الصورة النهائية خفيفة. عدّل الأوامر بما يناسب حزمتك الخاصة (Python أو Go أو PHP وغيرها):
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
الخطوة 4 — تعريف الأسرار في ملف .env
لا تضع بيانات الاعتماد بشكل ثابت داخل ملف compose أبدًا. ضعها في ملف .env الذي يقرأه Compose تلقائيًا:
POSTGRES_USER=appuser
POSTGRES_PASSWORD=change-me-to-a-strong-secret
POSTGRES_DB=appdb
APP_DOMAIN=app.example.sa
قيّد صلاحياته واستبعده من نظام إدارة الإصدارات:
chmod 600 .env
echo ".env" >> .gitignore
الخطوة 5 — كتابة ملف Compose
أنشئ ملف compose.yaml. يعرّف هذا الملف ثلاث خدمات، وشبكة خاصة، ووحدات تخزين مُسمّاة (volumes) حتى تبقى بياناتك وشهادات TLS سليمة بعد إعادة التشغيل:
services:
app:
build: .
restart: unless-stopped
environment:
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
depends_on:
db:
condition: service_healthy
expose:
- "3000"
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
depends_on:
- app
volumes:
db-data:
caddy-data:
caddy-config:
بعض التفاصيل الجديرة بالملاحظة:
- منفذ قاعدة البيانات غير منشور باستخدام
ports:؛ فهو متاح فقط على شبكة Compose الداخلية، وبالتالي لا يُعرَّض للإنترنت أبدًا. - استخدام
depends_onمعcondition: service_healthyيجعل التطبيق ينتظر حتى تقبل PostgreSQL الاتصالات فعليًا، وليس فقط حتى تبدأ حاويتها بالعمل. - يعيد
restart: unless-stoppedتشغيل خدماتك تلقائيًا بعد إعادة التشغيل أو حدوث عطل.
الخطوة 6 — إعداد الوكيل العكسي
أنشئ ملفًا باسم Caddyfile بجوار ملف compose. يحصل Caddy على شهادة Let's Encrypt ويجدّدها تلقائيًا، لتحصل على HTTPS دون أي إدارة يدوية للشهادات:
app.example.sa {
reverse_proxy app:3000
}
استبدل app.example.sa بنطاقك الحقيقي. يحوّل Caddy الاسم app إلى حاوية تطبيقك عبر الشبكة الداخلية ويمرّر الطلبات إلى المنفذ 3000.
الخطوة 7 — تشغيل الحزمة
ابنِ الصور وشغّل كل شيء في الخلفية:
docker compose up -d --build
تحقّق من أن جميع الخدمات سليمة:
docker compose ps
تابع السجلات لمراقبة بدء التطبيق وإصدار Caddy لشهادتك:
docker compose logs -f
افتح https://app.example.sa في المتصفح. سيكون Caddy قد جهّز بالفعل شهادة TLS صالحة.
الخطوة 8 — التشغيل والتحديث
أوامر يومية شائعة:
| المهمة | الأمر |
|---|---|
| عرض الخدمات العاملة | docker compose ps |
| متابعة سجلات خدمة واحدة | docker compose logs -f app |
| إعادة تشغيل خدمة واحدة | docker compose restart app |
| إيقاف الحزمة (مع حفظ البيانات) | docker compose down |
| سحب صور أساس أحدث | docker compose pull |
| إعادة البناء والنشر | docker compose up -d --build |
لإطلاق إصدار جديد من شيفرتك، اسحب تغييراتك ونفّذ docker compose up -d --build. يعيد Compose إنشاء الحاويات التي تغيّرت فقط ويترك قاعدة البيانات دون مساس، ما يمنحك توقفًا شبه معدوم للخدمات عديمة الحالة (stateless).
ولإزالة كل شيء بما في ذلك وحدات التخزين (وهذا يحذف بيانات قاعدة بياناتك)، نفّذ docker compose down -v — واستخدمه بحذر.
الخطوة 9 — النسخ الاحتياطي لبياناتك
تعيش بيانات تطبيقك في وحدة التخزين db-data. خذ نسخًا منتظمة واحفظها خارج الخادم. نسخة احتياطية بسيطة لـ PostgreSQL:
docker compose exec db pg_dump -U appuser appdb > backup-$(date +%F).sql
جدوِل ذلك باستخدام cron وادفع النسخ إلى التخزين الكائني (object storage) أو النسخ الاحتياطي السحابي من Skyline Cloud حتى لا يكلّفك عطل خادم واحد فقدان بياناتك.
الخاتمة
أصبح لديك الآن تطبيق متعدد الحاويات منشور باستخدام Docker Compose، تتقدّمه طبقة وكيل عكسي تفعّل HTTPS تلقائيًا، ويعمل على خادم تتحكم فيه بالكامل. ومن هنا يمكنك إضافة ذاكرة تخزين مؤقت Redis، أو توسيع الخدمات عديمة الحالة عبر docker compose up -d --scale app=3 خلف الوكيل، أو الانتقال إلى التنسيق (orchestration) — راجع دليلنا حول Kubernetes المُدار في المملكة العربية السعودية عندما يتجاوز نموك حدود خادم واحد.
وإذا كنت بحاجة أيضًا إلى صناديق بريد احترافية لنطاقك إلى جانب تطبيقك، فإن استضافة البريد الإلكتروني للأعمال من Skyline تُبقي بريدك داخل المملكة كذلك.
جاهز للنشر؟ أنشئ خادم Skyline Cloud وابدأ الآن.
Comments
0 total · 0 threads