آیا می توان از if و else در Dockerfile استفاده کرد؟
در Dockerfile به طور پیشفرض امکانات شرطی مانند if و else وحود ندارد. اما میتوان با استفاده از آرگومانها و تکنیکهای مناسب، شرطهایی در طول فرایند ساخت Image ایجاد کرد.
یکی از روشهای معمول برای تعریف شرایط در Dockerfile، استفاده از آرگومانها (ARG) و چند مرحله ای کردن (multi-stage builds) بیلد است. در این روش میتوان با استفاده از یک یا چند آرگومان که در زمان ساخت تصویر به آنها داده میشود، مراحل مختلفی را به صورت شرطی مشخص کرد.
ساختار Dockerfile با استفاده از ARG و multi-stage builds
در زیر نمونهای از Dockerfile آورده شده که در آن از آرگومانها و چندین مرحله استفاده شده است. در اینجا ما دو مرحله متفاوت به نام های branch-version-1 و branch-version-2 داریم که در بوسیله my_arg در مرحله final تصمیم می گیریم که از کدام یک از این مراحل استفاده کنیم. اگر مقدار my_arg برابر با یک باشد از branch-version-1 و در اگر دو باشد از branch-version-2 استفاده می کنیم.
ARG my_arg
FROM centos:7 AS base
RUN echo "در حال انجام کار با تصویر centos"
FROM base AS branch-version-1
RUN echo "این مرحله متغیر VAR را برابر TRUE تعیین میکند"
ENV VAR=TRUE
FROM base AS branch-version-2
RUN echo "این مرحله متغیر VAR را برابر FALSE تعیین میکند"
ENV VAR=FALSE
FROM branch-version-${my_arg} AS final
RUN echo "VAR برابر است با ${VAR}"
مثال ساخت Image:
docker build --build-arg my_arg=1 .
استفاده از Target و بیلد چند مرحله ای
این روش نیز مانند روش قبل است با این تفاوت که دیگر خبری از Arg نیست و ما مستقیم دستور اجرای استیج مورد نظر را با مشخص کردن وروی target به دستور docker build می دهیم:
FROM foo as base
RUN ...
# Build dev image
FROM base as image-dev
RUN ...
COPY ...
# Build prod image
FROM base as image-prod
RUN ...
COPY ...
مثال بیلد استفاده از پارامتر target در زمان بیلد ایمیج داکر:
docker build --target image-dev -t foo .
یا مثال فایل داکر کامپوز استفاده از پارامتر target در زمان بیلد داکر ایمیج:
version: '3.4'
services:
dev:
build:
context: .
dockerfile: Dockerfile
target: image-dev
استفاده از Arg و شل اسکریپت
راه دیگه استفاده از دستورهای شرطی شل اسکریپت بهمراه Arg است. برای مثال:
FROM centos:7
ARG arg
RUN if [[ -z "$arg" ]] ; then echo Argument not provided ; else echo Argument is $arg ; fi
با اجرای دستور docker build و ارسال مقدار 45 برای پارامتر arg به آن، مقدار Argument is 45 نمایش داده خواهد شد که می توانیم به جای آن هر دستوری که می خواهیم را اجرا کنیم. یا اگر این پارامتر در زمان بیلد پاس نشده بود مقدار Atgument not provided نمایش داده خواهد شد.
docker build -t my_docker . --build-arg arg=45