Moby: Setel ulang properti yang diwarisi dari gambar induk

Dibuat pada 6 Jan 2014  ·  153Komentar  ·  Sumber: moby/moby

Saat membuat gambar, saya mungkin ingin mengatur ulang beberapa propertinya alih-alih mewarisinya dari gambar induk. Masuk akal untuk mewarisi semua properti secara default, tetapi harus ada cara untuk secara eksplisit dan selektif menyetel ulang properti tersebut jika masuk akal.

Ini adalah solusi yang lebih umum untuk #2210 yang hanya membahas expose .

arebuilder kinenhancement statuneeds-attention

Komentar yang paling membantu

Saya pasti ingin memiliki beberapa cara untuk menghapus poin VOLUME yang diwarisi dari gambar induk.

Misalnya, saya memiliki gambar utama untuk aplikasi yang menggunakan titik pemasangan eksternal untuk data persisten, tetapi saya juga menginginkan gambar berdasarkan itu yang telah diisi sebelumnya dengan data uji. Apa adanya, saya tidak bisa melakukan itu jika gambar induk menggunakan VOLUME karena setiap perubahan/penambahan pada direktori tersebut, bahkan jika perubahan itu selama pembangunan buruh pelabuhan, hilang saat dikomit.

Semua 153 komentar

Saran diterima untuk sintaks.

Yang terbaik yang dapat saya buat adalah perintah yang sesuai seperti UNVOLUME atau lebih umum -VOLUME (tetapi itu akan menambah lebih banyak kebingungan, dan bahkan berpotensi menciptakan kesalahpahaman bahwa +VOLUME seharusnya berfungsi, dan harus bekerja secara berbeda dari hanya VOLUME ).

Saya sangat menginginkan hal seperti itu (terutama untuk VOLUME). Ini juga sedikit membingungkan bahwa hal-hal seperti VOLUME berlaku untuk mengikuti baris RUN, tetapi hal-hal seperti ENTRYPOINT tidak. Terkadang itu sangat berguna, dan terkadang tidak, tetapi "nonaktifkan instruksi X sebelumnya" yang umum dapat menyelesaikan masalah di sekitar itu dengan cukup baik.

Apakah ada solusi untuk ini sementara ini? Saya memperluas gambar dengan ENTRYPOINT (https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile) dan saya perlu menghapus titik masuk. Saya mencoba menggunakan yang berikut ini di Dockerfile saya:

FROM jagregory/pandoc
ENTRYPOINT [] # this basically gets ignored (bug?)

FROM jagregory/pandoc
ENTRYPOINT [""] # this will make docker try to exec '' (the empty string)

FROM jagregory/pandoc
ENTRYPOINT ["/bin/sh", "-c"] 
# this will only work if docker run args are quoted:
#   docker run dergachev/pandoc "echo a b c"

Terima kasih!

Saya pasti ingin memiliki beberapa cara untuk menghapus poin VOLUME yang diwarisi dari gambar induk.

Misalnya, saya memiliki gambar utama untuk aplikasi yang menggunakan titik pemasangan eksternal untuk data persisten, tetapi saya juga menginginkan gambar berdasarkan itu yang telah diisi sebelumnya dengan data uji. Apa adanya, saya tidak bisa melakukan itu jika gambar induk menggunakan VOLUME karena setiap perubahan/penambahan pada direktori tersebut, bahkan jika perubahan itu selama pembangunan buruh pelabuhan, hilang saat dikomit.

Hanya untuk memperbarui dari komentar @dergachev , CMD [] dan ENTRYPOINT [] berfungsi terakhir kali saya mengujinya baru-baru ini, dan seharusnya masih berfungsi (apa pun yang lain akan siap untuk pengarsipan bug).

Anda dapat mengatur ulang semua perintah opsi tunggal melalui

ENTRYPOINT []
CMD []
USER 0
WORKDIR /

Ini akan meninggalkan metadata yang tersisa dan tidak dapat disetel ulang sebagai ENV , VOLUME , EXPOSE dan mungkin ONBUILD .

(Ini berasal dari #8709)

Jika saya mengekspos soket 9000-9002 di induk, tetapi perlu membuka 9001 di anak, saya kemudian harus menulis dengan gaya "menghapus pengaturan"

MEMBUKA
EXPOSE 9000
Paparan 9002

yang akan berhasil tapi

UNEXPOSE 9001

terlihat lebih bagus.

Keuntungannya adalah, hal itu tidak memengaruhi EKSPOSE apa pun dari rantai pewarisan lebih lanjut, yang mungkin ingin saya tambahkan nanti.

+1 @ codeon-nat

Ini telah dibahas di #8177, kami menutup ini karena kurangnya kasus penggunaan dunia nyata.

Mengapa ini ditutup? Ada 9 orang yang berkomentar di sini. Saya pikir ini akan menjadi hal yang sangat berguna untuk dimiliki. Kasus penggunaan dunia nyata mampu membangun gambar yang ada dengan mudah. Terkadang Anda ingin menambahkan properti, terkadang Anda ingin menghapusnya. Ini normal.

Saya setuju, misalnya, saya memperluas gambar nginx untuk offloader SSL dan saya ingin UNEXPOSE 80 tetapi meninggalkan 443 .

Mampu mengekspos port cukup penting jika Anda ingin menjalankan beberapa instance, misalnya, nginx.

Nevermind, ini hanya konfigurasi yang buruk di pihak saya.

(15 April: "Tidak ada kasus penggunaan dunia nyata" Saya terkejut Anda tidak dapat membayangkan setidaknya satu dan menutup ini)

Saya memiliki gambar dasar yang memperlihatkan volume atau port untuk perangkat lunak opsional, kemudian DARI itu di Dockerfile lain untuk membuat gambar yang tidak boleh mengekspos apa pun yang tidak diinginkannya, atau bahkan hal-hal yang telah dihapus dari leluhurnya. Mengapa kami TIDAK ingin menghapus pengaturan ini?

Saya juga punya kasus penggunaan untuk ini. Saya ingin dapat membuat gambar yang berisi snapshot database, tetapi semua paket mysql memiliki VOLUME /var/lib/mysql disetel. Akan menyenangkan untuk dapat mematikan volume, perubahan pada database yang dibuat di Dockerfile saya akan menempel pada gambar.

Satu-satunya pilihan lain adalah benar-benar membuat ulang gambar mysql kustom, tetapi entah bagaimana tampaknya sia-sia karena banyak orang lain telah mengumpulkan server mysql default yang lebih baik daripada yang saya bisa.

Menambahkan kasus penggunaan tambahan - Saya mewarisi dari gambar resmi RabbitMQ, tetapi saya hanya ingin mengekspos port websocket (80 dan 443) dan bukan port AMQP default (5672). Sepertinya ini harus menjadi hal yang cukup masuk akal untuk dilakukan?

Menambahkan kasus penggunaan lain. Saya ingin membangun lingkungan pengujian git menggunakan gambar gogs tetapi sulit untuk menyimpan data karena semuanya disimpan dalam volume. Akan sangat bagus jika saya dapat dengan mudah UNVOLUME volume dan membangun gambar saya setelah mengatur lingkungan.

+1

mewarisi dari php resmi dan ingin menggunakan soket alih-alih port jadi perlu menghapus port 9000 yang terbuka

Siapa pun yang telah menggunakan Docker dalam kapasitas non-sepele akan menemukan batasan ini dengan wadah yang diwariskan.

@shykes @icecrime bagaimana ini sekarang ditutup? Apakah terlalu sulit untuk diselesaikan dengan sintaks saat ini dan kebutuhan untuk kompatibilitas mundur? Apa rencananya?

+1 - kasus penggunaan dunia nyata untuk penggantian EXPOSE di sini.

Mengingat ini telah berlangsung selama lebih dari 3 tahun (menemukan masalah sejak 2013) kapan kami dapat menghapus port yang terbuka?

+1. harus dapat "UNEXPOSE" port nginx default 80 dan 443.

Bagi orang-orang di sini meminta UNEXPOSE ; pernyataan EXPOSE hanya memberikan petunjuk port mana yang diekspos oleh container, tetapi sebenarnya tidak _mengekspos_ port tersebut; anda perlu _publish_ port tersebut ( -p / -P ) untuk mengeksposnya di Host. Dengan kata lain; menghilangkan pernyataan EXPOSE dari Dockerfile memang memiliki _no_ efek langsung pada gambar (Anda masih bisa, misalnya mencapai "port 80" dari wadah).

Selain itu, jika Anda ingin mengekspos port tambahan, buat saja layanan di wadah berjalan di port tersebut, dan ini akan berfungsi.

Benar, tetapi jika menggunakan -P (untuk mengekspos semua port) dan gambar dasar Anda mengekspos port yang tidak lagi ingin Anda ekspos maka Anda macet. Anda harus beralih untuk menggunakan -p dan mendaftar semua port lainnya .

@thaJeztah itu bagus untuk diketahui. Namun, apa salahnya menambahkan UNEXPOSE? Ini akan berguna bagi saya juga, bahkan jika itu hanya untuk memiliki wadah yang didokumentasikan dengan lebih baik.

@kgx tidak ada salahnya (terlepas dari kemungkinan fitur mengasapi), tetapi ingin menjelaskan bahwa tidak dapat " UNVOLUME (atau UNSET VOLUME ) masih ada di daftar keinginan pribadi saya. :-)

Saya geli saya mengalami masalah ini dalam 72 jam pertama mencoba buruh pelabuhan. Setiap konfigurasi atau bahasa untuk alat utama lainnya yang saya gunakan yang memiliki segala jenis warisan memiliki jenis kemampuan "mengganti induk".

Berikut adalah kasus penggunaan: Saya menggunakan gambar buruh pelabuhan default untuk go-ethereum, dan saya harus dapat menyiapkan versi uji yang sama sekali tidak akan pernah terhubung ke dunia luar. Saya harus dapat menghubungkannya dari Host dan wadah lainnya. Cara teraman untuk melakukan ini adalah dengan mengubah port karena program terlalu bersemangat mencoba untuk terhubung ke rekan-rekan. Saya juga harus dapat mengganti CMD dan ENTRYPOINT untuk membuat versi "set up the database" dari gambar yang saya jalankan sekali untuk membuat volume yang tepat. Semua ini sangat sulit dilakukan di Dockerfile.

Anda dapat menetapkannya ke alamat IP lain... Atau mengikat port host yang berbeda. Titik masuk dan cmd tentang over riding nanti adalah mendefinisikan ulang mereka.

---Dikirim dari Boxer | http://getboxer.com

Pada 20 Februari 2016 pukul 08:57:00 GMT, barkthins [email protected] menulis: Ini adalah kasus penggunaan: Saya menggunakan gambar buruh pelabuhan default untuk go-ethereum, dan saya harus dapat menyiapkan pengujian versi yang sama sekali tidak akan pernah terhubung ke dunia luar. Saya harus dapat menghubungkannya dari Host dan wadah lainnya. Cara teraman untuk melakukan ini adalah dengan mengubah port karena program terlalu bersemangat mencoba untuk terhubung ke rekan-rekan. Saya juga harus dapat mengganti CMD dan ENTRYPOINT untuk membuat versi "set up the database" dari gambar yang saya jalankan sekali untuk membuat volume yang tepat. Semua ini sangat sulit dilakukan di Dockerfile. —Balas email ini secara langsung atau lihat di GitHub.

CMD dan ENTRYPOINT dapat ditimpa saat runtime; docker run --entrypoint=foo myimage mycmd . Pertanyaan di sini adalah apakah berguna untuk memiliki gambar yang berbeda, dengan titik masuk/cmd yang berbeda selama pengujian, karena Anda tidak akan _menguji_ gambar sebenarnya yang akan berjalan dalam produksi. (hanya catatan sampingan)

dari balasan ini tampaknya dockerfile tidak digunakan lagi demi opsi baris perintah setidaknya sejauh titik masuk, cmd, ekspos, dan mungkin beberapa lainnya. Baris perintah sudah melakukan hal-hal yang tidak dapat dilakukan Dockerfile, sehingga tampaknya menjadi arahnya. Jika itu maksudnya, maka saya akan memindahkan sebanyak mungkin info Dockerfile ke waktu instantation hanya untuk mengurangi kebingungan. Apakah itu niatnya?

@barkthins tidak, Dockerfile tidak ditinggalkan. Menggunakan Dockerfile masih merupakan cara biasa untuk menghasilkan gambar. Selain itu, Anda dapat mengganti CMD dan ENTRYPOINT dalam gambar yang diwarisi. Contoh saya adalah untuk menunjukkan bahwa pada kasus tertentu (misalnya menjalankan perintah alternatif pada gambar Anda), Anda dapat menimpanya saat runtime.

Dari halaman manual Dockerfile:

     -- EXPOSE <port> [<port>...]
     The EXPOSE instruction informs Docker that the container listens

pada
port jaringan tertentu saat runtime. Docker menggunakan informasi ini untuk
menghubungkan wadah menggunakan tautan dan _untuk mengatur port
pengalihan pada host_

  • sistem.*
    [...]
    SEJARAH
    *Mei 2014, Disusun oleh Zac Dover (zdover di redhat dot com) berdasarkan
    pada docker.com dokumentasi Dockerfile. *Feb 2015, diperbarui oleh Brian Goff (
    [email protected])
    agar mudah dibaca *September 2015, diperbarui oleh Sally O'Malley (
    [email protected])

