Docker'a birim ekleyin, ancak bir alt klasörü hariç tutun


210

Ev sahibimde bir Docker kapsayıcı ve bir klasör var /hostFolder. Bir hacim olarak Docker konteyner için bu klasörü eklemek istiyorsanız Şimdi, o zaman kullanarak bunu yapabilirsiniz ADDbölgesi Dockerfileveya hacim olarak montaj.

Çok uzak çok iyi.

Şimdi /hostFolderbir alt klasör içeriyor /hostFolder/subFolder,.

Ben monte etmek istiyorum /hostFolderDocker kaba (ister okuma-yazma veya salt okunur olarak, önemli değil benim için hem çalışır), ama yok değil dahil etmek istiyoruz /hostFolder/subFolder. Bunu hariç tutmak istiyorum ve ayrıca Docker kapsayıcısının ana bilgisayarda da değiştirilmesinin sonucu olmadan bu alt klasörde değişiklikler yapabilmesini istiyorum.

Mümkün mü? Öyleyse nasıl?


2
@AbhijitSarkar bu çok yapıcı (ne de hiçbir şekilde yararlı) bir yorum değil.
kano

1
@Kano Bu bir yorum, cevap değil.
Abhijit Sarkar

Yanıtlar:


398

Docker-compose kullanarak node_modules'ü yerel olarak kullanabiliyorum, ancak aşağıdaki sözdizimini kullanarak docker kapsayıcısında yoksayıyorum docker-compose.yml

volumes:
   - './angularApp:/opt/app'
   - /opt/app/node_modules/

Böylece her şey ./angularAppeşlenir /opt/appve sonra /opt/app/node_modules/yerel makinemde boş olmasa bile, şimdi boş bir dizin olan başka bir bağlama birimi oluşturuyorum ./angularApp/node_modules.


3
Çalışıyor ama ben bu dirs konteyner içinde kaldıramıyorum Örneğin: i /opt/app/node_modules/aynı ada sahip başka bir dizin ile değiştirmeniz gerekir . Hata olur: 'hacim meşgul'
Stepan Yudin

32
Sondaki eğik çizgiyi unutmayın! Örneğin. / opt / app / node_modules değil iş, o ./angularApp/node_modules tarafından üzerine yazılır olacak gelmez
Stingus

3
Bu hile benim için çalışırdı, ancak artık aynı Oluştur dosyası için bile görünmüyor. Başkaları için de çalışmayı durdurduysa merak ediyorum.
plinehan

8
Teşekkürler! Günümü kurtardın! Basit liman işçisinin kullanılması durumunda, kompozitler değil, şöyle görünecektir: -v $(pwd):/build/ -v /build/node_modules
Bogdan Mart

3
Dokümanı buldum, docs.docker.com/storage/volumes/… . If you start a container which creates a new volume, as above, and the container has files or directories in the directory to be mounted (such as /app/ above), the directory’s contents are copied into the volume.
hiroshi

118

Alt dizinlerin docker-compose tarafından yok sayılmasını ancak kalıcı olmasını istiyorsanız, aşağıdakileri yapabilirsiniz docker-compose.yml:

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules

Bu, geçerli dizininizi paylaşılan birim olarak bağlar, ancak yerel node_modulesdizininizin yerine kalıcı bir docker birimi bağlar . Bu, @ kernix'in cevabına benzer, ancak bu , muhtemelen istenen davranış olan koşular node_modulesarasında kalmaya izin verecektir docker-compose up.


20
Adlandırılmış ciltler üstün bir yaklaşımdır. Koru: Tireli bir birim adı kullanmadığınızdan emin olun. Hayatınızın küçük bir bölümünü, bir kez daha saçma bir nüans tarafından kandırıldığınızı öğrenmek için bir hata ayıklama kabusu içinde geçireceksiniz.
dustintheweb

3
"Docker-compose'un bu kalıcı hacimleri öldüreceğini unutmayın." Bu, Docker for Mac v 17.0.5+ (ve muhtemelen daha eski sürümler) için geçerli değildir. docker-compose downkapları kaldıracak, ancak böyle bir şey çalışana kadar hacim devam edecekdocker system prune
BrDaHa

3
Birinin adı geçen birimi kullanmanın neden docker kapsayıcısında node_modules:"yoksaydığını" anlamaya ilgi /app/node_modulesduyması durumunda , bu yazıyı yararlı bulabilir Docker birden çok bağlama türünü nasıl işler?
Irak

3
Yanlış bir şey yapıp yapmadığımı bilmiyorum, ancak bunu yaparsam, kapsayıcıyı başlatın ve HOST makinesinde npm yüklemesini çalıştırın, CONTAINER içindeki node_modules'u değiştirir. Kimsenin bunu neden yapmak istediğini hayal edemiyorum, ama yine de daha temiz bir ayrım arıyorum.
Renra

3
@Renra aynı sorunu vardı, benim adı geçen birim olmasına rağmen ana makine sürekli node_modules üzerine yazmak istiyorum ... her türlü uyumsuzluk sorunları neden oldu. Sabitleme konusunda verdi ve tüm repo yerine sadece src klasörünü kopyalayarak etrafında çalıştı
dancypants

19

Bir dosyayı hariç tutmak için aşağıdakileri kullanın

volumes:
   - /hostFolder:/folder
   - /dev/null:/folder/fileToBeExcluded

6
Ne gerek için mükemmel bir çözüm (symlink şeyler bir Windows host kırdı çünkü node_modules ana bilgisayara eşlemek için). / Dev / null'a işaret etmek işe yaramadı, ancak boş bir dizin oluşturma ve bunu mükemmel bir şekilde çalıştıran ve yaşadığım sorunları çözen - bu fikir için teşekkürler.
Liam Hammett

