SALIN dengan buruh pelabuhan tetapi dengan pengecualian

231

Di Dockerfile, saya punya

COPY . .

Saya ingin mengecualikan seluruh direktori, dalam kasus saya, direktori node_modules.

Sesuatu seperti ini:

   COPY [all but **/node_modules/**] .

Apakah ini mungkin dengan Docker?

Alexander Mills
sumber
23
Bagaimana dengan .dockerignore?
Anthony Sottile
Saya mencari jawaban untuk pertanyaan terkait ini: stackoverflow.com/questions/50547489/…
Alexander Mills

Jawaban:

377

Buat file .dockerignoredi direktori konteks bangunan buruh pelabuhan Anda (jadi dalam kasus ini, kemungkinan besar direktori yang merupakan induk dari node_modules) dengan satu baris di dalamnya:

**/node_modules

walaupun Anda mungkin hanya ingin:

node_modules

Info tentang dockerignore: https://docs.docker.com/engine/reference/builder/#dockerignore-file

vith
sumber
5
terima kasih, jadi "COPY." perintah tidak perlu diubah, saya kira
Alexander Mills
Tidak juga /config/nginx/ /config/logstash/ls config/ gunicorn logs logstash nginx
:,
3
@SalahAdDin untuk alasan yang sama Anda tidak menulis ls /config/, apakah Anda mencoba menambahkan path tersebut ke .dockerignore Anda tanpa yang terdepan /?
Pablo
8
Hanya node_modulessaja tidak bekerja di subdirektori.
rustyx
5
Ini tidak benar-benar menyelesaikan masalah jika Anda ingin memilikinya COPY tetapi tidak di lapisan itu ...
Wes
33

Bagi mereka yang tidak dapat menggunakan file .dockerignore (mis. Jika Anda memerlukan file dalam satu COPY tetapi tidak yang lain):

Ya, tetapi Anda memerlukan beberapa instruksi COPY. Khususnya, Anda memerlukan SALINAN untuk setiap huruf dalam nama file yang ingin Anda kecualikan.

COPY [^n]*    # All files that don't start with 'n'
COPY n[^o]*   # All files that start with 'n', but not 'no'
COPY no[^d]*  # All files that start with 'no', but not 'nod'

Melanjutkan hingga Anda memiliki nama file lengkap, atau hanya awalan yang Anda yakini tidak akan memiliki file lain.

Alex
sumber
1
Ini tidak akan sia-sia karena Anda akan mendapatkan COPY failed: no source files were specifiedketika tidak ada file dimulai dengan 'tidak', tetapi tidak 'mengangguk'.
mheck
1
Atau, Anda dapat menggunakan dua sub-direktori yang berbeda (untuk target penyalinan yang berbeda), sehingga misalnya dalam pengaturan nginx saya, saya src/akan pergi ke /var/wwwdan /conf/nginx.confpergi ke /etc/nginx/conf.d/default.conf. Juga, Anda bisa menyalin semuanya, dan RUN rm -r confkemudian (juga menjaga pohon sumbernya seperti semula). Saya ingin mendengar jika seseorang memiliki saran lain.
Yuval
1
Apa yang akan menjadi solusi untuk jenis file tertentu atau akhir file jika saya mau melakukannya seperti ini?
Lea Reimann
Satu-satunya downside dari pendekatan ini adalah bahwa struktur folder Anda diratakan
Islam Q.
Jika Anda hanya memiliki beberapa direktori yang akan disalin (katakan saja '/ app' atau '/ src'). Cara yang lebih sederhana adalah menyalin direktori satu per satu (untuk menjaga strukturnya) dan kemudian Anda hanya perlu satu COPY [^node_modules]*untuk menyalin semua file tingkat atas.
smdufb
9

Dalam kasus saya, Dockerfile saya berisi langkah instalasi, yang menghasilkan vendordirektori (setara dengan PHP node_modules). Saya kemudian COPYdirektori ini ke gambar aplikasi akhir. Oleh karena itu, aku tidak bisa meletakkan vendordi saya .dockerignore. Solusi saya adalah menghapus direktori sebelum melakukan composer install(setara dengan PHP npm install).

FROM composer AS composer
WORKDIR /app
COPY . .
RUN rm -rf vendor \
    && composer install 

FROM richarvey/nginx-php-fpm
WORKDIR /var/www/html
COPY --from=composer /app .

Solusi ini berfungsi dan tidak mengasapi gambar akhir, tetapi tidak ideal, karena vendordirektori pada host disalin ke dalam konteks Docker selama proses pembangunan, yang menambah waktu.

Cameron Hudson
sumber
3
Catat yakin mengapa Anda harus menghapus composer.locksebelumnya composer install. Tanpa file kunci, satu set dependensi berbeda (folder vendor) dapat diinstal ketika Anda membangun di waktu berikutnya.
Lacek
1
@ Lacek: Kamu benar. Saya telah belajar lebih baik sejak saya memposting ini.
Cameron Hudson
1
@CameronHudson mungkin memperbarui jawaban asli Anda sebelum orang-orang menyalin / menempel praktik buruk ini.
Robin van Baalen
2

Menambahkan .dockerignore berfungsi untuk saya. Satu poin tambahan Mereka yang mencoba solusi ini di Windows , windows tidak akan membiarkan Anda membuat file .dockerignore (karena tidak secara default memungkinkan membuat file dimulai dengan.)

Untuk membuat file seperti itu dimulai dengan. pada Windows , sertakan juga titik akhir, seperti: .dockerignore.dan tekan enter (asalkan Anda telah mengaktifkan opsi ekstensi tampilan dari opsi folder)

Paras Patidar
sumber
6
Anda dapat membuat file di windows yang dimulai dengan titik dengan juga mengakhirinya dengan titik.
Jim Pedid
0

Tidak termasuk node_modules dari direktori saat ini

node_modules

Tidak termasuk node_modules dalam subdirektori langsung apa pun

*/node_modules

Ini dokumen resmi

kta
sumber