إنشاء سلسلة CI / CD وأتمتة العمل باستخدام Docker

لقد كتبت أول مواقع الويب الخاصة بي في أواخر التسعينيات. ثم كان من السهل جدًا وضعها في حالة صالحة للعمل. كان هناك خادم Apache على بعض الاستضافة المشتركة ، ويمكن الوصول إلى هذا الخادم عبر FTP عن طريق الكتابة في سطر المتصفح مثل ftp://ftp.example.com. ثم كان من الضروري إدخال اسم وكلمة مرور وتحميل الملفات على الخادم. كانت هناك أوقات أخرى ، كان كل شيء أبسط مما هو عليه الآن.

إنشاء سلسلة CI / CD وأتمتة العمل باستخدام Docker

لقد تغيرت الأمور كثيرًا في العقدين الماضيين. أصبحت المواقع أكثر تعقيدًا ، يجب تجميعها قبل إطلاقها في الإنتاج. أصبح خادم واحد العديد من الخوادم التي تعمل خلف موازين التحميل ، وأصبح استخدام أنظمة التحكم في الإصدار أمرًا شائعًا.

بالنسبة لمشروعي الشخصي ، كان لدي تكوين خاص. وأدركت أنني بحاجة إلى القدرة على نشر موقع في الإنتاج ، وتنفيذ إجراء واحد فقط: كتابة التعليمات البرمجية إلى أحد الفروع master على جيثب. علمت أيضًا أنني لم أرغب في إدارة مجموعة Kubernetes الضخمة ، أو استخدام تقنية Docker Swarm ، أو الحفاظ على ساحة خادم بها حواجز ووكلاء وجميع أنواع التعقيدات الأخرى ، لتشغيل تطبيق الويب الصغير الخاص بي. من أجل تحقيق الهدف المتمثل في جعل العمل أسهل ما يمكن ، كنت بحاجة للتعرف على CI / CD.

إذا كان لديك مشروع صغير (في حالتنا ، مشروع Node.js) وترغب في معرفة كيفية أتمتة نشر هذا المشروع ، مع التأكد من أن ما يتم تخزينه في المستودع يتطابق تمامًا مع ما يعمل في الإنتاج ، على ما أعتقد قد تكون مهتمًا بهذه المقالة.

المتطلبات الأساسية

من المتوقع أن يكون لدى قارئ هذه المقالة معرفة أساسية بسطر الأوامر ومعرفة البرمجة النصية لـ Bash. بالإضافة إلى ذلك ، سيحتاج إلى حسابات ترافيس سي и دوكر هاب.

الأهداف

لن أقول إن هذا المقال يمكن أن يسمى دون قيد أو شرط "دليل التدريب". هذا أكثر من مستند أتحدث فيه عن ما تعلمته وأصف العملية التي تناسبني لاختبار ونشر التعليمات البرمجية في الإنتاج ، والتي يتم إجراؤها في مسار آلي واحد.

هذا ما انتهى به سير العمل الخاص بي.

بالنسبة للرمز الذي تم دفعه إلى أي فرع من المستودعات بخلاف master، يتم تنفيذ الإجراءات التالية:

  • يبدأ مشروع البناء على Travis CI.
  • يتم إجراء جميع اختبارات الوحدة والتكامل والاختبارات الشاملة.

فقط للرمز الذي ينتهي به masterيتم القيام بما يلي:

  • كل ما سبق بالإضافة إلى ...
  • بناء صورة Docker بناءً على الكود والإعدادات والبيئة الحالية.
  • استضافة الصورة على Docker Hub.
  • الاتصال بخادم الإنتاج.
  • تحميل صورة من Docker Hub إلى الخادم.
  • أوقف الحاوية الحالية وابدأ حاوية جديدة بناءً على الصورة الجديدة.

إذا كنت لا تعرف شيئًا على الإطلاق عن Docker والصور والحاويات ، فلا تقلق. سأخبركم كل شيء عن ذلك.

ما هو CI / CD؟

يشير الاختصار CI / CD إلى "التكامل المستمر / النشر المستمر" - "التكامل المستمر / النشر المستمر".

▍ التكامل المستمر