[miring saya] tampaknya menyesatkan (atau setidaknya ambigu) jika apa yang Anda katakan adalah
benar.

Pada Kam, 28 Jan 2016 jam 06:43, Sebastiaan van Stijn <
[email protected]> menulis:

Bagi orang-orang di sini meminta UNEXPOSE; pernyataan EXPOSE saja
memberikan _hint_ port mana yang diekspos oleh wadah, tetapi tidak
sebenarnya _expose_ port tersebut; Anda perlu _mempublikasikan_ port tersebut (-p / -P)
untuk mengekspos mereka pada host. Dengan kata lain; menghilangkan pernyataan EXPOSE
dari Dockerfile memang memiliki _no_ efek langsung pada gambar (Anda dapat
masih, misalnya mencapai "port 80" dari wadah).

Selain itu, jika Anda ingin mengekspos port tambahan, buat saja
service dalam wadah berjalan di port tersebut, dan ini akan berfungsi.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/docker/docker/issues/3465#issuecomment -176012915.

Saat ini menulis bersama buku di Docker: Dapatkan diskon 39% dengan kode 39miell
http://manning.com/miell/?a_aid=zwischenzugs&a_bid=e0d48f62

thaJeztah Poin saya dan saya pikir poin thread ini adalah pewarisan yang tidak konsisten. Ya, Anda dapat mengganti ENTRYPOINT dan CMD tetapi EXPOSE menambahkan eksposur, Anda tidak dapat mengganti eksposur induk kecuali pada baris perintah. Saya belum memeriksa perintah lain untuk melihat apakah ada perilaku ketiga. Itu juga tidak didokumentasikan tentang perintah mana yang memperpanjang atau mengganti perintah orang tua.

@thaJeztah kita butuh UNEXPOSE

Ada beberapa solusi yang membaca metadata container dan menyediakan konfigurasi upstream tambahan. Sebagai contoh; dengan HAPROXY saya harus mengatur EXCLUDE_PORTS=8080 untuk memblokirnya mencoba memberikan akses secara dinamis ke port itu di aplikasi Tomcat saya.

Pengembang melihat port yang terbuka dan membuat asumsi tentang perilaku container. Misalnya saya memiliki gambar dasar yang memperluas Tomcat (EXPOSE 8080) tetapi gambar tersebut menggunakan port yang berbeda dengan default (EXPOSE 8888). Jika Anda menambahkan server web dalam gambar gabungan (mis. menjalankan NGINX dan Tomcat), Anda menyajikan konten melalui HTTP (EXPOSE 80 dan EXPOSE 443).

Dalam contoh terakhir Anda dapat berakhir dengan gambar yang mendokumentasikan diri sebagai mengekspos 8080, 8888, 80 dan 443 di mana hanya 80/443 yang relevan.

Ini adalah masalah nyata yang dibuktikan dengan fakta bahwa saya harus terus menjelaskan banyak hal kepada pengembang di komunitas kami meskipun dokumentasinya sangat spesifik; siapa yang butuh dokumentasi ketika Anda hanya bisa melihat gambarnya? <-- semua orang ketika gambar mendokumentasikan diri sendiri hal yang salah.

Ada solusi untuk masalah ini tetapi mereka adalah solusi. Apakah ini masalah arsitektur utama? Mengapa Docker tidak dapat mempertimbangkan solusi yang lebih elegan untuk masalah nyata ini.

Apa statusnya dalam hal ini?

Status @BillBrower adalah mereka menutup masalah tanpa memberikan alasan mengapa mereka percaya itu bukan masalah. Jelas bagi banyak dari kita itu terus menjadi masalah dunia nyata yang mengganggu kehidupan kita sehari-hari ;)

@modius @BillBrower meskipun ditutup, hal-hal selalu dapat dipertimbangkan kembali; pada dasarnya "tidak bersifat sementara", tetapi "ya selamanya" saat menggabungkan/mengimplementasikan fitur, jadi jika ada kekhawatiran tentang suatu fitur, pilihan yang tepat untuk pengelola adalah mengatakan "tidak".

PR yang mengimplementasikan ini ditutup karena ada pengelola yang tidak yakin dengan fitur tersebut, dan mencari contoh yang lebih aktual untuk penggunaannya; https://github.com/docker/docker/pull/8177#issuecomment -93587164

Kami menutup ini karena kami sebagian besar tidak setuju, tetapi jangan ragu untuk membuktikan bahwa kami salah di komentar dan kami dapat mempertimbangkan kembali

Itu lebih dari setahun yang lalu, jadi mungkin banyak hal telah berubah; Saya akan membuka kembali masalah ini, dan akan membahasnya di sesi pengelola berikutnya. (Perhatikan bahwa karena DockerCon dan rilis 1.12 yang tertunda, ini mungkin sedikit lebih lama dari biasanya)

