خادم التعليق الأصلي مع عامل بناء يؤلف

ملاحظة: هذه ترجمة لمنشورتي (باللغة الإنجليزية) ، تصف تنفيذ خادم التعليقات المستخدم في نفس الموقع حيث يوجد الأصل.


إصدار TL ؛ DR: لقد قمت بتطوير تهيئة خادم Commento ، والتي يتم نشرها بسهولة وبسهولة في الوضع شبه التلقائي. انسخ مستودع التخزين هذا إلى نفسك من GitHub واتبع الإرشادات الموجودة في README .

منذ بعض الوقت ، كنت أرغب في تغيير Disqus - وهو النظام الأكثر شيوعًا لإضافة التعليقات على الصفحات - إلى تعليق مجاني ومفتوح.


لماذا Commento؟


مشكلة Disqus ، مثل العديد من المنتجات "المجانية" الأخرى ، هي أن المنتج في هذه الحالة هو المستخدم - أي أنت. بالإضافة إلى ذلك ، Disqus "يثري" كل صفحة حيث يتم استخدامه مع ميغابايت من البرامج النصية وأكثر من مائة طلبات HTTP إضافية.


بالإضافة إلى ذلك ، تعرض نسختها المجانية الإعلانات التي يمكنك من خلالها سداد "فقط" مقابل 9 دولارات شهريًا (خطة بلس). هذا وحده يكفي للعثور على شيء أفضل.


في مرحلة ما ، عثرت على هذا المنشور واكتشفت وجود خادم تعليقات مجاني يسمى Commento . من قبيل الصدفة المحظوظة ، أصبح Commento مؤخرًا مفتوحًا تمامًا - قبل أن يكون متاحًا في نسختين ، هما Community and Enterprise مجانًا. بفضل مطورها Adhityaa Chandrasekar.


Commento هي أوامر حجمها أكثر فعالية من Disqus ، الحجم المعتاد للحمل الإضافي معها حوالي 11 كيلو بايت ، بالإضافة إلى التعليقات نفسها ، بالطبع. تقريبا نفس الموقف مع طلبات HTTP المطلوبة.


ميزة أخرى لخادم Commento هي أنه سريع جدًا ، كما هو مكتوب في Go.


حسنًا ، بصفته كرزًا على الكعكة ، لديه استيراد تعليقات من Disqus ، فما الذي يمكن أن يحلم به أيضًا؟


استخدام الحالات ل Commento


بالنسبة للمستخدمين غير المتقدمين (تقنيًا) ، لدى Commento خدمة سحابية جاهزة للاستخدام على commento.io . يقدم لك المؤلف اختيار الرسوم الشهرية بنفسك ، لكن لا يمكن أن يكون أقل من 3 دولارات "لأسباب فنية".


يقدم السيد Chandrasekar أيضًا بسخاء حسابًا مجانيًا على Commento.io في مقابل "تصحيحات غير تافهة" للمنتج.


حسنًا ، لقد اخترت الخيار الثالث: رفع خادم Commento بنفسي. في هذه الحالة ، فأنت لا تعتمد على أي شخص (إلى جانب المضيف ، بالطبع) ، وأنا أحب الاستقلال.


الصعوبات


أنا معجب كبير بحاويات Docker وكثيراً ما أستخدم Docker Compose ، وهي أداة لإدارة مجموعات من العديد من الحاويات ذات الصلة. يحتوي Commento على صورة Docker جاهزة للاستخدام في سجل حاويات GitLab.


لذلك ، فإن قرار استخدام الحاويات ينضج من تلقاء نفسه - ولكن يجب أولاً تحديد بعض الأشياء.


الصعوبة رقم 1: بوستجرس


يتطلب Commento إصدارًا حديثًا إلى حد ما من خادم PostgreSQL ، لسوء الحظ ، لا يتم دعم خوادم SQL أخرى.


حسنًا ، لا نزال نركض كل شيء في حاويات ، لذلك فهو بسيط للغاية.


الصعوبة رقم 2: لا يوجد دعم HTTPS


يعد Commento نفسه خادم ويب ، لكنه يدعم بروتوكول HTTP غير الآمن فقط.


تجدر الإشارة إلى أن هذه الممارسة شائعة جدًا هذه الأيام: في هذه الحالة ، يتم إخفاء الخادم خلف الوكيل العكسي ، والذي يؤدي أيضًا إلى إلغاء تحميل طبقة المقابس الآمنة. الشيء هو أن دعم SSL / HTTPS إلزامي للغاية في هذه الحالة ، بعد كل شيء ، في الفناء في عام 2019 وسيتم النظر في محاولات تفويض مستخدم باستخدام بروتوكول إنترنت غير آمن بشكل كبير.