التكامل المستمر هو العملية التي يلتزم بها المطورون بمخزون كود المصدر الرئيسي للمشروع (عادة ما يكون فرعًا master). في الوقت نفسه ، يتم ضمان جودة الشفرة من خلال الاختبار الآلي.

▍ النشر المستمر

النشر المستمر هو النشر الآلي المتكرر للرمز في الإنتاج. يُكشف أحيانًا عن الجزء الثاني من الاختصار CI / CD على أنه "تسليم مستمر" ("تسليم مستمر"). هذا هو في الأساس نفس "النشر المستمر" ، ولكن "التسليم المستمر" يعني الحاجة إلى الالتزام بالتغييرات يدويًا قبل بدء عملية نشر المشروع.

الشروع في العمل

يسمى التطبيق الذي أتقنت فيه كل هذا يحيط علما. هذا مشروع ويب أعمل عليه لتدوين الملاحظات. أولا حاولت أن أفعل JAMStack-مشروع ، أو مجرد تطبيق أمامي بدون خادم ، من أجل الاستفادة من خيارات الاستضافة القياسية ونشر المشروع التي يقدمها Netlify. مع تزايد تعقيد التطبيق ، كنت بحاجة إلى إنشاء نهايته الخلفية ، مما يعني أنه سيتعين علي تكوين إستراتيجيتي الخاصة للتكامل الآلي والنشر الآلي للمشروع.

في حالتي ، التطبيق هو خادم Express يعمل في بيئة Node.js ، يخدم تطبيق React من صفحة واحدة ويدعم واجهة برمجة تطبيقات آمنة من جانب الخادم. تتبع هذه البنية إستراتيجية يمكن العثور عليها في منح دليل المصادقة الكامل المكدس.

لقد تشاورت مع другом، وهو خبير في الأتمتة ، وسألته عما يجب أن أفعله لجعل كل شيء يعمل بالطريقة التي أريدها. لقد أعطاني فكرة عما يجب أن يبدو عليه سير العمل الآلي الموضح في قسم الأهداف من هذه المقالة. كان تحديد أهداف مثل هذا يعني أنني بحاجة إلى معرفة كيفية استخدام Docker.

عامل في حوض السفن

Docker هي أداة تسهل ، بفضل تقنية الحاوية ، توزيع التطبيقات ، وكذلك نشرها وتشغيلها في نفس البيئة ، حتى لو كانت منصة Docker نفسها تعمل في بيئات مختلفة. أولاً ، كنت بحاجة إلى وضع يدي على أدوات سطر أوامر Docker (CLI). تعليمات دليل التثبيت الخاص بـ Docker ليس واضحًا للغاية ، ولكن يمكنك أن تتعلم منه أنه من أجل اتخاذ الخطوة الأولى من التثبيت ، تحتاج إلى تنزيل Docker Desktop (لنظام التشغيل Mac أو Windows).

Docker Hub هو نفس ملف GitHub جيثب: لمستودعات git أو التسجيل الآلية الوقائية الوطنية لحزم JavaScript. هذا مستودع عبر الإنترنت لصور Docker. هذا هو المكان الذي يتصل به Docker Desktop.

لذلك ، لبدء استخدام Docker ، عليك القيام بأمرين:

بعد ذلك ، يمكنك التحقق مما إذا كان Docker CLI يعمل عن طريق تشغيل الأمر التالي للتحقق من إصدار Docker:

docker -v

بعد ذلك ، قم بتسجيل الدخول إلى Docker Hub عن طريق إدخال اسم المستخدم وكلمة المرور عندما يُطلب منك:

docker login

من أجل استخدام Docker ، يجب أن تفهم مفاهيم الصور والحاويات.

▍ الصور

الصورة هي نوع من مخطط يحتوي على تعليمات لبناء حاوية. هذه لقطة ثابتة لنظام الملفات وإعدادات التطبيق. يمكن للمطورين مشاركة الصور بسهولة.

# Вывод сведений обо всех образах
docker images

سيخرج هذا الأمر جدولاً بالعنوان التالي:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

بعد ذلك ، سننظر في بعض الأمثلة للأوامر في نفس التنسيق - يوجد أولاً أمر به تعليق ، ثم مثال على ما يمكن إخراجها.

▍ الحاويات

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

# Перечисление всех контейнеров
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍ العلامات

العلامة هي إشارة إلى إصدار معين من الصورة.