Terima kasih, @thaJeztah. Itu sangat masuk akal. Saya menghargai Anda menjelaskan alasan di balik keputusan awal dan menguraikan apa yang Anda butuhkan untuk melihat apakah kami ingin ini terjadi.

Satu kasus penggunaan untuk permintaan _UNVOLUME_

Khususnya karena saat ini, ketika Anda menggunakan driver volume khusus, itu berlaku untuk SEMUA volume wadah yang diberikan.

Saya memiliki kasing dengan driver volume EFS: berfungsi dengan baik ketika saya menentukan pengikatan volume saat startup. Jika saya tidak menetapkan pengikatan apa pun, itu gagal karena mencoba memasang bagian NFS dari UUID yang dibuat secara otomatis. Ini berarti saya harus memberikan pengikatan ke semua volume saya, bahkan yang tidak saya pedulikan, yang dibuat oleh gambar induk misalnya.

Satu-satunya solusi saat ini adalah mengikat saat startup semua volume yang saya tidak perlukan ke subfolder kosong sampah dari bagian EFS yang sama.

Catatan: Saya tidak dapat menggunakan perintah volume buruh pelabuhan karena semua itu dimulai oleh Marathon dan harus dapat digunakan dalam satu perintah menjalankan buruh pelabuhan.

+1 UNEXPOSE diperlukan

+1 untuk UNEXPOSE

+1 untuk UNEXPOSE

+1 untuk UNEXPOSE

+100 untuk UNEXPOSE

+9000 untuk UNEXPOSE

+∞
Misalnya, saya menggunakan repositori resmi nginx (FROM nginx:stable) , yang berisi Dockerfile:

EXPOSE 80 443

Tapi saya ingin menghapus ke lapisan lain, port 80. Misal:

UNEXPOSE 80

Silahkan!
Tambahkan fitur ini!!!!

@frekele , jika saya adalah ibu atau ayahmu, kamu tidak akan mendapatkannya. tidak mungkin.

UNEKSPOSKAN +++
Fitur yang sangat diperlukan!

Tolong, Anda tidak perlu mengirim spam ke orang lain dengan pemberitahuan email dan Anda pasti tidak perlu mengacaukan diskusi dengan semua komentar '+1' ini. Anda dapat bereaksi dengan 👍 pada deskripsi masalah untuk menyatakan persetujuan Anda.

@underyx ini di luar
Lihat https://github.com/isaacs/github/issues/9#issuecomment -195120703 (seluruh utasnya bagus, tapi ini sekitar waktu GH menambahkan reaksi).
Sekarang mari kita tidak mengacaukan diskusi ;)
/offtopic .

Kami membahas masalah ini dalam pertemuan pengelola, dan secara umum, kami baik-baik saja untuk mulai mengerjakan ini lagi.

@duglin apakah Anda mungkin tertarik untuk mengerjakan ini?

Tidak tahu apakah saya punya waktu, tetapi hanya untuk meringkas.... berdasarkan komentar di atas, saya percaya persyaratannya adalah memastikan bahwa orang dapat menghapus/menghapus yang berikut:

EXPOSE  (all or specific one)
ENV  (specific - not sure we need to clear all yet)
LABEL  (ditto)
VOLUME  (all or just specific paths? probably both)
CMD  (possible but only using the json format)
ENTRYPOINT  (possible with json format)

Apakah saya melewatkan sesuatu?

+10000 untuk UNVOLUME

@duglin Saya pikir memulai dengan yang saat ini _tidak_ mungkin, dan yang paling banyak diminta adalah yang terbaik ( EXPOSE , VOLUME ). Saya belum melihat banyak permintaan untuk yang lain (tetapi tidak menentangnya).

PR asli menggunakan UNSET <SOMETHING> , tetapi kemudian diubah menjadi UN<SOMETHING> . Saya _secara pribadi_ menyukai yang pertama (lebih umum), tetapi @shykes lebih suka UN<SOMETHING> , tidak yakin apakah itu telah berubah.

UNVOLUME akan menyenangkan.

Kasus penggunaan saya: Saya menggunakan gambar mysql dan ingin mengkomit database saya yang terdapat dalam direktori /var/lib/mysql ke gambar baru tetapi tidak bisa karena itu dinyatakan sebagai volume di Dockerfile induk.

@thaJeztah menurut saya UNSET <something> lebih mudah dibaca dan tidak aneh; tidak perlu mulai menciptakan kata-kata. Ini juga akrab bagi orang-orang yang membuat skrip. Seseorang juga bisa melakukannya

UNSET  EXPOSE VOLUME LABEL

Contoh saya,

Saya sedang menyiapkan instalasi dokuwiki. Gambar yang saya pilih memperlihatkan semua volume konfigurasi potensial. Apa yang ingin saya lakukan adalah menyesuaikan instalasi saya dari gambar dasar ini. Karena volume terbuka, saya tidak dapat memodifikasi file konfigurasi PHP pada waktu pembuatan gambar.

Saya dapat memodifikasi gambar dasar untuk UNVOLUME volume tersebut tetapi kemudian saya harus mempertahankan gambar itu selamanya... keajaiban tentang menggunakan "terbaru" hilang :(

+1 untuk UNEXPOSE :)

+1 untuk UNVOLUME atau lebih baik lagi UNSET VOLUME.

+1 untuk UNVOLUME. Ini bisa berguna bagi saya sekarang. Juga bisa berguna dalam skenario universitas di mana siswa berputar tanpa khawatir harus memasang volume.

tanpa khawatir harus memasang volume.

Saya tidak berpikir itu akan diperlukan untuk itu; definisi VOLUME dalam Dockerfile secara otomatis membuat volume "anonim" dari konten di lokasi itu dalam gambar.

@duglin , apakah Anda sudah mengerjakan ini? Jika tidak, saya akan mengambilnya dan mulai dengan yang paling banyak diminta (VOLUME dan EXPOSE). Biarkan aku tahu.

@runcom lakukan - belum dapat menemukan waktu.

Sebagai pengingat, perhatikan bahwa perintah UNENV akan tetap berguna, untuk menghapus variabel lingkungan secara selektif (misalnya, untuk mencocokkan dengan volume yang UNVOLUME d pada waktu yang sama). Variabel yang tidak disetel tidak sama dengan variabel yang disetel ke kosong, terutama bila digunakan dengan set -ue di shell.

Dimungkinkan untuk menghapus VOLUME dan EXPOSE dari gambar resmi jika
mereka adalah masalah.

Pada 28 Jan 2017 21:23, "henryptung" [email protected] menulis:

Sebagai pengingat, perhatikan bahwa perintah UNENV akan tetap berguna, untuk
hapus variabel lingkungan secara selektif (misalnya, untuk mencocokkan dengan a
volume yang UNVOLUMEd pada waktu yang sama). Variabel yang tidak disetel bukan
sama dengan variabel yang disetel ke kosong, terutama bila digunakan dengan set -ue in
kerang.


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/docker/docker/issues/3465#issuecomment-275875623 , atau bisu
benang
https://github.com/notifications/unsubscribe-auth/AAdcPAKP1tii706MY-8MxVPSFLTFme8Dks5rW7HggaJpZM4BXt2-
.

+1 untuk UNVOLUME

+1 untuk UNVOLUME

Kasus penggunaan saya untuk UNVOLUME:

Menggunakan gambar perpustakaan/worpress dalam skenario S2I di mana sumber situs web disalin ke /var/www/html

VOLUME menekannya dengan memasang FS kosong pada gambar yang dihasilkan. -> perpustakaan/wordpress tidak dapat digunakan.

@groulot Sebenarnya jika Anda tidak memasang volume secara eksplisit dengan --volume di atasnya, konten gambar akan disalin ke volume saat pembuatan wadah.

Perintah docker run menginisialisasi volume yang baru dibuat dengan data apa pun yang ada di lokasi yang ditentukan dalam gambar dasar.

https://docs.docker.com/engine/reference/builder/#/volume

Ada solusi peretasan menggunakan docker save/load, lihat http://stackoverflow.com/q/42316614/808723

+1 untuk UNVOLUME

Saya ingin menggemakan alasan @modius untuk dapat UN-EXPOSE. Salah satu hal pertama yang diperhatikan pengembang saat mempelajari buruh pelabuhan adalah mengetik docker ps untuk melihat apa yang terjadi dengan wadah mereka. Mereka akan melihat port standar terdaftar sebagai tersedia. Pengembang terbiasa dengan port standar untuk hal-hal dari lingkungan lokal atau pengujian mereka yang telah mereka siapkan di dunia pra-Docker, jadi memperkenalkan Docker sulit karena mereka melihat port standar dan menganggapnya akan berfungsi -- tetapi sebenarnya mereka tidak terhubung ke wadah buruh pelabuhan.

+1 untuk UNVOLUME, UNEXPOSE, UNENV, ...

Sepertinya ini telah terbuka untuk sementara waktu. Ada daya tarik di sini?
Saya juga ingin menggunakan gambar alpine PHP fpm resmi dan soket UNIX alih-alih port TCP 9000.
Tidak dapat mengganti EXPOSE dari induknya, dan lebih suka tidak membangun image itu hanya untuk menghilangkan EXPOSE.

