داکر چیست؟
قبل از پرداختن به تعریف داکر، کمی کانتینر رو مورد بحث قرار میدیم تا ببینیم کانتینرها چه کاری انجام میدن؟!
کانتینر در یک تعریف خلاصه، راهی برای بستهبندی و ارسال برنامههای شماست.
کانتینر یک واحد استاندارد نرمافزاریه که کدها و تمام وابستگیهای مربوط به اون رو بستهبندی میکنه.
بنابراین توسعهدهنده اطمینان پیدا میکنه که برنامه با انتقال از یک محیط محاسباتی به محیط محاسباتی دیگه، با سرعت بالا و به طور ایمن اجرا میشه.
حالا برای ساخت، مدیریت و استقرار کانتینرهایی که در بالا باهاش آشنا شدین، از ابزاری به نام داکر استفاده میشه.
داکر بستری برای کانتینری کردن برنامههاست:
یعنی برنامه و تمام وابستگیهای مربوط به اون رو به صورت یک کانتینر داکر بستهبندی میکنه، تا اطمینان حاصل بشه که برنامه در هر محیطی به طور یکپارچه کار میکنه.
این پست به شما کمک می کنه با جزئیات استفاده از داکر برای اجرای یک برنامهی تحت وب جاوا آشنا بشین.
پس در ادامه با همراه باشین!
اجرای یک برنامهی تحت وب جاوا با استفاده از داکر
داکر این امکان رو برای شما فراهم میکنه تا بتونین کل پروژهتون رو در یک ایمیج قابل حمل، داشته باشین.
ایمیج یک بستهی نرمافزاری سبک، مستقل و قابل اجراست که شامل تمام موارد لازم برای اجرای یک برنامه میشه:
مثلا کد، زمان اجرا، ابزار سیستم، کتابخانههای سیستم و تنظیمات.
این ایمیج، از لایههایRead-Only تشکیل شده.
لایهها روی هم قرار گرفتن و هر لایه، تغییرات لایه قبلی و دستورالعملهای موجود در Dockerfile رو مشخص میکنه.
این ایمیجها با صدا زدن Dockerfile ساخته میشن.
حالا سوال مهم اینه که Dockerfile چی هست؟
Dockerfile یک فایل متنیه که توی اون با یک سینتکس ساده و قابل فهم دستورالعملهای ساخت ایمیج قرار داده شده.
در واقع داکر با خوندن دستورالعملها از Dockerfile بهطور خودکار ایمیجها رو میسازه.
در قسمتهای بعدی این پست، چگونگی ایجاد Dockerfile برای پروژهی Spring.io/guides،
Push کردن ایمیج به Dockerhub و نحوهی اجرای local یک برنامهی کانتینری رو با هم بررسی میکنیم.
نگاه سریع به مفهوم داکر
چرا داکر؟
در بخشهای قبل گفتیم که داکر چه کاری انجام میده. حالا ببینیم استفاده از اون چه مزیتی میتونه داشته باشه؟
تصور کنین که در حال آنالیز یک کد هستین و این کد رو برای دوستتون ارسال میکنین.
دوست شما دقیقاً همون کد رو اجرا میکنه، اما نتیجهی متفاوت میگیره.
این امر میتونه، دلایل مختلفی داشته باشه. دلایلی مثل: سیستمعامل متفاوت، ورژن متفاوت یک برنامه و… . داکر در تلاشه تا مشکلاتی از این قبیل رو حل کنه.
برای اینکه این مفهوم رو بهتر درک کنین، یک کانتینر داکر رو میشه به یک رایانه در داخل کامپیوتر شما تشبیه کرد.
نکتهی جالب در مورد این کامپیوتر مجازی اینه که میتونین اون رو برای دوستانتون ارسال کنین؛
و زمانی که این رایانه رو راهاندازی کردن و کد شما رو اجرا کردن، دقیقاً نتیجهی یکسانی رو مشاهده میکنن.
داکر با استفاده از ایمیجها و کانتینرها، مشکل اجرای برنامه در سیستمهای مختلف رو حل میکنه.
تمام وابستگیهای برنامه در ایمیج ارائه میشه و برنامه در سیستم شما یا فرد مقابل، در کمتر از چند دقیقه یا حتی چند ثانیه اجرا میشه.
داکر رو به صورت محلی راهاندازی کنین
اولین قدم در ساخت کانتینر داکر برای برنامهی جاوا، اطمینان از نصب مجموعه ابزار Docker در سیستم شماست.
روش نصب و راهاندازی داکر برای سیستمعاملهای مختلف رو میتونین در وب سایت رسمی docker پیدا کنین!
توی این مثال روی سیستمعامل مک کار کردیم و در مورد نحوهی راهاندازی اون توضیح کوتاهی ارائه میکنیم.
خب اول یک حساب کاربری در سایت /https://cloud.docker.com ایجاد کنین.
به بخش Repositories برین، این قسمت خالیه و جاییه که ما میخوایم ایمیجهامون رو push کنیم.
و بعد برای نصب داکر در مک، دستورالعملهای موجود در سایت داکر رو دنبال کنین.
این کار بسیار سادهست و مشابه تصویر زیر، شما به یک علامت نهنگ دسترسی پیدا میکنین:
روی علامت نهنگ کلیک کنین و با حساب کاربری که هنگام ثبتنام در سایت cloud.docker.com ایجاد کرده بودین، لاگین کنین.
برای اینکه مطمئن بشین داکر نصب شده یا نه، بهترین روش اینه که از دستور زیر استفاده کنین:
$ docker --version
Docker version 18.09.0-ce, build 4d60db4
حالا در ادامه مراحل بعدی رو با هم بررسی میکنیم.
یک نمونه سورس برنامهی جاوا رو کلون کنین
همونطور که تو مقدمه هم گفتیم، میخوایم یک نمونه سورس برنامه spring.io/guides رو از گیتهاب دانلود کنیم.
و بعد برای اجرای این برنامه جاوا با استفاده از داکر، نیاز داریم Dockerfile رو بسازیم.
برای شروع کار، پروژه "Serving Web Content with Spring MVC" رو دانلود کنین تا کپی کاملی از ریپازیتوری مورد نظر به سیستم شما منتقل بشه:
git clone https://github.com/spring-guides/gs-serving-web-content.git
پروژهی spring guides، چند تا پوشه داره.
به دایرکتوری complete پروژهتون برین و فایل خالی به اسم Dockerfile رو به این دایرکتوری اضافه کنین:
cd ./complete
touch Dockerfile
حالا ساختار دایرکتوری فعلی شما باید شبیه ساختار زیر باشه:
├── Dockerfile
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── hello
│ │ ├── Application.java
│ │ └── GreetingController.java
│ └── resources
│ ├── static
│ │ └── index.html
│ └── templates
│ └── greeting.html
└── test
└── java
└── hello
└── ApplicationTest.java
کامپوننتهای دیگر داکر
قبل از این که بخوایم دستورهایی رو به Dockerfile اضافه کنیم، اجازه بدین کاری که Dockerfile انجام میده رو بیشتر براتون توضیح بدم!
Dockerfile همیشه با ایمیجی به نام "ایمیج بیس" شروع میشه.
یعنی هر ایمیج داکر از یک ایمیج پایه ساخته میشه:
این ایمیج پایه میتونه سیستم عامل سبک Red Hat باشه یا سیستم عامل بزرگی مثل Ubuntu.
بعد از اینکه ایمیج بیس رو مشخص کردین، ما بقی موارد روی این ایمیج انجام میشه.
یعنی میتونین چیزهای مختلفی رو به این ایمیج اضافه کنین یا "لایههایی" رو ایجاد کنین.
اگر با ایمیجی که پکیجهای جاوا رو نصب شده داره شروع کنین، دیگه لازم نیست جاوا رو
بعدا توی Dockerfile نصب کنین، اما اگه با ایمیجی که پکیجهای جاوا رو داره شروع نکنین، باید Java رو نصب کنین.
در پایان از این Dockerfile، برای ساخت ایمیجهای دیگه استفاده میشه.
حالا وقتشه که این ایمیج نهایی (با تمام وابستگیها و برنامههای اضافه شده به اون) رو با بقیه به اشتراک بذارین، تا به راحتی بتونن برنامهی شما رو نصب و اجرا کنن.
ساخت Dockerfile
گفتیم که برای ساخت Docker file باید یک ایمیج رو انتخاب کنیم تا به عنوان ایمیج بیس برنامه، مورد استفاده قرار بگیره.
در این مثال با Ubuntu شروع میکنیم.
برای ساخت ایمیج بیس Ubuntu، دستور زیر رو به داکر فایل اضافه کنین.
دستور FROM به داکر میگه که ایمیج شما از چه base ای قراره اجرا شه و بر پایهی چه چیزی باشه:
FROM ubuntu:latest
latest چیست؟
ایمیجها، tagهایی دارن که اغلب نشوندهندهی ورژن اون ایمیج هستن.
دستور "latest"، جدیدترین ایمیج منتشر شدهی Ubuntu رو از pull ،DockerHub میکنه.
و اما ببینیم DockerHub چیست؟
چون ایمیج به صورت local در سیستم ما قرار نداره، داکر اون رو از رجیستری دریافت میکنه و بعد ایمیج رو اجرا میکنه.
پس DockerHub رجیستری عمومی ایمیجها برای استفاده شما است!
نصب وابستگی در Dockerfile
حالا باید یک وابستگی رو نصب کنین؛ وابستگیای به نام jre (این وابستگی برای اجرای یک برنامه جاوا در هر دستگاهی مورد نیازه).
دستور RUN در Dockerfiles وجود داره که میتونین برای نصب وابستگی jre روی سیستم Ubuntu، ازش استفاده کنین:
RUN \
# Update
apt-get update -y && \
# Install Java
apt-get install default-jre -y
عالیه، تا الان توی ایمیج ما جاوا نصب شده.
حالا فایل jar کجاست؟
اگر ساختار پروژه رو به خاطر داشته باشین، یک برنامه جاوا رو به صورت local داشتیم. این برنامه رو باید به یک فایل rar تبدیل کنین. این کار رو میتونین با دستور mvn clean install، انجام بدین.
این دستور باید برنامهی جاوای شما رو بسازه و فایل jar اون رو توی دایرکتوری
target/gs-serving-web-content-0.1.0.jar/. قرار بده.
حالا که مسیر مربوط به فایل jar، در Dockerfile رو میشناسین، میتونین از دستور ADD داکر، استفاده کنین.
این دستور، فایل Spring-mvc-shembull.jar که حاوی برنامهی جاواست رو در دایرکتوری محلی target/gs-serving-web-content-0.1.0.jar/. قرار میده.
ADD ./target/gs-serving-web-content-0.1.0.jar spring-mvc-example.jar
وقتی برنامهی ما در حال اجراست، پورت 8080 اجرا میشه.
میتونین از دستور EXPOSE داکر، برای باز کردن این پورت استفاده کنین:
EXPOSE 8080
و در آخر، فایل jar رو اجرا کنین!
میتونین از دستور CMD داکر، برای اجرای فایل jar استفاده کنین.
با این دستور، داکر کانتینر رو وادار میکنه تا فایل spring-mvc-example.jar رو در زمان اجرا Run کنه:
CMD java -jar spring-mvc-example.jar
در مجموع، Dockerfile شما باید به شکل زیر باشه:
# Pull base image.
FROM ubuntu:latest
RUN \
# Update
apt-get update -y && \
# Install Java
apt-get install default-jre -y
ADD ./target/gs-serving-web-content-0.1.0.jar spring-mvc-example.jar
EXPOSE 8080
CMD java -jar spring-mvc-example.jar
احتمالا تا این مرحله به مزایای داکر پی برده باشین.
با استفاده از داکر میتونین روی کدنویسی تمرکز بیشتری داشته بشین و راحتتر از همیشه برنامهها رو در هر محیط عملیاتی اجرا کنین.
برای این کار از Dockerfile برای تولید ایمیجی استفاده میکنین که این ایمیج در هر محیطی که از داکر پشتیبانی کنه، میتونه رفتار و نتایج یکسانی رو به کاربر نشون بده.
بیایین ایمیج رو بصورت local بسازیم و اجرا کنیم
در این مرحله باز هم نیاز داریم تا فایل jar ساخته بشه. اگه تا الان نساختین، با دستور زیر این کار رو انجام بدین:
java -version
mvn --version
mvn clean install
برای ساخت ایمیجی به اسم spring-mvc-sample-image، از دستور docker build استفاده کنین:
docker build . -t spring-mvc-sample-image
ایمیج ساخته شده رو میتونین با دستور docker image مشاهده کنین:
$ docker images
REPOSITORY TAG IMAGE ID
CREATED SIZE
spring-mvc-sample-image latest 8fa27ad00edd 34 minutes ago 540MB
حالا بیایین بر اساس ایمیج spring-mvc-sample-image، کانتینری به اسم sample-mvc-sample-container رو بالا بیاریم:
docker run -t -p 8080:8080 --name sample-mvc-sample-container spring-mvc-sample-image
میتونین آپشن d- رو به دستور docker run، اضافه کنین تا کانتینر در background اجرا بشه؛
اما اگه دستور بالا رو با آپشن (t-) اجرا کنین، داخل کانتینر قرار میگیرین (و log های برنامهی Spring رو مشاهده میکنین).
با استفاده از آپشن t-، باید log هایی رو ببینین که نشون میده برنامه به درستی شروع شده.
اما اگه با d- کار کردین، برای پیدا کردن کانتینر از دستور docker ps -a و برای دیدن log های برنامهی Spring از دستور <docker logs <container_id استفاده کنین.
برای خروج از کانتینر از کلید ترکیبی ctrl + c استفاده کنین.
میتونین با دستور docker ps -a، گزارشی از کانتینرهای در حال اجرا رو مشاهده کنین:
$ docker ps -a
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
736f9cdc1499 spring-mvc-sample-image "/bin/sh -c 'java -j…"
2 hours ago Up 2 hours 8080/tcp sample-mvc-sample-container
کانتینر شما الان وجود داره و در حال اجراست!
اگه میخواین به کانتینری که برنامهی جاوا رو اجرا میکنه برگردین، دستور
docker exec -it <container-id> /bin/bash رو اجرا کنین.
tag و push کردن ایمیج در داکرهاب عمومی
زمانی که یک ایمیج جدید ساخته میشه، میتونین اون رو توی یک ریپازیتوری ریموت push کنین تا در دسترس بقیه هم قرار بگیره و بسته به نیاز بتونن اون ایمیج رو pull کرده و استفاده کنن.
اول با دستور docker images، ایمیجهای موجود رو لیست کنین و ایمیجی که ساختین رو پیدا کنین:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-mvc-sample-image latest 8fa27ad00edd 34 minutes ago 540MB
اگه ایمیج داکر رو اجرا میکنین، باید ریپازیتوری این ایمیج به شکل image name/نام کاربری (یا نام دلخواه) باشه.
مثلا اگه نام کاربری داکر شما gsweene2 باشه، میتونین به شکل
gsweene2/spring-mvc-sample-image:0.1 ایمیج رو tag گذاری کنین.
حالا شناسهٔ ایمیج خودمون رو پیدا میکنیم. در این مثال، id مورد نظر ما میشه 8fa27ad00edd.
از دستور docker tag و image id، برای tagگذاری ایمیج استفاده کنین.
دستوری که برای tag گذاری ایمیج تایپ میکنین شبیه دستور زیر است (یک تگ داکر شامل یک نام و یک ورژن است که با علامت : از هم جدا میشن):
docker tag 8fa27ad00edd gsweene2/spring-mvc-sample-image:0.1
این دستور نام مستعاری با نام gsweene2/spring-mvc-sample-image، ایجاد میکنه که به ایمیج 8fa27ad00edd اشاره داره.
رسیدیم به مرحلهی push؛ حالا میتونین ایمیجتون رو قرار بدین.
از دستور docker push، برای push کردن ایمیج استفاده کنین و از همون اسمی که در مرحلهی قبل برای تگگذاری استفاده کردین، در دستور push استفاده کنین، یعنی
gsweene2/spring-mvc-sample-image:0.1 .
docker push gsweene2/spring-mvc-sample-image:0.1
ایمیج خود را در DockerHub پیدا کنین
و در آخر بعد از لاگین در سایت cloud.docker.com، به صفحهی داکرهاب رفته و ایمیج جدید رو مشاهده کنین.
برای اینکه بتونین ایمیج رو راحتتر پیدا کنین، الگوی URL زیر رو بهتون پیشنهاد میکنیم:
https://cloud.docker.com/repository/docker/<username>/<image_name>
بعد از قرار دادن یک ایمیج، باید در داشبورد حساب کاربری شما مثل تصویر زیر نشون داده بشه:
سخن پایانی
تو این پست سعی کردیم ضمن معرفی داکر، شیوهی اجرای برنامههای جاوا با داکر رو براتون توضیح بدیم.
بهتون پیشنهاد میکنم برای آشنایی بیشتر با داکر، لینکهای زیر رو هم مطالعه کنین:
داکر برا توسعهدهندهها
چرا داکر میتواند به استارتاپها کمک کند؟