▍ مرجع سريع لأوامر Docker

فيما يلي نظرة عامة على بعض أوامر Docker شائعة الاستخدام.

فريق

السياق

عمل

بناء عامل ميناء

صورة

بناء صورة من Dockerfile

علامة عامل ميناء

صورة

وضع العلامات على الصورة

صور عامل ميناء

صورة

عرض قائمة بالصور

تشغيل عامل ميناء

حاوية

تشغيل حاوية قائمة على الصور

دفع عامل ميناء

صورة

إرسال صورة إلى السجل

سحب عامل ميناء

صورة

تحميل صورة من التسجيل

عامل الميناء

حاوية

قائمة الحاويات

تقليم نظام عامل ميناء

صورة / حاوية

إزالة الحاويات والصور غير المستخدمة

ملف Dockerfile

أعرف كيفية تشغيل تطبيق إنتاج محليًا. لدي webpack config لإنشاء تطبيق React مكتمل. بعد ذلك ، لدي أمر يبدأ خادمًا يستند إلى Node.js على المنفذ 5000. تبدو هكذا:

npm i         # установка зависимостей
npm run build # сборка React-приложения
npm run start # запуск Node-сервера

وتجدر الإشارة إلى أنه ليس لدي مثال على تطبيق لهذه المادة. ولكن هنا ، بالنسبة للتجارب ، فإن أي تطبيق بسيط للعقدة سيفي بالغرض.

من أجل استخدام الحاوية ، سوف تحتاج إلى إعطاء التعليمات لـ Docker. يتم ذلك من خلال ملف يسمى Dockerfileالموجود في الدليل الجذر للمشروع. هذا الملف ، في البداية ، يبدو إلى حد ما غير مفهوم.

لكن ما يحتويه فقط يصف ، في أوامر خاصة ، شيئًا مثل إعداد بيئة عمل. فيما يلي بعض هذه الأوامر:

  • من عند - هذا الأمر يبدأ ملف. يحدد الصورة الأساسية التي بنيت منها الحاوية.
  • COPY - نسخ الملفات من مصدر محلي إلى حاوية.
  • عمل - ضبط دليل العمل للأوامر التالية.
  • RUN - تشغيل الأوامر.
  • تعرض - ضبط المنفذ.
  • نقطة الدخول - إشارة إلى الأمر المطلوب تنفيذه.

Dockerfile قد يبدو مثل هذا:

# Загрузить базовый образ
FROM node:12-alpine

# Скопировать файлы из текущей директории в директорию app/
COPY . app/

# Использовать app/ в роли рабочей директории
WORKDIR app/

# Установить зависимости (команда npm ci похожа npm i, но используется для автоматизированных сборок)
RUN npm ci --only-production

# Собрать клиентское React-приложение для продакшна
RUN npm run build

# Прослушивать указанный порт
EXPOSE 5000

# Запустить Node-сервер
ENTRYPOINT npm run start

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

▍ بناء حاوية ووضع علامات عليها وتشغيلها

التجميع المحلي وإطلاق الحاوية ، بعد ذلك لدينا Dockerfileالمهام بسيطة للغاية. قبل دفع الصورة إلى Docker Hub ، يجب اختبارها محليًا.

▍ الجمعية

أولا تحتاج إلى جمع صورة، وتحديد اسم ، واختياريا ، علامة (إذا لم يتم تحديد علامة ، فسيقوم النظام تلقائيًا بتعيين علامة للصورة latest).

# Сборка образа
docker build -t <image>:<tag> .

بعد تشغيل هذا الأمر ، يمكنك مشاهدة Docker وهو يبني الصورة.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...выполнение этапов сборки...
Successfully built 123456789123
Successfully tagged <image>:<tag>

يمكن أن يستغرق البناء دقيقتين - كل هذا يتوقف على عدد التبعيات لديك. بعد اكتمال البناء ، يمكنك تشغيل الأمر docker images وإلقاء نظرة على وصف صورتك الجديدة.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        About a minute ago   x.xxGB

▍ الإطلاق

تم إنشاء الصورة. وهذا يعني أنه يمكنك تشغيل حاوية على أساسها. بما أنني أريد أن أتمكن من الوصول إلى التطبيق الذي يعمل في الحاوية في localhost:5000، أنا ، على الجانب الأيسر من الزوج 5000:5000 في مجموعة الأوامر التالية 5000. على الجانب الأيمن يوجد ميناء الحاوية.