1
Bu Mac 18.09.0 için Docker çalışmaz: Cannot start service xxx: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"rootfs_linux.go:58: mounting \\\"/dev/null\\\" to rootfs \\\"/var/lib/docker/overlay2/d15ed56ad020d408c63a1f6a6365dbb88d5d3b78a4605980d3faa9861102ef21/merged\\\" at [...] unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type. Sondaki eğik çizgi eklemek yardımcı olmadı.
Blaise

Dount 18.09.3 ile Ubuntu 16.04'te de çalışmadığını doğrulayabilirim.
Dirk

Bu benim için işe yaramıyor. Tek yaptığı /dev/nullkapsayıcıya bir cihaz dosyası olarak kopyalamak .
Radon Rosborough

1
Lütfen bunun yalnızca DOSYALAR hariç tutulduğunu unutmayın! / dev / null hata mesajı bu konuda oldukça açıktır, bir dosya ve böylece hedef olmalıdır: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type. Bu OP'nin tam olarak aradığı şey değildi, ama benim için çok yararlıydı, çünkü tek bir dosyayı hariç tutmam gerekiyordu.
Avius

13

İlk olarak, ADDbir Dockerfile içinde talimatı kullanmak, bir birimi kullanmaktan çok farklıdır ( Dockerfile -vparametresine docker runya da VOLUMEDockerfile'daki komutla). ADDVe COPYkomutlar sadece zaman dosyaların bir kopyasını almak docker buildçalıştırılır. Bu dosyalar, docker buildkomutla yeni bir görüntü oluşturulana kadar güncellenmez . Buna karşılık, bir birim kullanmak temelde "bu dizin kapsayıcı görüntüsünde saklanmamalıdır; bunun yerine ana bilgisayarda bir dizin kullanın"; birimin içindeki bir dosya değiştirildiğinde, hem ana bilgisayar hem de kapsayıcı dosyayı hemen görür.

Birimleri kullanarak istediğinizi elde edebileceğinize inanmıyorum, bunu yapmak istiyorsanız dizin yapınızı yeniden düşünmeniz gerekecek.

Bununla birlikte, kullanımı (oldukça COPYtercih edilir ADD) elde etmek oldukça basittir . .dockerignoreAlt dizini hariç tutmak için bir dosya kullanabilirsiniz ya da COPYtüm dosyaları RUN rm blaalt dizini kaldırmak için a yapabilirsiniz .

Görüntüye eklediğiniz COPYya da görüntüye eklediğiniz dosyaların ADDderleme bağlamının içinde, yani çalıştırdığınız dizinin içinde ya da altında olması gerektiğini unutmayın docker build.


1
her gün yeni bir şeyler öğrenmek :-) KOPYA ve EKLE yapı bağlamından çalışır (ana bilgisayar değil). Alt Klasörü maskelemek için bir birim kullanmak mümkün müdür? OP / hostFolder (sanırım) bağlamak ve / hostFolder / subFolder bağlantısını kesmek istiyor. Her biri için bir VOLUME varsa, ancak yalnızca hostFolder 'mount' (-v) olsaydı, bu, subFolder'ın kapsayıcı değişikliklerini yalıtır mı?
Greg

Emin değilim, hacimleri iç içe yerleştirmeyi hiç denemedim. Bunun iyi bir fikir olduğuna ikna olmadım, ama buna bakmak zorundayım.
Adrian Mouat

1
Ne .dockerignorebir alt dizini (hatta bir dizini) hariç tutmak için bir dosyaya koymak bir yerde bir örnek bulamıyorum . Dosyanın belirtilen amacı olduğu göz önüne alındığında, oldukça garip.
Lukas Oberhuber

1
herhangi bir dosya ekledikten sonra, yine de bazı katmanlarda kalırlar. Bu nedenle, kaldırılması, güvenlik duyarlıysa veya görüntü boyutunu küçültürse bunları gizlemenize yardımcı olmaz (çünkü altta yatan katmanlarda olacaklardır). squashKatmanlar için seçenekler vardır . Biri github.com/goldmann/docker-squash , diğeri oc ex dockerbuildopenshift projesinden kullanıyor.
akostadinov

6

Görünüşe göre eski çözüm artık çalışmıyor (en azından benim için). Boş bir klasör oluşturmak ve hedef klasörü bu klasöre eşlemek yardımcı oldu.

volumes:
   - ./angularApp:/opt/app
   - .empty:/opt/app/node_modules/

docker-compose 1.25.0-rc3Dosya sözdizimi v3 ile de benim için çalışmıyor .
thisismydesign

6

Docker komut satırı ile:

docker run \
    --mount type=bind,src=/hostFolder,dst=/containerFolder \
    --mount type=volume,dst=/containerFolder/subFolder \
    ...other-args...

Bu -vseçenek de kullanılabilir ( Bogdan Mart'a verilen kredi ), ancak --mountdaha net ve önerilir .


6

node_modules klasörünün yine de yerel sisteminizden ve diğer yoldan yazılması sorunu olan kişiler için

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules/

Bu çözümdür, /düğüm_modülleri düzeltildikten sonraki iz ile.


0

Makinenizin biriminde bulunan bağlı bir dosyayı hariç tutmak için, aynı dosyaya bir birim ayırarak dosyanın üzerine yazmanız gerekir. Yapılandırma dosyanızda:

services:
  server:
    build : ./Dockerfile
    volumes:
      - .:/app

Dockerfile dosyasında bir örnek:

# Image Location
FROM node:13.12.0-buster
VOLUME /app/you_overwrite_file
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.