+1

+1

Akan menyukai kemampuan untuk menghapus perintah VOLUME. Gambar resmi Wordpress secara paksa membuang basis kode lengkapnya ke dalam volume -- Saya lebih suka hanya memiliki volume untuk direktori wp-content/uploads sehingga sisa basis kode dapat dimasukkan ke dalam gambar.

Saat menyebarkan gambar ke cluster kubernetes yang membatasi akses root, direktori VOLUME tidak dapat diakses, solusinya adalah menimpa volume yang ditentukan dalam gambar induk

+1 dari saya

Gunakan kasus untuk UNEXPOSE

Misalkan saya memiliki empat host buruh pelabuhan dan saya ingin menjalankan 16 wadah maven Tomcat yang semuanya default ke port internal 8080.

Sekarang bayangkan saya menggunakan registrator dengan rancher CNI - yang mengunci saya ke port internal.
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Ini berarti saya hanya dapat menjalankan satu port internal 8080 per host. (Karena saya harus melakukan pemetaan port 8080:8080)

Dalam situasi ini - pemetaan port internal-> eksternal buruh pelabuhan tidak cukup untuk menyelesaikan masalah saya. Saya sebenarnya perlu mengganti pemetaan port internal, lebih disukai tanpa membangun kembali wadah aslinya.

Julian, saya tidak tahu bagaimana Anda memiliki pemetaan 1 banding 1. Bagi saya pendaftar sebagai
tidak ada hubungannya dengan merutekan lalu lintas, itu hanya mendaftar dan membatalkan pendaftaran
menjalankan kontainer. Misalnya saya menggunakannya dengan cara yang akan dipertahankan oleh Registrator
instance Dll dengan menempatkan IP yang dialokasikan Docker dan port yang terbuka di
di sana. Kemudian menggunakan confd itu akan menonton instance Etcd dan memperbarui nginx
config dalam wadahnya sendiri.
Pada Sabtu, 17 Jun 2017 pukul 04:06, Julian Gamble [email protected]
menulis:

Gunakan kasus untuk UNEXPOSE

Misalkan saya memiliki empat host buruh pelabuhan dan saya ingin menjalankan 16 maven Tomcat
wadah yang semuanya default ke port internal 8080.

Sekarang bayangkan saya menggunakan registrator dengan rancher CNI - yang mengunci saya
ke port internal.
gliderlabs/registrator#541 (komentar)
https://github.com/gliderlabs/registrator/issues/541#issuecomment-305012416
Ini berarti saya hanya dapat menjalankan satu port internal 8080 per host. (Karena saya punya
untuk melakukan pemetaan port 8080:8080)

Dalam situasi ini - pemetaan port internal->eksternal buruh pelabuhan tidak cukup
untuk memecahkan masalah saya. Saya sebenarnya perlu mengganti pemetaan port internal,
sebaiknya tanpa membangun kembali wadah aslinya.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/moby/moby/issues/3465#issuecomment-309189149 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/ABrq2QGgY81wbePOBKbkTSjpUSoPIocuks5sE0LCgaJpZM4BXt2-
.

Hai Bradley,

Terima kasih telah melihat ini. Saya menggunakan registrator yang dikombinasikan dengan ipsecurity yang ada di dalam Rancher. Seperti yang Anda lihat dari tautan di sini:
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Kemampuan untuk melihat port eksternal di registrator dalam kontainer terjadwal peternak dibatasi. Ini berarti Anda hanya dapat menggunakan port internal.

Anda dapat melihat ada pengguna yang mulai gelisah mencari solusi di sini:
https://forums.rancher.com/t/do-you-kill-registrator/5152

Dan solusi yang diusulkan di sini:
https://github.com/cabrinoob/rancher-registrator
(Yang tidak layak untuk sebagian orang).

Anda mungkin menemukan lebih banyak jika Anda mencari di google "registrator rancher".

Mereka menyarankan Anda menjalankan registrator dalam mode 'internal' - di mana Anda memetakan port internal 1:1 ke port eksternal. Hal ini menyebabkan masalah dengan UNEXPOSE - kehabisan port internal dengan cepat.

Maksud saya adalah bahwa ipsecurity yang digunakan untuk jaringan wadah buruh pelabuhan intra-Host dapat menyebabkan kasus penggunaan di mana Anda terkunci ke port internal yang dipetakan 1:1 ke port eksternal di buruh pelabuhan. Untuk ini, Anda perlu memiliki perintah UNEXPOSE .

Terima kasih telah melihat ini.

Bersulang
Julian

3,5 tahun telah berlalu dan tidak ada kemajuan dalam masalah ini?...

+10086 untuk UNEXPOSE. terkadang gambar induk mungkin tidak resmi, menggunakan port tidak resmi, kita harus memiliki kemampuan untuk menimpa port.

@pumba-lt
Saya yakin alasan mengapa ini tidak melihat resolusi adalah, karena mereka tidak tahu bagaimana melakukannya secara teknis.

Itu juga menambah kerumitan pada bahasa Dockerfile ketika ada solusi yang jelas. Jangan terlalu memaksakan konfigurasi di Dockerfile induk dan tinggalkan if untuk gambar yang diwarisi sebagai gantinya. (alias: hentikan sumber gambar acak di hub buruh pelabuhan: D)

Sejak buruh pelabuhan 17.05 ada juga cara baru untuk melakukan pembangunan multi-tahap yang menghilangkan sebagian besar kebutuhan untuk masalah ini (ini adalah satu Dockerfile ):

# First import the original image
FROM nginx AS source-image

# Second step of the build, start with an empty image
FROM scratch
# Copy the data from the original image
COPY --from=source-image / /
# Re-define all the config
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]

EDIT: Lupa mengatakan, solusi kedua menghancurkan semua lapisan sebelumnya. Saya tidak berpikir itu masalah besar tapi bagus untuk diketahui.

@zimbatm - Itu luar biasa!

Saya yakin alasan mengapa ini tidak melihat resolusi adalah, karena mereka tidak tahu bagaimana melakukannya secara teknis.

Perubahannya sendiri tidak terlalu rumit; implementasi dapat ditemukan dalam PR ini; https://github.com/moby/moby/pull/8177. Tidak ada konsensus pada saat itu, tetapi jika Anda mengikuti komentar saya dari Januari; https://github.com/moby/moby/issues/3465#issuecomment -247405438, banyak hal berubah dan (kecuali orang berubah pikiran sejak itu), kami akan menerima kontribusi untuk menerapkan ini.

Seperti mengapa itu belum ada; hanya karena tidak ada yang punya waktu untuk mulai mengerjakannya, tetapi jika seseorang tertarik, kemungkinan besar akan diterima.

@zimbatm ya, contoh Anda akan menyelesaikan masalah langsung, perlu diketahui bahwa itu juga membuat lapisan yang berbeda, dan meratakan semua lapisan gambar. Meskipun hal ini dalam beberapa kasus dapat mengurangi ukuran gambar, ini juga mengakibatkan lapisan tersebut tidak lagi dibagikan dengan gambar yang menggunakan nginx sebagai induknya, sehingga dapat mengakibatkan lebih banyak gambar yang perlu diunduh. Sebagai contoh;

Gambar nginx asli:

$ docker inspect nginx -f '{{json .RootFS.Layers}}' | jq .

[
  "sha256:54522c622682789028c72c5ba0b081d42a962b406cbc1eb35f3175c646ebf4dc",
  "sha256:1c3fae42c5007fd0e70309b5b964eb5d49046562bd425424da734784098894e7",
  "sha256:87823f21b7939eac6e099fa878871a806c1904a7698793edb63bf6e5f5371e1f"
]

Dan gambar nginx yang Anda buat;

$ docker inspect nginx2 -f '{{json .RootFS.Layers}}' | jq .
[
  "sha256:9a71ba430225d4f24e0d57837a71b6b2b68bf88ca7530c0a89c98783c98531b5"
]

Terima kasih atas pembaruannya @thaJeztah

Bolehkah saya mengulangi saran saya untuk menggunakan

UNSET XXXX

bukannya menciptakan kata-kata kosa kata baru dan aneh (misalnya: UNVOLUME).

Kami juga dapat menghapus beberapa properti dalam satu baris dengan cara itu.

UNSET VOLUME EXPOSE LABEL

Saya pribadi baik-baik saja dengan melakukan UNSET melakukan satu atau yang lain mungkin tidak akan menjadi perubahan besar, jadi saya akan meninggalkan itu untuk proses peninjauan ketika PR tiba

Hai, bahkan Jika menggunakan FROM untuk kedua kalinya, bagaimana cara saya mempertahankan semuanya dari gambar induk tetapi kecuali untuk tidak mengekspos beberapa port yang terpapar pada gambar buruh pelabuhan induk? apakah ada resolusi resmi tentang ini, mari kita terima ini dan kerjakan atau tolak

mari kita terima ini dan kerjakan atau tolak

@rajiff lihat komentar saya di atas https://github.com/moby/moby/issues/3465#issuecomment -313549657 kontribusi dipersilakan