# Запуск с использованием локального порта 5000 и порта контейнера 5000
docker run -p 5000:5000 <image>:<tag>

الآن بعد أن تم إنشاء الحاوية وتشغيلها ، يمكنك استخدام الأمر docker ps لإلقاء نظرة على معلومات حول هذه الحاوية (أو يمكنك استخدام الأمر docker ps -a، الذي يعرض معلومات حول جميع الحاويات ، وليس فقط الحاويات قيد التشغيل).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "/bin/sh -c 'npm run…"   6 seconds ago        Up 6 seconds                0.0.0.0:5000->5000/tcp   stoic_darwin

إذا ذهبت الآن إلى localhost:5000 - يمكنك رؤية صفحة التطبيق قيد التشغيل ، والتي تبدو تمامًا مثل صفحة التطبيق قيد التشغيل في بيئة الإنتاج.

▍تخصيص العلامات والنشر

لاستخدام إحدى الصور التي تم إنشاؤها على خادم الإنتاج ، نحتاج إلى أن نكون قادرين على تنزيل هذه الصورة من Docker Hub. هذا يعني أنك تحتاج أولاً إلى إنشاء مستودع للمشروع على Docker Hub. بعد ذلك ، سيكون لدينا مكان حيث يمكننا إرسال الصورة. يجب إعادة تسمية الصورة بحيث يبدأ اسمها باسم مستخدم Docker Hub الخاص بنا. يجب أن يتبع ذلك اسم المستودع. يمكن وضع أي علامة في نهاية الاسم. يوجد أدناه مثال لتسمية الصور وفقًا لهذا المخطط.

يمكنك الآن إنشاء الصورة باسم جديد مخصص لها وتشغيل الأمر docker push لدفعه إلى مستودع Docker Hub.

docker build -t <username>/<repository>:<tag> .
docker tag <username>/<repository>:<tag> <username>/<repository>:latest
docker push <username>/<repository>:<tag>

# На практике это может выглядеть, например, так:
docker build -t user/app:v1.0.0 .
docker tag user/app:v1.0.0 user/app:latest
docker push user/app:v1.0.0

إذا سارت الأمور على ما يرام ، فستكون الصورة متاحة على Docker Hub ويمكن تحميلها بسهولة على الخادم أو مشاركتها مع مطورين آخرين.

الخطوات التالية

لقد تحققنا الآن من أن التطبيق ، في شكل حاوية Docker ، يعمل محليًا. لقد قمنا بتحميل الحاوية إلى Docker Hub. كل هذا يعني أننا قد أحرزنا بالفعل تقدمًا جيدًا للغاية نحو هدفنا. الآن نحن بحاجة إلى حل سؤالين آخرين:

  • إعداد أداة CI لاختبار ونشر التعليمات البرمجية.
  • إعداد خادم الإنتاج حتى يتمكن من تنزيل التعليمات البرمجية الخاصة بنا وتشغيلها.

في حالتنا ، نستخدم حل CI / CD ترافيس سي. كخادم - ديجيتال أوشن.

وتجدر الإشارة إلى أنه يمكنك هنا استخدام مجموعة أخرى من الخدمات. على سبيل المثال ، بدلاً من Travis CI ، يمكنك استخدام إجراءات CircleCI أو Github. وبدلاً من DigitalOcean - AWS أو Linode.

قررنا العمل مع Travis CI ، ولدي بالفعل شيء تم إعداده في هذه الخدمة. لذلك ، سأتحدث الآن بإيجاز عن كيفية إعداده للعمل.

ترافيس سي

Travis CI هي أداة لاختبار ونشر الكود. لا أريد الخوض في تفاصيل إعداد Travis CI ، حيث أن كل مشروع فريد ولن يفيد كثيرًا. لكنني سأغطي الأساسيات لتبدأ إذا قررت استخدام Travis CI. مهما كان اختيارك - Travis CI أو CircleCI أو Jenkins أو أي شيء آخر ، سيتم تطبيق طرق تكوين مماثلة في كل مكان.

