Pertanyaan awal: Bagaimana cara menggunakan instruksi VOLUME di Dockerfile?
Pertanyaan sebenarnya yang ingin saya pecahkan adalah - bagaimana cara me-mount volume host ke dalam wadah buruh pelabuhan di Dockerfile selama pembuatan, yaitu, memiliki docker run -v /export:/export
kemampuan selama docker build
.
Alasan di baliknya, bagi saya, adalah ketika membangun sesuatu di Docker, saya tidak ingin apt-get install
cache ( ) itu terkunci di satu buruh pelabuhan, tetapi untuk membagikan / menggunakannya kembali. Itulah alasan utama saya bertanya tentang pertanyaan ini.
Pembaruan Terbaru:
Sebelum docker v18.09, jawaban yang benar haruslah yang dimulai dengan:
Ada cara untuk memasang volume selama membangun, tetapi tidak melibatkan Dockerfiles.
Namun, itu adalah jawaban yang dinyatakan dengan buruk, terorganisir dan didukung. Ketika saya sedang menginstal ulang buruh pelabuhan saya, saya kebetulan menemukan artikel berikut:
Dockerize layanan apt-cacher-ng
https://docs.docker.com/engine/examples/apt-cacher-ng/
Itulah solusi buruh pelabuhan untuk pertanyaan ini / saya, tidak secara langsung tetapi tidak langsung. Ini adalah cara buruh pelabuhan ortodoks menyarankan kita untuk melakukan. Dan saya akui itu lebih baik daripada yang saya coba tanyakan di sini.
Cara lain adalah, jawaban yang baru diterima , misalnya, Buildkit di v18.09.
Pilih mana yang cocok untuk Anda.
Was: Ada solusi - rocker, yang bukan dari Docker, tetapi sekarang rocker dihentikan, saya mengembalikan jawaban kembali ke "Tidak mungkin" lagi.
Pembaruan Lama: Jadi jawabannya adalah "Tidak mungkin". Saya dapat menerimanya sebagai jawaban karena saya tahu masalah ini telah dibahas secara luas di https://github.com/docker/docker/issues/3156 . Saya bisa mengerti bahwa portabilitas adalah masalah terpenting bagi pengembang buruh pelabuhan; tetapi sebagai pengguna buruh pelabuhan, saya harus mengatakan saya sangat kecewa dengan fitur yang hilang ini. Izinkan saya menutup argumen saya dengan kutipan dari diskusi di atas: " Saya ingin menggunakan Gentoo sebagai gambar dasar tapi jelas tidak ingin> 1GB data portage tree berada di salah satu lapisan setelah gambar dibuat. Anda bisa memiliki wadah kompak yang bagus jika bukan karena pohon portage raksasa harus muncul di gambar selama instalasi."Ya, saya dapat menggunakan wget atau curl untuk mengunduh apa pun yang saya butuhkan, tetapi fakta bahwa hanya pertimbangan portabilitas sekarang memaksa saya untuk mengunduh> 1GB pohon Portage setiap kali saya membangun gambar dasar Gentoo tidak efisien atau ramah pengguna. Lebih lanjut lebih lanjut, repositori paket AKAN SELALU berada di bawah / usr / portage, jadi SELALU PORTABEL di bawah Gentoo. Sekali lagi, saya menghargai keputusan itu, tetapi tolong izinkan saya mengungkapkan kekecewaan saya juga dalam waktu yang bersamaan. Terima kasih.
Pertanyaan asli secara terperinci:
Dari
Bagikan Direktori melalui Volume
http://docker.readthedocs.org/en/v0.7.3/use/working_with_volumes/
dikatakan bahwa fitur Volume data "telah tersedia sejak versi 1 dari Docker Remote API". Docker saya adalah versi 1.2.0, tetapi saya menemukan contoh yang diberikan dalam artikel di atas tidak berfungsi:
# BUILD-USING: docker build -t data .
# RUN-USING: docker run -name DATA data
FROM busybox
VOLUME ["/var/volume1", "/var/volume2"]
CMD ["/usr/bin/true"]
Apa cara yang tepat di Dockerfile untuk memasang volume yang dipasang di host ke dalam wadah buruh pelabuhan, melalui perintah VOLUME?
$ apt-cache policy lxc-docker
lxc-docker:
Installed: 1.2.0
Candidate: 1.2.0
Version table:
*** 1.2.0 0
500 https://get.docker.io/ubuntu/ docker/main amd64 Packages
100 /var/lib/dpkg/status
$ cat Dockerfile
FROM debian:sid
VOLUME ["/export"]
RUN ls -l /export
CMD ls -l /export
$ docker build -t data .
Sending build context to Docker daemon 2.56 kB
Sending build context to Docker daemon
Step 0 : FROM debian:sid
---> 77e97a48ce6a
Step 1 : VOLUME ["/export"]
---> Using cache
---> 59b69b65a074
Step 2 : RUN ls -l /export
---> Running in df43c78d74be
total 0
---> 9d29a6eb263f
Removing intermediate container df43c78d74be
Step 3 : CMD ls -l /export
---> Running in 8e4916d3e390
---> d6e7e1c52551
Removing intermediate container 8e4916d3e390
Successfully built d6e7e1c52551
$ docker run data
total 0
$ ls -l /export | wc
20 162 1131
$ docker -v
Docker version 1.2.0, build fa7b24f
VOLUME ~/host_dir ~/container_dir
. Pembahasannya cukup luas, dan ada cara singkat untuk meringkas apa alasannya?Jawaban:
Pertama, untuk menjawab "mengapa tidak
VOLUME
berhasil?" Ketika Anda mendefinisikan aVOLUME
di Dockerfile, Anda hanya bisa menentukan target, bukan sumber volume. Selama membangun, Anda hanya akan mendapatkan volume anonim dari ini. Volume anonim itu akan dipasang di setiapRUN
perintah, diisi terlebih dahulu dengan isi gambar, dan kemudian dibuang di akhirRUN
perintah. Hanya perubahan pada wadah yang disimpan, bukan perubahan volume.Karena pertanyaan ini telah diajukan, beberapa fitur telah dirilis yang dapat membantu. Pertama adalah multistage build yang memungkinkan Anda membangun ruang disk tahap pertama yang tidak efisien, dan menyalin hanya output yang dibutuhkan ke tahap akhir yang Anda kirimkan. Dan fitur kedua adalah Buildkit yang secara dramatis mengubah cara gambar dibangun dan kemampuan baru ditambahkan ke build.
Untuk pembuatan multi-tahap, Anda akan memiliki beberapa
FROM
baris, masing-masing memulai pembuatan gambar terpisah. Hanya gambar terakhir yang ditandai secara default, tetapi Anda dapat menyalin file dari tahap sebelumnya. Penggunaan standar adalah memiliki lingkungan kompiler untuk membangun biner atau artefak aplikasi lainnya, dan lingkungan runtime sebagai tahap kedua yang menyalin dari artefak itu. Kamu bisa saja:Itu akan menghasilkan build yang hanya berisi biner yang dihasilkan, dan bukan direktori penuh / ekspor.
Buildkit keluar dari percobaan di 18.09. Ini adalah desain ulang yang lengkap dari proses build, termasuk kemampuan untuk mengubah parser frontend. Salah satu perubahan parser telah menerapkan
RUN --mount
opsi yang memungkinkan Anda memasang direktori cache untuk menjalankan perintah Anda. Misalnya, inilah yang memasang beberapa direktori debian (dengan konfigurasi ulang gambar debian, ini dapat mempercepat menginstal ulang paket):Anda akan menyesuaikan direktori cache untuk cache aplikasi apa pun yang Anda miliki, mis. $ HOME / .m2 untuk maven, atau /root/.cache untuk golang.
TL; DR: Jawaban ada di sini: Dengan
RUN --mount
sintaks itu, Anda juga dapat mengikat mount direktori read-only dari build-context. Folder harus ada dalam konteks build, dan tidak dipetakan kembali ke host atau klien build:Perhatikan bahwa karena direktori di-mount dari konteks, itu juga di-mount hanya-baca, dan Anda tidak dapat mendorong perubahan kembali ke host atau klien. Saat Anda membangun, Anda ingin memasang 18.09 atau yang lebih baru dan mengaktifkan buildkit
export DOCKER_BUILDKIT=1
.Jika Anda mendapatkan kesalahan bahwa flag mount tidak didukung, itu menunjukkan bahwa Anda tidak mengaktifkan buildkit dengan variabel di atas, atau bahwa Anda tidak mengaktifkan sintaksis eksperimental dengan garis sintaksis di bagian atas Dockerfile sebelum baris lain, termasuk komentar. Perhatikan bahwa variabel toggle buildkit hanya akan berfungsi jika instalasi buruh pelabuhan Anda memiliki dukungan buildkit bawaan, yang membutuhkan versi 18.09 atau lebih baru dari Docker, baik pada klien maupun server.
sumber
Tidak mungkin menggunakan
VOLUME
instruksi untuk memberi tahu buruh pelabuhan apa yang harus dipasang. Itu akan sangat merusak portabilitas. Instruksi ini memberi tahu docker bahwa konten dalam direktori tersebut tidak masuk dalam gambar dan dapat diakses dari kontainer lain menggunakan--volumes-from
parameter baris perintah. Anda harus menjalankan wadah menggunakan-v /path/on/host:/path/in/container
untuk mengakses direktori dari tuan rumah.Memasang volume host selama pembuatan tidak dimungkinkan. Tidak ada bangunan istimewa dan pemasangan host juga akan secara serius menurunkan portabilitas. Anda mungkin ingin mencoba menggunakan wget atau ikal untuk mengunduh apa pun yang Anda perlukan untuk membangun dan meletakkannya.
sumber
PEMBARUAN: Seseorang tidak akan menerima jawaban sebagai tidak, dan saya sangat menyukainya, terutama untuk pertanyaan khusus ini.
BERITA BAIK, Ada jalan sekarang -
Solusinya adalah Rocker: https://github.com/grammarly/rocker
John Yani berkata , "IMO, ini menyelesaikan semua titik lemah Dockerfile, membuatnya cocok untuk pengembangan."
Kursi goyang
https://github.com/grammarly/rocker
Pembaruan: Rocker telah dihentikan, sesuai dengan repo proyek resmi di Github
sumber
MOUNT ~/code/docker-app-dev/new-editor/:/src/
dan perintah build Rocker saya adalah ini -rocker build -f Dockerfile .
. Apa yang saya lakukan salah?~
adalah metacharacter shell Bourne.Rocker build
tidak mengizinkandocker run
opsi baris perintah, jadi saat ini tidak mengizinkan hal-hal seperti--privileged
.Ada cara untuk memasang volume selama membangun, tetapi tidak melibatkan Dockerfiles.
Tekniknya adalah membuat wadah dari basis apa pun yang ingin Anda gunakan (memasang volume Anda di wadah dengan
-v
opsi), menjalankan skrip shell untuk melakukan pekerjaan pembangunan gambar Anda, kemudian komit wadah sebagai gambar ketika selesai .Ini tidak hanya akan menghilangkan file berlebih yang tidak Anda inginkan (ini juga baik untuk file yang aman, seperti file SSH), ini juga membuat satu gambar. Itu memiliki kelemahan: perintah komit tidak mendukung semua instruksi Dockerfile, dan itu tidak membiarkan Anda mengambil ketika Anda tinggalkan jika Anda perlu mengedit skrip pembangunan Anda.
MEMPERBARUI:
Sebagai contoh,
sumber
debian:wheezy
dan skrip shellbuild.sh
, instruksi spesifik apa yang akan digunakan seseorang?Saat Anda menjalankan wadah, direktori pada host Anda dibuat dan dipasang ke wadah. Anda dapat mengetahui direktori apa ini
Jika Anda ingin memasang direktori dari host Anda di dalam wadah Anda, Anda harus menggunakan
-v
parameter dan menentukan direktori. Dalam kasus Anda ini adalah:JADI, Anda akan menggunakan folder hosts di dalam wadah Anda.
sumber
Saya pikir Anda dapat melakukan apa yang ingin Anda lakukan dengan menjalankan build melalui perintah buruh pelabuhan yang sendiri dijalankan di dalam wadah buruh pelabuhan. Lihat Docker sekarang dapat berjalan dalam Docker | Blog Docker . Sebuah teknik seperti ini, tetapi yang benar-benar mengakses buruh pelabuhan luar dengan wadah, digunakan, misalnya, sambil menjelajahi cara Membuat wadah Docker sekecil mungkin | Blog Xebia .
Artikel lain yang relevan adalah Mengoptimalkan Gambar Docker | CenturyLink Labs , yang menjelaskan bahwa jika Anda akhirnya mengunduh hal-hal selama membangun, Anda dapat menghindari ruang yang terbuang dengannya di gambar akhir dengan mengunduh, membangun, dan menghapus unduhan semua dalam satu langkah RUN.
sumber
Ini jelek, tapi saya mencapai kemiripan seperti ini:
Dockerfile:
imageBuild.sh:
Saya memiliki java build yang mengunduh semesta ke /root/.m2, dan melakukannya setiap saat .
imageBuild.sh
menyalin isi folder itu ke host setelah membangun, danDockerfile
menyalinnya kembali ke gambar untuk membangun selanjutnya.Ini adalah sesuatu seperti bagaimana sebuah volume akan berfungsi (yaitu tetap ada di antara build).
sumber
Berikut adalah versi sederhana dari pendekatan 2 langkah menggunakan build dan commit, tanpa skrip shell. Ini melibatkan:
Dengan perubahan yang relatif kecil, langkah tambahan hanya menambahkan beberapa detik ke waktu pembuatan.
Pada dasarnya:
Dalam kasus penggunaan saya, saya ingin membuat file maven toolchains.xml, tetapi banyak instalasi JDK saya ada di volume yang tidak tersedia sampai runtime. Beberapa gambar saya tidak kompatibel dengan semua JDKS, jadi saya perlu menguji kompatibilitas pada waktu pembuatan dan mengisi toolchains.xml secara kondisional. Perhatikan bahwa saya tidak perlu gambar menjadi portabel, saya tidak menerbitkannya ke Docker Hub.
sumber
Seperti yang sudah banyak dijawab, pemasangan volume host selama pembangunan tidak dimungkinkan. Saya hanya ingin menambahkan
docker-compose
cara, saya pikir akan menyenangkan untuk dimiliki, sebagian besar untuk pengembangan / penggunaan pengujianDockerfile
docker-compose.yml
Dan jalankan wadah Anda dengan
docker-compose up -d --build
sumber