Dockerfile: Встановлення кількох змінних середовища в один рядок


77

У мене склалося враження, що змінні середовища можна встановлювати в один рядок наступним чином, щоб мінімізувати посередницькі зображення.

FROM alpine:3.6
ENV RUBY_MAJOR 2.4 \
    RUBY_VERSION 2.4.1 \
    RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION 2.6.12 \
    BUNDLER_VERSION 1.15.3

Однак, запускаючи контейнер на основі цього фрагмента та викликаючи, # set |grep RUя бачу, що змінні не призначаються окремо, а об'єднуються в єдиний рядок.

RUBY_MAJOR='2.4     RUBY_VERSION 2.4.1     RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654     RUBYGEMS_VERSION 2.6.12     BUNDLER_VERSION 1.15.3'

Однак, якщо явно встановити кожну змінну, як показано нижче, я отримую очікуваний результат і помилок при виклику змінних не виникає.

ENV RUBY_MAJOR 2.4
ENV RUBY_VERSION 2.4.1
ENV RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654
ENV RUBYGEMS_VERSION 2.6.12
ENV BUNDLER_VERSION 1.15.3

Питання: Чи можна поєднати встановлення змінних середовища в одному рядку? Якщо так, то як би я це зробив? І чи це хороша практика?

Відповіді:


135

Існує два формати для визначення середовищ. Якщо вам потрібна одна змінна, тоді вам формат нижче

ENV X Y

Це призначить X як Y

ENX X Y Z

Це призначить X як Y Z

Якщо вам потрібно призначити кілька змінних середовища, тоді ви використовуєте інший формат

ENV X=Y Z=A

Це присвоїть X як, Yа Z як A. Так і Dockerfileмає бути

FROM alpine:3.6
ENV RUBY_MAJOR=2.4 \
    RUBY_VERSION=2.4.1 \
    RUBY_DOWNLOAD_SHA256=4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION=2.6.12 \
    BUNDLER_VERSION=1.15.3

RUN env

Ви також можете поєднувати це з лапками та з розширенням існуючих змінних середовища. Наприклад, загальноприйнятим є бажання розширити шлях як частина набору змінних середовища:ENV PATH="$PATH:/app" \ APPVAR="foo"
JeremyDouglass

4
Як не дивно, я спробував використати перший var у другому var, і він просто вирішив порожній рядок, неважливо, це один рядок чи багаторядковий
milosmns

@milosmns Так, я також помітив таку поведінку
Кіран Чалла

1
Для цього потрібні аргументи для побудови
Тарун Лалвані

2
@milosmns @ kiran-challa Для пояснення коментаря Таруна будь-яка змінна, оголошена для даної ENVкоманди, не буде встановлена, доки команда не буде виконана, тому поведінка буде відповідно до очікуваних (спробуйте echo $V_NOT_SETна будь-якій системі * nix). Введіть аргументи побудови. Як додаткове зауваження, export V_NOT_SET="hello" echo $V_NOT_SETце також призведе до лише пробілів; додавання exportперед тим, що не допомагає; вставка &&(aka AND_IF) між і exportі echoбуде призводити до helloвідлуння, тому що тепер потрібно, щоб перша команда закінчилася перед обчисленням другої.
hlongmore

20

Вам не потрібно турбуватися про багато ENVкоманд, кожна з яких створює новий проміжний шар для вашого остаточного зображення, створеного вашим Dockerfile.

з найкращих практик написання файлів Docker

Мінімізуйте кількість шарів

До Docker 17.05 і навіть більше, до Docker 1.10, було важливо мінімізувати кількість шарів у вашому зображенні. Наступні вдосконалення пом’якшили цю потребу:

  • У Докер 1.10 і вище, тільки RUN, COPYі ADDінструкції створення шарів. Інші інструкції створюють тимчасові проміжні зображення і більше не безпосередньо збільшують розмір збірки.

  • Docker 17.05 і вище додають підтримку багатоступеневих збірок , які дозволяють копіювати лише потрібні артефакти в кінцеве зображення. Це дозволяє включати інструменти та інформацію про налагодження у ваші проміжні етапи побудови без збільшення розміру кінцевого зображення.


Це неправильно відповідно до: docs.docker.com/develop/develop-images/…
Томанов

@Tomanow Це пряма цитата з docker docs (див. Посилання), але я думаю, що плутанина полягає в тому, що шари, створені ENV, є "тимчасовими", що, на мою думку, в якийсь момент означає стиснуті в інший шар, але це просто здогадуйтесь щодо реалізації.
Mike Lippert

4
З мого тестування з докером 19 ENVрядків не створюють шарів на зображенні, при побудові зображення там написано "Видалення проміжного контейнера", а потім перевіряючи шари пікіруванням, я бачу, що для них не створено шарів ENV.
Стівен

3
Хоча чудово, що шари ENV роздавлюються, їх все-таки потрібно створити в першу чергу, що може зайняти деякий час на моєму ноутбуці (це незвично?), Тому я вважаю, що все ж краще піти по багатолінійному маршруту, щоб заощадити нарощувати час.
Чіното Вокро

Що сказав @ChinotoVokro .... Створюються шари, які потім руйнуються ... але тим не менше це біль.
Джонатан Альфаро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.