CONTAINERFILE(5) راهنمای کاربری کانتینر CONTAINERFILE(5)

Containerfile - خودکارسازی مراحل ایجاد و ساخت تصویر کانتینر (Dockerfile)

پرونده Containerfile یک فایل پیکربندی است که مراحل ایجاد تصویر کانتینر را خودکار می‌کند. این فایل عملکردی مشابه یک Makefile دارد. موتورهای کانتینر (Podman، Buildah، Docker) دستورالعمل‌های موجود در Containerfile را می‌خوانند تا مراحلی را که در غیر این صورت باید دستی انجام می‌شد، برای ساخت تصویر خودکار سازند. برای ساخت یک تصویر، فایلی به نام Containerfile بسازید.

پرونده Containerfile مراحل طی‌شده برای سرهم‌بندی تصویر را شرح می‌دهد. هنگامی که Containerfile ایجاد شد، دستورات buildah build، podman build یا docker build را فراخوانی کنید و مسیر دایرکتوری زمینه حاوی Containerfile را به عنوان آرگومان به آن بدهید. ابزارهای Podman و Buildah به طور پیش‌فرض از Containerfile استفاده می‌کنند و در صورت عدم وجود به Dockerfile رجوع می‌نمایند. موتور داکر تنها به دنبال Dockerfile در دایرکتوری زمینه می‌گردد.

نام Dockerfile نامی جایگزین برای همین فایل است. هر دو فایل Containerfile و Dockerfile از ساختار و دستورات یکسانی پشتیبانی می‌کنند.

INSTRUCTION arguments

برای نمونه:

FROM image

یک Containerfile فایلی است که مراحل ایجاد یک تصویر کانتینر را خودکارسازی می‌کند. یک Containerfile ساختاری مشابه یک Makefile دارد.

buildah build .
podman build .

-- مراحل را اجرا کرده و نتایج را تثبیت (commit) می‌کند تا تصویر نهایی ساخته شود.
مسیر منتهی به مخزن منبع مشخص می‌کند که زمینه ساخت در کجا یافت شود.

buildah build -t repository/tag .
podman build -t repository/tag .

-- در صورت موفقیت‌آمیز بودن ساخت، مخزن و برچسبی (tag) را که تصویر جدید در آن ذخیره می‌شود مشخص می‌کند. موتور کانتینر مراحل را گام‌به‌گام اجرا کرده و در صورت نیاز نتیجه را در یک تصویر جدید ثبت می‌کند، تا در نهایت شناسه (ID) تصویر جدید را ارائه دهد.

موتورهای کانتینر تا جای ممکن تصاویر میانی را مجدداً استفاده می‌کنند. این امر فرآیند ساخت را به شکل چشمگیری سریع‌تر می‌کند.

FROM image [AS <name>]

FROM image:tag [AS <name>]

FROM image@digest [AS <name>]

-- دستورالعمل FROM تصویر پایه را برای دستورالعمل‌های پس از خود تعیین می‌کند. یک Containerfile معتبر باید ARG یا FROM را به عنوان نخستین دستورالعمل خود داشته باشد.
اگر FROM نخستین دستورالعمل در فایل نباشد، تنها می‌تواند پس از یک یا چند دستورالعمل ARG بیاید که آرگومان‌های مورد استفاده در خط بعدی FROM را اعلان می‌کنند.
تصویر پایه می‌تواند هر تصویر معتبری باشد. ساده‌ترین راه شروع، دریافت یک تصویر از مخازن عمومی است.

-- دستورالعمل FROM باید دست‌کم یک بار در Containerfile درج شود.

-- نخستین دستور FROM باید پیش از تمام دستورالعمل‌های دیگر موجود در Containerfile به جز ARG بیاید.

-- دستورالعمل FROM می‌تواند چندین بار درون یک Containerfile تکرار شود تا چند تصویر ساخته شود. شناسه آخرین تصویری را که توسط commit پیش از هر دستور جدید FROM تولید می‌شود ثبت نمایید.

-- اگر هیچ تگی به دستورالعمل FROM داده نشود، موتورهای کانتینر برچسب latest را اعمال می‌کنند. در صورتی که برچسب استفاده‌شده وجود نداشته باشد، خطا برگردانده می‌شود.

