استخدام docker متعدد المراحل لبناء صور الويندوز

أهلاً بكم! اسمي أندري، وأعمل كمهندس DevOps في Exness ضمن فريق التطوير. يرتبط نشاطي الرئيسي ببناء التطبيقات ونشرها ودعمها في عامل الإرساء ضمن نظام التشغيل Linux (المشار إليه فيما يلي باسم نظام التشغيل). منذ وقت ليس ببعيد، كانت لدي مهمة بنفس الأنشطة، ولكن نظام التشغيل المستهدف للمشروع كان Windows Server ومجموعة من مشاريع C++. بالنسبة لي، كان هذا أول تفاعل وثيق مع حاويات الإرساء ضمن نظام التشغيل Windows، وبشكل عام، مع تطبيقات C++. بفضل هذا، حصلت على تجربة مثيرة للاهتمام وتعرفت على بعض التعقيدات الخاصة بتطبيقات النقل بالحاويات في Windows.

استخدام docker متعدد المراحل لبناء صور الويندوز

في هذه المقالة أريد أن أخبركم بالصعوبات التي واجهتها وكيف تمكنت من حلها. آمل أن يكون هذا مفيدًا لتحدياتك الحالية والمستقبلية. استمتع بالقراءة!

لماذا الحاويات؟

تمتلك الشركة بنية تحتية حالية لمنسق حاوية Hashicorp Nomad والمكونات ذات الصلة - Consul وVault. ولذلك، تم اختيار حاويات التطبيقات كوسيلة موحدة لتقديم حل كامل. نظرًا لأن البنية التحتية للمشروع تحتوي على مضيفات عامل الإرساء مع الإصدارين 1803 و1809 من نظام التشغيل Windows Server Core، فمن الضروري إنشاء إصدارات منفصلة من صور عامل الإرساء للإصدارين 1803 و1809. في الإصدار 1803، من المهم أن تتذكر أن رقم مراجعة مضيف عامل الإرساء للبناء يجب أن يتطابق مع رقم مراجعة صورة عامل الإرساء الأساسية والمضيف حيث سيتم تشغيل الحاوية من هذه الصورة. الإصدار 1809 ليس لديه مثل هذا العيب. يمكنك قراءة المزيد هنا.

لماذا متعدد المراحل؟

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

من النظرية إلى العمل

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

دعونا نلقي نظرة على النقاط الرئيسية في البرنامج النصي dockerfile لإنشاء هذه الصورة.

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

يمكن العثور على قائمة كاملة بعلامات صور Microsoft Windows Server هنا.

ARG WINDOWS_OS_VERSION=1809
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

بشكل افتراضي الأوامر في التعليمات RUN داخل ملف dockerfile على نظام التشغيل Windows، يتم تنفيذها في وحدة التحكم cmd.exe. لسهولة كتابة البرامج النصية وتوسيع وظائف الأوامر المستخدمة، سنعيد تعريف وحدة تنفيذ الأوامر في Powershell من خلال التعليمات SHELL.

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

الخطوة التالية هي تثبيت مدير الحزم Chocolatey والحزم الضرورية:

COPY chocolatey.pkg.config .
RUN Set-ExecutionPolicy Bypass -Scope Process -Force ;
    [System.Net.ServicePointManager]::SecurityProtocol = 
    [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 ;
    $env:chocolateyUseWindowsCompression = 'true' ;
    iex ((New-Object System.Net.WebClient).DownloadString( 
      'https://chocolatey.org/install.ps1')) ;
    choco install chocolatey.pkg.config -y --ignore-detected-reboot ;
    if ( @(0, 1605, 1614, 1641, 3010) -contains $LASTEXITCODE ) { 
      refreshenv; } else { exit $LASTEXITCODE; } ;
    Remove-Item 'chocolatey.pkg.config'

لتثبيت الحزم باستخدام Chocolatey، يمكنك ببساطة تمريرها كقائمة، أو تثبيتها واحدة تلو الأخرى إذا كنت بحاجة إلى تمرير معلمات فريدة لكل حزمة. في حالتنا، استخدمنا ملف بيان بتنسيق XML، والذي يحتوي على قائمة بالحزم المطلوبة ومعلماتها. محتوياته تبدو مثل هذا:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="python" version="3.8.2"/>
  <package id="nuget.commandline" version="5.5.1"/>
  <package id="git" version="2.26.2"/>
</packages>

بعد ذلك، نقوم بتثبيت بيئة بناء التطبيق، وهي MS Build Tools 2019 - وهي نسخة خفيفة الوزن من Visual Studio 2019، والتي تحتوي على الحد الأدنى المطلوب من مجموعة المكونات لتجميع التعليمات البرمجية.
للعمل بشكل كامل مع مشروعنا C++، سنحتاج إلى مكونات إضافية، وهي:

  • أدوات عبء العمل C++
  • مجموعة الأدوات v141
  • ويندوز 10 SDK (10.0.17134.0)

يمكنك تثبيت مجموعة موسعة من الأدوات تلقائيًا باستخدام ملف تكوين بتنسيق JSON. محتويات ملف التكوين:

يمكن العثور على قائمة كاملة بالمكونات المتوفرة على موقع التوثيق مايكروسوفت فيجوال ستوديو.

{
  "version": "1.0",
  "components": [
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Workload.VCTools;includeRecommended",
    "Microsoft.VisualStudio.Component.VC.v141.x86.x64",
    "Microsoft.VisualStudio.Component.Windows10SDK.17134"
  ]
}

يقوم ملف dockerfile بتشغيل البرنامج النصي للتثبيت، وللتسهيل، يضيف المسار إلى الملفات القابلة للتنفيذ لأدوات البناء إلى متغير البيئة PATH. يُنصح أيضًا بإزالة الملفات والأدلة غير الضرورية لتقليل حجم الصورة.

COPY buildtools.config.json .
RUN Invoke-WebRequest 'https://aka.ms/vs/16/release/vs_BuildTools.exe' 
      -OutFile '.vs_buildtools.exe' -UseBasicParsing ;
    Start-Process -FilePath '.vs_buildtools.exe' -Wait -ArgumentList 
      '--quiet --norestart --nocache --config C:buildtools.config.json' ;
    Remove-Item '.vs_buildtools.exe' ;
    Remove-Item '.buildtools.config.json' ;
    Remove-Item -Force -Recurse 
      'C:Program Files (x86)Microsoft Visual StudioInstaller' ;
    $env:PATH = 'C:Program Files (x86)Microsoft Visual Studio2019BuildToolsMSBuildCurrentBin;' + $env:PATH; 
    [Environment]::SetEnvironmentVariable('PATH', $env:PATH, 
      [EnvironmentVariableTarget]::Machine)

في هذه المرحلة، صورتنا لتجميع تطبيق C++ جاهزة، ويمكننا المتابعة مباشرة لإنشاء بناء إرساء متعدد المراحل للتطبيق.

متعدد المراحل في العمل

سوف نستخدم الصورة التي تم إنشاؤها مع جميع الأدوات الموجودة على اللوحة كصورة بناء. كما هو الحال في البرنامج النصي السابق لملف dockerfile، سنضيف القدرة على تحديد رقم الإصدار/علامة الصورة ديناميكيًا لتسهيل إعادة استخدام التعليمات البرمجية. من المهم إضافة تسمية as builder إلى صورة التجميع في التعليمات FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

الآن حان الوقت لبناء التطبيق. كل شيء هنا بسيط للغاية: انسخ الكود المصدري وكل ما يرتبط به، وابدأ عملية التجميع.

COPY myapp .
RUN nuget restore myapp.sln ;
    msbuild myapp.sln /t:myapp /p:Configuration=Release

المرحلة الأخيرة من إنشاء الصورة النهائية هي تحديد الصورة الأساسية للتطبيق، حيث سيتم وضع جميع عناصر التجميع وملفات التكوين. لنسخ الملفات المترجمة من صورة التجميع المتوسطة، يجب عليك تحديد المعلمة --from=builder في التعليمات COPY.

FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

COPY --from=builder C:/x64/Release/myapp/ ./
COPY ./configs ./

الآن كل ما تبقى هو إضافة التبعيات اللازمة لكي يعمل تطبيقنا وتحديد أمر التشغيل من خلال التعليمات ENTRYPOINT أو CMD.

اختتام

تحدثت في هذه المقالة عن كيفية إنشاء بيئة تجميع كاملة لتطبيقات C++ داخل حاوية ضمن Windows وكيفية استخدام إمكانيات إنشاءات Docker متعددة المراحل لإنشاء صور كاملة لتطبيقنا.

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

إضافة تعليق