خلاصه سریع ↬
استفاده از Docker برای ساخت و اجرای برنامه‌ها و دستورات، نیاز به دانش قبلی در برخی ابزارها یا زبان‌های برنامه‌نویسی را برطرف می‌کند. همچنین، از نیاز به نصب ماژول ها و وابستگی های جدید به طور مستقیم به سیستم جلوگیری می کند، که توسعه را مستقل از ماشین می کند.

وضعیت زیر را تصور کنید: شما شروع به کار روی یک پروژه جدید می کنید، شاید همچنین با یک زبان برنامه نویسی متفاوت که به آن عادت ندارید. بنابراین، پروژه وجود دارد و شما باید بتوانید آن را اجرا کنید.

امیدوارید اسنادی وجود داشته باشد که به شما بگوید چه کاری انجام دهید – که چندان رایج نیست – و اگر/وقتی وجود داشته باشد، معمولاً کار نمی کند. تو باید بدانی چی برای نصب، جایی که برای نصب آن، چگونه این یک سناریوی غیر معمول نیست، و شما در واقع می توانید آن را در نقطه ای انتظار داشته باشید. اما اگر راهی برای اطمینان از عدم تکرار این اتفاق وجود داشت، چه؟

در طول این پست، رویکردهای مختلفی را خواهیم دید که می‌توانیم از آنها برای آسان‌تر کردن این کار فقط با استفاده از Docker استفاده کنیم.

زبانهای برنامه نویسی
(منبع: pngfind.com) (پیش نمایش بزرگ)

سطح اول: استفاده از نام مستعار با داکر

مثال با جاوا + Maven

برای مثال یک پروژه جاوا را در نظر می گیریم. معمولاً برای اجرای یک برنامه جاوا، اجرا می کنید java -jar application.jar.

برای تولید jar فایل‌ها و مدیریت وابستگی‌های پروژه، می‌توانید از ابزارهای مختلفی استفاده کنید که معروف‌ترین آن‌ها Maven و Gradle هستند. بیایید Maven را برای این مثال در نظر بگیریم. بیایید برخی از دستورات Maven را ببینیم:

  • mvn dependency:copy-dependencies
    اگر وابستگی ها هنوز دانلود نشده باشند، آن ها را دانلود می کند.
  • mvn package
    برنامه را می سازد و آن را تولید می کند jar. همچنین اگر وابستگی ها هنوز دانلود نشده باشند را دانلود می کند. اگر می‌خواهید از اجرای آزمایش‌ها در فرآیند ساخت صرفنظر کنید، می‌توانید آن را نیز پاس کنید -Dmaven.test.skip=true پارامتر.

با فرض اینکه به Maven 3 و Java 11 نیاز داریم، به این ترتیب می توانید از Docker استفاده کنید:

alias java="docker run -v "$PWD":/home -w /home openjdk:11-jre-slim java"
alias mvn='docker run -it --rm --name maven -v "$(pwd)":/usr/src/mymaven -w /usr/src/mymaven maven:3-jdk-11-slim mvn'

به این ترتیب می توانید هر دستور Maven و Java را بدون نیاز به نصب جاوا یا Maven اجرا کنید. می توانید دستورات را با اجرا تست کنید java -version یا mvn -version. معمولاً تصویر رسمی Docker این ابزارها به شما دستورالعمل هایی در مورد نحوه اجرای آن می دهد و شما فقط می توانید یک نام مستعار برای آن ایجاد کنید.

طرفداران:

  • اگر دیگر نیازی به استفاده از آن ندارید، می توانید تصویر Docker مربوطه را حذف کنید.
  • تغییر نسخه آسان است.

معایب:

  • در این مثال، شما هنوز باید دریابید که از چه نسخه جاوا و چه ابزاری (در این مورد Maven) و نسخه آن استفاده شده است.
  • اگر با یک زبان برنامه نویسی سر و کار دارید که نمی دانید، زمان بیشتری طول می کشد تا بفهمید چه کاری باید انجام دهید.
  • هنوز باید بدانید که کدام دستورات را اجرا کنید.

این یک رویکرد منصفانه است، به خصوص اگر بدانید که چه کاری انجام می دهید. اما این با خود پروژه همراه نیست. بنابراین، بیایید سعی کنیم آن را کمی بهبود دهیم.

بیشتر بعد از پرش! ادامه مطلب زیر ↓