لتبدأ مع Travis CI ، انتقل إلى موقع المشروع وإنشاء حساب. ثم قم بدمج Travis CI مع حساب GitHub الخاص بك. عند إعداد النظام ، ستحتاج إلى تحديد المستودع الذي تريد أتمتة وتمكين الوصول إليه. (أستخدم GitHub ، لكنني متأكد من أن Travis CI يمكن أن يتكامل مع BitBucket و GitLab وغيرها من الخدمات المماثلة).

في كل مرة يتم فيها تشغيل Travis CI ، يتم بدء تشغيل خادم يقوم بتنفيذ الأوامر المحددة في ملف التكوين ، بما في ذلك نشر الفروع المناسبة للمستودع.

▍دورة حياة الوظيفة

تم استدعاء ملف تكوين Travis CI .travis.yml وتخزينها في الدليل الجذر للمشروع ، يدعم مفهوم الأحداث دورة الحياة مهام. فيما يلي الأحداث ، مُدرجة بالترتيب الذي حدثت به:

  • apt addons
  • cache components
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success или after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍ الاختبار

في ملف التكوين ، سأقوم بإعداد خادم Travis CI المحلي. اخترت Node 12 كلغة وأخبرت النظام بتثبيت التبعيات اللازمة لاستخدام Docker.

كل شيء مدرج في .travis.yml، على جميع طلبات السحب لجميع فروع المستودع ، ما لم ينص على خلاف ذلك. هذه ميزة مفيدة لأنها تعني أنه يمكننا اختبار كل التعليمات البرمجية التي تدخل المستودع. يتيح لك هذا معرفة ما إذا كان الرمز جاهزًا للكتابة إلى الفرع. master، وما إذا كان سيؤدي إلى كسر عملية بناء المشروع. في هذا التكوين العام ، أقوم بتثبيت كل شيء محليًا ، وتشغيل خادم Webpack dev في الخلفية (هذه إحدى ميزات سير العمل الخاص بي) ، وتشغيل الاختبارات.

إذا كنت تريد أن يعرض المستودع الخاص بك أيقونات تغطية الكود ، هنا يمكنك العثور على برنامج تعليمي سريع حول كيفية استخدام Jest و Travis CI و Coveralls لجمع هذه المعلومات وعرضها.

هذا هو محتوى الملف .travis.yml:

# Установить язык
language: node_js

# Установить версию Node.js
node_js:
  - '12'

services:
  # Использовать командную строку Docker
  - docker

install:
  # Установить зависимости для тестов
  - npm ci

before_script:
  # Запустить сервер и клиент для тестов
  - npm run dev &

script:
  # Запустить тесты
  - npm run test

هذا هو المكان الذي تنتهي فيه الإجراءات التي يتم تنفيذها لجميع فروع المستودع وطلبات السحب.

▍ الانتشار

استنادًا إلى افتراض أن جميع الاختبارات الآلية قد اكتملت بنجاح ، يمكننا اختياريًا نشر الكود على خادم الإنتاج. نظرًا لأننا نريد القيام بذلك فقط لرمز الفرع master، نعطي النظام التعليمات المناسبة في إعدادات النشر. قبل أن تحاول استخدام الكود الذي سننظر إليه بعد ذلك في مشروعك ، أود أن أحذرك من أنه يجب أن يكون لديك برنامج نصي فعلي مطلوب للنشر.

deploy:
  # Собрать Docker-контейнер и отправить его на Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

يقوم البرنامج النصي للنشر بأمرين:

  • بناء الصورة ووضع علامات عليها وإرسالها إلى Docker Hub باستخدام أداة CI (في حالتنا هي Travis CI).
  • تحميل الصورة على الخادم ، وإيقاف الحاوية القديمة وبدء حاوية جديدة (في حالتنا ، يعمل الخادم على منصة DigitalOcean).

أولاً ، تحتاج إلى إعداد عملية تلقائية لبناء الصورة ووضع علامات عليها ودفعها إلى Docker Hub. كل هذا مشابه جدًا لما فعلناه بالفعل يدويًا ، باستثناء أننا نحتاج هنا إلى استراتيجية لتعيين علامات فريدة للصور وأتمتة تسجيل الدخول. واجهت صعوبة في بعض تفاصيل البرنامج النصي للنشر ، مثل إستراتيجية وضع العلامات وتسجيل الدخول وتشفير مفاتيح SSH وإنشاء اتصال SSH. لكن لحسن الحظ ، صديقي جيد جدًا مع باش ، وكذلك مع العديد من الأشياء الأخرى. لقد ساعدني في كتابة هذا السيناريو.

