Docker ADD vs VOLUME


116

Ben Docker öğreniyorum ve ben kullanmaya ne zaman ve nerede hakkında şüphelerim var ADDve VOLUME. İşte bunların her ikisinin de yaptığını düşünüyorum:

EKLE

Derleme sırasında dosyaları görüntüye kopyalayın. Görüntü tüm dosyalara sahiptir, böylece çok kolay bir şekilde dağıtabilirsiniz. Öte yandan, her seferinde derleme ihtiyacı geliştirme aşamasında iyi bir fikir gibi görünmüyor çünkü inşa etmek için geliştiricinin kabı yeniden inşa etmek için bir komut çalıştırması gerekiyor; ayrıca konteyneri inşa etmek zaman alıcı olabilir.

SES

Kullanarak docker run -vkapsayıcınızın içine bir ana bilgisayar klasörü ekleyebileceğinizi anlıyorum , bu şekilde dosyaları kolayca değiştirebilir ve kapsayıcınızdaki uygulamanın değişikliklere tepki vermesini izleyebilirsiniz. Geliştirme aşamasında harika görünüyor, ancak dosyalarımı bu şekilde nasıl dağıtacağımdan emin değilim.


3
Genel olarak tercih COPYetmek en iyisidir ADD. Neredeyse ADDaynıdırlar , ancak şaşırtıcı olabilecek URL'ler ve arşiv dosyaları için bazı ekstra yetenekleri vardır.
Adrian Mouat

2
@jamesmstone - bu bağlantı (ve resmi docker belgeleri) tam tersini önerir - EKLE yerine KOPYALA kullanın.
Software Engineer

oops, haklısınız - şerefe!
jamesmstone

Yanıtlar:


183

EKLE

Bu ikisi arasındaki temel fark ADD, eklediğiniz her şeyi, bir klasör veya sadece bir dosya aslında görüntünüzün bir parçası haline getirmesidir . Daha sonra oluşturduğunuz görüntüyü kullanan herkes, siz ne olursa olsun erişebilir ADD. Bu, daha sonra kaldırsanız bile geçerlidir çünkü Docker katmanlar halinde çalışır ve ADDkatman, görüntünün bir parçası olarak var olmaya devam eder. Açık olmak gerekirse, yalnızca ADDderleme zamanında bir şey yaparsınız ve hiçbir ADDzaman çalışma zamanında yapamazsınız .

Kullanmak isteyeceğiniz birkaç vaka örneği ADD:

  • Dockerfile'ınıza başvurmak ve yüklemek istediğiniz bir requirements.txt dosyasında bazı gereksinimleriniz vardır. Daha sonra şunları yapabilirsiniz: ADD ./requirements.txt /requirements.txtardındanRUN pip install -r /requirements.txt
  • Uygulama kodunuzu Dockerfile'ınızda bağlam olarak kullanmak istiyorsunuz, örneğin, uygulama dizininizi görüntünüzde çalışan dizin olarak ayarlamak ve bir kapsayıcıdaki varsayılan komutun aslında uygulamanızı çalıştırmasını istiyorsanız, yapabilir:

    ADD ./ /usr/local/git/my_app

    WORKDIR /usr/local/git/my_app

    CMD python ./main.py

SES

Öte yandan hacim, görüntünüzden çalıştırılan bir konteynerin, konteynerin çalıştırıldığı yerel makinedeki bir yola erişmesine izin verir. Sen senin dosyaları kullanamaz VOLUMEsenin Dockerfile içinde dizine . Birim dizininizdeki herhangi bir şey , derleme sırasında erişilemez, ancak çalışma zamanında erişilebilir olacaktır .

Kullanmak isteyeceğiniz birkaç vaka örneği VOLUME:

  • Konteynırınızda çalıştırılan uygulama, girişler yapar /var/log/my_app. Bu günlüklerin ana makineden erişilebilir olmasını ve konteyner kaldırıldığında silinmemesini istiyorsunuz. Bunu Dockerfile'ınıza /var/log/my_appekleyerek VOLUME /var/log/my_appve ardından konteynerinizi çalıştırarak bir bağlama noktası oluşturarak yapabilirsiniz.docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
  • Kapsayıcıdaki uygulamanın erişmesini istediğiniz bazı yerel ayar dosyalarınız var. Belki de bu ayarlar dosyaları yerel makinenizde geliştirmeye karşı üretimden farklıdır. Özellikle bu ayar dosyaları gizliyse, bu durumda onları kesinlikle görüntünüzde istemezsiniz . Bu durumda iyi bir strateji VOLUME /etc/settings/my_app_settings, Dockerfile'ınıza eklemek , konteynerinizi birlikte çalıştırmak docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tagve uygulamanızın çalışmasını beklediğiniz tüm ortamlarda / host / settings / dizinin mevcut olduğundan emin olmaktır.

13
Şimdiye kadar bulduğum en kullanışlı gönderi ADD and VOLUME
Jasmeet

5
VOLUME belirtilirse, ancak docker çalışması sırasında sağlanmazsa ne olur (örn. -V xxx parametresi eksik)? Resp. VOLUME sonra etkili bir şekilde geçici hale geliyor mu?
col.panic

