Wstęp
Jeśli od jakiegoś czasu śledzisz moją serię o Dockerze, to wiesz już, że kontenery totalnie odmieniły sposób, w jaki budujemy i wdrażamy aplikacje. We wpisie o podstawach konteneryzacji wspominałem o jednej, bardzo ważnej cesze kontenerów: są ulotne. Co to znaczy? Po prostu tyle, że kiedy zatrzymasz i usuniesz kontener, wszystko, co w nim zapisałeś, znika bez śladu.
Wyobraź sobie sytuację, w której uruchamiasz kontener z bazą danych PostgreSQL. Dodajesz użytkowników, tworzysz tabele, ładujesz setki rekordów. Następnego dnia postanawiasz zaktualizować obraz bazy do nowszej wersji, więc usuwasz stary kontener i odpalasz nowy. Logujesz się… i baza jest pusta. Całe dane poszły w kosmos. Trochę niefajnie, prawda?
Nietrwałość danych to jeden z pierwszych poważnych tematów, na które trafia każdy, kto zaczyna z Dockerem. Kontenery są z założenia stanowe – ich system plików żyje tak długo, jak sam kontener. Na szczęście Docker ma na to rozwiązanie: wolumeny. To one pozwalają przechowywać dane na stałe, niezależnie od tego, ile razy zatrzymasz czy usuniesz kontener.
W tym artykule przejdziemy krok po kroku przez wszystko, co warto wiedzieć o wolumenach w Dockerze. Zaczniemy od podstaw – czym są wolumeny i dlaczego są tak istotne. Potem przyjrzymy się ich różnym typom, poznamy praktyczne komendy do ich obsługi, a także zajrzymy w bardziej zaawansowane tematy, jak backup danych czy współdzielenie plików między kontenerami. Na koniec omówimy najczęstsze problemy i odpowiemy na pytania, które często pojawiają się w pracy z Dockerem.
Wolumeny w dockerze – podstawy (docker volume)
Na początek zaczniemy od podstaw. W tej części skupimy się na tym, czym dokładnie są wolumeny, dlaczego są tak ważne i jak zacząć z nimi pracę za pomocą podstawowych komend.
Czym są wolumeny w Dockerze?
Najprościej mówiąc, wolumen (volume) to dedykowany mechanizm w Dockerze służący do trwałego przechowywania danych generowanych i używanych przez kontenery. Wolumeny są zarządzane bezpośrednio przez Dockera i istnieją niezależnie od kontenerów. Oznacza to, że nawet jeśli usuniesz kontener, który używał danego wolumenu, dane w tym wolumenie pozostaną nienaruszone.
Można je sobie wyobrazić jako specjalne, wirtualne dyski podłączane do naszych kontenerów. Docker dba o to, gdzie fizycznie te dane są przechowywane na maszynie-hoście (zazwyczaj w specjalnym katalogu w systemie plików Dockera), ale my, jako użytkownicy, nie musimy się tym przejmować. Interesuje nas tylko nazwa wolumenu i możliwość podłączenia go do kontenera.
Kluczowe cechy wolumenów:
- Trwałość – dane przetrwają restarty i usunięcie kontenera.
- Zarządzanie przez Docker CLI – możesz nimi zarządzać za pomocą prostych komend
docker volume .... - Wydajność – działają z natywną wydajnością operacji na plikach.
- Bezpieczeństwo – są bezpieczniejszym sposobem na udostępnianie danych niż montowanie bindowane, ponieważ są odizolowane od kluczowych części systemu plików hosta.
- Współdzielenie – ten sam wolumen może być używany przez wiele kontenerów jednocześnie.
Problem z danymi w kontenerach