لذلك ، الجزء الأول من البرنامج النصي هو إرسال الصورة إلى Docker Hub. للقيام بذلك بسيط للغاية. يتضمن مخطط وضع العلامات الذي استخدمته الجمع بين تجزئة git وعلامة git إذا كانت موجودة. هذا يضمن أن العلامة فريدة ويسهل تحديد التجميع الذي تستند إليه. DOCKER_USERNAME и DOCKER_PASSWORD هي متغيرات البيئة التي يحددها المستخدم والتي يمكن ضبطها باستخدام واجهة Travis CI. سيقوم Travis CI تلقائيًا بمعالجة البيانات الحساسة حتى لا تقع في الأيدي الخطأ.

هذا هو الجزء الأول من البرنامج النصي deploy.sh.

#!/bin/sh
set -e # Остановить скрипт при наличии ошибок

IMAGE="<username>/<repository>"                             # Образ Docker
GIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-хэш и теги

# Сборка и тегирование образа
docker build -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest

# Вход в Docker Hub и выгрузка образа
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker push ${IMAGE}:${GIT_VERSION}

يعتمد الجزء الثاني من البرنامج النصي كليًا على المضيف الذي تستخدمه وكيفية تنظيم الاتصال به. في حالتي ، بما أنني أستخدم Digital Ocean ، يتم استخدام الأوامر للاتصال بالخادم دكتل. عند العمل مع Aws ، سيتم استخدام الأداة المساعدة aws، وما إلى ذلك وهلم جرا.

لم يكن إعداد الخادم صعبًا بشكل خاص. لذلك ، قمت بإعداد تطبيق droplet الصغير بناءً على الصورة الأساسية. تجدر الإشارة إلى أن النظام الذي اخترته يتطلب تثبيتًا يدويًا لمرة واحدة لـ Docker وبدءًا يدويًا لمرة واحدة لـ Docker. لقد استخدمت Ubuntu 18.04 لتثبيت Docker ، لذلك إذا كنت تستخدم Ubuntu أيضًا ، يمكنك فقط اتباع هذا توجيه بسيط.

أنا لا أتحدث عن أوامر محددة للخدمة هنا ، لأن هذا الجانب يمكن أن يختلف اختلافًا كبيرًا في حالات مختلفة. سأقدم فقط خطة عمل عامة ليتم تنفيذها بعد الاتصال عبر SSH بالخادم حيث سيتم نشر المشروع:

  • تحتاج إلى العثور على الحاوية قيد التشغيل حاليًا وإيقافها.
  • ثم تحتاج إلى بدء حاوية جديدة في الخلفية.
  • ستحتاج إلى ضبط المنفذ المحلي للخادم على 80 - سيسمح لك هذا بالدخول إلى الموقع على عنوان النموذج example.com، بدون تحديد منفذ ، بدلاً من استخدام عنوان مثل example.com:5000.
  • وأخيرًا ، تحتاج إلى إزالة جميع الحاويات والصور القديمة.

هنا هو استمرار السيناريو.

# Найти ID работающего контейнера
CONTAINER_ID=$(docker ps | grep takenote | cut -d" " -f1)

# Остановить старый контейнер, запустить новый, очистить систему
docker stop ${CONTAINER_ID}
docker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}
docker system prune -a -f

بعض الأشياء التي يجب الانتباه إليها

من المحتمل أنه عند الاتصال بالخادم عبر SSH من Travis CI ، سترى تحذيرًا لن يسمح لك بمتابعة التثبيت ، حيث سينتظر النظام استجابة المستخدم.

The authenticity of host '<hostname> (<IP address>)' can't be established.
RSA key fingerprint is <key fingerprint>.
Are you sure you want to continue connecting (yes/no)?

تعلمت أن مفتاح السلسلة يمكن ترميزه في base64 لتخزينه في شكل يمكن استخدامه بشكل ملائم وموثوق به. في مرحلة التثبيت ، يمكنك فك تشفير المفتاح العام وكتابته في ملف known_hosts من أجل التخلص من الخطأ أعلاه.

