| DOCKERFILE(5) | Docker User Manuals | DOCKERFILE(5) |
نام (NAME)
Dockerfile - خودکارسازی مراحل ایجاد ایمیج Docker
مقدمه (INTRODUCTION)
پرونده Dockerfile یک فایل پیکربندی است که مراحل ایجاد یک ایمیج Docker را خودکار میکند. این فایل مشابه Makefile است. Docker دستورالعملها را از Dockerfile میخواند تا مراحلی را که در غیر این صورت برای ایجاد ایمیج به صورت دستی انجام میشدند، خودکار سازد. برای ساخت یک ایمیج، فایلی به نام Dockerfile ایجاد کنید.
پرونده Dockerfile مراحل انجامشده برای سرهمبندی ایمیج را توصیف میکند. پس از ایجاد Dockerfile، دستور docker build را فراخوانی کنید و مسیر دایرکتوری حاوی Dockerfile را به عنوان آرگومان به آن بدهید.
خلاصه دستور (SYNOPSIS)
INSTRUCTION arguments
برای مثال:
FROM image
شرح (DESCRIPTION)
پرونده Dockerfile فایلی است که مراحل ایجاد یک ایمیج Docker را خودکار میکند. یک Dockerfile شبیه به یک Makefile است.
نحوه استفاده (USAGE)
docker build .
-- مراحل را اجرا کرده و آنها را کامیت میکند، و یک ایمیج نهایی میسازد. مسیر منتهی به مخزن مبدأ مشخص میکند زمینه (context) ساخت کجا پیدا شود. ساخت توسط دیمن Docker اجرا میشود، نه CLI. کل زمینه باید به دیمن منتقل شود. هنگامی که زمینه به دیمن ارسال میشود، Docker CLI پیام "Sending build context to Docker daemon" را گزارش میدهد.
docker build -t repository/tag .
-- یک مخزن و یک برچسب (tag) را مشخص میکند که ایمیج جدید در صورت موفقیتآمیز بودن فرآیند ساخت در آن ذخیره شود. دیمن Docker مراحل را یکی پس از دیگری اجرا کرده، در صورت لزوم نتیجه را در یک ایمیج جدید کامیت میکند و در نهایت شناسه (ID) ایمیج جدید را در خروجی نمایش میدهد. دیمن Docker به طور خودکار زمینهای را که دریافت کرده پاکسازی میکند.
Docker هر زمان که ممکن باشد از ایمیجهای میانی مجدداً استفاده میکند. این کار فرآیند docker build را به طور چشمگیری سریعتر میکند.
قالب (FORMAT)
FROM image
FROM image:tag
FROM image@digest
-- دستورالعمل FROM ایمیج پایه را برای دستورالعملهای بعدی مشخص میکند. یک Dockerfile معتبر باید FROM را به عنوان نخستین دستورالعمل خود داشته باشد. ایمیج میتواند هر ایمیج معتبری باشد. شروع کار با دریافت (pull) یک ایمیج از مخازن عمومی آسان است.
-- دستورالعمل FROM باید نخستین دستورالعمل غیرکامنت در Dockerfile باشد.
-- دستورالعمل FROM میتواند چندین بار در یک Dockerfile ظاهر شود تا چندین ایمیج ایجاد کند. شناسه آخرین ایمیج تولیدشده توسط کامیت را قبل از هر دستور جدید FROM یادداشت کنید.
-- اگر هیچ برچسبی (tag) به دستورالعمل FROM داده نشود، Docker تگ latest را اعمال میکند. اگر تگ استفادهشده وجود نداشته باشد، یک خطا برگردانده میشود.
-- اگر هیچ دایجستی (digest) به دستورالعمل FROM داده نشود، Docker تگ latest را اعمال میکند. اگر تگ استفادهشده وجود نداشته باشد، یک خطا برگردانده میشود.
MAINTAINER
-- فیلد Author را
برای
ایمیجهای
تولیدشده
تنظیم
میکند.
برای ارائه
یک ایمیل یا
آدرس
اینترنتی (URL)
جهت
پشتیبانی
به کاربران
مفید است.
RUN
--
دستورالعمل
RUN دارای دو
شکل است:
# the command is run in a shell - /bin/sh -c RUN <command> # Executable form RUN ["executable", "param1", "param2"]
-- دستورالعمل RUN هر دستوری را در یک لایه جدید روی ایمیج فعلی اجرا کرده و نتایج را کامیت میکند. ایمیج کامیتشده برای مرحله بعدی در Dockerfile استفاده میشود.
-- لایهبندی دستورالعملهای RUN و ایجاد کامیتها با مفاهیم اصلی Docker مطابقت دارد، جایی که کامیتها کمهزینه هستند و کانتینرها را میتوان از هر نقطهای در تاریخچه یک ایمیج ایجاد کرد. این شبیه به سیستمهای کنترل نسخه است. فرمت exec امکان جلوگیری از دگرگونی رشته شل (shell string munging) را فراهم میکند. فرمت exec امکان اجرای دستورات RUN را با استفاده از یک ایمیج پایه که فاقد /bin/sh است فراهم میسازد.
توجه داشته باشید که فرمت exec به عنوان یک آرایه JSON تجزیه میشود، به این معنی که باید از نقلقول دوگانه (") در اطراف کلمات استفاده کنید نه نقلقول تکی (').
CMD
--
دستورالعمل
CMD سه شکل
دارد:
# Executable form CMD ["executable", "param1", "param2"] # Provide default arguments to ENTRYPOINT CMD ["param1", "param2"] # the command is run in a shell - /bin/sh -c CMD command param1 param2
-- باید تنها یک دستورالعمل CMD در یک Dockerfile وجود داشته باشد. اگر بیش از یک CMD درج شود، تنها آخرین CMD اعمال خواهد شد. هدف اصلی یک CMD ارائه مقادیر پیشفرض برای یک کانتینر در حال اجرا است. این پیشفرضها ممکن است شامل یک فایل اجرایی باشند، یا میتوانند فایل اجرایی را حذف کنند. اگر فایل اجرایی را حذف کنند، باید یک ENTRYPOINT مشخص شود. هنگامی که در قالبهای shell یا exec استفاده میشود، دستورالعمل CMD دستوری را که باید هنگام اجرای ایمیج اجرا شود تعیین میکند. اگر از فرم شل CMD استفاده کنید، <command> در /bin/sh -c اجرا میشود:
توجه داشته باشید که فرمت exec به عنوان یک آرایه JSON تجزیه میشود، به این معنی که باید از نقلقول دوگانه (") در اطراف کلمات استفاده کنید نه نقلقول تکی (').
FROM ubuntu CMD echo "This is a test." | wc -
-- اگر command را بدون شل اجرا میکنید، باید دستور را به صورت یک آرایه JSON بنویسید و مسیر کامل به فایل اجرایی را ارائه دهید. این فرم آرایهای، شکل ارجح CMD است. تمام پارامترهای اضافی باید به صورت جداگانه به عنوان رشته در آرایه مشخص شوند:
FROM ubuntu CMD ["/usr/bin/wc","--help"]
-- برای اینکه کانتینر هر بار همان فایل اجرایی یکسان را اجرا کند، از ENTRYPOINT در ترکیب با CMD استفاده کنید. اگر کاربر آرگومانهایی را برای docker run مشخص کند، دستورات مشخصشده مقادیر پیشفرض را در CMD بازنویسی میکنند. RUN را با CMD اشتباه نگیرید. RUN یک دستور را اجرا کرده و نتیجه را کامیت میکند. CMD در زمان ساخت هیچ چیزی اجرا نمیکند، بلکه دستور مورد نظر را برای ایمیج تعیین مینماید.
LABEL
-- LABEL <key>=<value> [<key>=<value> ...]
یا
LABEL <key>[ <value>] LABEL <key>[ <value>] ...
دستورالعمل LABEL متادیتا را به یک ایمیج اضافه میکند. یک LABEL یک جفت کلید-مقدار (key-value) است. برای مشخص کردن یک LABEL بدون مقدار، کافی است از یک رشته خالی استفاده کنید. برای گنجاندن فاصله درون مقدار یک LABEL، از نقلقول و بکاسلش همانطور که در پردازش خط فرمان انجام میدهید استفاده کنید.
LABEL com.example.vendor="ACME Incorporated" LABEL com.example.vendor "ACME Incorporated" LABEL com.example.vendor.is-beta "" LABEL com.example.vendor.is-beta= LABEL com.example.vendor.is-beta=""
یک ایمیج میتواند بیش از یک برچسب (label) داشته باشد. برای مشخص کردن چندین برچسب، هر جفت کلید-مقدار را با یک فاصله جدا کنید.
برچسبها خاصیت افزایشی دارند، از جمله LABELها در ایمیجهای FROM. هنگامی که سیستم با یک برچسب جدید مواجه شده و آن را اعمال میکند، keyهای جدید جایگزین هر برچسب قبلی با کلیدهای یکسان میشوند.
برای نمایش برچسبهای یک ایمیج، از دستور docker inspect استفاده کنید.
STOPSIGNAL
-- STOPSIGNAL <signal> دستورالعمل STOPSIGNAL سیگنال فراخوانی سیستمی را تنظیم میکند که برای خروج به کانتینر ارسال خواهد شد. این سیگنال میتواند یک نام سیگنال در قالب SIG، برای مثال SIGKILL، یا یک عدد بدون علامت باشد که با موقعیتی در جدول syscall هسته مطابقت دارد، برای مثال 9. در صورت عدم تعیین، مقدار پیشفرض SIGTERM است.
سیگنال خروج پیشفرض ایمیج را میتوان به ازای هر کانتینر با استفاده از پرچم --stop-signal در docker-run(1) و docker-create(1) بازنویسی کرد.
EXPOSE
-- EXPOSE <port> [<port>...]
دستورالعمل
EXPOSE به Docker
اطلاع
میدهد که
کانتینر در
زمان اجرا
به
پورتهای
شبکه
مشخصشده
گوش میدهد.
Docker از این
اطلاعات
برای
برقراری
ارتباط
متقابل
میان
کانتینرها
با استفاده
از لینکها
و تنظیم
بازهدایت
پورت (port redirection) روی
سیستم
میزبان
استفاده
میکند.
ENV
-- ENV <key> <value>
دستورالعمل
ENV متغیر
محیطی را
روی مقدار
<value> تنظیم
میکند. این
مقدار به
تمام
دستورالعملهای
بعدی RUN، ENTRYPOINT
و CMD ارسال
میشود. این
از نظر
عملکرد
معادل
پیشوند
قرار دادن
<key>=<value> قبل از
دستور است.
متغیرهای
محیطی که با
ENV تنظیم
میشوند،
هنگام
اجرای یک
کانتینر از
ایمیج حاصل
پایدار
میمانند.
از docker inspect برای
بررسی این
مقادیر
استفاده
کنید و با
استفاده از
docker run --env <key>=<value>
آنها را
تغییر
دهید.
توجه داشته باشید که تنظیم "ENV DEBIAN_FRONTEND=noninteractive" ممکن است عواقب ناخواستهای داشته باشد، زیرا هنگام اجرای تعاملی کانتینر، مانند دستور زیر، پایدار خواهد ماند: docker run -t -i image bash
ADD
--
دستورالعمل
ADD دو شکل
دارد:
ADD <src> <dest> # Required for paths with whitespace ADD ["<src>",... "<dest>"]
دستورالعمل ADD فایلها، دایرکتوریهای جدید یا URLهای فایلهای راه دور را در فایلسیستم کانتینر در مسیر <dest> کپی میکند. منابع چندگانه <src> را میتوان مشخص کرد، اما اگر آنها فایل یا دایرکتوری باشند باید نسبت به دایرکتوری مبدأ که در حال ساخت است (زمینه ساخت) نسبی باشند. مقدار <dest> یک مسیر مطلق یا مسیر نسبی به WORKDIR است که مبدأ در داخل کانتینر مقصد در آن کپی میشود. اگر آرگومان <src> یک فایل محلی در یک فرمت فشردهسازی شناختهشده (tar, gzip, bzip2 و غیره) باشد، در مسیر <dest> مشخصشده در فایلسیستم کانتینر باز (unpack) میشود. توجه داشته باشید که تنها فایلهای فشرده محلی باز خواهند شد، به این معنی که ویژگیهای دانلود URL و باز کردن آرشیو نمیتوانند با هم استفاده شوند. تمام دایرکتوریهای جدید با مجوز 0755 و با uid و gid برابر با 0 ایجاد میشوند.
COPY
--
دستورالعمل
COPY دو شکل
دارد:
COPY <src> <dest> # Required for paths with whitespace COPY ["<src>",... "<dest>"]
دستورالعمل COPY فایلهای جدید را از <src> کپی کرده و به فایلسیستم کانتینر در مسیر مشخصشده اضافه میکند. مقدار <src> باید مسیر یک فایل یا دایرکتوری نسبی به دایرکتوری مبدأ باشد که در حال ساخت است (زمینه ساخت) یا یک URL فایل راه دور. مقدار <dest> یک مسیر مطلق یا مسیر نسبی به WORKDIR است که مبدأ در داخل کانتینر مقصد در آن کپی خواهد شد. اگر یک فایل آرشیو را COPY کنید، دقیقاً همانطور که در زمینه ساخت ظاهر میشود در کانتینر قرار میگیرد، بدون اینکه تلاشی برای باز کردن آن انجام شود. تمام فایلها و دایرکتوریهای جدید با مجوز 0755 و با uid و gid برابر با 0 ایجاد میشوند.
ENTRYPOINT
--
دستورالعمل
ENTRYPOINT دو شکل
دارد:
# executable form ENTRYPOINT ["executable", "param1", "param2"] # run command in a shell - /bin/sh -c ENTRYPOINT command param1 param2
-- یک ENTRYPOINT به شما کمک میکند کانتینری را پیکربندی کنید که بتواند به عنوان یک فایل اجرایی اجرا شود. هنگامی که یک ENTRYPOINT را مشخص میکنید، کل کانتینر طوری اجرا میشود که گویی فقط همان فایل اجرایی است. دستورالعمل ENTRYPOINT یک دستور ورودی اضافه میکند که با ارسال آرگومانها به docker run بازنویسی نمیشود. این متفاوت از رفتار CMD است. این امر اجازه میدهد تا آرگومانها به entrypoint ارسال شوند، به عنوان مثال docker run <image> -d آرگومان -d را به ENTRYPOINT ارسال میکند. پارامترها را یا در آرایه JSON دستورالعمل ENTRYPOINT (همانند فرم ارجح exec در بالا)، یا با استفاده از یک عبارت CMD مشخص کنید. پارامترهای درون ENTRYPOINT توسط آرگومانهای docker run بازنویسی نمیشوند. پارامترهای مشخصشده از طریق CMD توسط آرگومانهای docker run بازنویسی میشوند. یک رشته ساده را برای ENTRYPOINT مشخص کنید، و آن همانند یک دستورالعمل CMD در /bin/sh -c اجرا خواهد شد:
FROM ubuntu ENTRYPOINT wc -l -
این بدان معناست که ایمیج این Dockerfile همیشه ورودی استاندارد (stdin) را به عنوان ورودی میگیرد (این معنای "-" است)، و تعداد خطوط را چاپ میکند (این معنای "-l" است). برای اینکه این رفتار اختیاری اما پیشفرض باشد، از یک CMD استفاده کنید:
FROM ubuntu CMD ["-l", "-"] ENTRYPOINT ["/usr/bin/wc"]
VOLUME
-- VOLUME ["/data"]
دستورالعمل
VOLUME یک نقطه
اتصال (mount point) با
نام
مشخصشده
ایجاد
میکند و آن
را به عنوان
نگهدارنده
حجمهای
متصلشده
خارجی از
میزبان
بومی یا از
سایر
کانتینرها
نشانهگذاری
مینماید.
USER
-- USER daemon
نام کاربری
یا UID مورد
استفاده
برای اجرای
دستورات
بعدی را
تنظیم
میکند.
دستورالعمل USER را میتوان به صورت اختیاری برای تنظیم گروه یا GID استفاده کرد. مثالهای زیر همگی معتبر هستند:
USER [user | user:group | uid | uid:gid | user:gid | uid:group ]
تا زمانی که دستورالعمل USER تنظیم نشده باشد، دستورالعملها به عنوان root اجرا خواهند شد. دستورالعمل USER را میتوان هر چند بار در یک Dockerfile استفاده کرد، و تنها بر دستورات بعدی تأثیر میگذارد.
WORKDIR
-- WORKDIR /path/to/workdir
دستورالعمل
WORKDIR
دایرکتوری
کاری را
برای
دستورات RUN،
CMD، ENTRYPOINT، COPY و ADD
در Dockerfile که پس
از آن
میآیند
تنظیم
میکند.
میتوان از
آن چندین
بار در یک Dockerfile
استفاده
کرد.
مسیرهای
نسبی نسبت
به مسیر
دستورالعمل
WORKDIR قبلی
تعریف
میشوند.
برای مثال:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
در مثال بالا، خروجی دستور pwd برابر با a/b/c است.
ARG
-- ARG [=]
دستورالعمل ARG متغیری را تعریف میکند که کاربران میتوانند در زمان ساخت با دستور docker build با استفاده از پرچم --build-arg <varname>=<value> به سازنده ارسال کنند. اگر کاربر یک آرگومان ساخت را مشخص کند که در Dockerfile تعریف نشده است، فرآیند ساخت یک هشدار صادر میکند.
[Warning] One or more build-args [foo] were not consumed
نویسنده Dockerfile میتواند با یک بار مشخص کردن ARG یک متغیر واحد تعریف کند یا با مشخص کردن ARG به دفعات، متغیرهای متعددی را تعریف نماید. به عنوان مثال، یک Dockerfile معتبر:
FROM busybox ARG user1 ARG buildno ...
یک نویسنده Dockerfile ممکن است به صورت اختیاری یک مقدار پیشفرض برای یک دستورالعمل ARG مشخص کند:
FROM busybox ARG user1=someuser ARG buildno=1 ...
اگر یک مقدار ARG دارای پیشفرض باشد و مقداری در زمان ساخت ارسال نشود، سازنده از مقدار پیشفرض استفاده میکند.
تعریف یک متغیر ARG از خطی که در آن در Dockerfile تعریف شده است اعمال میشود، نه از زمان استفاده از آرگومان در خط فرمان یا جای دیگر. برای مثال، این Dockerfile را در نظر بگیرید:
1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...
کاربر این فایل را با فراخوانی دستور زیر میسازد:
$ docker build --build-arg user=what_user Dockerfile
دستور USER در خط ۲ به some_user ارزیابی میشود، زیرا متغیر user در خط ۳ تعریف شده است. دستور USER در خط ۴ به what_user ارزیابی میشود، زیرا user تعریف شده و مقدار what_user در خط فرمان ارسال شده بود. پیش از تعریف آن توسط یک دستورالعمل ARG، هرگونه استفاده از متغیر منجر به یک رشته خالی میشود.
هشدار: استفاده از متغیرهای زمان ساخت برای انتقال دادههای محرمانه و اسرار مانند کلیدهای github، اعتبارنامههای کاربری و غیره توصیه نمیشود. مقادیر متغیرهای زمان ساخت با دستور docker history برای هر کاربری که به ایمیج دسترسی دارد قابل مشاهده است.
میتوانید از یک دستورالعمل ARG یا یک دستورالعمل ENV برای مشخص کردن متغیرهایی که در دسترس دستورالعمل RUN هستند استفاده کنید. متغیرهای محیطی تعریفشده با دستورالعمل ENV همیشه یک دستورالعمل ARG همنام را بازنویسی میکنند. این Dockerfile را با یک دستورالعمل ENV و ARG در نظر بگیرید.
1 FROM ubuntu 2 ARG CONT_IMG_VER 3 ENV CONT_IMG_VER=v1.0.0 4 RUN echo $CONT_IMG_VER
سپس، فرض کنید این ایمیج با این دستور ساخته شود:
$ docker build --build-arg CONT_IMG_VER=v2.0.1 Dockerfile
در این حالت، دستورالعمل RUN به جای تنظیمات ARG ارسالشده توسط کاربر یعنی v2.0.1، از v1.0.0 استفاده میکند. این رفتار مشابه یک اسکریپت شل است که در آن متغیری با محدوده محلی، از نقطه تعریف خود، متغیرهای ارسالشده به عنوان آرگومان یا به ارث رسیده از محیط را بازنویسی میکند.
با استفاده از مثال بالا اما با تعریف متفاوتی از ENV میتوانید تعاملات مفیدتری میان دستورالعملهای ARG و ENV ایجاد کنید:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
4 RUN echo $CONT_IMG_VER
برخلاف دستورالعمل ARG، مقادیر ENV همیشه در ایمیج ساختهشده پایدار میمانند. ساخت داکر را بدون فلگ --build-arg در نظر بگیرید:
$ docker build Dockerfile
با استفاده از این مثال Dockerfile، مقدار CONT_IMG_VER همچنان در ایمیج پایدار میماند، اما مقدار آن v1.0.0 خواهد بود زیرا پیشفرضی است که در خط ۳ توسط دستورالعمل ENV تنظیم شده است.
تکنیک بسط متغیر در این مثال به شما امکان میدهد آرگومانها را از خط فرمان ارسال کرده و با بهرهگیری از دستورالعمل ENV آنها را در ایمیج نهایی پایدار سازید. بسط متغیر تنها برای مجموعه محدودی از دستورالعملهای Dockerfile پشتیبانی میشود.
Docker مجموعهای از متغیرهای از پیش تعریفشده ARG دارد که میتوانید بدون یک دستورالعمل ARG متناظر در Dockerfile از آنها استفاده کنید.
- HTTP_PROXY
- http_proxy
- HTTPS_PROXY
- https_proxy
- FTP_PROXY
- ftp_proxy
- NO_PROXY
- no_proxy
- ALL_PROXY
- all_proxy
برای استفاده از این موارد، آنها را در خط فرمان با استفاده از پرچم --build-arg ارسال کنید، به عنوان مثال:
$ docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .
ONBUILD
-- ONBUILD [INSTRUCTION]
دستورالعمل
ONBUILD یک
دستورالعمل
محرک (trigger) به یک
ایمیج
اضافه
میکند. این
محرک در
زمان دیگری
اجرا
میشود،
زمانی که
ایمیج به
عنوان پایه
برای ساخت
دیگری
استفاده
شود. Docker محرک
را در زمینه
ساخت
پاییندستی
اجرا
میکند،
درست مانند
اینکه محرک
بلافاصله
پس از
دستورالعمل
FROM در Dockerfile
پاییندستی
قرار داشته
باشد.
میتوانید هر دستورالعمل ساخت را به عنوان یک محرک ثبت کنید. یک محرک زمانی مفید است که در حال تعریف یک ایمیج به عنوان پایه برای ساخت سایر ایمیجها هستید. به عنوان مثال، اگر در حال تعریف یک محیط ساخت برنامه یا یک دیمن هستید که با پیکربندی مخصوص کاربر سفارشیسازی میشود.
ایمیجی را در نظر بگیرید که به عنوان یک سازنده قابل استفاده مجدد برای برنامههای python طراحی شده است. این ایمیج باید کد مبدأ برنامه را به یک دایرکتوری خاص اضافه کند، و ممکن است بعد از آن به فراخوانی یک اسکریپت ساخت نیاز داشته باشد. اکنون نمیتوانید صرفاً ADD و RUN را فراخوانی کنید، زیرا هنوز به کد مبدأ برنامه دسترسی ندارید و این کد برای ساخت هر برنامه متفاوت است.
-- ارائه یک Dockerfile الگو (boilerplate) به توسعهدهندگان برنامه برای کپی و جایگذاری در برنامهشان ناکارآمد، مستعد خطا و بهروزرسانی آن دشوار است، زیرا با کدهای اختصاصی برنامه ترکیب میشود. راهحل استفاده از ONBUILD برای ثبت پیشاپیش دستورالعملها است تا بعداً در طول مرحله ساخت بعدی اجرا شوند.
تاریخچه (HISTORY)
* مه ۲۰۱۴، گردآوریشده توسط Zac Dover (zdover at redhat dot com) بر اساس مستندات Dockerfile در docker.com. * فوریه ۲۰۱۵، بهروزرسانیشده توسط Brian Goff (cpuguy83@gmail.com) جهت خوانایی بیشتر. * سپتامبر ۲۰۱۵، بهروزرسانیشده توسط Sally O'Malley (somalley@redhat.com). * اکتبر ۲۰۱۶، بهروزرسانیشده توسط Addam Hardy (addam.hardy@gmail.com).
| MAY 2014 | Docker Community |