Tworzenie obrazów Dockera dla aplikacji frontendowych

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 argumenty

Najważniejsze instrukcje:

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.0

Gdzie: - -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.0

W 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

  1. Używanie lekkich obrazów bazowych
    • Preferuj obrazy z dopiskiem alpine (np. node:18-alpine zamiast node:18)
  2. 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/*
  3. 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
  4. Usuwanie niepotrzebnych plików
    • Usuwaj pliki tymczasowe i cache po ich wykorzystaniu
    RUN npm install && \
        npm cache clean --force
  5. 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

  1. Utwórz prostą aplikację React:

    npx create-react-app moja-aplikacja
    cd moja-aplikacja
  2. Utwórz plik Dockerfile z podstawową konfiguracją (jak pokazano wcześniej)

  3. Utwórz plik .dockerignore

  4. Zbuduj i uruchom obraz:

    docker build -t moja-aplikacja:v1 .
    docker run -p 3000:3000 moja-aplikacja:v1

Ćwiczenie 2: Zastosowanie wieloetapowego budowania

  1. Zmodyfikuj Dockerfile do wersji z multi-stage build (jak pokazano wcześniej)

  2. Zbuduj i uruchom zoptymalizowany obraz:

    docker build -t moja-aplikacja:v2 .
    docker run -p 8080:80 moja-aplikacja:v2
  3. Porównaj rozmiary obrazów:

    docker images | grep moja-aplikacja

Ćwiczenie 3: Dodanie własnej konfiguracji nginx

  1. Utwórz plik nginx.conf z konfiguracją dla SPA (jak pokazano wcześniej)

  2. Zmodyfikuj Dockerfile, aby kopiować tę konfigurację:

    COPY nginx.conf /etc/nginx/conf.d/default.conf
  3. Zbuduj 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.

Zasoby dodatkowe