-- اگر هیچ شناسه دایجستی به دستورالعمل FROM داده نشود، موتورهای کانتینر برچسب latest را اعمال می‌کنند. اگر برچسب استفاده‌شده وجود نداشته باشد، یک خطا بازگردانده می‌شود.

-- می‌توان با افزودن AS name به دستورالعمل، نامی به مرحله ساخت اختصاص داد.
از این نام می‌توان بعداً در Containerfile با استفاده از دستورالعمل‌های FROM یا COPY --from= ارجاع داد.

MAINTAINER
-- دستورالعمل MAINTAINER فیلد Author (نویسنده/نگه‌دارنده) را برای تصاویر تولیدشده تعیین می‌کند.
این گزینه برای ارائه ایمیل یا آدرس اینترنتی پشتیبانی به کاربران کاربرد دارد.

RUN
-- دستورالعمل RUN دو قالب دارد:

# the command is run in a shell - /bin/sh -c
RUN <command>
# Executable form
RUN ["executable", "param1", "param2"]

RUN mounts

--mount=type=TYPE,TYPE-SPECIFIC-OPTION[,...]

اتصال یک مانت سیستم‌فایل به کانتینر

انواع در حال حاضر پشتیبانی‌شده برای mount عبارتند از bind، cache، secret و tmpfs.

e.g.
mount=type=bind,source=/path/on/host,destination=/path/in/container,relabel=shared
mount=type=tmpfs,tmpfs-size=512M,destination=/path/in/container
mount=type=secret,id=mysecret cat /run/secrets/mysecret
Common Options:
   · src, source: مشخص کردن منبع مانت برای bind و volume. برای bind الزامی است.
   · dst, destination, target: مشخص کردن مقصد مانت.
   · ro, read-only: فقط‌خواندنی: true (پیش‌فرض) یا false.
Options specific to bind:
   · bind-propagation: مقادیر shared, slave, private, rshared, rslave یا rprivate (پیش‌فرض).
   · bind-nonrecursive: عدم راه‌اندازی مانت بایندی بازگشتی (به‌طور پیش‌فرض بازگشتی است).
   · from: نام مرحله یا تصویر برای ریشه منبع. پیش‌فرض زمینه ساخت است.
   · relabel=shared, z: برچسب‌گذاری مجدد محتوای src با برچسب مشترک (shared).
   · relabel=private, Z: برچسب‌گذاری مجدد محتوای src با برچسب خصوصی (private).
   سیستم‌های برچسب‌گذاری مانند SELinux نیاز به برچسب‌های مناسب روی محتوای متصل‌شده دارند.
   گزینه relabel=shared و z نشان می‌دهد که دو یا چند کانتینر محتوا را به اشتراک می‌گذارند.
   گزینه relabel=private و Z نشان می‌دهد که تنها کانتینر جاری از مانت استفاده می‌کند.
   · rw, read-write: اجازه نوشتن روی مانت.
Options specific to tmpfs:
   · tmpfs-size: اندازه مانت tmpfs به بایت (نامحدود در لینوکس به طور پیش‌فرض).
   · tmpfs-mode: حالت مجوز فایل در فرمت هشت‌هشتی (مانند 700 یا 0700، پیش‌فرض 1777).
   · tmpcopyup: مسیری که زیر tmpfs قرار می‌گیرد به درون خود tmpfs کپی می‌شود.
Options specific to cache:
   · id: ایجاد یک دایرکتوری کش جداگانه برای یک شناسه خاص.
   · mode: حالت دسترسی برای دایرکتوری کش به صورت هشت‌هشتی (پیش‌فرض 0755).
   · ro, readonly: کش فقط‌خواندنی در صورت تنظیم.
   · uid: شناسه کاربر برای دایرکتوری کش.
   · gid: شناسه گروه برای دایرکتوری کش.
   · from: نام مرحله برای ریشه منبع (پیش‌فرض دایرکتوری کش میزبان).
   · rw, read-write: مجاز شمردن نوشتن روی مانت کش.

RUN --network

گزینه RUN --network امکان کنترل این را فراهم می‌کند که دستور در کدام محیط شبکه اجرا شود.

قالب دستور: --network=<TYPE>

انواع شبکه

