2.1 Podstawowe koncepcje Dockerfile
Dockerfile — to plik tekstowy, zawierający sekwencję poleceń, które Docker używa do stworzenia obrazu. Służy jako „przepis”, opisujący, jak ma być zbudowany obraz – od warstwy bazowej do stanu końcowego. Zrozumienie struktury i procesu tworzenia Dockerfile jest ważne dla efektywnego korzystania z Dockera.
Podstawowe koncepcje Dockerfile:
- Idempotencja: polecenia w Dockerfile powinny być idempotentne — ich wielokrotne wykonanie daje ten sam rezultat.
- Kolejność: polecenia są wykonywane w kolejności od góry do dołu. Kolejność ma znaczenie, bo każde polecenie tworzy nową warstwę obrazu.
- Struktura warstwowa: praktycznie każda instrukcja dodaje nową warstwę do obrazu. Te warstwy są buforowane, co pozwala zoptymalizować proces budowy.
Struktura Dockerfile:
Dockerfile składa się z instrukcji, z których każda wykonuje określoną funkcję. Oto podstawowe z nich:
- FROM: ustawia obraz bazowy, który zostanie użyty do stworzenia nowego obrazu.
- MAINTAINER: określa autora Dockerfile (przestarzałe, ale przydatne dla informacji).
- RUN: wykonuje polecenia w kontenerze i tworzy nową warstwę.
- COPY: kopiuje pliki i katalogi z kontekstu budowy do systemu plików kontenera.
- ADD: kopiuje pliki i katalogi, wspiera rozpakowywanie archiwów i pobieranie plików przez URL.
- WORKDIR: ustawia katalog roboczy dla kolejnych poleceń.
- ENV: ustawia zmienne środowiskowe.
- CMD: określa polecenie domyślne, które jest wykonywane przy uruchomieniu kontenera.
- ENTRYPOINT: ustawia polecenie wykonywane przy uruchomieniu kontenera, z możliwością przekazania argumentów.
- EXPOSE: wskazuje porty używane przez kontener.
- VOLUME: tworzy punkt montowania dla zewnętrznych woluminów.
2.2 Tworzenie Dockerfile
Przykład tworzenia Dockerfile
Zobaczmy prosty przykład tworzenia Dockerfile dla aplikacji webowej na Node.js.
Krok 1: Tworzenie podstawowego Dockerfile
Utwórz plik o nazwie Dockerfile w katalogu głównym swojego projektu i dodaj następujące linie:
# Używamy bazowego obrazu Node.js
FROM node:14
# Ustawiamy katalog roboczy
WORKDIR /app
# Kopiujemy package.json i package-lock.json
COPY package*.json ./
# Instalujemy zależności
RUN npm install
# Kopiujemy wszystkie pliki projektu
COPY . .
# Wskazujemy port, który będzie używany przez aplikację
EXPOSE 3000
# Definiujemy komendę do uruchamiania aplikacji
CMD ["node", "app.js"]
Ten Dockerfile wykonuje następujące kroki:
- FROM node:14: używa oficjalnego obrazu
Node.jsw wersji 14 jako bazy. - WORKDIR /app: ustawia katalog roboczy dla kolejnych komend.
- COPY package*.json ./: kopiuje pliki
package.jsonipackage-lock.jsondo katalogu roboczego. - RUN npm install: instaluje zależności z pliku
package.json. - COPY . .: kopiuje wszystkie pliki projektu do katalogu roboczego kontenera.
- EXPOSE 3000: wskazuje, że aplikacja będzie używać portu 3000.
- CMD ["node", "app.js"]: definiuje komendę do uruchomienia aplikacji.
Krok 2: Budowanie obrazu
Po stworzeniu Dockerfile zbuduj obraz za pomocą komendy docker build:
docker build -t my-node-app .
Ta komenda stworzy obraz o nazwie my-node-app, używając Dockerfile z bieżącego katalogu.
Krok 3: Uruchamianie kontenera
Uruchom kontener na podstawie stworzonego obrazu za pomocą komendy docker run:
docker run -d -p 3000:3000 my-node-app
Ten przykład uruchamia kontener w tle, przekierowując port 3000 kontenera na port 3000 maszyny hosta. Teraz możesz uzyskać dostęp do aplikacji pod http://localhost:3000.
2.3 Dodatkowe instrukcje Dockerfile
1. Ustawienie zmiennych środowiskowych
Możesz ustawić zmienne środowiskowe, które będą dostępne w kontenerze, używając instrukcji ENV.
ENV NODE_ENV=production
2. Używanie kilku komend RUN
Czasami warto połączyć kilka komend w jedną instrukcję RUN, aby zmniejszyć liczbę warstw, zmniejszyć rozmiar obrazu i przyspieszyć budowanie.
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
Przydatne! Jeśli komenda nie mieści się w jednej linii, można użyć symbolu \, aby kontynuować w następnej linii. Zostanie to zinterpretowane jako jedna komenda.
Przydatne! Aby zapisać kilka komend w jednej linii, można użyć &&: command1 && command2 && command3. To pozwala na sekwencyjne wykonanie kilku komend.
Optymalizacja kolejności komend
Aby efektywnie korzystać z cache Docker, najpierw kopiuj pliki, które rzadko się zmieniają (np. package.json), i instaluj zależności przed dodaniem pozostałych plików projektu.
Przykład zaawansowanego Dockerfile
W bardziej skomplikowanych projektach może być konieczne rozszerzone Dockerfile z dodatkowymi ustawieniami.
# Używamy minimalnego obrazu bazowego Node.js
FROM node:14-alpine
# Ustawiamy katalog roboczy
WORKDIR /usr/src/app
# Kopiujemy package.json i instalujemy zależności
COPY package*.json ./
RUN npm install --only=production
# Kopiujemy kod źródłowy
COPY . .
# Określamy port do pracy
EXPOSE 8080
# Ustawiamy zmienne środowiskowe
ENV NODE_ENV=production
# Uruchamiamy aplikację
CMD ["node", "server.js"]
GO TO FULL VERSION