Docker - volume-ny i ich rodzaje (przechowywanie i zapisywanie stanu poza kontenerem)

Stronę tą wyświetlono już: 47 razy

Docker-owe instancje stawia się szybko i łatwo, jest z nimi jednak taki mały problem. Mianowicie jeżeli wewnątrz takiej instancji zaczniesz zapisywać dane, które powinny być zachowane nawet gdy kontenera żywot dobiegnie końca to niestety te dane zostaną utracone. Innym problemem jest to, że często gęsto chciałoby się móc modyfikować kod projektu, który jest wewnątrz kontenera i tu znów przydałby się jakiś sprytny (żeby nie powiedzieć przebiegły) mechanizm umożliwiający przeładowywanie projektu z zewnątrz.

Pytanie, jakie ciśnie się na usta jest następujące: jak temu zaradzić? Odpowiedzią jest użycie volume-nów, które dzielą się na dwa podstawowe typy:

  • anonimowe - nadające się do tego aby podpiąć kod z lokalnego źródła i uruchamiać go w kontenerze (ten typ jest usuwany, gdy instancja kontenera przestaje istnieć;
  • nazwane - nadające się do zapisywania i podpinania danych z lokalnego źródła (z lokalnej maszyny, nie zaś z kontenera
  • bind mount - czyli połączenie do określonego folderu na lokalnej maszynie

Anonimowe valume-ny mogą posłużyć do wyeliminowania z konieczności kopiowania np. folderu node_modules, który jest folderem zawierającym jedynie pliki instalacyjne utworzone w wyniku uruchomienia polecenia:

npm install

ściśle powiązanego z Node i JavaScript-em.

Anonimowe valume-ny mogą być utworzone z poziomu pliku dockerfile, oto przykład takiego pliku:

Listing 1
  1. FROM node:14
  2. RUN apt-get update --fix-missing
  3. RUN apt-get install mc -y
  4. RUN apt-get install nano -y
  5. WORKDIR /app
  6. COPY / ./
  7. RUN npm install
  8. EXPOSE 8888
  9. VOLUME [ "/app/node_modules/" ]
  10. CMD ["npm", "start"]

Kluczowa w tym przypadku jest linia nr 15, gdzie wskazuje się folder volumenu. Ten sam efekt można uzyskać z linii poleceń:

docker run -p 8889:8888 --name node -v /app/node_modules/ --rm node-api:1.0

Jeżeli zaś chcesz skopiować pliki programu i przeładowywać je za każdym razem, gdy nastąpi zmiana w kodzie pliku na lokalnej maszynie to trzeba użyć następującego polecenia:

docker run -p 8889:8888 --name node -v "${pwd}:/app" --rm node-api:1.0

Powyższy volumen to jest zbindowany tzn. zapis: ${pwd} wstawia ścieżkę bezwzględną do bieżącego folderu na lokalnej maszynie, natomiast /app to bezwzględna ścieżka do folderu z projektem w kontenerze. W ten sposób każda zmiana zostanie odzwierciedlona w kontenerze, zaś wykorzystanie nodemon z wymaganą na Windowsie opcją -L spowoduje, że serwer się przebuduje.

Nazwany volumen nie zawiera ścieżki i jest zapisywany przez Docker-a gdzieś na dysku twardym. Taki typ volumen-ów wykorzystuje się do przechowywania stanu np. bazy danych. O tym jak wykorzystać tego typu volumeny opowiem na innej stronie, teraz nadmienię tylko, że listę voluen-ów można wyświetlić w następujący sposób:

docker volume ls
DRIVER    VOLUME NAME
local     2cd4855d16efc3f6506107ce14b2c53600e0a5fa56346169af4c3d0357f2e3e5

Anonimowe volumeny mają jako nazwę losowy ciąg znaków, nazwane będą miały nazwę podaną przez użytkownika.

Jeżeli zakończysz istnienie instancji to anonimowy vollumen zniknie z listy.

Nazwany volumen można utworzyć przy uruchamianiu, lub przed uruchomieniem niezależnie:

docker volume create name

Co nie zmienia faktu, że jeżeli chcesz go użyć i tak musisz użyć opcji przy uruchamianiu kontenera:

docker run -p 8889:8888 --name node -v "${pwd}:/app" -v name:/app/folder --rm -it node-api:1.0

A więc opcja -v name:/app/folder łączy volumen nazwany z wskazanym folderem.

Usuwanie volume-nu:

docker volume rm name

zakończy się powodzeniem tylko gdy ten nie jest używany przez uruchomiony kontener.

Uwuwanie wszystkich nieużywanych volumenów:

docker volume prune

Komentarze