مقدمة
ووردبريس هو نظام إدارة محتوى مجاني ومفتوح المصدر، مبني على قاعدة بيانات MySQL باستخدام لغة PHP. بفضل بنية الإضافات ونظام القوالب القابل للتوسيع، يُمكن إدارة معظمه عبر واجهة ويب. لهذا السبب، يُعد ووردبريس خيارًا شائعًا لإنشاء جميع أنواع المواقع الإلكترونية، من المدونات إلى صفحات المنتجات ومواقع التجارة الإلكترونية.
يتطلب تشغيل ووردبريس عادةً تثبيت حزمة LAMP (لينكس، أباتشي، ماي إس كيو إل، وبي إتش بي) أو LEMP (لينكس، إنجينكس، ماي إس كيو إل، وبي إتش بي)، وهو ما قد يستغرق وقتًا طويلاً. ولكن باستخدام أدوات مثل دوكر ودوكر كومبوز، يمكنك تبسيط عملية إعداد حزمة مخصصة وتثبيت ووردبريس. فبدلاً من تثبيت المكونات بشكل فردي يدويًا، يمكنك استخدام صور تُوحّد عناصر مثل المكتبات وملفات التكوين ومتغيرات البيئة. ثم تشغيل هذه الصور في حاويات، وهي عمليات معزولة تعمل على نظام تشغيل مشترك. بالإضافة إلى ذلك، باستخدام كومبوز، يمكنك تنسيق حاويات متعددة - على سبيل المثال، تطبيق وقاعدة بيانات - للتواصل فيما بينها.
في هذا الدرس، ستنشئ تثبيتًا متعدد الحاويات لـ WordPress. ستحتوي حاوياتك على قاعدة بيانات MySQL، وخادم الويب Nginx، وWordPress نفسه. كما ستؤمّن تثبيتك بالحصول على شهادات TLS/SSL من Let's Encrypt للنطاق الذي ترغب بربطه بموقعك. وأخيرًا، ستُعدّ مهمة مجدولة (cron job) لتجديد شهاداتك لضمان أمان نطاقك.
المتطلبات الأساسية
- خادم يعمل بنظام Ubuntu، مع مستخدم غير جذر يتمتع بامتيازات
سودوو جدار الحماية نشط. - تم تثبيت Docker على خادمك.
- يجب تثبيت Docker Compose على خادمك.
- اسم نطاق مسجل. سيستخدم هذا الشرح اسم نطاقك بالكامل.
- تم إعداد كلا سجلي نظام أسماء النطاقات التاليين لخادمك.
سجل يحتوي على your_domain يشير إلى عنوان IP العام لخادمك.
سجل يحتوي على www.your_domain يشير إلى عنوان IP العام لخادمك.
الخطوة 1 - تحديد تكوين خادم الويب
قبل تشغيل أي حاويات، تتمثل خطوتك الأولى في تحديد إعدادات خادم الويب Nginx. يتضمن ملف الإعدادات بعض أقسام الموقع الخاصة بـ WordPress، بالإضافة إلى قسم موقع لتوجيه طلبات التحقق من Let's Encrypt إلى عميل Certbot لتجديد الشهادة تلقائيًا.
أولاً، أنشئ مجلدًا خاصًا بمشروعك على ووردبريس. في هذا المثال، سيُسمى المجلد "ووردبريس". يمكنك تسمية هذا المجلد باسم آخر إذا أردت.
mkdir wordpressثم انتقل إلى الدليل:
cd wordpressبعد ذلك، أنشئ مجلدًا لملف التكوين:
mkdir nginx-confملف يحتوي على نانو أو افتح محرر النصوص المفضل لديك:
nano nginx-conf/nginx.confفي هذا الملف، أضف كتلة الخادم مع تعليمات لاسم الخادم وجذر المستند، وكتل الموقع لتوجيه طلبات عميل Certbot للشهادات ومعالجة PHP وطلبات الأصول الثابتة.
أضف الكود التالي إلى الملف. تأكد من استبدال your_domain باسم نطاقك:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
} يحتوي قسم الخادم لدينا على المعلومات التالية:
تعليمات:
يستمعيُخبر هذا الأمر خادم Nginx بالاستماع على المنفذ 80، مما يسمح لك باستخدام إضافة Webroot Certbot لطلبات الشهادات. لاحظ أنك لم تُدخل المنفذ 443 بعد، وستُحدّث إعداداتك لتضمين SSL بمجرد استلام شهاداتك بنجاح.اسم الخادميُحدد هذا الخيار اسم خادمك ونطاق الخادم الذي سيُستخدم لاستقبال الطلبات. تأكد من استبدال your_domain باسم نطاقك في هذا السطر.فِهرِسيُحدد هذا التوجيه الملفات التي تُستخدم كفهارس عند معالجة الطلبات المُرسلة إلى خادمك. لقد غيّرتَ ترتيب الأولوية الافتراضي هنا، ونقلتَ ملف index.php قبل ملف index.html، بحيث يُعطي Nginx الأولوية للملفات التي تحمل اسم index.php كلما أمكن ذلك.جذريُحدد هذا التوجيه اسم المجلد الرئيسي لطلبات الخادم. يتم إنشاء هذا المجلد، /var/www/html، كنقطة ربط أثناء عملية البناء بواسطة التوجيهات الموجودة في ملف Dockerfile الخاص بـ WordPress. كما تضمن هذه التوجيهات تثبيت ملفات إصدار WordPress على هذا المجلد.
مواقع الكتل:
الموقع ~ /.well-known/acme-challengeتتولى هذه الوحدة معالجة الطلبات المُرسلة إلى مجلد .well-known، حيث يقوم Certbot بإنشاء ملف مؤقت للتحقق من أن نظام أسماء النطاقات (DNS) الخاص بنطاقك يُشير إلى خادمك. باستخدام هذا الإعداد، يمكنك استخدام إضافة Webroot Certbot للحصول على شهادة لنطاقك.موقعفي هذا الجزء من التعليمات البرمجية، تُستخدم توجيهة try_files للتحقق من وجود ملفات تطابق عنوان URI المطلوب. ولكن بدلاً من إرجاع حالة 404 (غير موجود) كما هو الوضع الافتراضي، يتم تمرير التحكم إلى ملف index.php الخاص بـ WordPress مع وسائط الطلب.الموقع ~ \.php$: يتولى هذا الجزء معالجة طلبات PHP وتوجيهها إلى حاوية ووردبريس الخاصة بك. بما أن صورة ووردبريس Docker الخاصة بك مبنية على صورة php:fpm، فستُضمّن أيضًا خيارات تكوين خاصة ببروتوكول FastCGI في هذا الجزء. يتطلب Nginx معالج PHP منفصلًا لطلبات PHP. في هذه الحالة، ستتم معالجة هذه الطلبات بواسطة معالج php-fpm المُضمّن في صورة php:fpm. بالإضافة إلى ذلك، يحتوي هذا الجزء على توجيهات ومتغيرات وخيارات خاصة بـ FastCGI تُهيئ طلبات التوجيه إلى تطبيق ووردبريس المُشغّل في حاوية ووردبريس، وتُحدد قائمة تفضيلات لعنوان URI للطلب المُحلل، وتُحلل عنوان URI للطلب.الموقع ~ /\.htهذا الجزء من الكود يتعامل مع ملفات .htaccess لأن Nginx لا يقوم بعرضها. يضمن توجيه deny_all عدم عرض ملفات .htaccess للمستخدمين مطلقًا.location = /favicon.ico, location = /robots.txtتضمن هذه الكتل عدم تسجيل الطلبات الخاصة بـ /favicon.ico و /robots.txt.location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: تعمل هذه الكتلة على تعطيل تسجيل طلبات الأصول الثابتة وتضمن أن تكون هذه الأصول قابلة للتخزين المؤقت بدرجة عالية، حيث أن صيانتها عادة ما تكون مكلفة.
احفظ الملف وأغلقه بعد الانتهاء من التحرير. إذا كنت تستخدم محرر النصوص nano، فافعل ذلك بالضغط على CTRL+X، ثم Y، ثم ENTER. بعد تهيئة Nginx، يمكنك الانتقال إلى إنشاء متغيرات البيئة لتمريرها إلى تطبيقك وحاويات قاعدة البيانات أثناء التشغيل.
الخطوة 2 - تحديد متغيرات البيئة
يحتاج تطبيق ووردبريس الخاص بك وقاعدة بياناته وحاوياته إلى الوصول إلى بعض متغيرات البيئة أثناء التشغيل للحفاظ على بيانات التطبيق متاحة له. تحتوي هذه المتغيرات على معلومات حساسة وغير حساسة: القيم الحساسة لكلمة مرور جذر MySQL واسم مستخدم وكلمة مرور قاعدة بيانات التطبيق، والقيم غير الحساسة لاسم قاعدة بيانات التطبيق ومضيفها. بدلاً من تعيين جميع هذه القيم في ملف Docker Compose - الملف الرئيسي الذي يحتوي على معلومات حول كيفية تشغيل الحاويات - عيّن القيم الحساسة في ملف env. وقيّد تداوله. هذا يمنع نسخ هذه القيم عبر مستودعات مشروعك وظهورها للعامة.
في الدليل الرئيسي لمشروعك، ~/wordpress، افتح ملفًا باسم .env:
nano .envتتضمن القيم السرية التي تحددها في هذا الملف كلمة مرور لمستخدم MySQL الرئيسي، واسم مستخدم وكلمة مرور سيستخدمهما WordPress للوصول إلى قاعدة البيانات. أضف أسماء المتغيرات وقيمها التالية إلى الملف. تذكر أن تُدخل قيمك الخاصة هنا لكل متغير:
MYSQL_ROOT_PASSWORD=your_root_password MYSQL_USER=your_wordpress_database_user MYSQL_PASSWORD=your_wordpress_database_password
أضف كلمة مرور لحساب مدير النظام الرئيسي، بالإضافة إلى اسم المستخدم وكلمة المرور اللذين ترغب بهما لقاعدة بيانات تطبيقك. احفظ الملف وأغلقه عند الانتهاء من التحرير.
بما أن ملف env الخاص بك يحتوي على معلومات حساسة، فمن المهم التأكد من تضمينه في ملفي .gitignore و .dockerignore الخاصين بمشروعك. هذا يُخبر Git و Docker بالملفات التي لا يجب نسخها إلى مستودعات Git وصور Docker، على التوالي.
باستخدام git init:
git initثم قم بإنشاء ملف .gitignore وافتحه:
nano .gitignoreأضف متغير البيئة إلى الملف:
.envاحفظ الملف وأغلقه عند الانتهاء من التحرير.
وبالمثل، فإن إضافة .env إلى ملف .dockerignore هو إجراء احترازي جيد حتى لا يتم تضمينه في حاوياتك عند استخدام هذا الدليل كسياق بناء.
افتح الملف:
nano .dockerignoreأضف متغير البيئة إلى الملف:
.env
أسفل هذا، يمكنك إضافة الملفات والمجلدات المتعلقة بتطوير تطبيقك بشكل اختياري:
.env
.git
docker-compose.yml
.dockerignoreاحفظ الملف وأغلقه عند الانتهاء.
بعد وضع معلوماتك الحساسة في مكانها، يمكنك الآن الانتقال إلى تحديد خدماتك في ملف docker-compose.yml.
الخطوة 3 - تعريف الخدمات باستخدام Docker Compose
سيحتوي ملف docker-compose.yml على تعريفات الخدمات الخاصة بإعدادك. الخدمة في Compose هي حاوية قيد التشغيل، وتحدد تعريفات الخدمات معلومات حول كيفية تشغيل كل حاوية.
باستخدام Compose، يمكنك تعريف خدمات مختلفة لتشغيل تطبيقات متعددة الحاويات، حيث يتيح لك Compose ربط هذه الخدمات معًا عبر شبكات ووحدات تخزين مشتركة. سيكون هذا مفيدًا لإعدادك الحالي، إذ ستنشئ حاويات منفصلة لقاعدة البيانات، وتطبيق WordPress، وخادم الويب. كما ستنشئ حاوية لتشغيل عميل Certbot للحصول على الشهادات اللازمة لخادم الويب.
للبدء، قم بإنشاء ملف docker-compose.yml وافتحه:
nano docker-compose.ymlأضف الكود التالي لتحديد إصدار ملف Compose وخدمة قاعدة البيانات:
version: '3' services: db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network
يتضمن تعريف خدمة قاعدة البيانات الخيارات التالية:
صورةيُحدد هذا الأمر لـ Compose الصورة التي يجب سحبها لإنشاء الحاوية. يتم تثبيت صورة mysql:8.0 هنا لتجنب التعارضات المستقبلية مع استمرار تحديث صورة mysql:latest. لمزيد من المعلومات حول تثبيت الإصدارات وتجنب تعارضات التبعيات، يُرجى مراجعة وثائق Docker حول أفضل ممارسات Dockerfile.اسم الحاوية: يحدد اسم الحاوية.إعادة تشغيلتحدد هذه السياسة ما إذا كان سيتم إعادة تشغيل الحاوية أم لا. القيمة الافتراضية هي لا، ولكنك قمت بضبط الحاوية لإعادة التشغيل ما لم يتم إيقافها يدويًا.ملف البيئةيُخبر هذا الخيار Compose أنك تريد إضافة متغيرات البيئة من ملف يُسمى .env موجود في سياق البناء الخاص بك. في هذه الحالة، سياق البناء هو دليلك الحالي.بيئةيُتيح لك هذا الخيار إضافة متغيرات بيئية إضافية تتجاوز تلك المُعرّفة في ملف .env. يمكنك تعيين قيمة المتغير MYSQL_DATABASE إلى wordpress لتحديد اسم قاعدة بيانات تطبيقك. ولأن هذه المعلومة غير حساسة، يمكنك إضافتها مباشرةً إلى ملف docker-compose.yml.مجلداتهنا، تقوم بتثبيت وحدة تخزين باسم dbdata في المجلد /var/lib/mysql داخل الحاوية. هذا هو دليل البيانات القياسي لـ MySQL في معظم التوزيعات.يأمريُحدد هذا الخيار أمرًا لتجاوز أمر CMD الافتراضي للصورة. في هذه الحالة، تُضيف خيارًا إلى أمر صورة Docker القياسي mysqld الذي يُشغّل خادم MySQL على الحاوية. يُعيّن هذا الخيار، –default-authentication-plugin=mysql_native_password، متغير النظام –default-authentication-plugin إلى mysql_native_password، ويُحدد آلية المصادقة التي ستُستخدم في طلبات المصادقة الجديدة للخادم. بما أن PHP، وبالتالي صورة WordPress الخاصة بك، لا تدعم مصادقة MySQL الافتراضية الجديدة، فستحتاج إلى ضبط هذا الخيار لمصادقة مستخدم قاعدة بيانات تطبيقك.- الشبكات: يحدد هذا أن خدمة التطبيق الخاصة بك ستنضم إلى شبكة التطبيق التي تحددها في أسفل الملف.
ثم، أسفل تعريف خدمة قاعدة البيانات، أضف تعريف خدمة تطبيق ووردبريس الخاص بك:
... wordpress: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - wordpress:/var/www/html networks: - app-network
في تعريف الخدمة هذا، تقوم بتسمية الحاوية وتحديد سياسة إعادة التشغيل، تمامًا كما فعلت مع خدمة قاعدة البيانات. كما تضيف بعض الخيارات المحددة لهذه الحاوية:
يعتمد علىيضمن هذا الخيار تشغيل حاوياتك وفقًا لترتيب التبعية، حيث تبدأ حاوية ووردبريس بعد حاوية قاعدة البيانات. يعتمد تطبيق ووردبريس الخاص بك على وجود قاعدة البيانات ومستخدم التطبيق، لذا فإن تحديد ترتيب التبعية هذا يضمن بدء تشغيل تطبيقك بشكل صحيح.صورةفي هذا الإعداد، ستستخدم صورة WordPress 5.1.1-fpm-alpine. كما هو موضح في الخطوة 1، يضمن استخدام هذه الصورة أن تطبيقك يحتوي على معالج php-fpm الذي يحتاجه Nginx لمعالجة PHP. هذه الصورة أيضًا من نوع Alpine، مشتقة من مشروع Alpine Linux، مما يُساعد على تقليل الحجم الإجمالي للصورة. لمزيد من المعلومات حول مزايا وعيوب استخدام صور Alpine، وما إذا كانت مناسبة لتطبيقك، راجع المناقشة الكاملة في قسم "أنواع الصور" على صفحة صورة WordPress في Docker Hub.ملف البيئة: مرة أخرى، أنت تحدد أنك تريد استخراج القيم من ملف .env الخاص بك، حيث قمت بتحديد اسم مستخدم وكلمة مرور قاعدة بيانات التطبيق الخاص بك.بيئةهنا، تستخدم القيم التي حددتها في ملف .env، ولكنك تُسندها إلى أسماء المتغيرات التي تتوقعها صورة ووردبريس: WORDPRESS_DB_USER و WORDPRESS_DB_PASSWORD. كما تُحدد WORDPRESS_DB_HOST، وهو خادم MySQL الذي يعمل على حاوية قاعدة البيانات التي يمكن الوصول إليها عبر منفذ MySQL الافتراضي، 3306. سيكون WORDPRESS_DB_NAME هو نفس القيمة التي حددتها لـ MYSQL_DATABASE في تعريف خدمة MySQL: wordpress.مجلداتأنت تقوم بتثبيت وحدة تخزين باسم wordpress على نقطة التثبيت /var/www/html التي أنشأتها صورة WordPress. يتيح لك استخدام وحدة تخزين مُسماة بهذه الطريقة مشاركة كود تطبيقك مع حاويات أخرى.شبكةأنت تقوم أيضًا بإضافة حاوية ووردبريس إلى شبكة التطبيقات.
ثم، ضمن تعريف خدمة تطبيق ووردبريس، أضف التعريف التالي لخدمة خادم الويب Nginx الخاص بك:
... webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network
هنا، تقوم بتسمية الحاوية الخاصة بك وتجعلها تابعة لحاوية ووردبريس بالترتيب الأساسي. كما تستخدم صورة Alpine - صورة Nginx 1.15.12-alpine.
يتضمن تعريف هذه الخدمة أيضًا الخيارات التالية:
المنافذ: هذا يكشف المنفذ 80 لتمكين خيارات التكوين التي حددتها في ملف nginx.conf في الخطوة 1.مجلداتهنا، تقوم بتحديد مجموعة من وحدات التخزين المسماة ونقاط التحميل:- wordpress:/var/www/html: سيضع هذا الكود تطبيق WordPress الخاص بك في مجلد /var/www/html، وهو الدليل الذي قمت بتعيينه كجذر في كتلة خادم Nginx الخاصة بك.
./nginx-conf:/etc/nginx/conf.dسيؤدي هذا إلى ربط مجلد تكوين Nginx على المضيف بالدليل المقابل في الحاوية، مما يضمن أن أي تغييرات تقوم بها على الملفات الموجودة على المضيف تنعكس على المضيف.certbot-etc:/etc/letsencryptسيؤدي هذا إلى تثبيت شهادات ومفاتيح Let's Encrypt الخاصة بنطاقك في الدليل المناسب على الحاوية.
لقد أضفت هذا الحاوية أيضًا إلى شبكة التطبيقات.
أخيرًا، ضمن تعريف خادم الويب الخاص بك، أضف تعريف الخدمة النهائي لخدمة certbot. تأكد من استبدال عنوان البريد الإلكتروني واسم النطاق المذكورين هنا بمعلوماتك الخاصة.
certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
يُخبر هذا التعريف Compose بسحب صورة certbot/certbot من Docker Hub. كما يستخدم وحدات تخزين مُسماة لمشاركة الموارد مع حاوية Nginx، بما في ذلك شهادات ومفاتيح النطاق في certbot-etc وشفرة التطبيق في WordPress. مرة أخرى، استخدمتَ dependent_on لتحديد أنه يجب بدء تشغيل حاوية certbot بعد بدء تشغيل خدمة خادم الويب. أضفتَ أيضًا خيار أمر يُحدد أمرًا فرعيًا ليتم تشغيله مع أمر certbot الافتراضي للحاوية. يحصل الأمر الفرعي certonly على الشهادة بالخيارات التالية:
--webrootيُخبر هذا الأمر Certbot باستخدام إضافة webroot لوضع الملفات في مجلد webroot لأغراض المصادقة. تعتمد الإضافة على طريقة المصادقة HTTP-01، التي تستخدم طلب HTTP لإثبات قدرة Certbot على الوصول إلى موارد من خادم يستجيب لاسم نطاق مُحدد.--مسار جذر الويب: يحدد هذا المسار إلى دليل جذر الموقع الإلكتروني.--بريد إلكتروني: البريد الإلكتروني الذي ترغب في استخدامه للتسجيل والاستعادة.--الشروط والأحكامهذا يشير إلى موافقتك على الاتفاقية العامة لشركة ACME.--no-eff-emailهذا يُخبر برنامج Certbot بأنك لا ترغب في مشاركة بريدك الإلكتروني مع مؤسسة Electronic Frontier Foundation (EFF). يمكنك حذف هذا الخيار إذا رغبت.--التجهيزيُخبر هذا الخيار Certbot أنك ترغب في استخدام بيئة Let's Encrypt التجريبية للحصول على شهادات اختبارية. يتيح لك هذا الخيار اختبار إعداداتك وتجنب أي قيود محتملة على طلبات النطاق. لمزيد من المعلومات حول هذه القيود، يُرجى مراجعة وثائق حدود معدل Let's Encrypt.-ديتيح لك هذا تحديد أسماء النطاقات التي ترغب في تطبيقها على طلبك. في هذه الحالة، أدخلتَ your_domain و www.your_domain. تأكد من استبدالها بنطاقك.
أسفل تعريف خدمة certbot، أضف تعريفات الشبكة ووحدة التخزين الخاصة بك:
... volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
يُحدد مفتاح وحدة التخزين الرئيسية وحدات التخزين certbot-etc و wordpress و dbdata. عند إنشاء Docker لوحدات التخزين، تُخزَّن محتوياتها في دليل على نظام ملفات المضيف، /var/lib/docker/volumes/، والذي يُديره Docker. ثم تُربط محتويات كل وحدة تخزين من هذا الدليل بأي حاوية تستخدمها. وهذا يسمح بمشاركة التعليمات البرمجية والبيانات بين الحاويات.
تُمكّن شبكة الجسر المُعرّفة من قِبل المستخدم تطبيقاتك من التواصل بين حاوياتك لأنها موجودة على نفس المضيف الذي يعمل عليه برنامج Docker. يُبسّط هذا الأمر حركة البيانات والتواصل داخل التطبيق، حيث يفتح جميع المنافذ بين الحاويات على نفس شبكة الجسر، دون كشف أي منفذ للعالم الخارجي. بالتالي، يُمكن لحاويات قاعدة البيانات، ووردبريس، وخادم الويب التواصل فيما بينها، ولا تحتاج إلا إلى كشف المنفذ 80 للوصول إلى واجهة المستخدم للتطبيق.
يظهر ملف docker-compose.yml بالكامل أدناه:
version: '3' services: db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network wordpress: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - wordpress:/var/www/html networks: - app-network webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
احفظ الملف وأغلقه عند الانتهاء من التحرير. بعد إعداد تعريفات الخدمة، أنت الآن جاهز لتشغيل الحاويات واختبار طلبات الشهادات.
الخطوة 4 - الحصول على شهادات وبيانات اعتماد SSL
ابدأ تشغيل حاوياتك باستخدام الأمر docker-compose up، الذي سيقوم بإنشاء وتشغيل حاوياتك بالترتيب الذي تحدده. بإضافة الخيار -d، سيقوم الأمر بتشغيل حاويات قاعدة البيانات، ووردبريس، وخادم الويب في الخلفية.
docker-compose up -dتؤكد المخرجات التالية أنه تم إنشاء خدمتك:
Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... doneتحقق من حالة خدماتك باستخدام docker-compose ps:
docker-compose psبمجرد اكتمال العملية، ستكون خدمات قاعدة البيانات ووردبريس وخادم الويب جاهزة للعمل، وسيخرج حاوية certbot برسالة حالة 0:
Output
Name Command State Ports
-------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcpأي شيء آخر غير المذكور أعلاه في عمود الحالة لخدمات قاعدة البيانات أو ووردبريس أو خادم الويب، أو حالة خروج غير 0 لحاوية certbot يعني أنك قد تحتاج إلى التحقق من سجلات الخدمة باستخدام أمر docker-compose logs:
docker-compose logs service_nameيمكنك الآن التحقق من تثبيت شهاداتك في حاوية خادم الويب باستخدام الأمر docker-compose exec:
docker-compose exec webserver ls -la /etc/letsencrypt/liveعندما تنجح طلبات الشهادات الخاصة بك، يكون ناتج الكود كما يلي:
Output
total 16
drwx------ 3 root root 4096 May 10 15:45 .
drwxr-xr-x 9 root root 4096 May 10 15:45 ..
-rw-r--r-- 1 root root 740 May 10 15:45 README
drwxr-xr-x 2 root root 4096 May 10 15:45 your_domainالآن بعد أن عرفت أن طلبك ناجح، يمكنك تعديل تعريف خدمة certbot لإزالة --staging.
افتح ملف docker-compose.yml:
nano docker-compose.ymlابحث عن جزء الملف الذي يحتوي على تعريف خدمة Certbot، واستبدل الخيار –staging في أمر Certbot بالخيار –force-renewal، الذي يُخبر Certbot برغبتك في طلب شهادة جديدة بنفس النطاقات. يتم تحديث الشهادة أسفل تعريف خدمة Certbot باستخدام المتغير التالي:
...
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...يمكنك الآن تشغيل docker-compose لإعادة إنشاء حاوية certbot. أضف أيضًا الخيار --no-deps لإخبار Compose بأنه يمكنه تخطي بدء تشغيل خدمة خادم الويب، لأنها قيد التشغيل بالفعل.
docker-compose up --force-recreate --no-deps certbotتشير المخرجات التالية إلى أن طلب الشهادة الخاص بك قد تم بنجاح:
Output Recreating certbot ... done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for your_domain certbot | http-01 challenge for www.your_domain certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification... certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/your_domain/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/your_domain/privkey.pem certbot | Your cert will expire on 2019-08-08. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew *all* of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0
بعد حصولك على شهاداتك، يمكنك تعديل إعدادات Nginx لتضمين SSL.
الخطوة 5 - تغيير إعدادات خادم الويب وتعريف الخدمة
يتطلب تفعيل بروتوكول SSL في إعدادات Nginx إضافة إعادة توجيه من HTTP إلى HTTPS، وتحديد موقع شهادة SSL ومفتاحها، وإضافة معلمات الأمان والعناوين. بما أنك ترغب في إعادة بناء خدمة خادم الويب لتضمين هذه الإضافات، يمكنك إيقافها الآن.
docker-compose stop webserverقبل تعديل ملف التكوين، احصل على معلمات أمان Nginx الموصى بها من Certbot باستخدام curl:
curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.confيقوم هذا الأمر بحفظ هذه المعلمات في ملف يسمى options-ssl-nginx.conf موجود في دليل nginx-conf.
بعد ذلك، احذف ملف تكوين Nginx الذي أنشأته سابقًا:
rm nginx-conf/nginx.confأنشئ وافتح نسخة أخرى من الملف:
nano nginx-conf/nginx.confأضف الكود التالي إلى الملف لإعادة توجيه HTTP إلى HTTPS، وأضف بيانات الاعتماد والبروتوكولات وعناوين أمان SSL. لا تنسَ استبدال your_domain بنطاقك.
server { listen 80; listen [::]:80; server_name your_domain www.your_domain; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { rewrite ^ https://$host$request_uri? permanent; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name your_domain www.your_domain; index index.php index.html index.htm; root /var/www/html; server_tokens off; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; include /etc/nginx/conf.d/options-ssl-nginx.conf; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # enable strict transport security only if you understand the implications location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location ~ /\.ht { deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } }
يُحدد قسم خادم HTTP مسار الموقع الرئيسي لطلبات تجديد شهادة Certbot إلى الدليل .well-known/acme-challenge. كما يتضمن توجيه إعادة كتابة يُعيد توجيه طلبات HTTP إلى الدليل الرئيسي إلى HTTPS.
يُمكّن قسم خادم HTTPS بروتوكولي SSL وHTTP2. لمعرفة المزيد حول كيفية محاكاة HTTP/2 في بروتوكولات HTTP والفوائد التي يُمكن أن يُحققها لأداء الموقع الإلكتروني، يُرجى قراءة مقدمة "كيفية إعداد Nginx مع دعم HTTP/2 على Ubuntu 18.04".
يحتوي هذا القسم أيضًا على شهادة SSL الخاصة بك ومواقع المفاتيح بالإضافة إلى معلمات الأمان الموصى بها من Certbot التي قمت بتخزينها في nginx-conf/options-ssl-nginx.conf.
بالإضافة إلى ذلك، تتضمن هذه النسخة بعض رؤوس الأمان التي تُمكّنك من الحصول على تصنيف ممتاز (A) في مواقع اختبار الخوادم مثل SSL Labs وSecurity Headers. تشمل هذه الرؤوس X-Frame-Options وX-Content-Type-Options وReferrer Policy وContent-Security-Policy وX-XSS-Protection. كما تم شرح رأس HTTP Strict Transport Security (HSTS) - لا تقم بتفعيله إلا إذا كنت تفهم مفاهيمه وقمت بتقييم وظيفة "التحميل المسبق" الخاصة به.
توجد توجيهات الجذر والدليل الخاصة بك أيضًا في هذا القسم، وكذلك بقية أقسام الموقع الخاصة بـ WordPress التي تمت مناقشتها في الخطوة 1. بمجرد الانتهاء من التحرير، احفظ الملف وأغلقه.
قبل إعادة إنشاء خدمة خادم الويب، تحتاج إلى إضافة تعيين منفذ 443 إلى تعريف خدمة خادم الويب الخاص بك.
افتح ملف docker-compose.yml الخاص بك:
nano docker-compose.ymlفي تعريف خدمة خادم الويب، أضف تعيين المنفذ التالي:
...
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-networkإليكم ملف docker-compose.yml كاملاً بعد التعديل:
version: '3' services: db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network wordpress: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - wordpress:/var/www/html networks: - app-network webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
احفظ الملف وأغلقه عند الانتهاء من التحرير.
أعد إنشاء خدمة خادم الويب:
docker-compose up -d --force-recreate --no-deps webserverتحقق من خدماتك باستخدام docker-compose ps:
docker-compose psيجب أن تُظهر المخرجات أن خدمات قاعدة البيانات، ووردبريس، وخادم الويب تعمل:
Output
Name Command State Ports
----------------------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcpبعد تشغيل الحاويات، يمكنك إكمال تثبيت ووردبريس الخاص بك عبر واجهة الويب.
الخطوة 6 - أكمل التثبيت عبر واجهة الويب
أثناء تشغيل حاوياتك، أكمل التثبيت عبر واجهة الويب الخاصة بـ WordPress.
في متصفح الويب الخاص بك، انتقل إلى نطاق الخادم الخاص بك. لا تنسَ استبدال your_domain باسم نطاقك:
https://your_domainاختر اللغة التي تريد استخدامها:
بعد النقر على "متابعة"، ستنتقل إلى صفحة الإعداد الرئيسية، حيث ستحتاج إلى اختيار اسم لموقعك واسم مستخدم. يُنصح باختيار اسم مستخدم يسهل تذكره (بدلاً من "admin") وكلمة مرور قوية. يمكنك استخدام كلمة المرور التي يُنشئها ووردبريس تلقائيًا أو إنشاء كلمة مرور خاصة بك. أخيرًا، ستحتاج إلى إدخال بريدك الإلكتروني وتحديد ما إذا كنت ترغب في منع محركات البحث من فهرسة موقعك.
بالنقر على "تثبيت ووردبريس" أسفل الصفحة، سيتم توجيهك إلى نافذة تسجيل الدخول:
بمجرد تسجيل الدخول، ستتمكن من الوصول إلى لوحة تحكم إدارة ووردبريس:
بمجرد الانتهاء من تثبيت ووردبريس، يمكنك اتخاذ خطوات لضمان تجديد شهادات SSL الخاصة بك تلقائيًا.
الخطوة 7 - تجديد الشهادات
شهادات Let's Encrypt صالحة لمدة 90 يومًا. يمكنك إعداد عملية تجديد تلقائي لضمان عدم انتهاء صلاحيتها. إحدى طرق القيام بذلك هي إنشاء مهمة مجدولة (cron job). في المثال أدناه، ستنشئ مهمة مجدولة لتشغيل برنامج نصي بشكل دوري يقوم بتجديد شهاداتك وإعادة تحميل إعدادات Nginx.
أولاً، افتح ملفًا نصيًا يسمى ssl_renew.sh:
nano ssl_renew.shأضف الكود التالي إلى البرنامج النصي لتجديد شهاداتك وإعادة تحميل إعدادات خادم الويب. تذكر استبدال اسم المستخدم المذكور هنا باسم المستخدم الخاص بك (ليس اسم المستخدم الجذر).
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose --no-ansi" DOCKER="/usr/bin/docker" cd /home/sammy/wordpress/ $COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
يقوم هذا البرنامج النصي أولاً بتعيين ملف docker-compose الثنائي إلى متغير يُسمى COMPOSE، ويُحدد الخيار --no-ansi، الذي يُشغّل أوامر docker-compose بدون أحرف تحكم ANSI. ثم يُكرر الأمر نفسه مع ملف docker الثنائي. وأخيرًا، ينتقل إلى دليل مشروع ~/wordpress ويُشغّل أوامر docker-compose التالية:
-
docker-composeيبدأ هذا الأمر تشغيل حاوية certbot ويستبدل الأمر المُحدد في تعريف خدمة certbot. بدلاً من استخدام الأمر الفرعي certonly، يُستخدم الأمر الفرعي renew، الذي يُجدد الشهادات التي أوشكت على الانتهاء. كما يتضمن خيار --dry-run لاختبار البرنامج النصي. docker-compose kill: هذا يرسل إشارة SIGHUP إلى حاوية خادم الويب لإعادة تحميل تكوين Nginx.
ثم يقوم النظام بتشغيل أمر docker prune لإزالة جميع الحاويات والصور غير المستخدمة.
بعد الانتهاء من تعديل الملف، أغلقه. اجعله قابلاً للتنفيذ باستخدام الأمر التالي:
chmod +x ssl_renew.shبعد ذلك، افتح ملف crontab الرئيسي لتشغيل برنامج التجديد على فترات زمنية محددة:
sudo crontab -eإذا كانت هذه هي المرة الأولى التي تقوم فيها بتحرير هذا الملف، فسيُطلب منك اختيار محرر:
Outputno crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/nano <---- easiest 2. /usr/bin/vim.basic 3. /usr/bin/vim.tiny 4. /bin/ed Choose 1-4 [1]: ...
أضف السطر التالي في نهاية هذا الملف:
...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1يُحدد هذا الإعداد فاصل تشغيل المهمة كل خمس دقائق، مما يُتيح لك التحقق من نجاح طلب التمديد كما هو مُخطط له. ويتم إنشاء ملف سجل، cron.log، لتسجيل المخرجات ذات الصلة من المهمة.
بعد خمس دقائق، تحقق من ملف cron.log للتأكد من نجاح طلب الإضافة:
tail -f /var/log/cron.logتؤكد المخرجات التالية نجاح عملية التمديد:
Output- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
للخروج، اضغط على CTRL+C في نافذة الأوامر.
يمكنك تعديل ملف crontab لضبط فاصل زمني يومي. على سبيل المثال، لتشغيل البرنامج النصي كل يوم عند الظهر، غيّر السطر الأخير من الملف ليصبح كالتالي:
...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1كما يجب عليك إزالة خيار --dry-run من برنامج ssl_renew.sh النصي الخاص بك:
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose --no-ansi" DOCKER="/usr/bin/docker" cd /home/sammy/wordpress/ $COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
تضمن مهمة cron الخاصة بك عدم انتهاء صلاحية شهادات Let's Encrypt الخاصة بك عن طريق تجديدها عند استحقاقها. يمكنك أيضًا إعداد تدوير السجلات باستخدام أداة Logrotate في Ubuntu 22.04 / 20.04 لتدوير ملفات السجلات وضغطها.
نتيجة
في هذا الدرس، استخدمتَ Docker Compose لإنشاء تثبيت WordPress باستخدام خادم الويب Nginx. وكجزء من هذه العملية، حصلتَ على شهادات TLS/SSL للنطاق الذي ترغب في ربطه بموقع WordPress الخاص بك. بالإضافة إلى ذلك، أنشأتَ مهمة مجدولة (cron job) لتجديد هذه الشهادات عند الحاجة.













