Uczę się Dockera i mam wątpliwości, kiedy i gdzie używać ADD
i VOLUME
. Oto, co myślę, że oba z nich robią:
DODAJ
Skopiuj pliki do obrazu w czasie kompilacji. Obraz zawiera wszystkie pliki, dzięki czemu można je bardzo łatwo wdrożyć. Z drugiej strony, konieczność kompilowania za każdym razem nie wygląda na dobry pomysł w programowaniu, ponieważ budowanie wymaga od dewelopera uruchomienia polecenia przebudowania kontenera; dodatkowo budowanie kontenera może być czasochłonne.
TOM
Rozumiem, że za pomocą docker run -v
możesz zamontować folder hosta w swoim kontenerze, w ten sposób możesz łatwo modyfikować pliki i obserwować, jak aplikacja w Twoim kontenerze reaguje na zmiany. Wygląda świetnie w programowaniu, ale nie jestem pewien, jak wdrożyć moje pliki w ten sposób.
COPY
sięADD
. Są prawie takie same, aleADD
mają dodatkowe możliwości zapisywania adresów URL i plików archiwów, które mogą być zaskakujące.Odpowiedzi:
DODAJ
Podstawowa różnica między tymi dwoma polega na tym,
ADD
że wszystko, co dodajesz, czy to folder, czy tylko plik, jest w rzeczywistości częścią obrazu . Każdy, kto użyje utworzonego później obrazu, będzie miał dostęp do wszystkiego, co TyADD
. Dzieje się tak, nawet jeśli później go usuniesz, ponieważ Docker działa w warstwach, aADD
warstwa będzie nadal istnieć jako część obrazu. Żeby było jasne,ADD
coś jest tylko w czasie kompilacji i nigdy nie możeszADD
w czasie wykonywania.Kilka przykładów przypadków, w których chciałbyś użyć
ADD
:ADD ./requirements.txt /requirements.txt
a następnieRUN pip install -r /requirements.txt
Chcesz użyć kodu aplikacji jako kontekstu w pliku Dockerfile, na przykład, jeśli chcesz ustawić katalog aplikacji jako katalog roboczy w obrazie i mieć domyślne polecenie w kontenerze uruchamiane z obrazu, aby faktycznie uruchomić aplikację, potrafi:
ADD ./ /usr/local/git/my_app
WORKDIR /usr/local/git/my_app
CMD python ./main.py
TOM
Z drugiej strony, wolumin po prostu pozwala kontenerowi uruchamianemu z twojego obrazu mieć dostęp do jakiejś ścieżki na dowolnym komputerze lokalnym, na którym jest uruchamiany kontener. Nie możesz używać plików z
VOLUME
katalogu w pliku Dockerfile . Wszystko w katalogu woluminu nie będzie dostępne w czasie kompilacji, ale będzie dostępne w czasie wykonywania .Kilka przykładów przypadków, w których chciałbyś użyć
VOLUME
:/var/log/my_app
. Chcesz, aby te dzienniki były dostępne na komputerze hosta i nie były usuwane po usunięciu kontenera. Możesz to zrobić, tworząc punkt montowania w/var/log/my_app
, dodającVOLUME /var/log/my_app
do pliku Dockerfile, a następnie uruchamiając kontener zdocker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
VOLUME /etc/settings/my_app_settings
do pliku Dockerfile, uruchomienie konteneradocker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag
i upewnienie się, że / host / settings / dir istnieje we wszystkich środowiskach, w których spodziewasz się uruchomienia aplikacji.źródło
docker run -v $HOST_PATH:$CONTAINER_PATH node:latest node $CONTAINER_PATH/app.js
.VOLUME
Instrukcja tworzy wolumin danych w kontenerze Docker przy starcie. Katalog podany jako argumentVOLUME
to katalog, który pomija Union File System i jest używany głównie do przechowywania trwałych i udostępnianych danych.Jeśli uruchomisz
docker inspect <your-container>
, zobaczysz podMounts
sekcją,Source
która reprezentuje lokalizację katalogu na hoście iDestination
która reprezentuje lokalizację zamontowanego katalogu w kontenerze. Na przykład,Oto 3 przypadki użycia
docker run -v
:docker run -v /data
: Jest to analogiczne do określeniaVOLUME
instrukcji w pliku Dockerfile.docker run -v $host_path:$container_path
: Pozwala to na instalację$host_path
z hosta do$container_path
kontenera w czasie wykonywania. W programowaniu jest to przydatne do udostępniania kodu źródłowego na hoście z kontenerem. W środowisku produkcyjnym można to wykorzystać do zamontowania/etc/resolv.conf
w kontenerze takich rzeczy, jak informacje DNS hosta (znalezione w ) lub sekrety. I odwrotnie, możesz również użyć tej techniki do zapisania dzienników kontenera w określonych folderach na hoście. Obie$host_path
i$container_path
muszą być ścieżkami absolutnymi.docker run -v my_volume:$container_path
: Spowoduje to utworzenie wolumenu danych w kontenerze w lokalizacji$container_path
i nazwanie gomy_volume
. Zasadniczo jest to to samo, co tworzenie i nazywanie wolumenu przy użyciudocker volume create my_volume
. Takie nazwanie woluminu jest przydatne w przypadku woluminu danych kontenera i woluminu pamięci współużytkowanej przy użyciu sterownika pamięci masowej dla wielu hostów, takiego jak Flocker .Zwróć uwagę, że podejście polegające na zamontowaniu folderu hosta jako woluminu danych nie jest dostępne w pliku Dockerfile. Cytując dokumentację Dockera ,
Teraz, jeśli chcesz skopiować pliki do kontenerów w środowiskach innych niż programistyczne, możesz użyć instrukcji
ADD
lubCOPY
w pliku Dockerfile. To jest to, czego zwykle używam do wdrażania innych niż programistyczne.źródło
ADD
instrukcji w pliku Dockerfile, ponieważ jest ona wykonywana tylko przezdocker build
polecenie. Jest to potrzebne, gdy inne osoby budują kontener po raz pierwszy i gdy jesteś gotowy do wdrożenia go w innych środowiskach niezwiązanych z programowaniem.-v
polecenia do programowania, a inny plik Dockera utworzyłby obraz zawierający plikiADD
do wdrożenia?ADD
tak trwa kompilacja ? W sumie kilka sekund? Jeśli masz dwa pliki Dockerfile i udostępniasz je innym (lub publikujesz w rejestrze Docker ), który z nich jest domyślny? Będziesz mieć dodatkowe koszty utrzymania, aby upewnić się, że właściwy domyślny plik Dockerfile dotrze do właściwych użytkowników. Ale ostatecznie to Ty decydujesz, co jest dla Ciebie najlepsze. Osobiście lubię mieć pewność, że istnieje jeden i tylko jeden plik Dockerfile do zbudowania mojego kontenera.