نوع (Type) توضیحات (Description)
⟨#run---networkdefault⟩ (پیش‌فرض) اجرا در شبکه پیش‌فرض.
⟨#run---networknone⟩ اجرا بدون دسترسی به شبکه.
⟨#run---networkhost⟩ اجرا در محیط شبکه میزبان.

معادل با عدم ارائه هیچ فلگی است، و دستور در شبکه پیش‌فرض ساخت اجرا می‌شود.

دستور بدون دسترسی به شبکه اجرا می‌شود (رابط lo همچنان در دسترس است، اما منحصر به این فرآیند خواهد بود).

FROM python:3.6
ADD mypackage.tgz wheels/
RUN --network=none pip install --find-links wheels mypackage

ابزار pip تنها قادر خواهد بود بسته‌های ارائه‌شده در فایل tar را نصب کند، که می‌توان آن را توسط یک مرحله ساخت قبلی کنترل کرد.

دستور در محیط شبکه میزبان اجرا می‌شود (مشابه buildah build --network=host، اما برای هر دستورالعمل به صورت جداگانه).

اسرار RUN (Secrets)

دستور RUN قابلیتی برای انتقال اطلاعات محرمانه (رازها) به فرآیند ساخت تصویر دارد. این فایل‌های محرمانه می‌توانند در طول اجرای دستور RUN استفاده شوند، اما در تصویر نهایی ذخیره (commit) نمی‌شوند. دستور RUN از گزینه --mount برای شناسایی فایل محرمانه پشتیبانی می‌کند. یک فایل محرمانه از میزبان در حین ساخته شدن تصویر به درون کانتینر متصل (مانت) می‌شود.

موتورهای کانتینر فایل محرمانه را با استفاده از فلگ --secret به فرآیند ساخت ارسال می‌کنند.

--mount=type=secret,TYPE-SPECIFIC-OPTION[,...]

  • شناسه id همان شناسه فایل محرمانه‌ای است که به دستور buildah build --secret یا podman build --secret ارسال شده است. این شناسه با شناسه RUN --mount در Containerfile پیوند می‌خورد.
  • گزینه‌های dst|target|destination نام فایل محرمانه را به یک فایل مشخص در دستور RUN کانتینرفایل تغییر می‌دهند تا استفاده شود.
  • مقدار type=secret به دستور --mount اعلام می‌کند که در حال اتصال یک فایل محرمانه است.
    # نمایش راز از مسیر پیش‌فرض راز:
    RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
    # نمایش راز از مسیر سفارشی راز:
    RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar

راز باید با استفاده از فلگ --secret به ساخت ارسال شود. تصویر نهایی ساخته‌شده حاوی این فایل محرمانه نخواهد بود:

buildah build --no-cache --secret id=mysecret,src=mysecret.txt .

-- دستورالعمل RUN هر دستوری را در یک لایه جدید بر روی تصویر فعلی اجرا کرده و نتایج را ثبت (commit) می‌کند. تصویر ثبت‌شده برای مرحله بعدی در Containerfile به کار می‌رود.

-- لایه‌بندی دستورالعمل‌های RUN و ایجاد commit با مفاهیم اصلی موتورهای کانتینر مطابقت دارد؛ جایی که commitها کم‌هزینه هستند و می‌توان کانتینرها را از هر نقطه‌ای از تاریخچه یک تصویر ایجاد کرد. این کار شبیه به سیستم‌های کنترل نسخه است. فرم اجرایی (exec form) از دستکاری رشته‌های شل جلوگیری می‌کند و امکان اجرای دستورات 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

-- در هر Containerfile باید تنها یک دستورالعمل CMD وجود داشته باشد. اگر بیش از یک 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 استفاده کنید. اگر کاربر آرگومان‌هایی را به podman run یا docker run ارائه دهد، دستورات مشخص‌شده جایگزین مقدار پیش‌فرض در CMD می‌شوند. دستور RUN را با CMD اشتباه نگیرید. دستور RUN یک دستور را در زمان ساخت اجرا کرده و نتیجه را ثبت می‌کند. دستور CMD در زمان ساخت چیزی را اجرا نمی‌کند، بلکه دستور پیش‌بینی‌شده برای زمان اجرای تصویر را مشخص می‌سازد.

LABEL
-- LABEL <key>=<value> [<key>=<value> ...] یا