Perubahannya sendiri tidak terlalu rumit; implementasi dapat ditemukan dalam PR ini; #8177. Tidak ada konsensus pada saat itu, tetapi jika Anda mengikuti komentar saya dari Januari; #3465 (komentar), banyak hal berubah dan (kecuali orang berubah pikiran sejak itu), kami akan menerima kontribusi untuk menerapkan ini.

Jadi jika konsensus mungkin telah berubah, mengapa tidak membuka kembali #8177 ?

Jadi jika konsensus mungkin telah berubah, mengapa tidak membuka kembali #8177 saja?

PR itu dibuka lebih dari tiga tahun lalu; kode tidak lagi berlaku

Alih-alih harus secara khusus menggunakan perintah UNsomething,
mengapa tidak meningkatkan perintah FROM dan memungkinkan untuk membuat daftar apa yang sebenarnya ingin kita warisi?

Kita bisa menggunakan sesuatu seperti:
DARI gambar dasar (VOLUME, EXPOSE, PORT, ..)
atau jika Anda benar-benar menginginkannya dengan negasi:
DARI gambar dasar (*, -VOLUME, -EXPOSE)
atau memiliki sintaks yang lebih baik ;)

Tampaknya bagi saya bahwa semua ini harus menjadi bagian dari perintah FROM sejak awal.

Mengubah volume dari dalam Dockerfile: Jika ada langkah build yang mengubah data di dalam volume setelah dideklarasikan, perubahan tersebut akan dibuang.

Itu tampaknya tidak sepenuhnya benar. Anda masih dapat melakukan ini:

VOLUME /avolume/subdir
WORKDIR /avolume
COPY ./Dockerfile /avolume/subdir

Saya tidak tahu apakah itu bisa digunakan untuk membatalkan volume.

Mengganti gambar induk/wadah ENTRYPOINT tidak berfungsi di versi terbaru.

17.09.1-ce versi

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

sejak versi 17.10.0-ce

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[/bin/bash]

UNSET ENTRYPOINT juga tidak berfungsi.
Apakah itu bug?

@alexey-igrychev dapatkah Anda membuka masalah terpisah untuk itu? Masalah yang Anda komentari adalah _permintaan fitur_ untuk mengimplementasikan instruksi UNSET xx di Dockerfile. (Instruksi UNSET belum diimplementasikan, jadi itu yang diharapkan.)

Sebagai solusi untuk masalah itu, menggunakan [""] alih-alih [] untuk titik masuk tampaknya berhasil;

IMAGE=$(docker commit -c "ENTRYPOINT [\"\"]" experiment)
docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

Saya juga membutuhkan cara untuk menghapus volume, sehingga saya dapat membuat gambar database yang dimuat dengan tabel dan data.
Sayangnya, gambar dasar bersifat pribadi (Oracle) dan oleh karena itu saya bahkan tidak dapat menyalin file docker dasar karena saya tidak memiliki akses ke sana. Saya hanya bisa memperpanjang gambar.
Masalah ini memiliki banyak +1 dan kasus penggunaan dunia nyata yang terdaftar, dan ada beberapa PR yang dibuat untuk itu, namun PR telah ditutup. Jadi apa yang perlu kita lakukan untuk mendapatkan fitur ini?

@veqryn sejak membuka kembali masalah ini, tidak ada yang mulai mengerjakan permintaan tarik; permintaan tarik yang ada tidak lagi berlaku bersih pada basis kode sehingga yang baru harus dibuka; jika ada yang tertarik untuk mengerjakan ini, maka semuanya bisa berjalan lagi.

Lihat komentar saya sebelumnya; https://github.com/moby/moby/issues/3465#issuecomment -247405438

Kami membahas masalah ini dalam pertemuan pengelola, dan secara umum, kami baik-baik saja untuk mulai mengerjakan ini lagi.

@duglin apakah Anda mungkin tertarik untuk mengerjakan ini?

Dan https://github.com/moby/moby/issues/3465#issuecomment -313549657

Seperti mengapa itu belum ada; hanya karena tidak ada yang punya waktu untuk mulai mengerjakannya, tetapi jika seseorang tertarik, kemungkinan besar akan diterima.

Kasus penggunaan saya berasal dari docker-compose.yaml: Saya ingin memiliki file penulisan untuk pengembangan dengan penggantian untuk produksi yang menambahkan proxy-balik TLS, repositori Maven, mengambil alih PORT 80/443, membuka port 80 dan 5432 itu file penulisan pengembangan terekspos. Atau file penulisan untuk produksi dengan penggantian pengembangan.

Sifat tambahan dari file penulisan layering yang diwarisi dari Dockerfiles memperumit desain sistem. Akan sangat keren jika beberapa parameter dapat ditarik kembali, atau jika saya hanya membuat wadah berbeda yang dibuat dengan penggantian aktif. Saya tidak pilih-pilih cara kerjanya di bawah tenda wrt docker-compose.

Terima kasih @thaJeztah - bisakah Anda mengarahkan kami ke baris kode yang menurut Anda adalah tempat untuk mulai membaca untuk melihat memperbaikinya dengan permintaan tarik?

Saya sendiri belum banyak mengerjakan kode builder, tetapi perubahan kemungkinan harus ada di paket https://github.com/moby/moby/tree/master/builder .

Masalah ini memiliki 3 tahun! Apakah sangat sulit untuk menyetujui fitur yang sangat mendasar, atau apakah saya melewatkan sesuatu?

@caruccio ya, Anda melewatkan sesuatu: gulir ke atas 4 komentar https://github.com/moby/moby/issues/3465#issuecomment -356988520

Saya juga memiliki beberapa kasus penggunaan (satu proyek pribadi, dan yang kedua proyek kerja) di mana saya ingin membebani pernyataan VOLUME , EXPOSE dan ENTRYPOINT dari a gambar orang tua.

Sementara saya memiliki solusi untuk ENTRYPOINT hanya dengan menetapkan titik masuk kosong baru dengan ENTRYPOINT [] , dan mungkin dapat belajar hidup dengan mengabaikan EXPOSE , ... Saya dibiarkan menggaruk kepala saya tentang bagaimana tidak mewarisi definisi VOLUME .

Saya baru saja menemukan masalah ini di basis kode saya di mana gambar induk memiliki VOLUME, yang berarti semua perubahan saya pada volume ini dalam gambar anak dibuang. Saya pikir saya akan gila selama 2 hari sampai akhirnya saya menemukan jalan untuk masalah ini. Tolong bisakah seseorang mengimplementasikan ini.

Ada SOLUSI.

Anda selalu dapat docker save image -o image.tar , membongkar arsip itu, mengedit metadata, dan mengemas ulang untuk docker load -i image2.tar . Dengan cara itu seseorang dapat membuat image2 yang tidak memiliki deklarasi VOLUME sebelumnya di dalamnya.

Karena saya harus melakukan langkah-langkah itu secara teratur, saya telah membuat skrip kecil untuk membantu tugas membersihkan gambar pihak ketiga. Lihat docker-copyedit

Kerja yang fantastis @gdraheim ! Solusi yang bisa diterapkan dalam <250 baris python.

@gdraheim wow, ini bagus! Dari README:

Keinginan untuk MENGHAPUS SEMUA VOLUME berasal dari fakta bahwa saya memang ingin mengunduh gambar yang diuji untuk pengujian lokal di mana bagian data harus dikomit ke riwayat juga untuk mengembalikan program dan data ke keadaan yang ditentukan sehingga yang lain uji coba akan dimulai dari pos pemeriksaan yang sama persis.

Ini adalah kasus penggunaan kami juga.

Saya telah memperluas docker-copyedit untuk mencakup semua entri metadata dari suatu gambar, sehingga dapat bekerja pada semua properti yang diwariskan bahkan di luar kasus bermasalah dari daftar EXPOSE dan VOLUME. Itu akan menjadi pengguna, workingdir, label, pengaturan env untuk hal-hal yang sering terlihat. Menyalin ENTRYPOINT ke CMD juga merupakan modifikasi yang saya lakukan cukup teratur. Tidak perlu lagi membuat langkah docker-build perantara, cukup gunakan docker-copyedit . ;)

Waktu yang digunakan oleh tim Docker untuk melacak dan berulang kali mengabaikan masalah ini mungkin sudah cukup untuk memperbaikinya.

