Dlaczego kontener traci dane po restarcie

Zapisz wiersz do bazy danych działającej w kontenerze Docker, zatrzymaj kontener, uruchom go ponownie: wiersza nie ma.

Każdy kontener przy każdym starcie dostaje swój system plików na nowo z obrazu. Wszystko, co kontener sam zapisze — pliki bazy danych, przesłane pliki, logi — trafia do warstwy zapisywalnej, która jest kasowana przy usunięciu kontenera. Wolumin Docker to sposób na trzymanie tych danych poza kontenerem, tam gdzie przetrwają.

Czym jest Wolumin Docker?

Wolumin Docker to mechanizm do zapisywania danych poza kontenerem, tak aby przetrwały nawet gdy kontener zostanie zatrzymany, uruchomiony ponownie lub usunięty.

Pomyśl o woluminach jak o zewnętrznym dysku twardym, który podłączasz do kontenera. Dane są zapisywane na tym “zewnętrznym dysku” i pozostają bezpieczne niezależnie od tego, co stanie się z kontenerem.

Dlaczego Używać Woluminów?

  • Trwałość: dane przeżywają cykl życia kontenera
  • Współdzielenie: wiele kontenerów może mieć dostęp do tych samych danych
  • Backup: łatwiej jest tworzyć kopie zapasowe danych
  • Wydajność: woluminy są zoptymalizowane pod kątem operacji I/O
  • Przenośność: możesz przenosić dane między różnymi hostami

Woluminy, bind mounts i tmpfs: czego użyć

Dane utrwalisz na trzy sposoby, w kolejności, po jaką powinieneś sięgać: woluminy, bind mounts, tmpfs.

1. Woluminy (Volumes) - Zalecany Wybór

Woluminy są w pełni zarządzane przez Docker i zapisywane w specjalnym katalogu na hoście (/var/lib/docker/volumes/ na Linuksie).

1
2
3
4
5
# Utworzenie woluminu
docker volume create moj-wolumin

# Użycie woluminu w kontenerze
docker run -v moj-wolumin:/app/data moj-obraz

Zalety:

  • Zarządzane przez Docker (łatwe do tworzenia, usuwania, inspekcji)
  • Działają na Linuksie, Windows i Mac
  • Mogą być współdzielone między wieloma kontenerami
  • Obsługują sterowniki do zdalnego przechowywania (chmura, NFS itp.)

2. Bind Mounts - Bezpośrednie Połączenie

Bind mounts łączą konkretny folder na twoim komputerze bezpośrednio z kontenerem.

1
2
# Połączenie lokalnego folderu z kontenerem
docker run -v /sciezka/na/twoim/pc:/app/data moj-obraz

Kiedy ich używać:

  • Podczas developmentu, aby widzieć zmiany w kodzie w czasie rzeczywistym
  • Gdy potrzebujesz dostępu do konkretnych plików systemu hosta
  • Do współdzielenia konfiguracji między hostem a kontenerem

Uwaga: bind mounts zależą od struktury systemu plików hosta, więc są mniej przenośne.

3. tmpfs Mounts - Tymczasowe Dane w Pamięci

tmpfs mounts zapisują dane w RAM hosta, nie na dysku.

1
docker run --tmpfs /app/temp moj-obraz

Kiedy ich używać:

  • Dla wrażliwych danych, które nie powinny być zapisywane na dysku
  • Dla tymczasowych cache’ów o wysokiej wydajności
  • Dane są tracone po zatrzymaniu kontenera (i dokładnie o to chodzi)

Polecenia woluminów Docker: create, list, inspect, remove

Tworzenie Woluminu

1
docker volume create nazwa-woluminu

Listowanie Woluminów

1
docker volume ls

Inspekcja Woluminu

1
docker volume inspect nazwa-woluminu

To polecenie pokazuje, gdzie wolumin jest fizycznie zapisany i inne przydatne informacje.

Usuwanie Woluminu

1
2
3
4
5
# Usunięcie konkretnego woluminu
docker volume rm nazwa-woluminu

# Usunięcie wszystkich nieużywanych woluminów
docker volume prune

Uwaga: usunięcie woluminu oznacza utratę wszystkich zawartych danych. Nie ma kosza ani odzyskiwania.

Przykłady woluminów Docker: baza danych, development z przeładowaniem, współdzielenie

Przykład 1: Baza Danych MySQL z Trwałymi Danymi