قررت استخدام خادم Nginx ، أولاً ، كانت لدي خبرة كبيرة في العمل به ، وثانيًا ، إنه سريع جدًا واقتصاديًا ومستقرًا. وتنشر التصميمات الرسمية لصور Docker .


المكون الثاني في وصفة HTTPS هو شهادة SSL للمجال. أنا ممتن أبدًا لـ EFF و Mozilla على إنشاء " Let's Encrypt Certificate Authority" ، الذي يصدر ملايين الشهادات المجانية كل شهر.


يتيح Let's Encrypt أيضًا أداة مساعدة مجانية لسطر الأوامر تسمى certbot ، والتي تعمل على تبسيط عملية الحصول على الشهادة وتحديثها إلى حد كبير. حسنًا ، وبطبيعة الحال - صورة عامل ميناء له!


الصعوبة # 3: مشكلة سرتبوت بيض الدجاج


لكن هذه الخدعة أكثر صعوبة.


نريد أن نشير إلى شهادة طبقة المقابس الآمنة (SSL) في تهيئة الخادم الوكيل العكسي على Nginx ، مما يعني أنه بدون شهادة ، فإنه ببساطة يرفض البدء. في الوقت نفسه ، للحصول على شهادة طبقة المقابس الآمنة لنطاق ما ، فأنت بحاجة إلى خادم HTTP عامل ، والذي سوف نثبت أنه ملكك لهذا المجال.


تمكنت من حل هذه المشكلة ، ويبدو لي ، بأناقة تامة:


  1. أولاً ، يتم إنشاء شهادة وهمية غير صالحة ، هدفها الوحيد هو السماح لـ Nginx بالبدء.
  2. يتلقى كل من Nginx و certbot شهادة جديدة صالحة الآن.
  3. بمجرد استلام الشهادة ، يذهب certbot إلى "وضع الاستعداد" ، حيث يستيقظ كل 12 ساعة للتحقق مما إذا كان يحتاج إلى تحديث - وفقًا لتوصيات Let's Encrypt.
  4. عندما تأتي اللحظة وتم تجديد الشهادة ، ستشير certbot إلى Nginx لإعادة التشغيل.

الصعوبة رقم 4: يجب الحفاظ على شيء ما


أظن بشدة أنك تريد حفظ تعليقات المستخدم بعد إعادة التشغيل أو تحديث النظام.


أيضًا ، حتى لا يحظرنا Encrypt تشفيرًا بسبب كثرة الطلبات ، سيكون من الجيد الاحتفاظ بالشهادات المستلمة لكامل تاريخ انتهاء الصلاحية.


تم حل كلتا النقطتين في التكوين المقترح باستخدام مجلدات Docker ، التي تم إنشاؤها تلقائيًا بواسطة systemd عند إطلاق Commento لأول مرة. يتم تمييز وحدات التخزين على أنها external ، لذلك يتخطى Docker عند إزالة الحاويات باستخدام docker-compose down -v .


أحضرها جميعًا معًا


الآن يمكنك أن ترى كيف يعمل كل شيء معًا.


يوضح الشكل أدناه التفاعل والحركة بين الحاويات الأربعة:



قمت بتطبيق خيار Docker depends_on لضمان تشغيل الحاويات بالترتيب الصحيح.


إذا كنت تريد فقط بدء تشغيل خادم Commento الخاص بك ، فيمكنك تخطي بقية المقالة والانتقال مباشرةً إلى الكود على GitHub .


حسنًا ، سأتحدث أكثر عن هذا التطبيق بمزيد من التفاصيل لاحقًا.


كيف يعمل كل شيء


إنشاء ملف


كما ترون في الصورة أعلاه ، "تكويني" يتكون من أربع خدمات:


  1. certbot - الأداة المساعدة certbot من EFF
  2. nginx - وكيل عكسي يقوم بتفريغ SSL
  3. app - خادم Commento
  4. postgres - قاعدة بيانات PostgreSQL

يحتوي docker-compose.yml على تعريفات لشبكة Docker الخاصة به ، وتسمى commento_network ، وثلاثة مجلدات ، اثنان منها خارجي (أي ، يجب إنشاءهما خارج Compose):


  • commento_postgres_volume يخزن بيانات خادم PostgreSQL لـ Commento: المستخدمون ، المشرفون ، التعليقات ، إلخ.
  • يحتوي certbot_etc_volume على شهادات تم استلامها بواسطة certbot .

إنجن إكس