Bir Dockerfile içinde, birimler muhtemelen yalnızca kalıcılık ve / veya hata ayıklama içindir, ancak bir uygulamayı mevcut bir görüntüye (Dockerfile gerekmez) almak ve bu şekilde çalıştırmak için hacim komut satırı anahtarını kullanabilirsiniz docker run -v $HOST_PATH:$CONTAINER_PATH node:latest node $CONTAINER_PATH/app.js.
Chinoto Vokro

güzel "katman" ayrıntısı
stratovarius

27

VOLUMETalimat zamanında sizin Docker kapta bir veri hacmini oluşturur. Bir argüman olarak sağlanan VOLUMEdizin, Birlik Dosya Sistemini atlayan bir dizindir ve esas olarak kalıcı ve paylaşılan veriler için kullanılır.

Çalıştırırsanız docker inspect <your-container>, Mountsbölümün altında Sourceana bilgisayardaki Destinationdizin konumunu ve kapsayıcıdaki bağlanmış dizin konumunu temsil eden bir göreceksiniz . Örneğin,

"Mounts": [
  {
    "Name": "fac362...80535",
    "Source": "/var/lib/docker/volumes/fac362...80535/_data",
    "Destination": "/webapp",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
  }
]

İşte 3 kullanım durumu docker run -v:

  1. docker run -v /data: Bu, VOLUMEDockerfile'ınızdaki talimatı belirtmeye benzer .
  2. docker run -v $host_path:$container_path: Bu, çalışma süresi boyunca $host_pathana bilgisayarınızdan $container_pathkonteynırınıza bağlamanızı sağlar . Geliştirme aşamasında bu, ana makinenizdeki kaynak kodunu kapsayıcıyla paylaşmak için kullanışlıdır. Üretimde bu, ana bilgisayarın DNS bilgileri (içinde bulunur /etc/resolv.conf) veya sırlar gibi şeyleri kapsayıcıya bağlamak için kullanılabilir . Tersine, bu tekniği, kapsayıcının günlüklerini ana bilgisayardaki belirli klasörlere yazmak için de kullanabilirsiniz. Her ikisi de $host_pathve $container_pathmutlak yollar olmalıdır.
  3. docker run -v my_volume:$container_path: Bu, adresindeki kapsayıcınızda bir veri birimi oluşturur $container_pathve onu adlandırır my_volume. Temelde kullanarak bir birimi oluşturmak ve adlandırmakla aynıdır docker volume create my_volume. Bir birimi bu şekilde adlandırmak, Flocker gibi çok ana bilgisayarlı bir depolama sürücüsü kullanan bir konteyner veri hacmi ve paylaşılan bir depolama birimi için kullanışlıdır .

Bir ana bilgisayar klasörünü veri birimi olarak bağlama yaklaşımının Dockerfile'da kullanılamadığına dikkat edin. Docker belgelerinden alıntı yapmak için ,

Not: Bu, taşınabilirliği ve paylaşım amacı nedeniyle bir Dockerfile'da mevcut değildir. Ana bilgisayar dizini doğası gereği ana bilgisayara bağımlı olduğundan, bir Dockerfile'da belirtilen bir ana bilgisayar dizini muhtemelen tüm ana bilgisayarlarda çalışmayacaktır.

Artık dosyalarınızı geliştirme dışı ortamlarda kapsayıcılara kopyalamak istiyorsanız , Dockerfile'ınızdaki ADDveya COPYtalimatlarını kullanabilirsiniz . Bunlar genellikle geliştirme dışı dağıtım için kullandığım şeylerdir.


3
2 docker dosyası oluşturmalı mıyım? Biri geliştirme için diğeri dağıtım için mi?
Cristian Garcia

Ben öyle düşünmüyorum. ADDTalimatın Dockerfile'ınızda olması yanlış bir şey değildir, çünkü sadece docker buildkomut tarafından yürütülür . Bu, başkaları kapsayıcınızı ilk kez oluşturduğunda ve onu geliştirme dışı ortamlara dağıtmaya hazır olduğunuzda gereklidir.
ivan.sim

3
Ancak, dosyalar olmadan bir görüntü oluşturmak ve -vgeliştirme için komutu kullanmak ve başka bir docker dosyasının ADD, dağıtım için dosyaları içeren bir görüntü oluşturmasını sağlamak daha verimli olmaz mıydı ?
Cristian Garcia

1
Karar vermen gereken bir değiş tokuş. Sizin için neyin işe yaradığını seçin. ADDZaten bir çekimle inşa etmek ne kadar sürer? Toplamda birkaç saniye mi? İki Dockerfile dosyanız varsa ve bunu başkalarıyla paylaşıyorsanız (veya docker kayıt defterinde yayınlıyorsanız ), hangisi varsayılandır? Doğru varsayılan Dockerfile'ın doğru kullanıcılara ulaşmasını sağlamak için bazı ekstra bakım yüküne sahip olacaksınız. Ancak günün sonunda, sizin için en iyi olana karar verirsiniz. Kişisel olarak, konteynerimi oluşturmak için tek bir Dockerfile olduğundan emin olmak isterim.
ivan.sim

11
Bu arada, geliştirme için önce EKLE, sonra bu eklemeyi -v ile geçersiz kılmanın iyi olduğunu düşünüyorum. Bu şekilde ayrı Dockerfile'lara ihtiyacınız olmayacak.
Attila Szeremi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.