Tworzenie obrazów Dockera dla aplikacji frontendowych
Czym jest Dockerfile?
Dockerfile to skrypt zawierający instrukcje budowania obrazu Docker. Pozwala on na zdefiniowanie środowiska i procesu budowania aplikacji w sposób powtarzalny i zautomatyzowany.
Podstawowa składnia Dockerfile
# Komentarz
INSTRUKCJA argumentyNajważniejsze instrukcje:
FROM- określa obraz bazowy (punkt startowy)WORKDIR- ustawia katalog roboczy wewnątrz konteneraCOPY- kopiuje pliki z hosta do obrazuRUN- wykonuje polecenia podczas budowania obrazuCMD- określa domyślne polecenie do uruchomienia konteneraEXPOSE- informuje, które porty kontener będzie nasłuchiwaćENV- ustawia zmienne środowiskowe
Tworzenie obrazu Docker dla aplikacji React
1. Podstawowy Dockerfile
Poniżej znajduje się przykładowy Dockerfile dla aplikacji React:
FROM node:18-alpine
# Ustawienie katalogu roboczego
WORKDIR /app
# Kopiowanie plików zależności
COPY package*.json ./
RUN npm install
# Kopiowanie kodu źródłowego
COPY . .
# Budowanie aplikacji
RUN npm run build
# Instalacja serwera do serwowania statycznych plików
RUN npm install -g serve
# Informacja o porcie
EXPOSE 3000
# Uruchomienie aplikacji
CMD ["serve", "-s", "build", "-l", "3000"]2. Budowanie i uruchamianie obrazu
# Budowanie obrazu
docker build -t moja-aplikacja-react:1.0 .
# Uruchamianie kontenera
docker run -p 3000:3000 moja-aplikacja-react:1.0Gdzie: - -t moja-aplikacja-react:1.0 - nazwa
i tag obrazu - -p 3000:3000 - mapowanie portu
kontenera (3000) na port hosta (3000)
Wieloetapowe budowanie (Multi-stage builds)
Wieloetapowe budowanie pozwala na optymalizację procesu budowania i rozmiaru końcowego obrazu. W tym podejściu używamy wielu obrazów bazowych - jeden do budowania aplikacji i drugi (mniejszy) do jej uruchamiania.
Dockerfile z wieloetapowym budowaniem:
# Etap budowania
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Etap produkcyjny
FROM nginx:alpine
# Kopiowanie plików z etapu budowania
COPY --from=build /app/build /usr/share/nginx/html
# Opcjonalnie: własna konfiguracja nginx
# COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Budowanie i uruchamianie:
# Budowanie obrazu
docker build -t moja-aplikacja-react:2.0 .
# Uruchamianie kontenera
docker run -p 8080:80 moja-aplikacja-react:2.0W tym przypadku aplikacja będzie dostępna pod adresem http://localhost:8080
Plik .dockerignore
Podobnie jak .gitignore, plik
.dockerignore pozwala na wykluczenie plików i
katalogów z kontekstu budowania. Pomaga to zmniejszyć
rozmiar obrazu i przyspieszyć proces budowania.
Przykładowy plik .dockerignore dla aplikacji
React:
node_modules
npm-debug.log
build
.git
.gitignore
.env
.env.local
.env.development
.env.test
.env.production
README.md
Techniki optymalizacji obrazów Docker
- Używanie lekkich obrazów bazowych
- Preferuj obrazy z dopiskiem
alpine(np.node:18-alpinezamiastnode:18)
- Preferuj obrazy z dopiskiem
- Minimalizacja warstw
- Łącz polecenia RUN za pomocą operatora
&&i\
RUN apt-get update && \ apt-get install -y package1 package2 && \ rm -rf /var/lib/apt/lists/* - Łącz polecenia RUN za pomocą operatora
- Właściwa kolejność kopiowania plików
- Najpierw kopiuj pliki, które rzadko się zmieniają (np. package.json)
- Następnie kopiuj kod źródłowy, który zmienia się częściej
- Usuwanie niepotrzebnych plików
- Usuwaj pliki tymczasowe i cache po ich wykorzystaniu
RUN npm install && \ npm cache clean --force - Używanie wieloetapowego budowania
- Zmniejsza rozmiar końcowego obrazu
- Eliminuje narzędzia deweloperskie z obrazu produkcyjnego
Konfiguracja nginx dla aplikacji Single Page Application (SPA)
Aplikacje SPA (jak React, Vue, Angular) wymagają specjalnej konfiguracji serwera WWW, aby obsługiwać routing po stronie klienta. Poniżej znajduje się przykładowa konfiguracja dla nginx:
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
# Obsługa routingu SPA
location / {
try_files $uri $uri/ /index.html;
}
# Cache statycznych zasobów
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
add_header Cache-Control "public, immutable";
}
}
Zapisz tę konfigurację w pliku nginx.conf i
dodaj do Dockerfile:
COPY nginx.conf /etc/nginx/conf.d/default.confĆwiczenia praktyczne
Ćwiczenie 1: Podstawowy obraz dla aplikacji React
Utwórz prostą aplikację React:
npx create-react-app moja-aplikacja cd moja-aplikacjaUtwórz plik
Dockerfilez podstawową konfiguracją (jak pokazano wcześniej)Utwórz plik
.dockerignoreZbuduj i uruchom obraz:
docker build -t moja-aplikacja:v1 . docker run -p 3000:3000 moja-aplikacja:v1
Ćwiczenie 2: Zastosowanie wieloetapowego budowania
Zmodyfikuj
Dockerfiledo wersji z multi-stage build (jak pokazano wcześniej)Zbuduj i uruchom zoptymalizowany obraz:
docker build -t moja-aplikacja:v2 . docker run -p 8080:80 moja-aplikacja:v2Porównaj rozmiary obrazów:
docker images | grep moja-aplikacja
Ćwiczenie 3: Dodanie własnej konfiguracji nginx
Utwórz plik
nginx.confz konfiguracją dla SPA (jak pokazano wcześniej)Zmodyfikuj
Dockerfile, aby kopiować tę konfigurację:COPY nginx.conf /etc/nginx/conf.d/default.confZbuduj i uruchom obraz:
docker build -t moja-aplikacja:v3 . docker run -p 8080:80 moja-aplikacja:v3
Rozwiązywanie typowych problemów
Problem z routingiem SPA
Jeśli po odświeżeniu strony otrzymujesz błąd 404, prawdopodobnie brakuje konfiguracji nginx dla SPA. Dodaj konfigurację z sekcji “Konfiguracja nginx dla SPA”.
CORS (Cross-Origin Resource Sharing)
Jeśli aplikacja React ma problemy z dostępem do API, możesz dodać proxy w nginx:
location /api/ {
proxy_pass http://api-server:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Problemy z wydajnością
Jeśli obraz Docker jest zbyt duży, zastosuj techniki
optymalizacji opisane wcześniej. Sprawdź rozmiar obrazu
poleceniem docker images.