Aby w pełni docenić wolumeny, musimy zrozumieć, co dzieje się z danymi bez nich. Każdy kontener Dockera ma swój własny, izolowany system plików. Kiedy uruchamiasz aplikację w kontenerze – na przykład bazę danych, która tworzy swoje pliki – te dane są zapisywane właśnie w tej izolowanej przestrzeni.
Problem pojawia się w momencie, gdy kontener zostanie usunięty (np. komendą docker rm). Wraz z nim bezpowrotnie znika cały jego system plików, a co za tym idzie – wszystkie dane. Tak, więc tutaj możemy dojść do wniowsku, że kontenery bez zewnętrznego mechanizmu przechowywania danych są bezstanowe (stateless). Świetnie nadają się do uruchamiania aplikacji, które nie muszą niczego zapisywać, ale stają się problematyczne w przypadku baz danych, systemów logowania czy aplikacji, które przechowują pliki użytkowników. Wolumeny rozwiązują ten problem, wprowadzając stanowość (statefulness).
Typy wolumenów
Docker oferuje trzy główne sposoby na montowanie danych w kontenerach. Chociaż w potocznym języku często wszystko nazywamy „wolumenami”, warto znać formalny podział:
- Wolumeny (Volumes) – To preferowany i najczęściej używany mechanizm. Są w pełni zarządzane przez Dockera (tworzone, usuwane, listowane za pomocą komend
docker volume ...). Przechowywane są w dedykowanej lokalizacji na hoście (np./var/lib/docker/volumes/na Linuksie), ale nie powinniśmy bezpośrednio modyfikować plików w tym miejscu. Wolumeny są najlepszym wyborem do trwałego przechowywania danych, takich jak bazy danych, logi czy konfiguracje. - Montowanie Bindowane (Bind Mounts) – W tym przypadku montujemy istniejący plik lub katalog z maszyny-hosta (np. naszego komputera) bezpośrednio do kontenera. W przeciwieństwie do wolumenów, pliki te nie są zarządzane przez Dockera i mogą znajdować się w dowolnym miejscu na naszym komputerze. Ten typ wolumenów jest bardzo przydatny w środowisku deweloperskim – np. gdy chcemy udostępnić kod źródłowy naszej aplikacji do kontenera, aby zmiany w kodzie na hoście były natychmiast widoczne w kontenerze (tzw. hot-reloading). Trzeba jednak uważać na problemy z uprawnieniami, zwłaszcza na Linuksie.
- Montowanie tmpfs (tmpfs mounts) – To specyficzny typ montowania, który przechowuje dane wyłącznie w pamięci RAM hosta. Dane te nigdy nie są zapisywane na dysku twardym. Są ulotne – znikają po zatrzymaniu kontenera. Przydają się, gdy aplikacja potrzebuje zapisywać duże ilości nietrwałych danych i chcemy uniknąć obciążania dysku, np. dla tymczasowych plików cache. Działa tylko na hostach linuksowych.
Tworzenie i zarządzanie wolumenami
Już wiemy, że wolumeny typu volume to podstawa, jeśli chcemy w Dockerze trwale przechowywać dane. Teraz pora przyjrzeć się, jak je tworzyć, sprawdzać i usuwać. Docker daje nam do ręki cały zestaw komend, dzięki którym bez problemu możemy nimi zarządzać z poziomu konsoli. Zobaczmy, które z tych komend warto znać na co dzień.
Tworzenie nowego wolumenu (docker volume create)
Zanim podłączymy wolumen do kontenera, najpierw musimy go stworzyć. To trochę jak przygotowanie dedykowanego dysku dla naszej aplikacji. Robimy to za pomocą prostej komendy:
docker volume create dane-mojej-aplikacji
Po jej wykonaniu Docker stworzy wolumen o nazwie dane-mojej-aplikacji i zwróci jego nazwę jako potwierdzenie. Od tej pory wolumen ten istnieje w systemie Dockera i czeka, aż jakiś kontener zacznie z niego korzystać.
Listowanie dostępnych wolumenów (docker volume ls)
W sytuacji, gdy pracujemy z wieloma projektami, liczba wolumenów może szybko rosnąć. Aby sprawdzić, jakie wolumeny aktualnie istnieją na maszynie, używamy komendy:
docker volume ls
W odpowiedzi powinna ukazać się prosta tabelę z nazwami wszystkich wolumenów zarządzanych przez Dockera (między innymi powinieneś dostać wolumen utworzony w poprzednim punkcie):