Bez woluminu, za każdym razem gdy restartujesz kontener MySQL, tracisz wszystkie dane. Oto jak to rozwiązać:

1
2
3
4
5
6
7
8
9
# Utworzenie woluminu dla danych MySQL
docker volume create mysql-data

# Uruchomienie MySQL używając woluminu
docker run -d \
  --name moj-mysql \
  -e MYSQL_ROOT_PASSWORD=password123 \
  -v mysql-data:/var/lib/mysql \
  mysql:8

Teraz możesz zatrzymać, zrestartować lub nawet usunąć i odtworzyć kontener: dane bazy danych pozostaną nienaruszone w woluminie mysql-data.

Przykład 2: Development Webowy z Bind Mount

Podczas developmentu chcesz, aby zmiany w kodzie były natychmiast widoczne w kontenerze:

1
2
3
4
5
docker run -d \
  --name moja-strona \
  -p 8080:80 \
  -v $(pwd)/src:/var/www/html \
  php:apache

Każda zmiana plików w folderze src będzie natychmiast dostępna w kontenerze.

Przykład 3: Współdzielenie Danych Między Kontenerami

Dwa kontenery, które muszą mieć dostęp do tych samych plików:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Utworzenie współdzielonego woluminu
docker volume create wspoldzielone-dane

# Kontener piszący
docker run -d --name pisarz -v wspoldzielone-dane:/data alpine \
  sh -c "while true; do date >> /data/log.txt; sleep 5; done"

# Kontener czytający
docker run -it --name czytelnik -v wspoldzielone-dane:/data alpine \
  tail -f /data/log.txt

Woluminy w Docker Compose

W Docker Compose woluminy deklarujesz raz, a każda usługa, która ich potrzebuje, odwołuje się do nich po nazwie:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '3.8'

services:
  database:
    image: postgres:15
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  app:
    image: moja-aplikacja
    volumes:
      - ./kod:/app              # Bind mount dla developmentu
      - logi:/app/logs          # Wolumin dla logów

volumes:
  postgres-data:    # Wolumin zarządzany przez Docker
  logi:             # Wolumin zarządzany przez Docker

Za pomocą prostego docker-compose up, Docker automatycznie tworzy potrzebne woluminy.

Backup i Przywracanie Woluminów

Tworzenie Backupu Woluminu

1
2
3
4
docker run --rm \
  -v nazwa-woluminu:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

To polecenie:

  1. Montuje wolumin w trybie tylko do odczytu (ro)
  2. Tworzy skompresowane archiwum w bieżącym katalogu

Przywracanie Backupu

1
2
3
4
docker run --rm \
  -v nazwa-woluminu:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/backup.tar.gz -C /target

Błędy z woluminami Docker, których warto unikać

1. Zapominanie o Używaniu Woluminów dla Baz Danych

Jeśli używasz bazy danych w Dockerze bez woluminu, stracisz wszystkie dane. Zawsze.

2. Używanie Bind Mounts na Produkcji

Bind mounts są świetne do developmentu, ale na produkcji używaj woluminów Docker dla lepszej przenośności i bezpieczeństwa.

3. Brak Backupów Woluminów

Woluminy nie są automatycznie uwzględniane w backupach systemu. Planuj regularne kopie zapasowe.

4. Gromadzenie Osieroconych Woluminów

Gdy usuwasz kontenery, woluminy pozostają. Używaj okresowo:

1
docker volume prune

Aby usunąć woluminy, które nie są już połączone z żadnym kontenerem.

Która opcja przechowywania do czego

ScenariuszRozwiązanie
Baza danych na produkcjiWolumin Docker
Lokalny developmentBind mount
Wrażliwe dane tymczasowetmpfs
Współdzielenie między konteneramiWolumin Docker
Pliki konfiguracyjneBind mount lub Wolumin
Logi aplikacjiWolumin Docker

Zasada, która wystarcza w większości przypadków

Użyj nazwanego woluminu do wszystkiego, co kontener zapisuje, a co chcesz zachować — przede wszystkim baz danych. Użyj bind mounta, gdy chcesz, żeby kontener widział folder na twojej maszynie w trakcie edycji, czyli głównie przy lokalnym developmencie. tmpfs zostaw na dane, które nie mogą trafić na dysk.

Gdy baza danych ma wolumin, możesz usuwać i odtwarzać jej kontener dowolnie często, a dane zostają na miejscu. O to właśnie chodzi.

Powiązane artykuły