LABEL <key>[ <value>]
LABEL <key>[ <value>]
...

دستورالعمل LABEL متاداده را به تصویر اضافه می‌کند. یک LABEL جفتی از کلید-مقدار است. برای تعیین 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 موجود در تصاویر FROM پایه. با مواجهه و اعمال هر برچسب جدید، keyهای جدید جایگزین برچسب‌های قبلی با کلیدهای یکسان می‌شوند.

برای نمایش برچسب‌های یک تصویر، از دستور buildah inspect استفاده کنید.

EXPOSE
-- EXPOSE <port> [<port>...]
دستورالعمل EXPOSE به موتور کانتینر اعلام می‌کند که کانتینر در زمان اجرا به پورت‌های شبکه مشخص‌شده گوش می‌دهد. موتور کانتینر از این اطلاعات برای اتصال متقابل کانتینرها و راه‌اندازی تغییر مسیر پورت (port redirection) در سیستم میزبان استفاده می‌کند.

ENV
-- ENV <key> <value>
دستورالعمل ENV متغیر محیطی را روی مقدار <value> تنظیم می‌کند. این مقدار به تمامی دستورالعمل‌های RUN، ENTRYPOINT و CMD بعدی منتقل می‌شود. این معادل با قرار دادن پیشوند <key>=<value> پیش از دستور است. متغیرهای محیطی تنظیم‌شده با ENV هنگام اجرای کانتینر از تصویر نهایی پایدار باقی می‌مانند. برای مشاهده این مقادیر از podman inspect استفاده کنید و برای تغییر آن‌ها از podman run --env <key>=<value> بهره ببرید.