To świetny sposób, aby szybko zorientować się, co dzieje się w naszym środowisku i czy nie mamy jakichś zapomnianych wolumenów.
Inspekcja szczegółów wolumenu (docker volume inspect)
Czasem potrzebujemy zajrzeć i dowiedzieć się czegoś więcej o konkretnym wolumenie. Gdzie on tak naprawdę się znajduje? Kiedy został stworzony? Do tego służy komenda inspect:
docker volume inspect dane-mojej-aplikacji
Wynikiem będzie obiekt JSON ze szczegółowymi informacjami. Najciekawszy dla nas jest klucz Mountpoint, który pokazuje dokładną fizyczną ścieżkę na dysku maszyny-hosta, gdzie Docker przechowuje pliki tego wolumenu.
[
{
"CreatedAt": "2025-06-29T20:10:00Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/dane-mojej-aplikacji/_data",
"Name": "dane-mojej-aplikacji",
"Options": {},
"Scope": "local"
}
]
Uwaga: Chociaż widać tutaj fizyczną ścieżkę, dobrze jest unikać bezpośredniego modyfikowania plików w tym katalogu. Wolumeny powinny być zarządzane wyłącznie przez Dockera, aby uniknąć problemów z uprawnieniami i spójnością danych.
Usuwanie wolumenów (docker volume rm i docker volume prune)
Utrzymanie porządku jest kluczowe. Jeśli dany wolumen nie jest Ci już potrzebny, możesz go usunąć:
docker volume rm dane-mojej-aplikacji
Docker dba o bezpieczeństwo Twoich danych, więc nie pozwoli usunąć wolumenu, który jest aktualnie używany przez jakikolwiek kontener. Najpierw musisz zatrzymać i usunąć kontener, który z niego korzysta.
A co jeśli mamy dziesiątki zapomnianych wolumenów, które tylko zajmują cenne miejsce na dysku? Z pomocą przychodzi poniższa komenda:
docker volume prune
To polecenie wyszukuje i usuwa wszystkie „wiszące” (dangling) wolumeny, czyli takie, które nie są podłączone do żadnego istniejącego kontenera. Przed usunięciem Docker poprosi o potwierdzenie, więc operacja jest bezpieczna. Co jakiś czas warto sobie przypomnieć o tej komendzie i ją wykonać – pozwoli to utrzymać czystość środowiska deweloperskiego.
Jak połączyć kontener z dyskiem lokalnym?
Najprostszym sposobem na połączenie kontenera z konkretnym folderem na naszym dysku jest użycie bind mount. Służy do tego flaga -v lub --mount. Załóżmy, że chcemy uruchomić serwer Nginx i serwować pliki z naszego lokalnego katalogu C:\Users\Piotr\MojaStrona.
Użyjemy do tego następującej komendy:
# Składnia dla Windows docker run -d --name moj-serwer-www -p 8080:80 -v C:\Users\Piotr\MojaStrona:/usr/share/nginx/html nginx # Składnia dla Linux/MacOS docker run -d --name moj-serwer-www -p 8080:80 -v /home/piotr/moja-strona:/usr/share/nginx/html nginx
Przeanalizujmy fragment -v /home/piotr/moja-strona:/usr/share/nginx/html:
/home/piotr/moja-stronato ścieżka na maszynie-hoście./usr/share/nginx/htmlto ścieżka wewnątrz kontenera, gdzie Nginx domyślnie szuka plików do serwowania.
Po uruchomieniu tej komendy, każda zmiana w plikach w lokalnym folderze /home/piotr/moja-strona będzie natychmiast widoczna dla serwera Nginx działającego w kontenerze. To idealne rozwiązanie podczas developmentu!
Praktyczny przykład
Poniżej przykład użycia z bazą danych:
# Tworzymy wolumen dla PostgreSQL docker volume create postgres-data # Uruchamiamy kontener z zamontowanym wolumenem docker run -d \ --name my-postgres \ -e POSTGRES_PASSWORD=mypassword \ -v postgres-data:/var/lib/postgresql/data \ postgres:16 # Teraz możemy bezpiecznie usunąć kontener docker rm -f my-postgres # I uruchomić ponownie - dane pozostaną! docker run -d \ --name my-postgres-new \ -e POSTGRES_PASSWORD=mypassword \ -v postgres-data:/var/lib/postgresql/data \ postgres:16
Więcej o wolumenach w Dockerze
Po zapoznaniu się z podstawami dobrze jest też się zagłębić w bardziej zaawansowane tematy. Także w tej sekcji przyjrzymy się kilku tematom, które pozwolą nam zagłębić się jeszcze bardziej w wolumeny w Dockerze.
Składnia -v vs --mount – Którą wybrać?
Do montowania wolumenów i bind mountów możemy używać dwóch flag: -v (lub --volume) oraz --mount. Chociaż często prowadzą do tego samego rezultatu, różnią się składnią i czytelnością.
- Flaga
-v– Jest starsza, bardziej zwięzła i często spotykana w tutorialach.- Wolumen:
docker run -v moj-wolumen:/app ... - Bind Mount:
docker run -v /sciezka/hosta:/app ...
- Wolumen:
- Flaga
--mount– Jest nowsza, bardziej opisowa i rekomendowana przez Dockera. Jej składnia jest bardziej uporządkowana i składa się z par klucz-wartość.- Wolumen:
docker run --mount type=volume,source=moj-wolumen,target=/app ... - Bind Mount:
docker run --mount type=bind,source=/sciezka/hosta,target=/app ... - tmpfs:
docker run --mount type=tmpfs,target=/app ...
- Wolumen:
Tak, więc którą wybrać? Osobiście najczęściej używam składni --mount. Dlaczego?
- Czytelność – Jest bardziej jednoznaczna. Na pierwszy rzut oka widać, z jakim typem montowania mamy do czynienia (
type=volumevstype=bind). - Więcej opcji – Składnia
--mountpozwala na przekazywanie dodatkowych opcji, np.readonlydo montowania w trybie tylko do odczytu. - Mniej pomyłek – W przypadku
-v, Docker próbuje „zgadnąć”, czy chodzi nam o wolumen, czy o bind mount. Jeśli podana ścieżka źródłowa nie jest absolutną ścieżką na hoście, Docker założy, że to nazwa wolumenu i go stworzy, co czasem może prowadzić do nieporozumień.
Mimo wszystko, składnia -v jest wciąż bardzo popularna i w prostych przypadkach sprawdza się świetnie np. w przypadku tworzenia lokalnych wolumenów. Najlepiej jest znać obie i rozumieć róźnice.
Współdzielenie plików między kontenerami
Jedną z dużych zalet wolumenów jest możliwość ich współdzielenia. Wyobraź sobie scenariusz, w którym jedna aplikacja (np. w kontenerze A) generuje pliki, a druga (w kontenerze B) ma je przetwarzać.
Możemy stworzyć jeden wolumen i podłączyć go do obu kontenerów:
Tworzymy wolumen:
docker volume create wspolne-dane
Uruchom kontener A (producenta) odpowiedzialnego za generowanie plików:
docker run -d --name producent --mount type=volume,source=wspolne-dane,target=/app/output ubuntu bash -c "while true; do echo Log_$(date) >> /app/output/log.txt; sleep 5; done"
A na koniec uruchamiamy drugi kontener B (konsumenta), który będzie przetwarzać te pliku:
docker run -it --name konsument --mount type=volume,source=wspolne-dane,target=/app/input ubuntu tail -f /app/input/log.txt
Oba kontenery operują na tych samych danych, które żyją w wolumenie wspolne-dane, całkowicie niezależnie od samych kontenerów.
Trwałość danych w bazach
To chyba najczęstszy i najważniejszy przypadek użycia wolumenów. Uruchamianie bazy danych, np. PostgreSQL, bez wolumenu to proszenie się o kłopoty.
Aby zapewnić trwałość danych, musimy zamontować wolumen w katalogu, w którym PostgreSQL przechowuje swoje pliki (dla oficjalnego obrazu jest to /var/lib/postgresql/data).
# 1. Stwórz wolumen dla danych bazy docker volume create postgres-data # 2. Uruchom kontener PostgreSQL z zamontowanym wolumenem docker run -d --name moja-baza \ -e POSTGRES_PASSWORD=moje_super_haslo \ --mount type=volume,source=postgres-data,target=/var/lib/postgresql/data \ postgres:16
Teraz, nawet jeśli zatrzymasz i usuniesz kontener moja-baza, a następnie uruchomisz nowy kontener z tym samym wolumenem, wszystkie Twoje tabele i dane będą na swoim miejscu.
Backup i odtwarzanie danych
Skoro nasze cenne dane znajdują się w wolumenie, naturalnym krokiem jest zadbanie o ich kopie zapasowe. Docker nie ma wbudowanego magicznego przycisku „backup”, ale proces ten jest stosunkowo prosty.
Możemy uruchomić tymczasowy kontener, który zamontuje nasz wolumen z danymi oraz lokalny katalog (przez bind mount), a następnie spakuje zawartość wolumenu do archiwum.
# Załóżmy, że chcemy zbackupować wolumen 'postgres-data' do pliku 'backup.tar.gz' # w bieżącym katalogu na hoście. docker run --rm \ --mount type=volume,source=postgres-data,target=/data-do-backupu \ --mount type=bind,source=$(pwd),target=/backup \ ubuntu tar -czvf /backup/backup.tar.gz /data-do-backupu
No dobrze, ale co tutaj się dzieje?
--rm: Usuwa kontener po zakończeniu jego pracy.- Montujemy wolumen
postgres-datado katalogu/data-do-backupuw kontenerze. - Montujemy bieżący katalog hosta (
$(pwd)) do/backupw kontenerze. - Uruchamiamy komendę
tar, która pakuje zawartość/data-do-backupudo pliku/backup/backup.tar.gz.
Mamy już nasz backup, a teraz chcemy odtworzyć z niego dane. Proces jest odwrotny. Tworzymy nowy (lub używamy pustego) wolumen i rozpakowujemy do niego archiwum.
# 1. Stwórz nowy wolumen docker volume create postgres-data-z-backupu # 2. Uruchom kontener, który rozpakuje archiwum do nowego wolumenu docker run --rm \ --mount type=volume,source=postgres-data-z-backupu,target=/dane-do-przywrocenia \ --mount type=bind,source=$(pwd),target=/backup \ ubuntu bash -c "cd /dane-do-przywrocenia && tar -xzvf /backup/backup.tar.gz --strip 1"
Parametr --strip 1 jest tu przydatny, aby usunąć pierwszy poziom katalogu z archiwum (data-do-backupu), dzięki czemu pliki trafią bezpośrednio do wolumenu.
Typowe problemy i najczęstsze pytania
Praca z wolumenami jest zazwyczaj bezproblemowa, ale jak z każdą technologią, można natknąć się na kilka typowych pułapek. Tak, więc przyjrzyjmy się kilku z nim.
Diagnostyka podstawowych błędów.
Problem z uprawnienia do plików (Permission Denied). Najczęściej spotykany przy używaniu bind mounts na Linuksie. Użytkownik wewnątrz kontenera (np. nginx lub postgres) ma inne UID/GID niż właściciel plików na hoście. W efekcie proces w kontenerze nie może odczytać lub zapisać plików.
Najprostszym rozwiązaniem na to, choć nie zawsze najbezpieczniejszym, sposobem jest nadanie odpowiednich uprawnień na hoście (chmod, chown). Lepszym podejściem jest uruchomienie kontenera z flagą --user, podając UID/GID użytkownika z hosta, lub budowanie własnego obrazu, który rozwiązuje ten problem na poziomie Dockerfile.
Inny problem to jak kontener nie widzi plików lub ścieżka nie istnieje. Zazwyczaj wynika to z literówki w ścieżce na hoście lub w kontenerze. Wtedy najlepiej jest użyć komendy docker inspect <nazwa_kontenera> i znaleźć sekcję Mounts. Zobaczysz tam dokładnie, co i gdzie zostało zamontowane. Dobrze jest sprawdzić, czy ścieżki (Source i Destination) są poprawne.
Różnice między Linux a Windows/Mac
Chociaż Docker dąży do unifikacji, praca z wolumenami, a zwłaszcza z bind mounts, może się różnić w zależności od systemu operacyjnego:
- Ścieżki – Na Windowsie używamy składni
C:\Users\..., podczas gdy na Linuksie/Macu/home/.... Docker Desktop jest na tyle inteligentny, że często potrafi sobie z tym poradzić, ale warto trzymać się konwencji swojego systemu. - Wydajność – Na Linuksie Docker działa natywnie. Na Windowsie i Macu Docker Desktop używa lekkiej maszyny wirtualnej. Operacje na plikach w bind mounts (intensywny odczyt/zapis) mogą być zauważalnie wolniejsze niż na natywnym Linuksie, ponieważ dane muszą być synchronizowane między systemem hosta a maszyną wirtualną Dockera. Wolumeny (volumes) są zazwyczaj wydajniejsze, ponieważ są zarządzane wewnątrz systemu plików maszyny wirtualnej.
- Uprawnienia – Problemy z uprawnieniami to głównie domena Linuksa. Na Windowsie/Macu Docker Desktop często radzi sobie z tym bardziej transparentnie dla użytkownika.
Niekontrolowany przyrost liczby nieużywanych wolumenów
Bardzo częsty scenariusz: pracujesz nad projektem, tworzysz i usuwasz dziesiątki kontenerów (np. z bazą danych). Jeśli przy usuwaniu kontenera nie użyjesz flagi -v (np. docker rm -v kontener), wolumeny z nim powiązane nie zostaną usunięte. Po kilku tygodniach możesz mieć na dysku dziesiątki gigabajtów zajętych przez zapomniane, nieużywane wolumeny.
Jakie jest na to rozwiązanie? Dobrze jest regularnie używać komendy docker volume prune. Docker zapyta o potwierdzenie i usunie wszystkie wolumeny, które nie są aktualnie podłączone do żadnego kontenera. To bezpieczna i skuteczna metoda na utrzymanie porządku.
Zbiór przydatnych komend
Dla utrwalenia poniżej spisałem kilka najciekawszych komend dotyczących wolumenów:
docker volume create <nazwa_wolumenu>– Tworzy nowy, nazwany wolumen.docker volume ls– Wyświetla listę wszystkich wolumenów.docker volume inspect <nazwa_wolumenu>– Pokazuje szczegółowe informacje o wolumenie.docker volume rm <nazwa_wolumenu>– Usuwa jeden lub więcej wolumenów.docker volume prune– Usuwa wszystkie nieużywane (dangling) wolumeny.docker run -v <źródło>:<cel> ...– Skrócona składnia do montowania (wolumen lub bind mount).docker run --mount type=volume,source=<nazwa_wolumenu>,target=<ścieżka_w_kontenerze> ...– Uruchamia kontener z zamontowanym wolumenem.docker run --mount type=bind,source=<ścieżka_na_hoście>,target=<ścieżka_w_kontenerze> ...– Uruchamia kontener z zamontowanym katalogiem z hosta.docker container rm -v <nazwa_kontenera>– Usuwa kontener wraz z powiązanymi z nim anonimowymi wolumenami.docker system df -v– Zwraca informacje o zużyciu miejsca.
Podsumowanie
Jeśli miałbym wskazać jeden temat, który koniecznie trzeba ogarnąć w pracy z Dockerem, to byłyby to wolumeny. To one sprawiają, że kontenery przestają być tylko tymczasowymi bytami, a stają się częścią solidnych systemów, w których dane muszą przetrwać restart, usunięcie kontenera czy pełny deploy środowiska od nowa. Zasada jest prosta: jeśli dane w kontenerze mają przeżyć dłużej niż sam kontener – potrzebujesz wolumenu.
Nieważne, czy korzystasz z bind mountów podczas developmentu, czy z zarządzanych wolumenów w produkcji – świadome podejście do przechowywania danych pozwala uniknąć masy problemów i zaoszczędzić sporo czasu. Bazy danych, uploadowane pliki, logi – wszystko to musi mieć swoje trwałe miejsce poza ulotnym systemem plików kontenera. Jeśli więc planujesz w Dockerze coś poważniejszego niż „hello world”, temat wolumenów i tak Cię nie ominie. Lepiej ogarnąć go od razu, niż potem ratować dane, które zniknęły po restarcie kontenera.
Zachęcam Cię do działania. Odpal bazę danych z wolumenem, spróbuj zrobić jej backup, a potem przywrócić dane. Jest to najlepsza opcja, żeby sobie odpowiednio utrwalić wiedzę. Nie tylko w tym przypadku, ale ogólnie, w dowolnym.
Także to tyle w tym wpisie. Jeśli masz jakiekolwiek pytania to oczywiście zapraszam do sekcji komentarzy.