Docker compose stop a down: różnice i usuwanie danych
Dowiedz się, czym różni się docker compose stop od down. Pierwsze polecenie zatrzymuje kontenery, drugie usuwa je wraz z siecią. Sprawdź, kiedy użyć flagi --volumes.
Krótka odpowiedź
docker compose stop zatrzymuje kontenery i pozostawia je na dysku. docker compose down zatrzymuje je, a następnie usuwa kontenery oraz sieć utworzoną przez Compose dla danego projektu. Żadne z tych poleceń nie narusza wolumenów nazwanych. Baza danych zostanie usunięta dopiero po dodaniu -v, jak w przypadku docker compose down -v, co usuwa wolumeny nazwane zadeklarowane w sekcji volumes pliku Compose.
To cała różnica w jednym akapicie. Reszta tego przewodnika dowodzi tego na przykładzie wolumenu Postgres, który przetrwa down, a zniknie po użyciu down -v, oraz wyjaśnia dwa przypadki, w których wymagane jest --force-recreate.
docker compose stop: kontenery pozostają
stop wysyła sygnał SIGTERM do głównego procesu w każdym kontenerze, czeka, a następnie wysyła SIGKILL, jeśli proces nadal działa. Domyślny czas oczekiwania wynosi 10 sekund, a -t pozwala go zmienić. Nic nie jest usuwane. Kontener zachowuje swój identyfikator, warstwę zapisu, rezerwację adresu IP oraz logi.
docker compose stop
docker compose ps -adocker compose ps domyślnie wyświetla tylko uruchomione kontenery, więc po wykonaniu stop polecenie to wypisuje pustą tabelę, co sugeruje błędne przekonanie o usunięciu kontenerów. ps -a uwzględnia również zatrzymane jednostki; tam przy każdej z nich widoczny będzie status Exited (0). Przywrócenie ich do działania odbywa się za pomocą docker compose start, co wykorzystuje dokładnie te same kontenery.
Ponieważ kontenery nadal istnieją, wszystko, co zostało zapisane wewnątrz nich poza wolumenami, pozostaje nienaruszone. Dotyczy to pakietów zainstalowanych ręcznie za pomocą docker compose exec oraz plików konfiguracyjnych edytowanych wewnątrz kontenera. Jest to praktyczny powód, dla którego podczas debugowania warto preferować stop: pozwala to na restart do dokładnie tego samego stanu.
docker compose down: kontenery i sieci są usuwane
down zatrzymuje kontenery, a następnie usuwa je wraz z domyślną siecią utworzoną przez Compose dla danego projektu. Dokumentacja Docker opisuje to jako zatrzymywanie kontenerów oraz usuwanie kontenerów, sieci, wolumenów i obrazów utworzonych przez up, jednak usuwanie wolumenów i obrazów następuje tylko wtedy, gdy zostanie to wymuszone za pomocą -v oraz --rmi.
docker compose down
docker compose ps -a
docker network lsPo wykonaniu down, polecenie ps -a nie wyświetla żadnych informacji dla projektu, a sieć <project>_default przestaje istnieć. Nazwa projektu pochodzi od nazwy katalogu, chyba że w pliku Compose zdefiniowano name: lub przekazano parametr -p. Każda zmiana wprowadzona w zapisywalnej warstwie kontenera jest teraz nieodwracalna, dlatego należy traktować down jako polecenie, które usuwa kontener, zachowując jedynie dane umieszczone w wolumenach.
Uruchomienie polecenia w niewłaściwym katalogu skutkuje błędem no configuration file provided: not found. Compose nie posiada informacji o tym, który projekt miał zostać wybrany, więc odmawia wykonania operacji. W przypadku pracy poza folderem projektu należy użyć docker compose -f /srv/myapp/compose.yaml down.
Czy docker compose down usuwa wolumeny?
Nie. Nazwany wolumen zadeklarowany w sekcji najwyższego poziomu volumes przetrwa wykonanie down, a także przetrwa kontener, do którego był podłączony. Jest to najczęstsza obawa związana z tym poleceniem, a odpowiedź pozostaje niezmienna w Compose v2.
Skonfiguruj stos, na którym możesz przeprowadzić test. Umieść poniższą zawartość w compose.yaml w pustym katalogu o nazwie voltest.
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Uruchom stos i zapisz wiersz, który rozpoznasz później.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"Teraz usuń kontener i sprawdź wolumen.
docker compose down
docker volume lsDane wyjściowe nadal wyświetlają voltest_pgdata. Kontener został usunięty, ale dane pozostały. Przywróć stos i odczytaj wiersz.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"Otrzymasz jeden wiersz zawierający survived. Nowy kontener jest innym kontenerem o innym identyfikatorze, podłączonym do tego samego wolumenu. Jeśli chcesz poznać szerszy kontekst, przewodnik po podstawach Compose omawia nazwane wolumeny w zestawieniu z bind mounts oraz wyjaśnia, gdzie fizycznie znajdują się one na hoście.
Co dokładnie usuwa polecenie down -v
-v (wersja pełna --volumes) usuwa nazwane wolumeny zadeklarowane w sekcji volumes pliku Compose, a także wolumeny anonimowe przypisane do kontenerów. Uruchom to polecenie dla tego samego stosu.
docker compose down -v
docker volume lsvoltest_pgdata nie znajduje się już na liście. Uruchom stos ponownie, a punkt wejścia Postgres wykryje pusty katalog danych i zainicjuje nowy klaster. Dziennik kontenera informuje o tym wprost.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.Zobaczenie takiego komunikatu w stosie działającym od miesięcy oznacza, że wolumen został usunięty. Twoja tabela marker przepadła, a jedynym sposobem na odzyskanie danych jest kopia zapasowa.
Niektóre zasoby pamięci nie są usuwane przez -v. Bind mount to ścieżka w systemie hosta, więc Docker jedynie odmontowuje ją, a pliki pozostają w swoim miejscu. Wolumen oznaczony jako external: true jest zadeklarowany jako należący do zasobu spoza tego projektu, więc Compose nigdy go nie usuwa. Nazwany wolumen, który usunięto z pliku Compose przed uruchomieniem down -v, nie jest już zadeklarowany, więc Compose nie wie, że należy go usunąć, i pozostaje on jako osierocony zasób dla docker volume prune.
Ten ostatni przypadek często zdarza się podczas refaktoryzacji. Usunięcie usługi i jej wolumenu z pliku oraz uruchomienie down -v powoduje, że wolumen przetrwa, ponieważ plik już o nim nie wspomina. Uruchom down -v przed edycją pliku, a nie po niej.
Kiedy faktycznie potrzebna jest flaga --force-recreate
docker compose up -d nie przebudowuje całego środowiska przy każdym uruchomieniu. Compose przechowuje skrót (hash) rozpoznanej konfiguracji każdej usługi jako etykietę kontenera. Jeśli skrót jest zgodny, a ID obrazu się zgadza, kontener pozostaje bez zmian, a użytkownik otrzymuje komunikat Container voltest-db-1 Running zamiast Recreated. Jest to zachowanie pożądane w niemal każdym przypadku, ponieważ sprawia, że up -d można bezpiecznie uruchamiać wielokrotnie.
Jest to również powód, dla którego niektóre zmiany wydają się nie przynosić efektu. Compose oblicza skrót z definicji usługi, a nie z zawartości plików, na które ta definicja wskazuje. Plik konfiguracyjny zamontowany w kontenerze i odczytany raz podczas startu nie wywoła odtworzenia kontenera po edycji, ponieważ ścieżka montowania nie uległa zmianie. Usługa kontynuuje działanie z wartościami odczytanymi podczas rozruchu.
docker compose up -d --force-recreateTo polecenie zatrzymuje i usuwa każdy kontener, a następnie tworzy nowy na podstawie tej samej definicji. Należy go użyć po edycji zamontowanego pliku konfiguracyjnego oraz w sytuacji, gdy kontener przeszedł w stan, którego nie można wyjaśnić. Wolumeny pozostają nienaruszone, więc baza danych przetrwa wymuszone odtworzenie. Aby pobrać nowszą wersję obrazu o tym samym tagu, konieczne jest również wykonanie operacji pobrania (pull).
docker compose pull
docker compose up -dpull pobiera nowe ID obrazu, a up -d wykrywa różnicę między tym ID a ID działającego kontenera, co powoduje jego automatyczne odtworzenie. Użycie --force-recreate bez pull skutkuje utworzeniem nowego kontenera na podstawie tego samego, starego obrazu. Dlatego tak częstym problemem jest zgłoszenie: "Wymusiłem odtworzenie, a nadal mam starą wersję".
docker compose restart nie wykonuje żadnej z tych czynności. Restartuje istniejące kontenery i w ogóle nie odczytuje ponownie pliku Compose, więc zmiana zmiennej środowiskowej lub mapowania portów nie zostanie zastosowana. Jeśli plik został edytowany, należy użyć up -d.
Model mentalny, o którym należy pamiętać
Kontenery są wymienne. Kontener to proces oraz cienka warstwa zapisu, a Compose potrafi zbudować identyczny kontener z pliku w około sekundę. Wolumeny nie są wymienne, ponieważ przechowują jedyną kopię stanu, której żaden plik w repozytorium nie jest w stanie odtworzyć.
Każde polecenie Compose jest zgodne z tym podziałem. stop oraz start zachowują kontener. down oraz up zastępują kontener, zachowując wolumen. down -v to jedyne rutynowe polecenie usuwające stan, dlatego wymaga jawnej flagi. Zanim użyjesz go w środowisku produkcyjnym, upewnij się, że posiadasz kopię zapasową, którą przynajmniej raz udało się przywrócić.
Ta sama logika dotyczy sekretów. Hasło ustawione przez POSTGRES_PASSWORD jest odczytywane tylko podczas pierwszej inicjalizacji bazy danych, więc zmiana go w pliku środowiskowym i uruchomienie up -d skutkuje password authentication failed for user "postgres". Kontener jest nowy, a wolumen stary, przy czym stary wolumen nadal przechowuje stare hasło. Jak Compose rozwiązuje pliki env i sekrety wyjaśnia, która warstwa ma pierwszeństwo, gdy ta sama zmienna jest ustawiona dwukrotnie.
Tryby awarii i komunikaty, które zobaczysz
no configuration file provided: not found oznacza, że Compose jest uruchamiany w katalogu, w którym nie ma plików compose.yaml ani docker-compose.yml. Należy przekazać flagę -f z pełną ścieżką.
network voltest_default has active endpoints w down oznacza, że kontener spoza tego projektu jest podłączony do sieci projektu, zazwyczaj uruchomiony ręcznie za pomocą docker run --network. Należy usunąć ten kontener, a następnie ponownie uruchomić down.
Found orphan containers ([voltest-old-1]) for this project pojawia się po zmianie nazwy lub usunięciu usługi. Stary kontener nadal posiada etykietę projektu. docker compose down --remove-orphans usuwa te etykiety i jest bezpieczne do wykonania w działającym stosie.
Error response from daemon: remove voltest_pgdata: volume is in use przy ręcznym docker volume rm oznacza, że jakiś kontener nadal odwołuje się do wolumenu, w tym kontener zatrzymany. Należy najpierw wykonać docker compose down, a następnie usunąć wolumen lub po prostu użyć down -v. W większych projektach stos Compose z wieloma usługami pokazuje, jak wiele wolumenów może zgromadzić jeden projekt.
FAQ
Czy docker compose down usuwa moją bazę danych?
Nie, jeśli baza danych znajduje się w nazwanym wolumenie lub zamontowanym katalogu (bind mount). down usuwa kontenery oraz sieć projektu, natomiast wolumen pozostaje na dysku wraz z nienaruszonymi danymi. Kolejne polecenie docker compose up -d podłącza nowy kontener do tego samego wolumenu, przywracając dostęp do danych. Tylko docker compose down -v usuwa nazwane wolumeny, i to wyłącznie te zadeklarowane w sekcji volumes pliku Compose.
Jaka jest różnica między stop a down w przypadku kontenera, który chcę zachować?
stop zatrzymuje kontener, więc docker compose start przywraca ten sam kontener z tą samą warstwą zapisu. Wszystkie zmiany i instalacje wykonane ręcznie wewnątrz kontenera zostają zachowane. down usuwa kontener, więc kolejne up -d tworzy świeżą instancję z obrazu, a ręczne zmiany przepadają. Podczas debugowania należy używać stop.
Jak usunąć wszystko, co utworzył projekt Compose?
docker compose down -v --rmi all --remove-orphans usuwa kontenery, sieć projektu, nazwane wolumeny zadeklarowane w pliku, obrazy używane przez usługi oraz każdy kontener oznaczony etykietą projektu. Polecenie to nie usuwa zamontowanych katalogów (bind mounts) ani wolumenów oznaczonych jako external: true. Przed uruchomieniem warto sprawdzić, co zostanie usunięte, za pomocą docker volume ls.
Dlaczego kontener ignoruje zmiany wprowadzone w zamontowanym pliku konfiguracyjnym?
Compose decyduje o odtworzeniu kontenera na podstawie porównania skrótu (hash) definicji usługi, a skrót ten nie uwzględnia zawartości zamontowanego pliku. Ścieżka nie uległa zmianie, więc Compose pozostawia kontener uruchomiony z wartościami odczytanymi podczas startu. Należy wykonać docker compose up -d --force-recreate, aby utworzyć nowy kontener, który ponownie odczyta plik.
Dlaczego nowe hasło POSTGRES_PASSWORD nie działa po jego zmianie?
Obraz Postgres odczytuje POSTGRES_PASSWORD tylko podczas inicjalizacji pustego katalogu danych. Wolumen zawiera już zainicjalizowany klaster, więc zmienna jest ignorowana, a stare hasło pozostaje w mocy. W logach pojawi się komunikat password authentication failed for user "postgres". Hasło należy zmienić za pomocą ALTER USER wewnątrz działającej bazy danych lub zaakceptować utratę danych i rozpocząć od nowa za pomocą docker compose down -v.