Zmienne środowiskowe i plik .env
1. Wprowadzenie
W nowoczesnych aplikacjach kontenerowych niezwykle ważne jest oddzielenie konfiguracji od kodu źródłowego. Dzięki temu:
- ten sam obraz Dockera może być używany w różnych środowiskach (dev, test, production),
- dane wrażliwe (np. hasła, klucze API) nie są przechowywane w repozytorium kodu,
- łatwiej jest zarządzać konfiguracją i wdrażać aplikację w sposób bezpieczny oraz powtarzalny.
Docker i Docker Compose oferują prosty mechanizm do pracy z zmiennymi środowiskowymi (environment variables) i plikami .env, które pełnią rolę centralnego miejsca przechowywania konfiguracji aplikacji.
2. Czym są zmienne środowiskowe
Zmienne środowiskowe (ang. environment variables) to wartości konfiguracyjne przekazywane do aplikacji w czasie uruchomienia kontenera. Zazwyczaj definiują one m.in.:
- dane dostępowe do bazy danych (host, użytkownik, hasło),
- klucze API,
- adresy serwerów zewnętrznych,
- porty aplikacji czy tryb uruchomienia (np.
DEBUG=True).
W kontenerach Dockera można je przekazać na kilka sposobów:
- Bezpośrednio w poleceniu
docker run:
- W pliku
docker-compose.yml(sekcjaenvironment):
- W osobnym pliku
.env, który Compose automatycznie odczytuje.
3. Przechowywanie sekretów i konfiguracji poza kodem
Przechowywanie poufnych danych w plikach źródłowych jest niebezpieczne — może prowadzić do przypadkowego wycieku haseł lub kluczy API (np. przy publikacji repozytorium na GitHubie). Dlatego najlepszą praktyką jest:
- Nie umieszczać sekretów w plikach Dockerfile ani docker-compose.yml.
- Przechowywać je w pliku
.env, który nie jest wersjonowany (dodany do.gitignore).
Przykład pliku .env:
Taki plik może być potem użyty przez Docker Compose bez konieczności wpisywania tych wartości do pliku YAML.
4. Użycie pliku .env w Docker Compose
Docker Compose automatycznie wykrywa plik .env znajdujący się w tym samym katalogu co docker-compose.yml i wczytuje jego zawartość.
W pliku Compose możemy następnie odwoływać się do tych zmiennych, korzystając z notacji ${NAZWA_ZMIENNEJ}.
Przykład:
Plik .env:
Plik docker-compose.yml:
W tym przykładzie Compose automatycznie zastąpi wszystkie wystąpienia ${POSTGRES_USER}, ${POSTGRES_PASSWORD} itd. wartościami z pliku .env.
5. Oddzielanie środowisk: dev / prod
W projektach rzeczywistych bardzo często istnieje potrzeba posiadania różnych konfiguracji dla środowisk:
- dev (development) – dla programistów, z logami, trybem debugowania i lokalną bazą danych,
- prod (production) – dla środowiska produkcyjnego, z optymalizacjami, innym portem, bez debugowania.
5.1 Podejście 1 – Różne pliki .env
Możemy stworzyć osobne pliki .env.dev i .env.prod, np.:
.env.dev
.env.prod
A następnie uruchamiać środowisko z odpowiednim plikiem:
lub
W ten sposób możesz kontrolować różne konfiguracje przy użyciu tego samego pliku Compose.
5.2 Podejście 2 – Różne pliki Compose
Innym rozwiązaniem jest posiadanie osobnych plików Compose:
docker-compose.yml– podstawowa konfiguracja wspólna dla wszystkich środowisk,docker-compose.dev.yml– dodatkowe ustawienia dla środowiska developerskiego (np. mount kodu lokalnego),docker-compose.prod.yml– optymalizacje produkcyjne (np. bez mapowania katalogów).
Uruchamianie:
lub
To rozwiązanie daje większą elastyczność, gdy środowiska różnią się znacznie konfiguracją.
6. Najczęstsze zastosowania zmiennych środowiskowych
| Zmienna | Opis | Przykład |
|---|---|---|
POSTGRES_USER |
Użytkownik bazy danych | postgres |
POSTGRES_PASSWORD |
Hasło do bazy | haslo123 |
POSTGRES_DB |
Nazwa bazy danych | mydb |
FLASK_ENV |
Tryb aplikacji Flask | development / production |
NODE_ENV |
Tryb aplikacji Node.js | production |
API_URL |
Adres API backendu | http://backend:5000 |
PORT |
Port aplikacji | 8080 |
Warto także przekazywać zmienne z .env do kontenerów frontendu (np. Angulara) przy budowie, aby aplikacja mogła komunikować się z odpowiednim backendem w zależności od środowiska.
7. Dobre praktyki dotyczące pracy z plikiem .env
- Dodaj plik
.envdo.gitignore, aby nie został przypadkowo opublikowany w repozytorium. - Utwórz plik
.env.example, który zawiera tylko nazwy zmiennych bez wartości:
Taki plik można bezpiecznie przechowywać w repozytorium, aby nowi członkowie zespołu wiedzieli, jakie zmienne należy ustawić.
- Stosuj prefiksy dla zmiennych, np.
DB_,API_,APP_, aby zachować porządek. - Używaj wielkich liter i nie stosuj spacji (standardowa konwencja UNIX).
- Nie mieszaj konfiguracji dla różnych środowisk w jednym pliku
.env. - Używaj managerów sekretów (np. HashiCorp Vault, AWS Secrets Manager, Docker Secrets) dla środowisk produkcyjnych.
8. Przykładowa struktura projektu z .env
projekt/
├── backend/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── frontend/
│ ├── Dockerfile
│ └── package.json
├── docker-compose.yml
├── .env
├── .env.dev
├── .env.prod
└── .gitignore
.gitignore:
9. Sprawdzenie wczytanych zmiennych
Aby zobaczyć, jakie zmienne środowiskowe zostały zastosowane w kontenerze:
Możesz też użyć:
To polecenie pokaże pełną konfigurację Compose po zastąpieniu zmiennych ich wartościami z .env.
10. Podsumowanie
W tej lekcji poznałeś kluczowy element zarządzania konfiguracją w Dockerze i Docker Compose — zmienne środowiskowe oraz pliki .env.
Nauczyłeś się:
- jak oddzielać konfigurację od kodu,
- jak bezpiecznie przechowywać hasła i klucze,
- jak używać pliku
.envw Compose, - jak tworzyć osobne konfiguracje dla środowisk dev i prod.
Dzięki temu Twoje aplikacje stają się:
- bezpieczniejsze – sekrety nie trafiają do repozytorium,
- bardziej elastyczne – łatwo zmienić konfigurację bez modyfikacji kodu,
- łatwiejsze w utrzymaniu – to samo środowisko może działać na wielu maszynach z różnymi ustawieniami.
Docker + pliki .env to potężne narzędzie, które pozwala utrzymać porządek, bezpieczeństwo i skalowalność w każdym projekcie kontenerowym.