سطح دو: استفاده از Docker برای اجرای برنامه

آنجاست Dockerfile شروع به درخشش می کند ما می دانیم که چگونه فقط با استفاده از Docker دستورات را اجرا کنیم، اما چگونه برنامه را اجرا کنیم؟

یک Dockerfile رایج برای آن موقعیت می تواند این باشد:

FROM openjdk:11-jre-slim

ARG JAR_FILE=target/*.jar

ADD ${JAR_FILE} app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

و شما می توانید آن را به روشی که معمولاً یک تصویر داکر می سازید، با استفاده از آن بسازید docker build -t my-application .، مثلا.

می توانید ببینید که به یک موجود بستگی دارد JAR فایل برای ساخت آن همانطور که در مبحث قبلی دیدید، ما می دانیم که چگونه آن را تولید کنیم، اما اگر زبان برنامه نویسی یا ابزار دیگری باشد، با مشکل مواجه می شویم.

به نظر می رسد یک پیشرفت بسیار جزئی است، اما در حال حاضر بسیار کمک می کند، همانطور که می توانید در مزایا / معایب آن ببینید:

طرفداران

  • Dockerfile باید داخل پروژه باشد. بنابراین، از قبل به شما می گوید که چگونه برنامه را بدون توجه به دانش زبان برنامه نویسی اجرا کنید.
  • همچنین به شما می گوید که از کدام نسخه و تصویر استفاده می شود.
  • آن را از جوانب مثبت به ارث می برد مرحله اول موضوع اگر شما نیز درخواست دهید مرحله اول دانش

منفی

  • هنوز باید نحوه ساخت اپلیکیشن را بیابید.
  • همچنین به این معنی است که شما هنوز باید بدانید که کدام دستورات را اجرا کنید.

رویکرد خوبی است. می توانید ادغام کنید مرحله اول و سطح دو برای رسیدن به نتیجه بهتر این پروژه باید Dockerfile داشته باشد و زندگی در حال حاضر کمی آسان تر می شود. اما بیایید ببینیم زندگی چگونه می تواند یکنواخت باشد آسان تر.

سطح سه: استفاده از Docker برای ساخت و اجرای برنامه

اگر چیزی در مورد جاوا و Maven نمی دانستید و هنوز هم می توانستید برنامه را فقط با یک دستور که قبلاً می دانید بسازید، چه می کنید؟

آنجاست ساخت های چند مرحله ای درخشیدن

با ساخت‌های چند مرحله‌ای، از چندین عبارت «FROM» در Dockerfile خود استفاده می‌کنید. هر دستور «FROM» می‌تواند از پایه متفاوتی استفاده کند و هر کدام از آنها مرحله جدیدی از ساخت را آغاز می‌کنند. شما می توانید به طور انتخابی مصنوعات را از یک مرحله به مرحله دیگر کپی کنید و هر چیزی را که نمی خواهید در تصویر نهایی پشت سر بگذارید.

چگونه می تواند به ما کمک کند؟ خوب، اجازه دهید Dockerfile قبلی را در نظر بگیریم. ما به یک نیاز داشتیم JAR فایل برای ساخت تصویر داکر. با ساخت چند مرحله ای، خود Dockerfile می تواند مسئول تولید آن باشد. در یک رویکرد ساده، Dockerfile به شکل زیر است:

# ============= DEPENDENCY + BUILD ===========================
# Download the dependencies on container and build application
# ============================================================

FROM maven:3-jdk-11-slim AS builder

COPY ./pom.xml /app/pom.xml
COPY . /app

WORKDIR /app

RUN mvn package $MAVEN_CLI_OPTS -Dmaven.test.skip=true

# ============= DOCKER IMAGE ================
# Prepare container image with application artifacts
# ===========================================

FROM openjdk:11-jre-slim

COPY --from=builder /app/target/*.jar app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

بیایید ببینیم اینجا چه خبر است.

از اول FROM به اولی RUN بیانیه، در حال انجام کارهای مربوط به Maven است – کپی کردن فایل هایی که باید کپی شوند و دستوری را اجرا می کند که وابستگی ها را دانلود می کند و برنامه را می سازد. این کار را با استفاده از maven:3-jdk-11-slim تصویر، و نام را تنظیم می کند builder.

بعد از آن دومی را می بینید FROM بیانیه با استفاده از openjdk:11-jre-slim تصویر شما همچنین می بینید COPY بیانیه ای که از مکانی به نام کپی می شود builder. اما اون چیه محل? آن چیست سازنده?

این نامی است که در ابتدا برای تصویر Maven تعیین کردیم FROM بیانیه. داره کپی میکنه jar فایل از آن ظرف بنابراین، شما می توانید به معنای واقعی کلمه با موارد مختلف بازی کنید FROM ورودی‌ها برای ساختن هر چیزی که می‌خواهید، و دستور ساخت تصویر Docker همچنان یکسان است: docker build -t my-application ..

طرفداران:

  • صرف نظر از زبان برنامه نویسی، اگر پروژه دارای این رویکرد باشد، می توانید برنامه را بدون نصب چیزی غیر از Docker اجرا کنید.
  • از جوانب مثبت به ارث می برد مرحله اول و سطح دو.

شایان ذکر است که می توانید از این Dockerfile نیز استفاده کنید Docker Compose، که می تواند واقعاً قدرتمند باشد، به خصوص اگر برنامه شما نیاز به نمایش پورت ها، به اشتراک گذاری حجم ها یا بستگی به تصاویر دیگر دارد.

پیوست: استفاده از Docker برای هر دستور اصلی

اکنون که می دانید چگونه با بازی های مختلف بازی کنید FROM اظهارات، یک Dockerfile ممکن دیگر می تواند باشد:

# ============= DEPENDENCY RESOLVER =============
# Download the dependencies on container
# ===============================================

FROM maven:3-jdk-11-slim AS dependency_resolver

# Download all library dependencies
COPY ./pom.xml /app/pom.xml

WORKDIR /app

RUN mvn dependency:copy-dependencies $MAVEN_CLI_OPTS

# ============= TESTING =================
# Run tests on container
# =======================================

FROM dependency_resolver AS tester

WORKDIR /app

CMD mvn clean test $MAVEN_CLI_OPTS

# ============= BUILDER =================
# Build the artifact on container
# =======================================

FROM dependency_resolver as builder

# Build application
COPY . /app

RUN mvn package $MAVEN_CLI_OPTS -Dmaven.test.skip=true

# ============= DOCKER IMAGE ================
# Prepare container image with application artifacts
# ===========================================

FROM openjdk:11-jre-slim

COPY --from=builder /app/target/*.jar app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

بنابراین، اکنون ما چهار مرحله مختلف داریم: dependency_resolver، tester، builderو خود برنامه

اگر بخواهیم برنامه را بسازیم یا آن را آزمایش کنیم، به وابستگی های پروژه نیاز داریم. بنابراین، یک وجود دارد dependency_resolver آنجا قدم بگذار در دومی و سومی FROM بیانیه ها، می توانید ببینید که به آنها بستگی دارند dependency_resolver.

مهم: اگر سعی کنید تصویر داکر را با docker build -t my-application .، فقط اولین و سومین و آخرین مرحله (dependency_resolver، builderو خود برنامه به ترتیب) اجرا می شود.

اما چرا؟

وقتی سعی می‌کنید تصویر را بسازید، سعی می‌کند ببیند وضعیت نهایی تصویر چیست، که خود برنامه کاربردی خواهد بود. همانطور که می دانیم و می بینیم، آخرین مرحله بستگی به این دارد builder (COPY بیانیه). اگر بررسی کنیم builder مرحله، خواهیم دید که بستگی دارد dependency_resolver (FROM بیانیه). بنابراین، به ترتیب زیر اجرا می شود:

dependency_resolver -> builder -> برنامه

بعدش چیه tester مرحله انجام وجود دارد؟ آیا راهی برای رسیدن به آن وجود دارد؟

با استفاده از آن می توانید یک هدف را مشخص کنید --target: docker build --target tester -t my-application ..

این هم هست سازگار با Docker Compose.

نتیجه

ما دیدیم که چگونه می توان از Docker برای ساخت و اجرای برنامه ها و دستورات استفاده کرد و نیاز به دانش قبلی در برخی ابزارها یا زبان های برنامه نویسی را از بین برد. همچنین، شایان ذکر است که اگرچه ما از Docker برای این نمونه‌ها استفاده کرده‌ایم، این کار با سایر زمان‌های اجرای کانتینر مانند Podman نیز کار می‌کند.

امیدوارم این پست برای شما مفید بوده باشد و در مورد Docker اطلاعاتی را منتشر کنید.

سرمقاله Smashing
(yk, il)