Пошук уроків, статей та іншого контенту
Розберете відмінності ARG і ENV, області їхньої дії та безпечну передачу параметрів під час складання і запуску.
ARG і ENVУ Docker ARG і ENV використовують для передачі параметрів, але вони працюють на різних етапах:
ARG — параметр складання образу, доступний під час виконання docker build;
ENV — змінна середовища, доступна під час складання образу та запуску контейнера.
Головна відмінність:
ARGпризначений для build time, аENV— для build time і runtime.
ARG: параметри під час складанняІнструкція ARG оголошує змінну, значення якої можна передати команді docker build.
FROM alpine:3.20
ARG APP_VERSION=dev
RUN echo "Версія під час складання: $APP_VERSION" > /build-info.txt
CMD ["cat", "/build-info.txt"]Значення APP_VERSION можна змінити під час складання:
docker build \
--build-arg APP_VERSION=1.4.0 \
-t demo-arg .Запуск контейнера:
docker run --rm demo-argРезультат:
Версія під час складання: 1.4.0ARG доступний інструкціям, які виконуються після його оголошення. Наприклад:
RUN;
COPY;
ENV;
деяким частинам FROM.
Після завершення складання контейнер не отримує ARG як змінну середовища автоматично.
Для ARG можна вказати значення за замовчуванням:
ARG NODE_ENV=productionЯкщо під час складання не передати --build-arg NODE_ENV=..., буде використано production.
docker build -t demo .Значення за замовчуванням зручно використовувати для необов’язкових параметрів, які іноді перевизначаються в CI/CD.
ARGARG, оголошений після FROM, доступний лише в поточному етапі складання:
FROM alpine:3.20
ARG APP_VERSION=dev
RUN echo "$APP_VERSION"Якщо Dockerfile використовує кілька етапів, параметр потрібно оголосити в кожному етапі, де він необхідний:
FROM alpine:3.20 AS builder
ARG APP_VERSION=dev
RUN echo "$APP_VERSION" > /version.txt
FROM alpine:3.20
ARG APP_VERSION=dev
COPY --from=builder /version.txt /version.txtОкремий випадок — ARG, оголошений перед FROM. Такий параметр можна використати в самому FROM:
ARG ALPINE_VERSION=3.20
FROM alpine:${ALPINE_VERSION}Але після FROM цей параметр потрібно оголосити повторно, якщо він потрібен в інструкціях етапу:
ARG ALPINE_VERSION=3.20
FROM alpine:${ALPINE_VERSION}
ARG ALPINE_VERSION
RUN echo "Версія Alpine: $ALPINE_VERSION"ENV: змінні середовища контейнераІнструкція ENV створює змінну середовища в образі:
FROM alpine:3.20
ENV APP_ENV=production
CMD ["sh", "-c", "echo Оточення: $APP_ENV"]Складання та запуск:
docker build -t demo-env .
docker run --rm demo-envРезультат:
Оточення: productionЗмінна ENV доступна:
наступним інструкціям Dockerfile під час складання;
процесам усередині контейнера після запуску;
дочірнім процесам, запущеним основним процесом контейнера.
Значення ENV можна перевизначити під час запуску:
docker run --rm -e APP_ENV=staging demo-envРезультат:
Оточення: stagingПеревизначення під час запуску не змінює сам образ. Воно діє лише для конкретного контейнера.
ARG і ENV| Властивість | ARG | ENV | |---|---|---| | Доступний під час docker build | Так | Так | | Доступний у запущеному контейнері | Ні | Так | | Передача через --build-arg | Так | Ні | | Передача через docker run -e | Ні | Так | | Зберігається в конфігурації образу | Може залишати сліди у шарах і метаданих | Так | | Призначення | Параметри складання | Налаштування середовища |
Ця таблиця описує типовий сценарій. Наприклад, значення ARG можна використати, щоб під час складання створити ENV.
ARG у ENVІноді параметр потрібен і під час складання, і під час запуску. У такому разі його можна передати з ARG у ENV:
FROM alpine:3.20
ARG APP_VERSION=dev
ENV APP_VERSION=$APP_VERSION
RUN printf 'Версія образу: %s\n' "$APP_VERSION" > /build-info.txt
CMD ["sh", "-c", "printf 'APP_VERSION у контейнері: %s\n' \"$APP_VERSION\"; cat /build-info.txt"]Створіть файл Dockerfile із цим вмістом і виконайте:
docker build --build-arg APP_VERSION=1.4.0 -t demo-version .
docker run --rm demo-versionРезультат:
APP_VERSION у контейнері: 1.4.0
Версія образу: 1.4.0У цьому прикладі:
ARG APP_VERSION отримує значення під час складання;
RUN використовує це значення для створення файлу;
ENV APP_VERSION=$APP_VERSION записує його в середовище образу;
після запуску контейнер бачить APP_VERSION як звичайну змінну середовища.
Також значення можна перевизначити під час запуску:
docker run --rm -e APP_VERSION=custom demo-versionТоді змінна в контейнері матиме значення custom, але файл /build-info.txt залишиться зі значенням 1.4.0, яке було записано під час складання.
Для ENV найчастіше використовують параметр -e або --env:
docker run --rm \
-e APP_ENV=staging \
-e LOG_LEVEL=debug \
demo-versionМожна передати значення з локальної змінної оболонки:
export APP_ENV=staging
docker run --rm \
-e APP_ENV \
demo-versionУ цьому випадку Docker візьме значення APP_ENV із середовища, у якому виконується команда.
Для кількох змінних зручно використовувати файл, наприклад .env.container:
APP_ENV=staging
LOG_LEVEL=debugЗапуск:
docker run --rm --env-file .env.container demo-versionФайл із конфігурацією не потрібно копіювати в образ. Він передається контейнеру лише під час запуску.
Для ARG використовують --build-arg:
docker build \
--build-arg APP_VERSION=2.0.0 \
--build-arg BASE_IMAGE=alpine:3.20 \
-t demo .Значення можна передавати з локальних змінних:
export APP_VERSION=2.0.0
docker build \
--build-arg APP_VERSION \
-t demo .Якщо параметр не передано і в Dockerfile немає значення за замовчуванням, його значення буде порожнім.
FROM alpine:3.20
ARG RELEASE_CHANNEL
RUN echo "Канал: ${RELEASE_CHANNEL:-не вказано}"ARG і ENV не призначені для секретів.
Не передавайте через них:
паролі;
токени доступу;
приватні ключі;
ключі API;
інші конфіденційні дані.
Причини:
значення ENV зберігаються в конфігурації образу;
значення можуть бути доступні через метадані образу;
ARG може потрапити в історію складання або шари образу;
секрет може залишитися в логах команд RUN.
Небезпечний приклад:
FROM alpine:3.20
ARG API_TOKEN
RUN echo "Токен: $API_TOKEN"Навіть якщо після складання API_TOKEN не є змінною середовища контейнера, він уже міг потрапити в історію складання або журнал CI.
Для звичайних несекретних параметрів ARG і ENV підходять добре:
версія застосунку;
назва середовища;
режим роботи;
назва пакета;
URL публічного сервісу.
Секрети потрібно передавати спеціальними механізмами Docker або інструментів оркестрації, які не записують їх у фінальний образ.
Параметри, потрібні лише для складання:
FROM alpine:3.20
ARG BUILD_VERSION=dev
RUN printf 'Build version: %s\n' "$BUILD_VERSION" > /build-info.txt
CMD ["cat", "/build-info.txt"]Налаштування, потрібні контейнеру під час роботи:
FROM alpine:3.20
ENV APP_ENV=production
ENV LOG_LEVEL=info
CMD ["sh", "-c", "echo \"$APP_ENV / $LOG_LEVEL\""]Параметр, який потрібен на обох етапах:
FROM alpine:3.20
ARG APP_VERSION=dev
ENV APP_VERSION=$APP_VERSION
RUN echo "Building version $APP_VERSION"
CMD ["sh", "-c", "echo \"Running version $APP_VERSION\""]Вибір залежить від моменту, коли значення потрібне:
лише під час створення образу — ARG;
лише під час роботи контейнера — ENV або docker run -e;
на обох етапах — ARG разом із ENV.
ARG буде доступний у контейнеріFROM alpine:3.20
ARG APP_VERSION=1.0.0
CMD ["sh", "-c", "echo \"$APP_VERSION\""]APP_VERSION не буде доступним після запуску, оскільки ARG не створює змінну середовища.
Якщо вона потрібна в контейнері, використайте:
ARG APP_VERSION=1.0.0
ENV APP_VERSION=$APP_VERSIONENV замість ARG для вибору під час складанняENV не передається через docker build --build-arg. Наприклад, ця команда не змінить APP_ENV:
docker build --build-arg APP_ENV=staging -t demo .Якщо значення потрібно змінювати саме під час складання, у Dockerfile має бути ARG:
ARG APP_ENV=production
ENV APP_ENV=$APP_ENVENVКоманда:
docker run --rm -e APP_ENV=staging demoне змінює Dockerfile і не створює новий образ. Значення змінюється лише для запущеного контейнера.
--build-argdocker build --build-arg PASSWORD=secret -t demo .Так робити не слід: секрет може зберегтися в історії складання, метаданих або логах CI.
ARG — змінна лише для етапу складання образу.
ENV — змінна середовища образу та контейнера.
ARG передають через docker build --build-arg.
ENV перевизначають під час запуску через docker run -e або --env-file.
ARG має область дії в межах Dockerfile або окремого етапу складання.
ARG перед FROM потрібно повторно оголошувати після FROM, якщо він використовується в інструкціях етапу.
Для передачі значення від складання до контейнера можна використати ARG разом із ENV.
Секрети не слід зберігати в ARG або ENV.