Docker Compose: env_file, environment i .env, co do czego służy
Przewodnik po env_file w Docker Compose
Docker Compose: env_file vs environment vs .env, wyjaśnienie | We.Inc
Co robią env_file, environment i plik .env w Docker Compose, która wartość wygrywa, gdy się ze sobą kłócą, i jak działa interpolacja ${VAR:-default}, z resolverem do sprawdzania.
W Docker Compose env_file wczytuje plik z liniami KEY=value do kontenera jednej usługi. Atrybut environment ustawia zmienne kontenera bezpośrednio w pliku i wygrywa z env_file, gdy oba podają ten sam klucz. Plik .env obok compose.yaml to coś innego: Compose czyta go, aby wypełnić placeholdery ${VAR} w samym pliku YAML.
Trzy sposoby przekazywania zmiennych do Compose
Mechanizm
Zakres
Czy trafia do kontenera?
.env obok compose.yaml
Interpolacja ${VAR} w pliku Compose
Tylko jeśli odwołuje się do niej usługa
env_file: w usłudze
Kontener tej usługi
Tak, każda linia
environment: w usłudze
Kontener tej usługi
Tak, i wygrywa z env_file
--env-file w CLI
Zastępuje domyślny .env przy interpolacji
Tylko jeśli jest użyta
Zamieszanie bierze się z nazwy: plik o nazwie .env i atrybut o nazwie env_file brzmią jak to samo, ale pierwszy konfiguruje plik Compose, a drugi kontener. Użyj resolvera, aby zobaczyć, które źródło wygrywa dla danej zmiennej, a potem wypróbuj formy interpolacji na zmiennej ustawionej, pustej lub nieustawionej.
Zaznacz każde miejsce, w którym ustawiona jest Twoja zmienna, i wpisz wartość, jaką tam ma.
Resolver przechodzi od góry przez udokumentowaną przez Docker listę priorytetów i pokazuje, jaką wartość ostatecznie dostanie kontener.
W polu interpolacji wybierz formę, na przykład ${VAR:-default}, określ, czy VAR jest ustawiona, pusta czy nieustawiona, i odczytaj wynik.
Uruchom docker compose config w swoim projekcie, aby potwierdzić, co Compose faktycznie wyliczył.
Uruchom docker compose config --environment, aby wypisać zmienne użyte przez Compose do interpolacji. To rozstrzyga większość sporów w kilka sekund.
Oznacz opcjonalne pliki env przez required: false (Compose 2.24.0 i nowsze), aby brak lokalnego nadpisania nie zatrzymał całego stosu.
Pisz $$, gdy potrzebujesz dosłownego znaku dolara w compose.yaml, na przykład w haśle lub poleceniu powłoki.
Wartości logiczne w mapie environment ujmuj w cudzysłów, na przykład SHOW: "true", aby YAML nie zamienił ich na wartości true i false.
Najczęściej zadawane pytania
Czym różni się env_file od environment?
Oba umieszczają zmienne w kontenerze usługi. env_file czyta je z jednego lub kilku plików, environment wymienia je w compose.yaml. Gdy ten sam klucz pojawia się w obu, wygrywa wartość z environment, nawet jeśli jest pusta.
Czy Compose automatycznie przekazuje mój plik .env do kontenerów?
Nie. Plik .env projektu służy tylko do podstawiania ${VAR} w pliku Compose. Zmienna trafia do kontenera tylko wtedy, gdy usługa wymienia ją w environment albo wczytuje plik przez env_file.
Gdzie Compose szuka pliku .env?
W katalogu projektu, czyli w folderze podanym przez --project-directory, a w przeciwnym razie w folderze pierwszego pliku -f, a jeśli go nie ma, w bieżącym folderze. Użyj --env-file, aby wskazać inny plik; przy kilku plikach późniejsze nadpisują wcześniejsze.
Czy ścieżki w env_file są względne wobec miejsca, z którego uruchamiam polecenie?
Nie. Względne ścieżki w env_file są rozwiązywane względem folderu, w którym leży plik Compose, więc stos działa niezależnie od tego, skąd go uruchomisz.
Co się dzieje z ${VAR}, gdy VAR nie jest ustawiona?
Compose wypisuje ostrzeżenie i podstawia pusty ciąg. Użyj ${VAR:-fallback}, aby podać wartość domyślną, lub ${VAR:?message}, aby zamiast tego zatrzymać się z błędem.
Lista priorytetów od góry do dołu
Docker dokumentuje pięć poziomów. Najsilniejsza jest wartość przekazana przez docker compose run -e. Dalej jest environment lub env_file, gdy wartość jest interpolowana z Twojej powłoki lub pliku środowiskowego, potem dosłowna wartość w environment, potem wartość z env_file, a na końcu linia ENV wbudowana w obraz.
Zwróć uwagę, że tylko jeden z tych poziomów to plik .env, i to pośrednio: zasila poziom drugi przez interpolację. Wartość w .env, o której nie wspomina żadna usługa, nigdy nie pojawi się w kontenerze.
Klucze bez wartości
Sama nazwa w environment, na przykład - API_TOKEN bez znaku równości, kopiuje wartość z powłoki, w której działa Compose. Jeśli powłoka jej nie ma, zmienna pozostaje nieustawiona.
W env_file linia zawierająca tylko klucz usuwa tę zmienną ze środowiska kontenera, co przydaje się do celowego wyczyszczenia czegoś, co ustawia obraz.
Wszystkie formy interpolacji
Co daje każda forma dla VAR ustawionej, pustej lub nieustawionej
Forma
VAR=abc
VAR pusta
VAR nieustawiona
${VAR} or $VAR
pusty ciąg, z ostrzeżeniem
${VAR:-default}
${VAR-default}
${VAR:?msg}
błąd msg
błąd msg
${VAR?msg}
błąd msg
${VAR:+other}
${VAR+other}
dosłowny $
dosłowny $
dosłowny $
Pliki Compose do skopiowania
env_file plus nadpisania w environment
Wspólne ustawienia pochodzą z plików; wpisy environment wygrywają dla kluczy, które wymieniają. Plik lokalny jest opcjonalny.
Plik .env projektu używany tylko do interpolacji
Te dwie wartości wypełniają placeholdery w compose.yaml. Żadna nie trafia do kontenera, chyba że wspomina o niej usługa.
Użycie tych wartości w compose.yaml
Tag obrazu i publikowany port pochodzą z .env; hasło musi być ustawione, inaczej Compose zatrzyma się z jasnym komunikatem.
Sprawdź, co wyliczył Compose
config wypisuje ostateczny model z wypełnionymi wszystkimi zmiennymi; --environment wymienia wartości użyte do podstawienia.
Która wartość wygrywa?
Zmienna APP_MODE jest ustawiona w miejscach zaznaczonych poniżej.
Gdzie ustawiona jest zmienna
Wartość
Kontener dostaje APP_MODE={v} z: {n}
Nigdzie nieustawiona, więc APP_MODE nie istnieje w kontenerze.