Birime tek bir dosya nasıl bağlanır


259

Bir php uygulaması dockerize çalışıyorum. Dockerfile'da arşivi indiriyorum, çıkarıyorum vb.

Her şey iyi çalışıyor, ancak yeni bir sürüm yayınlanırsa ve dockerfile'ı güncellersem Uygulamayı yeniden yüklemem gerekir, çünkü config.php'nin üzerine yazılır.

Bu yüzden veritabanıyla yaptığım gibi dosyayı bir birim olarak bağlayabileceğimi düşündüm.

Bir birim ve doğrudan bir yolla iki şekilde denedim.

liman işçisi-oluşturma:

version: '2'
services:
  app:
    build: src
    ports:
      - "8080:80"
    depends_on:
      - mysql
    volumes:
      -  app-conf:/var/www/html/upload
      -  app-conf:/var/www/html/config.php
    environment:
      DB_TYPE: mysql
      DB_MANAGER: MysqlManager

  mysql:
    image: mysql:5.6
    container_name: mysql
    volumes:
      - mysqldata:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD:
      MYSQL_DATABASE:
      MYSQL_USER:
      MYSQL_PASSWORD:

volumes:
  mysqldata:
  app-conf:

Hangi hataya neden olur:

Ve bunu monte edilmiş bir hacim olarak belirli bir yolla denedim.

/src/docker/myapp/upload:/var/www/html/upload
/src/docker/myapp/upload:/var/www/html/config.php

Ancak her iki yol da çalışmıyor. Takılan birim ile yüklemenin oluşturulduğunu görüyorum.

Ama sonra başarısız olur

/var/www/html/config.php \\ "\\" dizin değil \\ "\" "

Eğer denersem

/src/docker/myapp/upload/config.php:/var/www/html/config.php

Docker yükleme klasörünü ve ardından bir config.php klasörü oluşturur. Dosya değil.

Yoksa yapılandırmayı devam ettirmenin başka bir yolu var mı?


Benim durumumda, kap / birim oluşturmadan önce boş bir dosyaya "dokunmak" basit. Dosya yoksa, bir dizin oluşturdu.
FreeSoftwareServers

Yanıtlar:


314

TL; DR / Uyarı:

Bağlamaya çalıştığınız dosyanın yerine bir dizin oluşturuluyorsa, geçerli ve mutlak bir yol sağlayamamış olabilirsiniz . Bu, sessiz ve kafa karıştırıcı bir arıza modunda yaygın bir hatadır.

Dosya birimleri docker'da bu şekilde yapılır (mutlak yol örneği (env değişkenlerini kullanabilir) ve dosya adını belirtmeniz gerekir):

    volumes:
      - /src/docker/myapp/upload:/var/www/html/upload
      - /src/docker/myapp/upload/config.php:/var/www/html/config.php

Ayrıca şunları da yapabilirsiniz:

    volumes:
      - ${PWD}/upload:/var/www/html/upload
      - ${PWD}/upload/config.php:/var/www/html/config.php

Docker-compose'u /src/docker/myappklasörden tetiklerseniz


81
Dediğim gibi, /src/docker/myapp/upload/config.php:/var/www/html/config.php denersem Docker yükleme klasörünü ve ardından bir config.php klasörü oluşturur. Dosya değil.
Jakub Juszczak

9
Yayınınızda farklı yazdınız. Dosya oradaysa, dosya olarak takılmalıdır.
BlackStork

16
Bunun çalışması için mutlak bir yol sağlamam gerekiyordu. PWD kullanarak ipucu burada çok yardımcı oldu, teşekkürler!
Steve Smith

4
Benim için dosyaları yerine bir klasör oluşturmak, ama bu dosya daha sonra bu yolda kopyalandığı için zaten bağlamayı ertelemek için yine de var mı?
eKelvin

18
/src/docker/myapp/upload/config.php ana bilgisayarında yoksa docker bir klasör oluşturur ... Yaptığım şey, docker çalıştırmayı çalıştırmadan önce boş bir dosya oluşturan bir komut dosyası oluşturmaktır - ideal olur eğer docker'a cmd line argümanları aracılığıyla benim için yapmasını söyleyebilirsem.
cancerbero

78

Benzer bir sorundan muzdariptim. Yapılandırma dosyamı kabıma aktarmaya çalışıyordum, böylece görüntüyü yeniden oluşturmadan her ihtiyacım olduğunda düzeltebiliyorum.

Yani aşağıdaki komutun $(pwd)/config.pyDocker ana bilgisayarından /root/app/config.pykonteynere bir dosya olarak eşleneceğini düşündüm .