توجه داشته باشید که تنظیم "ENV DEBIAN_FRONTEND=noninteractive" ممکن است پیامدهای ناخواسته‌ای داشته باشد، زیرا هنگام اجرای تعاملی کانتینر (مانند دستور podman 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> در سیستم‌فایل کانتینر استخراج می‌شود. توجه داشته باشید که تنها فایل‌های فشرده محلی از حالت فشرده خارج می‌شوند، یعنی ویژگی‌های دانلود URL و استخراج آرشیو را نمی‌توان همزمان با هم استفاده کرد. تمامی دایرکتوری‌های جدید با حالت دسترسی 0755 و با uid و gid برابر 0 ایجاد می‌شوند.

COPY
-- دستورالعمل COPY دو قالب دارد:

COPY [--chown=<user>:<group>] [--chmod=<mode>] <src> <dest>
# Required for paths with whitespace
COPY [--chown=<user>:<group>] [--chmod=<mode>] ["<src>",... "<dest>"]

دستورالعمل COPY فایل‌های جدید را از <src> کپی کرده و به سیستم‌فایل کانتینر در مسیر مقصد اضافه می‌کند. منبع <src> باید مسیر یک فایل یا دایرکتوری نسبی نسبت به دایرکتوری ساخت یا یک آدرس URL راه دور باشد. مقدار <dest> یک مسیر مطلق یا نسبی نسبت به WORKDIR است. اگر یک فایل آرشیو را COPY کنید، دقیقاً همان‌طور که در زمینه ساخت قرار دارد و بدون استخراج درون کانتینر قرار می‌گیرد. تمامی فایل‌ها و دایرکتوری‌های جدید با حالت 0755 و با uid و gid برابر 0 ساخته می‌شوند.

گزینه --chown=<user>:<group> مالکیت فایل‌ها و دایرکتوری‌های جدید را تغییر می‌دهد. از نام‌ها (در صورت تعریف در فایل‌های /etc/passwd و /etc/groups کانتینر) یا شناسه‌های عددی uid و gid پشتیبانی می‌کند. در صورتی که نام کاربر یا گروه در کانتینر یافت نشود، فرآیند ساخت با خطا مواجه خواهد شد. شناسه‌های عددی بدون نیاز به وجود در کانتینر اعمال می‌شوند.

گزینه --chmod=<mode> حالت مجوز دسترسی فایل‌ها و پوشه‌های جدید را تغییر می‌دهد.

فلگ اختیاری --from=name می‌تواند برای کپی کردن فایل‌ها از یک مرحله ساخت نام‌گذاری‌شده پیشین استفاده شود. این فلگ زمینه <src> را از زمینه ساخت به مرحله ساخت نام‌برده تغییر می‌دهد.

ENTRYPOINT
-- دستورالعمل ENTRYPOINT دارای دو قالب است:

# executable form
ENTRYPOINT ["executable", "param1", "param2"]`
# run command in a shell - /bin/sh -c
ENTRYPOINT command param1 param2

-- دستورالعمل ENTRYPOINT به شما در پیکربندی کانتینری که مانند یک فایل اجرایی اجرا می‌شود کمک می‌کند. هنگامی که یک ENTRYPOINT تعیین می‌کنید، کل کانتینر طوری رفتار می‌کند که گویی تنها همان فایل اجرایی است. دستورالعمل ENTRYPOINT یک دستور ورودی اضافه می‌کند که با ارسال آرگومان‌ها به podman run بازنویسی نمی‌شود. این تفاوت عمده آن با رفتار CMD است. این قابلیت اجازه می‌دهد تا آرگومان‌ها به entrypoint ارسال شوند؛ برای نمونه دستور podman run <image> -d آرگومان -d را به ENTRYPOINT ارسال می‌کند. پارامترها را یا در آرایه JSON دستور ENTRYPOINT مشخص کنید (مانند فرم اجرایی توصیه‌شده در بالا)، یا از یک دستور CMD استفاده کنید. پارامترهای موجود در ENTRYPOINT با آرگومان‌های podman run بازنویسی نمی‌شوند، در حالی که پارامترهای مشخص‌شده از طریق CMD با آرگومان‌های podman run بازنویسی خواهند شد. اگر برای ENTRYPOINT یک رشته ساده مشخص کنید، مانند دستورالعمل CMD در /bin/sh -c اجرا می‌شود:

FROM ubuntu
ENTRYPOINT wc -l -

این به این معنی است که تصویر Containerfile همیشه 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 می‌تواند به هر تعداد بار در Containerfile استفاده شود و تنها بر دستورات بعدی تأثیر می‌گذارد.

WORKDIR
-- WORKDIR /path/to/workdir
دستورالعمل WORKDIR دایرکتوری کاری را برای دستورات RUN، CMD، ENTRYPOINT، COPY و ADD پس از خود در Containerfile تنظیم می‌کند. این دستور می‌تواند چندین بار در یک فایل Containerfile تکرار شود. مسیرهای نسبی، نسبت به مسیر دستور قبلی WORKDIR تعریف می‌شوند. برای نمونه:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

در مثال بالا، خروجی دستور pwd برابر با a/b/c خواهد بود.

ARG
-- ARG <name>[=<default value>]

دستورالعمل ARG متغیری را تعریف می‌کند که کاربران می‌توانند در زمان ساخت با دستورات podman build و buildah build و با استفاده از فلگ --build-arg <varname>=<value> به سازنده ارسال کنند. اگر کاربر آرگومان ساختی را مشخص کند که در Containerfile تعریف نشده است، فرآیند ساخت یک هشدار نمایش می‌دهد.

توجه داشته باشید که دومین دستور FROM در یک Containerfile مقادیر مرتبط با متغیر Arg را به nil تنظیم می‌کند و اگر قرار است بعداً در Containerfile استفاده شوند، باید مجدداً تنظیم شوند.

[Warning] One or more build-args [foo] were not consumed

نویسنده Containerfile می‌تواند با تعیین یک‌باره ARG یک متغیر، یا با تعیین چندین‌باره آن چندین متغیر را تعریف کند. برای نمونه، یک Containerfile معتبر:

FROM busybox
ARG user1
ARG buildno
...

نویسنده Containerfile می‌تواند به صورت اختیاری مقدار پیش‌فرضی را برای دستورالعمل ARG مشخص کند:

FROM busybox
ARG user1=someuser
ARG buildno=1
...

اگر یک متغیر ARG دارای مقدار پیش‌فرض باشد و هیچ مقداری در زمان ساخت ارسال نشود، سازنده از همان مقدار پیش‌فرض استفاده می‌کند.

تعریف متغیر ARG از همان خطی که در آن در Containerfile تعریف شده است اعمال می‌شود، نه از زمان استفاده آرگومان در خط فرمان یا جای دیگر. برای نمونه، این Containerfile را در نظر بگیرید:

1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...

کاربر این فایل را با این دستور می‌سازد:

$ podman build --build-arg user=what_user Containerfile

مقدار USER در خط ۲ برابر با some_user ارزیابی می‌شود زیرا متغیر user در خط ۳ بعدی تعریف شده است. مقدار USER در خط ۴ برابر با what_user خواهد بود زیرا user تعریف شده و مقدار what_user از خط فرمان ارسال شده است. پیش از تعریف توسط دستورالعمل ARG، هرگونه استفاده از یک متغیر منجر به یک رشته خالی می‌شود.

هشدار: استفاده از متغیرهای زمان ساخت برای ارسال اطلاعات محرمانه مانند کلیدهای گیت‌هاب، اطلاعات ورود کاربران و غیره توصیه نمی‌شود. مقادیر متغیرهای زمان ساخت برای هر کاربری که از تصویر با دستور podman history استفاده کند قابل مشاهده است.

می‌توانید از دستورالعمل ARG یا ENV برای تعیین متغیرهایی که در دسترس دستورالعمل RUN قرار دارند استفاده کنید. متغیرهای محیطی تعریف‌شده با دستورالعمل ENV همیشه بر دستورالعمل ARG هم‌نام خود اولویت دارند. این Containerfile را با دستورالعمل‌های ENV و ARG در نظر بگیرید:

1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER=v1.0.0
4 RUN echo $CONT_IMG_VER

سپس فرض کنید این تصویر با این دستور ساخته می‌شود:

$ podman build --build-arg CONT_IMG_VER=v2.0.1 Containerfile

در این حالت، دستورالعمل 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 همیشه در تصویر ساخته‌شده پایدار باقی می‌مانند. اجرای podman build بدون فلگ --build-arg را در نظر بگیرید:

$ podman build Containerfile

با استفاده از این مثال Containerfile، مقدار CONT_IMG_VER همچنان در تصویر ماندگار است اما مقدار آن برابر با v1.0.0 خواهد بود، زیرا این مقدار پیش‌فرض تنظیم‌شده در خط ۳ توسط دستورالعمل ENV است.

تکنیک بسط متغیر در این مثال به شما اجازه می‌دهد آرگومان‌ها را از خط فرمان ارسال کرده و با بهره‌گیری از دستورالعمل ENV آن‌ها را در تصویر نهایی ماندگار سازید. بسط متغیر تنها برای مجموعه محدودی از دستورالعمل‌های Containerfile پشتیبانی می‌شود. ⟨#environment-replacement⟩

موتورهای کانتینر دارای مجموعه‌ای از متغیرهای ARG از پیش تعریف‌شده هستند که می‌توانید بدون نیاز به دستورالعمل متناظر ARG در Containerfile از آن‌ها استفاده کنید:

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • FTP_PROXY
  • ftp_proxy
  • NO_PROXY
  • no_proxy
  • ALL_PROXY
  • all_proxy

برای استفاده از این موارد، آن‌ها را در خط فرمان با استفاده از فلگ --build-arg ارسال کنید، برای نمونه:

$ podman build --build-arg HTTPS_PROXY=https://my-proxy.example.com .

ARG برای پلتفرم/سیستم‌عامل/معماری (Platform/OS/Arch ARG)
-- ARG <name>

هنگام ساخت لیست‌های مانیفست چندمعماری (multi-arch) یا تصاویر برای یک معماری دیگر، اغلب دسترسی به جزئیات پلتفرم در Containerfile مفید است. برای نمونه، هنگام استفاده از دستور RUN curl ... برای نصب باینری مخصوص سیستم‌عامل/معماری خاص در تصویر، یا اگر مشخص باشد که برخی عملیات RUN در هنگام شبیه‌سازی یک معماری خاص ناسازگار بوده یا عملکرد پایینی دارند.

چندین متغیر نام‌گذاری‌شده ARG در دسترس هستند. هدف هر یک باید از روی نام آن مشخص باشد. با این حال، در تمام موارد این مقادیر ARG به طور خودکار مقداردهی نمی‌شوند. شما باید همیشه آن‌ها را درون هر بخش FROM در Containerfile اعلان کنید.

متغیرهای در دسترس ARG <name> با دو پیشوند عرضه می‌شوند:

•
نام متغیرهای TARGET... جزئیات مربوط به زمینه ساخت در حال اجرا (یعنی «درون» کانتینر) را نشان می‌دهند. این موارد اغلب مفیدترین هستند:
  • TARGETOS: برای نمونه linux
  • TARGETARCH: برای نمونه amd64
  • TARGETPLATFORM: برای نمونه linux/amd64
  • TARGETVARIANT: کاربرد نادر، ویژه برای TARGETARCH
•
نام متغیرهای BUILD... نشان‌دهنده جزئیات درباره میزبان انجام‌دهنده ساخت (یعنی «بیرون» کانتینر) هستند:
  • BUILDOS: سیستم‌عامل میزبان انجام‌دهنده ساخت
  • BUILDARCH: معماری میزبان انجام‌دهنده ساخت
  • BUILDPLATFORM: ترکیب سیستم‌عامل/معماری میزبان ساخت
  • BUILDVARIANT: کاربرد نادر، ویژه برای BUILDARCH

یک نمونه Containerfile که از TARGETARCH برای واکشی یک فایل باینری وابسته به معماری استفاده می‌کند می‌تواند چنین باشد:

FROM busybox
ARG TARGETARCH
RUN curl -sSf -O https://example.com/downloads/bin-${TARGETARCH}.zip

با فرض اینکه پلتفرم میزبان linux/amd64 بوده و شبیه‌سازی معماری خارجی فعال باشد (مانند qemu-user-static)، اجرای دستور زیر:

$ podman build --platform linux/s390x .

منجر به اجرای curl بر روی نشانی https://example.com/downloads/bin-s390x.zip و تولید یک تصویر کانتینر متناسب با پلتفرم linux/s390x خواهد شد. توجه: شبیه‌سازی اکیداً الزامی نیست؛ این build-argهای ویژه در زمان ساخت با podman farm build نیز کار می‌کنند.

ONBUILD
-- ONBUILD [INSTRUCTION]
دستورالعمل ONBUILD یک دستورالعمل محرک (تریگر) را به تصویر اضافه می‌کند. این محرک در زمان بعد، یعنی هنگامی که از این تصویر به عنوان پایه برای ساخت تصویر دیگری استفاده می‌شود، اجرا می‌گردد. موتورهای کانتینر محرک را در زمینه ساخت پایین‌دستی اجرا می‌کنند، گویی که این محرک بلافاصله پس از دستورالعمل FROM در Containerfile پایین‌دستی قرار داشته است.

شما می‌توانید هر دستورالعمل ساختی را به عنوان یک محرک ثبت کنید. اگر در حال تعریف تصویری برای استفاده به عنوان پایه ساخت سایر تصاویر هستید، محرک بسیار مفید است. برای نمونه، اگر در حال تعریف محیط ساخت یک برنامه کاربردی یا دیمنی هستید که با پیکربندی ویژه کاربر سفارشی می‌شود.

تصویری را در نظر بگیرید که به عنوان یک سازنده برنامه پایتون با قابلیت استفاده مجدد در نظر گرفته شده است. این تصویر باید کد منبع برنامه را به یک دایرکتوری خاص اضافه کند و ممکن است لازم باشد پس از آن یک اسکریپت ساخت فراخوانی شود. شما نمی‌توانید در این مرحله صرفاً ADD و RUN را فراخوانی کنید، زیرا هنوز به کد منبع برنامه دسترسی ندارید و این کد برای ساخت هر برنامه متفاوت است.

-- در اختیار قرار دادن یک فایل Containerfile اولیه به توسعه‌دهندگان برنامه برای کپی-پیست در برنامه‌شان ناکارآمد، مستعد خطا و به‌روزرسانی آن دشوار است زیرا با کدهای ویژه برنامه ترکیب می‌شود. راه‌حل این است که از ONBUILD برای ثبت دستورالعمل‌ها از قبل استفاده کنید تا بعداً، در طول مرحله ساخت بعدی اجرا شوند.

buildah(1), podman(1), docker(1)

مه ۲۰۱۴، گردآوری‌شده توسط 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)
اوت ۲۰۲۱، تبدیل صفحه راهنمای Dockerfile به Containerfile توسط Dan Walsh (dwalsh@redhat.com)
اوت ۲۰۲۱