تعتمد حاوية Nginx على صورة رسمية خفيفة الوزن تعتمد على جبال الألب وتستخدم البرنامج النصي التالي لتشغيله:


 #!/bin/sh trap exit TERM # Wait for the certificate file to arrive wait_for_certs() { echo 'Waiting for config files from certbot...' i=0 while [[ ! -f /etc/letsencrypt/options-ssl-nginx.conf ]]; do sleep 0.5 [[ $((i++)) -gt 20 ]] && echo 'No files after 10 seconds, aborting' && exit 2 done } # Watches for a "reload flag" (planted by certbot container) file and reloads nginx config once it's there watch_restart_flag() { while :; do [[ -f /var/www/certbot/.nginx-reload ]] && rm -f /var/www/certbot/.nginx-reload && echo 'Reloading nginx' && nginx -s reload sleep 10 done } # Wait for certbot wait_for_certs # Start "reload flag" watcher watch_restart_flag & # Run nginx in the foreground echo 'Starting nginx' exec nginx -g 'daemon off;' 

  • السطر 3 ( ARRGHHH ، لا يدعم Habr عرض أرقام الأسطر في الكود - الترجمة تقريبًا. ) يتم تسجيل معالج المقاطعة بحيث تعمل Nginx وعملية مراقبة الخلفية بنجاح عند توقف الحاوية.
  • يستدعي السطر 27 وظيفة الانتظار ، التي تتوقف مؤقتًا عن عملية بدء تشغيل Nginx حتى تظهر ملفات تكوين SSL التي certbot حاوية certbot . بدون هذا ، فإن Nginx يرفض البدء.
  • ينشئ السطر 30 عملية خلفية تقوم بانتظام ، كل عشر ثوانٍ ، بالتحقق من وجود ملف علامة باسم .nginx-reload ، .nginx-reload ، يرشد Nginx إلى إعادة تحميل التكوين. يقوم هذا الملف أيضًا بإنشاء certbot عند تحديث الشهادة.
  • السطر 34 يبدأ تشغيل Nginx في الوضع العادي. في هذه الحالة ، يعني exec أن عملية shell الحالية يتم استبدالها بعملية Nginx.