docker run -v $(pwd)/config.py:/root/app/config.py my_docker_image

Ancak, her zaman config.pybir dosya değil, adlı bir dizin oluşturdu .

ipucu ararken nedenini buldum ( buradan )

Docker ana bilgisayarında henüz bulunmayan bir dosyayı veya dizini bağlamak için -v veya --volume kullanırsanız, -v sizin için bir bitiş noktası oluşturur. Her zaman bir dizin olarak oluşturulur .

Bu nedenle, docker ana bilgisayarımda olmadığı için her zaman dizin olarak oluşturulur $(pwd)/config.py.

Docker ana bilgisayarında config.py oluştursam bile. $(pwd)/config.pysadece aşırı /root/app/config.pyihracat değil /root/app/config.py.


16
Sadece bir ilave touch path/to/filede Dockerfileböylece ben hala bir dosya (bir yaratılmış dir) olacağını monte zaman
vasiliy

8
sol tarafı :tam yol olmalıdır. Bu şekilde çalışır
sdkks

touch, Cevap oldu Dockerfile sonra da liman işçisi-oluşturma hacmi bir dizin oluşturmadan düzgün çalışacağını monte bunu
ctrlbrk

27

Kullanım bağlama ( --mountyerine) hacim ( -v)

Daha fazla bilgi: https://docs.docker.com/storage/bind-mounts/

Misal:

Docker ana bilgisayarında /tmp/a.txt dosyasının bulunduğundan emin olun

docker run -it --mount type=bind,source=/tmp/a.txt,target=/root/a.txt alpine sh

Teşekkür ederim Subbu, @ Jakub Juszczak bu kabul edilen cevap olmalı, soruyu cevaplayan tek cevap bu ve benim için çalıştı
neokyle

2
Bu soruya gerçekten cevap vermiyor. birimler de çalışacaktır (çünkü sorun mutlak yoldadır). Arasındaki tek fark --mountve -vhacim konak kısmı henüz yok olduğunda davranıştır. Bağlantınıza göre:> Docker ana bilgisayarında henüz bulunmayan bir dosya veya dizini bağlamak için -v veya --volume kullanırsanız, -v sizin için bir bitiş noktası oluşturur. Her zaman bir dizin olarak oluşturulur.
The Godfather

2
Bunu docker-compose'a nasıl çevireceğimi bilmiyorum. 'Biraz yardım?
msanford

@ msanford Cevaba docker-compose örneği ekledim.
sebisnow

10

Benim gibi Windows kapsayıcısı kullanan herkes için, Windows kapsayıcısını kullanarak tek dosyaları bağlayamayacağınızı veya bağlayamayacağınızı bilin.

Kapsayıcı içindeki bir birim veya bağlama bağının hedefi şunlardan biri olması gerektiğinden, Windows tabanlı kapsayıcılar kullanılırken aşağıdaki örnekler başarısız olur: varolmayan veya boş bir dizin; veya C: dışında bir sürücü. Ayrıca, bağlama bağının kaynağı bir dosya değil, yerel bir dizin olmalıdır .

net use z: \\remotemachine\share

docker run -v z:\foo:c:\dest ...

docker run -v \\uncpath\to\directory:c:\dest ...

docker run -v c:\foo\somefile.txt:c:\dest ...

docker run -v c:\foo:c: ...

docker run -v c:\foo:c:\existing-directory-with-contents ...

Tespit etmek zor ama orada

Dosyaları Windows kapsayıcısına eşleme ile ilgili Github sorununa bağlantı



7

Docker-compose dosyası sürüm 3.2'den itibaren, konteynere tek bir dosya monte etmenize izin veren "bind" tipinde (varsayılan "birim" yerine) bir birim montajı belirtebilirsiniz . Docker-compose birim dokümanlarında "bağlama bağlama" araması yapın : https://docs.docker.com/compose/compose-file/#volumes

Benim durumumda, sadece yerel geliştirme ve test için sırları içeren uygulamama tek bir ".secrets" dosyası bağlamaya çalışıyordum. Üretimde uygulamam bu sırları AWS'den alıyor.

Bu dosyayı steno sözdizimini kullanarak bir birim olarak bağladıysam:

volumes:
 - ./.secrets:/data/app/.secrets

Docker , kapsayıcı dışındaki dosyayı eşlemek yerine kapsayıcı içinde bir ".secrets" dizini oluşturur . Kodum daha sonra "IsADirectoryError: [Errno 21] Bir dizin: '.secrets'" gibi bir hata oluşturur.

