استفاده از Docker برای ساخت و اجرای برنامهها و دستورات، نیاز به دانش قبلی در برخی ابزارها یا زبانهای برنامهنویسی را برطرف میکند. همچنین، از نیاز به نصب ماژول ها و وابستگی های جدید به طور مستقیم به سیستم جلوگیری می کند، که توسعه را مستقل از ماشین می کند.
وضعیت زیر را تصور کنید: شما شروع به کار روی یک پروژه جدید می کنید، شاید همچنین با یک زبان برنامه نویسی متفاوت که به آن عادت ندارید. بنابراین، پروژه وجود دارد و شما باید بتوانید آن را اجرا کنید.
امیدوارید اسنادی وجود داشته باشد که به شما بگوید چه کاری انجام دهید – که چندان رایج نیست – و اگر/وقتی وجود داشته باشد، معمولاً کار نمی کند. تو باید بدانی چی برای نصب، جایی که برای نصب آن، چگونه این یک سناریوی غیر معمول نیست، و شما در واقع می توانید آن را در نقطه ای انتظار داشته باشید. اما اگر راهی برای اطمینان از عدم تکرار این اتفاق وجود داشت، چه؟
در طول این پست، رویکردهای مختلفی را خواهیم دید که میتوانیم از آنها برای آسانتر کردن این کار فقط با استفاده از Docker استفاده کنیم.
سطح اول: استفاده از نام مستعار با داکر
مثال با جاوا + 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 اطلاعاتی را منتشر کنید.
(yk, il)