echo <public key> | base64 # выводит <публичный ключ, закодированный в base64>

في الممارسة العملية ، قد يبدو هذا الأمر كما يلي:

echo "123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== [email protected]" | base64

وإليكم ما تقدمه - سلسلة مشفرة base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

هنا هو الأمر المذكور أعلاه

install:
  - echo < публичный ключ, закодированный в base64> | base64 -d >> $HOME/.ssh/known_hosts

يمكن استخدام نفس الأسلوب مع مفتاح خاص عند إنشاء اتصال ، حيث قد تحتاج إلى مفتاح خاص للوصول إلى الخادم. عند العمل باستخدام مفتاح ، ما عليك سوى التأكد من تخزينه بشكل آمن في متغير بيئة Travis CI ، وعدم عرضه في أي مكان.

شيء آخر يجب ملاحظته هو أنك قد تحتاج إلى تشغيل البرنامج النصي للنشر بأكمله كسطر واحد ، على سبيل المثال مع doctl. قد يتطلب هذا بعض الجهد الإضافي.

doctl compute ssh <droplet> --ssh-command "все команды будут здесь && здесь"

TLS / SSL وموازنة الحمل

بعد أن فعلت كل ما سبق ، كانت المشكلة الأخيرة التي واجهتها هي أن الخادم لا يحتوي على SSL. نظرًا لأنني أستخدم خادم Node.js ، من أجل فرض عمل عكس الوكيل Nginx و Let's Encrypt ، فأنت بحاجة إلى العبث كثيرًا.

لم أرغب حقًا في القيام بكل إعدادات SSL يدويًا ، لذلك قمت للتو بإنشاء موازن تحميل وتسجيل معلومات عنه في DNS. في حالة DigitalOcean ، على سبيل المثال ، يعد إنشاء شهادة موقعة ذاتيًا للتجديد التلقائي على موازن التحميل إجراءً بسيطًا ومجانيًا وسريعًا. هذا النهج له فائدة إضافية تتمثل في تسهيل إعداد SSL على خوادم متعددة تعمل خلف موازن التحميل إذا لزم الأمر. هذا يسمح للخوادم نفسها بعدم "التفكير" في SSL على الإطلاق ، ولكن في نفس الوقت تستخدم ، كالعادة ، المنفذ 80. لذا فإن تكوين SSL على موازن التحميل أسهل بكثير وأكثر ملاءمة من طرق تكوين SSL البديلة.

يمكنك الآن إغلاق جميع المنافذ الموجودة على الخادم التي تقبل الاتصالات الواردة - باستثناء المنفذ 80، تستخدم للتواصل مع موازن التحميل والمنفذ 22 لـ SSH. نتيجة لذلك ، ستفشل محاولة الاتصال بالخادم مباشرة على أي منفذين بخلاف هذين المنفذين.

نتائج

بعد أن فعلت كل ما تحدثت عنه في هذه المقالة ، لم تعد منصة Docker ولا مفهوم سلاسل CI / CD المؤتمتة تخيفني بعد الآن. لقد تمكنت من إعداد سلسلة تكامل مستمرة ، يتم خلالها اختبار الكود قبل أن يدخل الإنتاج ويتم نشر الكود تلقائيًا على الخادم. كل هذا لا يزال جديدًا نسبيًا بالنسبة لي ، وأنا متأكد من أن هناك طرقًا لتحسين سير العمل الآلي الخاص بي وجعله أكثر كفاءة. لذلك إذا كان لديك أي أفكار حول هذا - أعط أنا يعرف. آمل أن يكون هذا المقال قد ساعدك في مساعيك. أريد أن أصدق أنه من خلال قراءته ، تعلمت قدر ما تعلمته بينما كنت أتعامل مع كل ما قلته عنه.

PS لدينا في المتجر هناك صورة عامل في حوض السفن، والتي يتم تثبيتها بنقرة واحدة. يمكنك التحقق من عمل الحاويات VPS. يتم منح جميع العملاء الجدد 3 أيام من الاختبار مجانًا.

القراء الأعزاء! هل تستخدم تقنيات CI / CD في مشاريعك؟

إنشاء سلسلة CI / CD وأتمتة العمل باستخدام Docker

المصدر: www.habr.com

إضافة تعليق