Bisakah sekarang kami membuka kembali ini setelah jelas-jelas banyak pengguna yang meminta ini...
atau setidaknya berikan argumen yang masuk akal untuk menentangnya tidak hanya mengabaikan semua kasus penggunaan (saya ingin membuka port juga dan hanya untuk mendapatkan output docker ps yang lebih bersih tanpa sialan (80/80/tcp) sebelum saya akan membangun gambar saya sendiri .. .. (yang lebih sulit untuk Dockerfiles non opensource)

Masalah ini masih terbuka; Ini sumber terbuka; kontribusi dipersilakan https://github.com/moby/moby/issues/3465#issuecomment -356988520

Apakah saya benar berpikir bahwa ini akan diperbaiki di moby/buildkit sekarang? Saya melihat sebagian besar infrastruktur perintah Dockerfile di sana.

Saya juga penggemar UNSET , seperti

UNSET EXPOSE 9000

atau

UNSET LABEL foo

Jadi, saya melihat perintah yang memiliki bentuk sub-perintah, seperti formulir HEALTHCHECK CMD dan saya perhatikan bahwa HEALTHCHECK sudah memiliki bentuk yang tidak disetel...

HEALTHCHECK NONE

Ini adalah pilihan yang menarik, tetapi HEALTHCHECK juga hanya mendefinisikan 1 konfigurasi (dan menimpa w/ yang terbaru), tidak memungkinkan mendefinisikan beberapa, seperti LABEL , EXPOSE , dan VOLUME lakukan.

Saya hanya ingin tahu bagaimana ini harus berinteraksi atau apakah ada semacam formulir NONE yang mungkin berfungsi.

Beberapa cara untuk menghapus port yang terbuka sangat diperlukan untuk mengontrol apa yang terbuka saat menggunakan jaringan host.

+1 PANJANG []

Jadi .... selama 5 tahun tim Docker tidak dapat mengimplementasikan operator UNSET, fantastis

Seperti yang dikatakan @AnthonyMastrean , haruskah kita memindahkan masalah ini ke proyek moby/buildkit ?

Ada juga PR, didokumentasikan dan diuji dengan baik tetapi tidak digabungkan, haruskah kami memindahkan/mengubah basis PR ini juga?

Fitur ini akan sangat dihargai dan mengatasi masalah dengan gambar berbasis nginx di Azure.

UNSET , CLEAR , RESET , OVERRIDE , IGNORE akan baik-baik saja - Saya akan menghindari UNxxx karena itu akan menduplikasi daftar kunci yang dicadangkan untuk mendukung dan mendokumentasikan.

Apa yang harus diabaikan/direset juga dapat ditentukan saat menggunakan FROM , misalnya

FROM nginx:1.13 IGNORE EXPOSE, ENTRYPOINT

Saya menyarankan satu solusi lagi, menggunakan build multistage.
Ini akan menyalin semua file dari gambar asli ke gambar baru, tetapi tanpa metadata.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Aku tidak percaya aku tidak memikirkan itu. Itu sebenarnya cukup bagus @kotofos. Anda kehilangan lapisan wadah hulu, tapi itu bukan kerugian besar.

@kotofos Mengapa tidak FROM scratch as postgres ?

@farcaller tangkapan yang bagus. awal pasti akan lebih baik karena Anda menimpa seluruh sistem file

Terakhir saya mengujinya, COPY --from=xxx ... tidak akan mempertahankan sistem file
kepemilikan, jadi Anda mungkin ingin berhati-hati dengan solusi itu.

@tianon Anda benar, meskipun untuk wadah proses tunggal ini seharusnya tidak menjadi masalah karena Anda dapat menggunakan tanda --chown untuk mengatur pengguna yang Anda jalankan seperti dalam wadah

https://docs.docker.com/engine/reference/builder/#copy

Tanggal ini kembali ke tahun 2014. Sudah 5 tahun dan sepertinya tidak akan ada "tidak disetel" atau "setel ulang" generik untuk semua properti dalam waktu dekat. Saya juga menyukai pendekatan umum tetapi ada banyak hal yang perlu dipertimbangkan dan sungguh: itu tidak akan terjadi dalam waktu dekat.

Jadi: bisakah kita setidaknya mendapatkan "UNEXPOSE" untuk menutup semua port yang terbuka atau mendapatkan setidaknya perilaku yang sama seperti untuk CMD dan ENTRYPOINT (yang terakhir menang)? Ini adalah properti "tidak disetel" yang paling banyak diminta dan risiko keamanan potensial bagi pengguna yang tidak mengetahui perilaku (tidak intuitif), mengingat perilaku "yang terakhir menang" dari perintah lain.

Saya menyarankan satu solusi lagi, menggunakan build multistage.
Ini akan menyalin semua file dari gambar asli ke gambar baru, tetapi tanpa metadata.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Saya ingin mengabaikan volume buruh pelabuhan yang ditunjuk oleh PGDATA sehingga saya dapat membuat isinya dibundel dengan gambar dan bukan sebagai volume.
Solusi yang lebih ringan bagi saya hanyalah mengubah nilai PGDATA :

FROM postgres:11.2-alpine
ENV PGDATA /var/lib/postgresql/test-data

# stuff that will create all my schemas
COPY create-scripts /docker-entrypoint-initdb.d/

# a weird way to trigger the entrypoint script to run the stuff in docker-entrypoint-initdb.d but not hang after starting postgres
RUN /docker-entrypoint.sh postgres --version

Apakah ada manfaat memiliki EXPOSE dan VOLUME di dockerfiles sama sekali? Lagi pula, Anda dapat mendefinisikannya dengan mudah dalam docker run (dan dalam file docker-compose ), dengan --expose (atau -p ) dan bernama volume atau bind mount. Saya digigit karena mereka lebih dari sekali dan tidak ada cara untuk meresetnya (membuat file docker baru tidak banyak berguna, khususnya ketika memperluas gambar resmi atau gambar yang dibuat dengan makefile). Saya melihat mereka sebagai anti-pola dan saya pikir akan lebih baik untuk mencela mereka.

@lucasbasquerotto EXPOSE digunakan oleh alat seperti gitlab-runner untuk mendeteksi apakah port yang dinyatakan terekspos oleh gambar benar-benar terbuka atau tidak. Saya setuju bahwa ini seharusnya lebih merupakan tugas HEALTHCHECK untuk mendeteksi apakah wadah sudah siap atau tidak, tetapi memiliki daftar port yang dideklarasikan memang dapat berguna untuk otomatisasi.
VOLUME diperlukan untuk memberikan pengalaman yang ramah pengguna untuk menghentikan/memulai wadah dan menyimpan data secara otomatis. Sekali lagi, saya pikir ini dapat diselesaikan dengan cara lain tetapi memiliki data yang dapat diperiksa baik untuk perkakas (dan juga untuk manusia dalam kasus ini).

ps tidak membela sintaks Dockerfile, saya hanya menunjukkan bahwa anti-pola tidak disebabkan oleh kata kunci itu sendiri melainkan karena ekosistem tidak bergerak maju untuk menyelesaikan masalah yang mungkin muncul dalam kasus penggunaan umum seperti ini, atau seperti menyediakan gambar dengan volume yang dideklarasikan dan beberapa data awal dalam volume (misalnya gambar mysql dengan skema yang dimuat sebelumnya)

@zarelit Saya tidak tahu persis bagaimana gitlab-runner bekerja, tapi saya pikir harus ada cara untuk menentukan port yang akan diperiksa di luar Dockerfile (saya menemukan masalah yang mungkin karena itu, karena MySQL mengekspos 2 port tetapi seharusnya hanya memeriksa port 3306: https://gitlab.com/gitlab-org/gitlab-runner/issues/4143 . Dari apa yang saya lihat, itu juga hanya menggunakan port terbuka dari Dockerfile terakhir.

Tentang VOLUME , Anda dapat mempertahankan data stateful menggunakan volume bernama atau memasangnya dengan -v ke direktori yang ada (jika Anda ingin menyimpan data saat membuat ulang conainer). Saya juga berpikir akan lebih baik menggunakan pendekatan ini karena VOLUME di dalam dockerfile agak tidak jelas bagi siapa pun yang memperluas dockerfile itu, dan jika Anda tidak tahu itu ada di sana, Anda mungkin berpikir bahwa wadah Anda dapat direproduksi di lingkungan yang berbeda dan Anda dapat mengubah versi tanpa efek samping, hanya untuk digigit nanti karena menggunakan data persisten di bawah tenda.

Itu juga tidak memungkinkan Anda untuk memindahkan file ke direktori itu selama pembangunan (dengan asumsi Anda tidak ingin menggunakannya sebagai volume, tetapi mewarisi Dockerfile yang mendefinisikan direktori sebagai volume, seperti wordpress yang mendefinisikan /var/www/html/ sebagai VOLUME, dan saya perlu menggunakan beberapa peretasan untuk menggunakan direktori lain).

Menggunakan -v Anda menyatakan secara eksplisit bahwa Anda menginginkan volume dan menghindari kejutan yang tidak diinginkan karena sihir hitam VOLUME di Dockerfile.

Juga, itu mungkin berakhir dengan membuat banyak volume anonim:

Mendefinisikan volume di dalam gambar memberi tahu buruh pelabuhan untuk menyimpan data ini secara terpisah dari wadah lainnya, bahkan jika Anda tidak menentukan volume saat memutar wadah. Cara Docker menyimpan data ini adalah dengan membuat volume lokal tanpa nama. Nama itu sendiri adalah string id unik panjang yang tidak berisi referensi ke gambar atau wadah yang dilampirkannya. Dan kecuali Anda secara eksplisit memberi tahu buruh pelabuhan untuk menghapus volume saat Anda menghapus wadah, volume ini tetap ada, tidak mungkin digunakan lagi

Sumber: https://boxboat.com/2017/01/23/volumes-and-dockerfiles-dont-mix/

@lucasbasquerotto Saya sebagian besar setuju dengan Anda, ada semua masalah lama, saya pikir penghentian harus mengikuti jalur di mana mereka tidak menjadi tidak valid, mereka menjadi informatif seperti ... jalur yang disarankan yang dapat Anda ubah dalam volume, menyarankan port yang dapat didengarkan oleh server.

Saya pikir bagian yang baik dari perjalanan Docker sekarang telah diekstraksi ke dalam standar OCI dan dengan demikian kita harus menulis alat baru yang tidak memiliki semua warisan ini di pundak.

Bagi siapa saja yang merasa berguna, jangan ragu untuk menggunakan gambar buruh pelabuhan tugboat.qa . Mereka adalah ekstensi dari beberapa gambar buruh pelabuhan resmi dengan volume yang dihapus. Repositori GitHub yang didokumentasikan secara minimal di sini tempat pengangkatan berat dilakukan: https://github.com/TugboatQA/images

Apakah ada manfaat memiliki EXPOSE dan VOLUME di dockerfiles sama sekali? Lagi pula, Anda dapat mendefinisikannya dengan mudah dalam docker run (dan dalam file docker-compose ), dengan --expose (atau -p ) dan bernama volume atau bind mount. Saya digigit karena mereka lebih dari sekali dan tidak ada cara untuk meresetnya (membuat file docker baru tidak banyak berguna, khususnya ketika memperluas gambar resmi atau gambar yang dibuat dengan makefile). Saya melihat mereka sebagai anti-pola dan saya pikir akan lebih baik untuk mencela mereka.

Banyak vendor saat ini menyediakan aplikasi mereka sebagai image container sederhana dan menyediakan file docker bersamanya.
Memiliki EXPOSE dan VOLUME dalam file tersebut memungkinkan penggunaan aplikasi sederhana dengan docker run di direktori aplikasi. Anda tidak perlu tahu apa pun tentang parameter apa yang diharapkan aplikasi, ini berfungsi dengan semua default yang disediakan di file docker.
Jadi ya: sementara kami memiliki senjata yang lebih baik dan lebih besar seperti compose atau k8s untuk aplikasi kompleks untuk aplikasi sederhana, dockerfiles aplikasi lokal masih sangat cocok. Dan memiliki default yang berfungsi membuat penggunaan menjadi nyaman.

@ m451 Docker run yang lebih pendek mungkin lebih disukai daripada yang lebih lama (dengan lebih banyak opsi yang ditentukan), tetapi saya tidak menganggap itu argumen yang baik untuk mengekspos port dan volume di dockerfile.

Alih-alih docker run some_image Anda dapat dengan mudah menjalankan docker run --expose 3000 -v my_volume:/container/dir some_image dan memiliki pemahaman yang jelas tentang port yang diekspos ke host dan volume yang akan tetap ada bahkan setelah penampung dihancurkan.

Juga, ini adalah hal sepele untuk dilakukan , dan Anda mengekspos dan memetakan volume hanya ketika Anda perlu (mungkin Anda tidak perlu semua port diekspos di dockerfile, atau semua volume ditentukan. Jika memang penting untuk mengekspos beberapa port atau gunakan beberapa volume, lebih baik untuk mendokumentasikannya di repositori sehingga orang tidak hanya tahu apa yang perlu diekspos atau dipetakan, tetapi mengapa, bagaimanapun juga, ini adalah sesuatu yang akan memengaruhi bagian luar wadah, dan dapat bertahan setelahnya wadah hancur).

Jika ada di dockerfile, itu mungkin benar-benar mempersulit untuk mengetahui apa yang terjadi dan menyebabkan kejutan tak terduga dalam jangka panjang ketika volume bertahan dan Anda tidak tahu (terutama jika dockerfile diwarisi dari yang lain, Anda mungkin tidak tahu sebelumnya bahwa volume ditentukan kecuali Anda memeriksa lebih dalam apa fungsinya). Jadi saya akan menganggap VOLUME dan EXPOSE buruk bahkan jika masalah ini diselesaikan.

Selain itu, sementara masalah ini tidak terpecahkan (dan saya tidak tahu berapa tahun yang diperlukan untuk menyelesaikannya, mengingat itu dibuka selama lebih dari 5 setengah tahun) maka saya TIDAK ADA CARA untuk mengatur ulang mereka .

Apakah ada manfaat memiliki EXPOSE dan VOLUME di dockerfiles sama sekali? Lagi pula, Anda dapat mendefinisikannya dengan mudah dalam docker run (dan dalam file docker-compose ), dengan --expose (atau -p ) dan bernama volume atau bind mount. Saya digigit karena mereka lebih dari sekali dan tidak ada cara untuk meresetnya (membuat file docker baru tidak banyak berguna, khususnya ketika memperluas gambar resmi atau gambar yang dibuat dengan makefile). Saya melihat mereka sebagai anti-pola dan saya pikir akan lebih baik untuk mencela mereka.

Banyak vendor saat ini menyediakan aplikasi mereka sebagai image container sederhana dan menyediakan file docker bersamanya.
Memiliki EXPOSE dan VOLUME dalam file tersebut memungkinkan penggunaan aplikasi sederhana dengan docker run di direktori aplikasi. Anda tidak perlu tahu apa pun tentang parameter apa yang diharapkan aplikasi, ini berfungsi dengan semua default yang disediakan di file docker.
Jadi ya: sementara kami memiliki senjata yang lebih baik dan lebih besar seperti compose atau k8s untuk aplikasi kompleks untuk aplikasi sederhana, dockerfiles aplikasi lokal masih sangat cocok. Dan memiliki default yang berfungsi membuat penggunaan menjadi nyaman.

Saya berpendapat bahwa vendor yang melakukan itu, melakukannya karena ketidaktahuan. Tidak memahami masalah ini menyebabkan orang-orang yang ingin menggunakan produk mereka di lingkungan produksi. Tentu itu memudahkan seseorang untuk membuat contoh uji/demo produk. Tetapi sekarang, jika saya ingin menjalankannya secara nyata, saya harus git clone/sed Dockerfile mereka atau buat sendiri hanya untuk mendapatkan gambar yang berfungsi.

@ m451 Docker run yang lebih pendek mungkin lebih disukai daripada yang lebih lama (dengan lebih banyak opsi yang ditentukan), tetapi saya tidak menganggap itu argumen yang baik untuk mengekspos port dan volume di dockerfile.

Alih-alih docker run some_image Anda dapat dengan mudah menjalankan docker run --expose 3000 -v my_volume:/container/dir some_image dan memiliki pemahaman yang jelas tentang port yang diekspos ke host dan volume yang akan tetap ada bahkan setelah penampung dihancurkan.

Juga, ini adalah hal sepele untuk dilakukan , dan Anda mengekspos dan memetakan volume hanya ketika Anda perlu (mungkin Anda tidak perlu semua port diekspos di dockerfile, atau semua volume ditentukan. Jika memang penting untuk mengekspos beberapa port atau gunakan beberapa volume, lebih baik untuk mendokumentasikannya di repositori sehingga orang tidak hanya tahu apa yang perlu diekspos atau dipetakan, tetapi mengapa, bagaimanapun juga, ini adalah sesuatu yang akan memengaruhi bagian luar wadah, dan dapat bertahan setelahnya wadah hancur).

Jika ada di dockerfile, itu mungkin benar-benar mempersulit untuk mengetahui apa yang terjadi dan menyebabkan kejutan tak terduga dalam jangka panjang ketika volume bertahan dan Anda tidak tahu (terutama jika dockerfile diwarisi dari yang lain, Anda mungkin tidak tahu sebelumnya bahwa volume ditentukan kecuali Anda memeriksa lebih dalam apa fungsinya). Jadi saya akan menganggap VOLUME dan EXPOSE buruk bahkan jika masalah ini diselesaikan.

Selain itu, sementara masalah ini tidak terpecahkan (dan saya tidak tahu berapa tahun yang diperlukan untuk menyelesaikannya, mengingat itu dibuka selama lebih dari 5 setengah tahun) maka saya TIDAK ADA CARA untuk mengatur ulang mereka .

Sepakat. Jadi mari kita definisikan cara standar untuk mengomunikasikan parameter apa yang diperlukan.
Jika tidak ada, kami hanya akan berakhir dengan kekacauan yang sama seperti yang kami alami di aplikasi lawas: dokumen khusus vendor dan format dokumentasi. Beberapa memberi tahu Anda port apa yang harus dibuka, beberapa tidak. Beberapa hanya memberi tahu Anda setengahnya, beberapa memberi tahu Anda port yang salah. Beberapa hanya memberi tahu Anda nomor port tetapi tidak protokol dan sebagainya.

Dockerfiles telah menjadi cara yang bagus untuk membakukan kekacauan itu.

@ m451 Saya setuju dengan Anda dalam hal itu, tetapi ada baiknya untuk mempertimbangkan bahwa hanya mengekspos port tidak menyampaikan informasi yang berguna. Jenis data/koneksi apa yang diharapkan oleh port yang terbuka? Jika ada beberapa port, apa yang dilakukan setiap port?

Jika Anda ingin mempertahankan data yang Anda inginkan untuk dipasang ke volume bernama atau ke beberapa lokasi di host, VOLUME tidak membantu dengan itu. Jika Anda ingin data sementara disimpan dengan kinerja yang lebih baik, maka VOLUME membantu (ini adalah satu-satunya kasus di mana VOLUME mungkin membantu). Menulis di wadah lebih lambat karena menggunakan strategi copy on write . Tetapi sekali lagi, memetakan volume pada docker run menghindari CoW juga (Anda tidak perlu VOLUME), satu-satunya downside adalah bahwa instruksi Anda lebih panjang dan Anda perlu mengetahui jalurnya (tetapi ini hanya jika Anda mengalami penurunan kinerja karena ke KK).

Menggunakan VOLUME dan EXPOSE sebagai jenis dokumentasi tidak membenarkan buruk (atau kurang dari) dokumentasi. Dan itu juga dapat (dan mungkin akan) merugikan beberapa konsumen citra tersebut.

@ m451 Saya setuju dengan Anda dalam hal itu, tetapi ada baiknya untuk mempertimbangkan bahwa hanya mengekspos port tidak menyampaikan informasi yang berguna. Jenis data/koneksi apa yang diharapkan oleh port yang terbuka? Jika ada beberapa port, apa yang dilakukan setiap port?

Benar. Ide lubang port dari detik. perspektif sudah ketinggalan zaman. Namun: di sini kami mencoba untuk menentukan port apa yang perlu dibuka dan port apa yang dapat tetap ditutup dan untuk memahami data apa yang dipertukarkan di setiap port. HTTPS telah menjadi pembungkus untuk hampir semua hal hari ini dan selain pembuat kode biasanya tidak ada seorang pun yang tahu persis data apa yang ditransfer melalui port tertentu. Dan bahkan itu mungkin berubah dengan setiap pembaruan.

Di RL Anda tidak peduli tentang data / informasi apa yang diangkut melalui port apa selain Anda akhirnya memecahkan masalah aplikasi. Anda memutuskan untuk mempercayai aplikasi tersebut. Jadi jika aplikasi membuka port X dan Y maka Anda mempercayainya juga.
Untuk standar, operasi harian, ada baiknya untuk memulai aplikasi dan itu bekerja di luar kotak (diasumsikan default yang aman).
Wadah telah menjadi bentuk aplikasi pengemasan untuk membuatnya bekerja di luar kotak.

Yang mengatakan saya setuju bahwa dokumen yang baik itu penting. Namun di RL tidak ada yang mau membaca dokumen berjam-jam hanya untuk mengetahui port apa yang harus dibuka. Itu tidak membawa manfaat apa pun untuk tugas operasi harian.

Potongan kue saya.

Menggunakan VOLUME di Dockerfile tidak ada UNVOLUME , atau menghilangkannya sama sekali , saya tidak dapat mengubah _apa pun_ yang terkait dengan folder yang ditentukan. Ini kurang dari ideal, terutama ketika Anda sadar akan ingin menentukan UID tertentu, gambar harus dijalankan sebagai , untuk menghindari pengguna acak, dengan izin lebih dari yang diperlukan, menjalankan perangkat lunak di host Anda.

Seharusnya ada cara untuk mengganti arahan VOLUME ini saat memperluas gambar untuk penyesuaian pengguna. Satu-satunya solusi saya saat ini adalah membuat ulang gambar sendiri sepenuhnya, menjadikan seluruh _Dockerfile FROM_ dinamis tidak berguna.

DARI nginx:terbaru
setelah di-deploy ke heroku, port 80 terekspos oleh nginx, tapi itu tidak diizinkan oleh heroku, jadi apa yang bisa saya lakukan? salin semua dockerfile dari nginx dan hapus EXPOSE 80?

Saya tidak akan menulis yang baru... tetapi akan sangat menyenangkan untuk mengesampingkan direktif EXPOSE.

Berbagi ini - https://github.com/gdraheim/docker-copyedit/blob/master/docker-copyedit.py (bukan kreasi saya, untuk lebih jelasnya, terima kasih @gdraheim!)

Ini membantu saya menghapus volume dari wadah postgres yang disetel di dockerfile dengan perintah:

python docker-copyedit.py FROM postgres:11.5-alpine INTO postgres:11.5-alpine remove volume /var/lib/postgresql/data

Tampaknya telah melakukan pekerjaan tanpa merusak wadah, mengambil gambar asli, mengadaptasinya, membuat gambar baru tanpa volume (sesuai dengan docker inspect dijalankan pada wadah yang dibuat dari gambar yang disesuaikan), bukan menggunakannya untuk hal lain selain git README memungkinkan untuk berbagai operasi, yaitu

 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     REMOVE PORT 4444
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove port ldap and rm port ldaps
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove all ports
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     add port ldap and add port ldaps

LABEL adalah 'properti' lain (belum disebutkan) yang dapat menggunakan kemampuan untuk 'tidak disetel'

Seperti yang disebutkan dalam posting SO ini: https://stackoverflow.com/questions/50978051/how-do-i-unset-a-docker-image-label

Kasus penggunaan lain untuk mengatur ulang / menghapus VOLUME dari gambar upstream:

Saya sedang berupaya memperluas gambar basis data Oracle tetapi memiliki volume pada /opt/oracle/oradata . Dalam gambar oracle default, database dibuat pada startup kontainer dan menulis ke volume itu. Namun hal tersebut menyebabkan container membutuhkan waktu 25 menit untuk start pertama yang tidak dapat diterima. Jadi saya sedang mengerjakan gambar di mana database dibuat pada pembuatan gambar tetapi untuk itu saya harus menghapus VOLUME /opt/oracle/oradata karena database saya dibuat tetapi ketika saya memulai wadah, sistem file /opt/oracle/oradata kosong lagi dan database saya gagal untuk memulai.

Saya sedang berupaya memperluas gambar database Oracle tetapi memiliki volume pada /opt/oracle/oradata .

Persis kasus penggunaan saya juga. Saya ingin membuat database pluggable yang telah dialokasikan sebelumnya yang dapat ditarik orang lain dari registri buruh pelabuhan pribadi kami ... tetapi volumenya hilang. Saya harus menggali lebih dalam dan memutuskan solusi yang paling tidak jelek.

Saya telah menyelesaikannya sebagai berikut:

Saya telah menggunakan docker-copyedit untuk menghapus volume, kemudian saya telah menulis skrip bash untuk membuat database (Anda dapat melihat skrip startup dari Oracle untuk melihat bagaimana hal itu dilakukan). Sekarang dengan PDB yang telah dikonfigurasikan, hanya dibutuhkan 25 detik untuk meluncurkan wadah dari gambar. Tapi gambar menjadi sangat besar.

Apakah pendekatan yang lebih baik adalah dengan memperluas spesifikasi buruh pelabuhan yang ada untuk memasukkan konsep variabel env yang lengket/opsi override, seperti;

misalnya proyek saya berdasarkan gambar Tomcat hulu:

--ENV CATALINA_HOME /beberapa/lainnya/jalur
DARI kucing jantan:8.5.54-jdk8-openjdk
...

Di mana ENV dideklarasikan dengan -- ENV harus dinaikkan ke status lengket dan mempertahankan nilai yang dideklarasikan / menimpa nilai apa pun yang ditemukan untuk variabel ini nanti dalam rantai pemrosesan Dockerfile.

--ENV = dari titik ini ke depan di Dockerfile.

Oleh karena itu, ini dapat digunakan di awal Dockerfile jika Anda ingin itu didahulukan daripada pertemuan lebih lanjut dari variabel yang sama seperti di build multistage. Juga akan memungkinkan fleksibilitas tergantung di mana di Dockerfile itu ditempatkan untuk referensi yang lebih tinggi dalam file untuk menjadi independen.

Tidak akan memerlukan UNVOLUME karena pendekatan yang benar adalah agar VOLUME dideklarasikan dengan referensi ENV yang dapat ditimpa orang lain.

misalnya

ENV PROJ_VOL /beberapa/jalur
VOLUME $PROJ_VOL

Sepertinya ENTRYPOINT [] dan ENTRYPOINT [""] keduanya membatalkan cache pada setiap build saat tidak menggunakan BuildKit. Dockerfile untuk didemonstrasikan:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT []

RUN echo "HERE!"

Langkah 2 dan 3 akan _tidak pernah_ menggunakan cache. Ini adalah solusi saya:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT ["/usr/bin/env"]

RUN echo "HERE!"

Saya tidak dapat mereproduksi kegagalan cache pada pola pertama Anda: :confused:

$ cat Dockerfile
FROM alpine:3.12
ENTRYPOINT []
RUN echo 'HERE!'

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Running in d921be2e563d
Removing intermediate container d921be2e563d
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Running in 9e2ca2cf1f9f
HERE!
Removing intermediate container 9e2ca2cf1f9f
 ---> d398fdd442b1
Successfully built d398fdd442b1

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Using cache
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Using cache
 ---> d398fdd442b1
Successfully built d398fdd442b1

Saya pikir Anda harus menggunakan gambar yang mendefinisikan ENTRYPOINT . Coba gunakan gambar yang saya buat atau mysql .

Oh menarik -- Saya dapat mereproduksi menggunakan mysql:8.0 . Serangga padat! :+1:

Apakah halaman ini membantu?
0 / 5 - 0 peringkat