الملف المهم الآخر في هذه الصورة هو تكوين الخادم الظاهري Commento ، والذي يفرض على Nginx إعادة توجيه طلبات HTTPS إلى حاوية commento :


 server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; server_tokens off; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name __DOMAIN__; location / { proxy_pass http://app:8080/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ssl_certificate /etc/letsencrypt/live/__DOMAIN__/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/__DOMAIN__/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80 default_server; listen [::]:80 default_server; server_tokens off; server_name __DOMAIN__; location /.well-known/acme-challenge/ { root /var/www/certbot; } # Redirect to HTTPS on port 80 location / { return 301 https://$host$request_uri; } } 

تصف كتلة الخادم الأولى (الأسطر 1-21 ) كيفية العمل مع HTTPS وقاعدة إعادة التوجيه. هذا هو المكان الذي يتم فيه ذكر دعونا نشفّر ملفات الشهادة (أو تستخدم الدعائم بدلاً من ذلك).


يتم تمرير المجال الذي يقدمه الخادم كوسيطة عند إنشاء الصورة ؛ يستبدل السطر __DOMAIN__ في تهيئة الخادم.


الكتلة الثانية (الأسطر 23-38 ) هي تكوين خادم HTTP ، والذي يستخدمه certbot لتأكيد ملكية المجال (ما يسمى "تحدي ACME"). تتسبب جميع الطلبات الأخرى في إعادة توجيه إلى العنوان المقابل عبر HTTPS.


certbot


تعتمد صورة certbot الخاصة بنا على البنية الرسمية باستخدام النص التالي:


 #!/bin/sh trap exit TERM # Wait until nginx is up and running, up to 10 seconds wait_for_nginx() { echo 'Waiting for nginx...' i=0 while ! nc -z nginx 80 &>/dev/null; do sleep 0.5 [[ $((i++)) -gt 20 ]] && echo "nginx isn't online after 10 seconds, aborting" && exit 4 done echo 'nginx is up and running' } # Check vars [[ -z "$DOMAIN" ]] && echo "Environment variable 'DOMAIN' isn't defined" && exit 2 [[ -z "$EMAIL" ]] && echo "Environment variable 'EMAIL' isn't defined" && exit 2 TEST="${TEST:-false}" # Check external mounts data_dir='/etc/letsencrypt' www_dir='/var/www/certbot' [[ ! -d "$data_dir" ]] && echo "Directory $data_dir must be externally mounted" [[ ! -d "$www_dir" ]] && echo "Directory $www_dir must be externally mounted" # If the config/certificates haven't been initialised yet if [[ ! -e "$data_dir/options-ssl-nginx.conf" ]]; then # Copy config over from the initial location echo 'Initialising nginx config' cp /conf/options-ssl-nginx.conf /conf/ssl-dhparams.pem "$data_dir/" # Copy dummy certificates mkdir -p "$data_dir/live/$DOMAIN" cp /conf/privkey.pem /conf/fullchain.pem "$data_dir/live/$DOMAIN/" # Wait for nginx wait_for_nginx # Remove dummy certificates rm -rf "$data_dir/live/$DOMAIN/" # Run certbot to validate/renew certificate test_arg= $TEST && test_arg='--test-cert' certbot certonly --webroot -w /var/www/certbot -n -d "$DOMAIN" $test_arg -m "$EMAIL" --rsa-key-size 4096 --agree-tos --force-renewal # Reload nginx config touch /var/www/certbot/.nginx-reload # nginx config has been already initialised - just give nginx time to come up else wait_for_nginx fi # Run certbot in a loop for renewals while :; do certbot renew # Reload nginx config touch /var/www/certbot/.nginx-reload sleep 12h done 

جولة قصيرة لخطوطها:


  • السطر 3 ، كما في البرنامج النصي السابق ، مطلوب لإكمال الحاوية بشكل منتظم.
  • تحقق الخطوط 17-19 من المتغيرات المطلوبة.
  • وفي الأسطر 22-25 - أن الدلائل المطلوبة لتشغيل certbot مثبتة بشكل صحيح.
  • يتبع الشوكة:
    • يتم تنفيذ الخطوط 30-50 فقط في البداية الأولى للحاوية:
      • يتم نسخ شهادة وهمية ، مما يتيح بدء تشغيل Nginx بشكل طبيعي.
      • في الوقت نفسه ، تنتظر Nginx نهاية هذه العملية ، وبعد ذلك تستمر في التنزيل.
      • بمجرد بدء تشغيل Nginx ، يبدأ certbot عملية الحصول على شهادة صالحة من Let's Encrypt.
      • وأخيرًا ، بمجرد استلام الشهادة ، يتم إنشاء ملف .nginx-reload ، ملمحًا إلى Nginx أن الوقت قد حان لإعادة تحميل التكوين.
    • ينتظر السطر 54 بدء تشغيل Nginx - في حالة توفر شهادة كاملة بالفعل.
  • بعد كل هذا (الأسطر 58-63 ) ، يستمر في التدوير ، مرة كل 12 ساعة يتحقق من الحاجة إلى تجديد الشهادة وإشارة Nginx إلى إعادة التشغيل.

Commento و PostgreSQL


تستخدم حاويات app و postgres الصور الأصلية المقدمة من قبل المطورين دون أي تغييرات.


خدمة Systemd


آخر جزء من هذا اللغز هو ملف systemd commento.service unit ، الذي تحتاج إليه لإنشاء /etc/systemd/system/commento.service في /etc/systemd/system/commento.service بحيث يبدأ في وقت مناسب عندما يبدأ النظام:


 [Unit] Description=Commento server [Service] TimeoutStopSec=30 WorkingDirectory=/opt/commento ExecStartPre=-/usr/bin/docker volume create commento_postgres_volume ExecStartPre=-/usr/bin/docker volume create certbot_etc_volume ExecStartPre=-/usr/local/bin/docker-compose -p commento down -v ExecStart=/usr/local/bin/docker-compose -p commento up --abort-on-container-exit ExecStop=/usr/local/bin/docker-compose -p commento down -v [Install] WantedBy=multi-user.target 

السطر:


  • يشير السطر 6 إلى أن رمز المشروع تم استنساخه إلى دليل /opt/commento - وهذا أبسط بكثير.
  • إنشاء خطوط 7-8 وحدات تخزين خارجية ، إذا لم تكن بالفعل.
  • في السطر 9 ، يتم حذف البقايا المحتملة للحاويات السابقة. يتم الاحتفاظ وحدات التخزين الخارجية.
  • يشير السطر 10 إلى الإطلاق الفعلي لـ Docker Compose. --abort-on-container-exit علم --abort-on-container-exit قطيع الحاويات بالكامل عند --abort-on-container-exit أي منها. بفضل هذا ، سيكون systemd على الأقل على دراية بإيقاف الخدمة.
  • يقوم الخط 11 مرة أخرى بتنظيف وحذف الحاويات والشبكات والأحجام.

شفرة المصدر


تطبيق العمل الكامل ، الذي يتطلب فقط تكوين المتغيرات في docker-compose.yml ، متاح على GitHub . تحتاج فقط إلى اتباع الخطوات الموضحة في README بعناية.


يخضع الرمز لترخيص معهد ماساتشوستس للتكنولوجيا .


شكرا لقراءتك لهذا المكان ، التعليقات مرحب بها بشكل محموم!

Source: https://habr.com/ru/post/ar464105/


All Articles