Bunun yerine uzun süreli sözdizimini kullanarak, salt okunur bir "bağlama" birim bağlaması kullanarak sırlarımı belirterek bunu düzelttim:

volumes:
 - type: bind
   source: ./.secrets
   target: /data/app/.secrets
   read_only: true

Artık Docker, .secrets dosyamı doğru bir şekilde kabın içine bağlar ve bir dizin yerine kap içinde bir dosya oluşturur. Başkalarının bu örneği faydalı bulmasını umuyoruz!


Teşekkürler bayım! WordPress wp-config.php dosyamı bağlayabilmem (ve bir dizin olarak oluşturulmasını durdurmam) için gereken çözüm buydu
Jono

6

docker-compose.ymlDosyanıza aşağıdaki gibi göreli bir yol da kullanabilirsiniz (Windows ana bilgisayarında, Linux kapsayıcısında test edilmiştir):

 volumes:
      - ./test.conf:/fluentd/etc/test.conf

1
Bunu docker-compose sürüm 1.24.1, build 4667896b ile version: '3.7'belirtilen docker-compose.ymldosyada Mac'te test ettim ve çalıştı.
Acumenus

6
Hala dosya yerine bir dizin alıyorum.
chovy

0

Benim için sorun, konteynere monte etmeye çalıştığım dosyada bozuk bir sembolik bağlantım olmasıydı.


0

Aynı sorunu Windows'ta da yaşadım Docker 18.06.1-ce-win73 (19507).

Docker ayarları panelinden paylaşılan sürücüyü kaldırıp yeniden eklemek ve her şey tekrar çalıştı.


0

Windows'ta docker-compose.yml dosyasında $ {PWD} env değişkenine ihtiyacınız varsa, docker-compose.yml dosyanızla aynı dizinde bir .env dosyası oluşturabilir ve ardından klasörünüzü el ile ekleyebilirsiniz.

CMD (pwd_var.bat):

echo PWD=%cd% >> .env

Powershell (pwd_var.ps1):

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'; echo "PWD=$(get-location).path" >> .env

Docker-compose .env değişkenlerini duymak için daha iyi özellikler vardır: https://docs.docker.com/compose/reference/envvars/ özellikle COMPOSE_CONVERT_WINDOWS_PATHSdocker compos'un baskslash ile windows yolunu kabul etmesine izin veren env değişkeni için "\".

Windows'da bir dosyayı paylaşmak istediğinizde, dosyanın kapla paylaşılmadan önce dosyanın mevcut olması gerekir.


PowerShell'i docker ile kullanamazsınız, bir satıcı kilidi oluşturur ve topluluğa zarar verir ...
Matej 'Yin' Gagyi

0

Belki bu birisine yardım eder.

Bu sorunu yaşadım ve her şeyi denedim. Birim bağlamaları iyi görünüyordu ve dizin (dosyalar değil) monte etsem bile, dosya isimlerini monte edilmiş dizinde doğru bir şekilde vardı ama dirs olarak monte ettim.

Paylaşılan sürücüleri yeniden etkinleştirmeyi denedim ve Docker, güvenlik duvarının etkin olduğundan şikayet etti.

Güvenlik duvarını devre dışı bıraktıktan sonra hepsi iyi çalışıyordu.


Bunun için teşekkür ederim! Gönderiniz bana selinux'umun uygulamaya koyulduğunu ve bunun tüm sıkıntılarıma neden olduğunu anlamamı sağladı. Niçin aşağı oylandığınızı bilmiyorum ¯_ (ツ) _ / ¯
Octavian

0

Tümü Kaynak dosya veya dizine bağlı olan dosyaları veya dizinleri / klasörleri bağlayabilirsiniz. Ayrıca tam yol sağlamanız veya PWD'yi kullanabileceğinizden emin değilseniz. İşte basit bir çalışma örneği.

Bu örnekte, çalışma dizinimde zaten bulunan env-commands dosyasını bağlıyorum

$ docker run  --rm -it -v ${PWD}/env-commands:/env-commands aravindgv/eosdt:1.0.5 /bin/bash -c "cat /env-commands"

-1

Windows 8.1'imde de aynı sorun var

Bunun yolun büyük / küçük harf duyarlılığından kaynaklandığı ortaya çıktı. Aradım docker-compose updizinden cd /c/users/alex/ve bir dosya dizinine dönüştürülmüştür iç kap.

Ama o zaman cd /c/Users/alex/(Kullanıcılar büyük değil) ve docker-compose uporadan aradığımda işe yaradı.

Sistemimde, Users dir ve Alex dir değerleri büyük harfle yazılır, ancak yalnızca Users dir gibi görünür.

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.