Perbedaan antara RUN dan CMD di Dockerfile

293

Saya bingung tentang kapan saya harus menggunakan CMDvs RUN. Misalnya, untuk menjalankan perintah bash / shell (yaitu ls -la) saya akan selalu menggunakan CMDatau apakah ada situasi di mana saya akan menggunakan RUN? Mencoba memahami praktik terbaik tentang dua Dockerfilearahan serupa ini .

TakeSoUp
sumber

Jawaban:

425

RUN adalah langkah membangun gambar, keadaan wadah setelah RUNperintah akan berkomitmen untuk gambar wadah. Dockerfile dapat memiliki banyak RUNlangkah yang berlapis-lapis untuk membangun gambar.

CMD adalah perintah yang dijalankan oleh wadah secara default saat Anda meluncurkan gambar buatan. Dockerfile hanya akan menggunakan final yang CMDditentukan. The CMDbisa ditimpa ketika memulai sebuah wadah dengan docker run $image $other_command.

ENTRYPOINT juga terkait erat dengan CMDdan dapat memodifikasi cara wadah memulai gambar.

Mat
sumber
15
Anda melakukan semua yang RUNdiperlukan untuk mengatur lingkungan Anda, dan CMD Anda (hanya) meluncurkan proses yang berjalan di wadah Anda, misalnya, untuk nginx, ekstrak dari github.com/nginxinc/docker-nginx/blob/… Anda melihat barisCMD ["nginx", "-g", "daemon off;"]
user2915097
"Dockerfile hanya dapat memiliki satu CMD" - secara teknis tidak benar, tetapi secara efektif semua kecuali satu akan diabaikan. Lihat jawaban GingerBeer.
Colm Bhandal
"Dockerfile hanya akan menggunakan CMD akhir yang ditentukan"? sebenarnya, CMD akhir yang ditentukan akan digunakan dalam meluncurkan gambar sebagai wadah, bukan?
paul cheung
1
Ya @paulcheung, perintah terakhir di dockerfile ditulis ke gambar dan merupakan perintah yang dijalankan oleh wadah secara default saat Anda meluncurkan gambar yang dibuat.
Matt
126

RUN - Perintah memicu sementara kami membuat gambar buruh pelabuhan.

CMD - Perintah terpicu saat kami meluncurkan gambar buruh pelabuhan yang dibuat.

Nisal Edu
sumber
67

Saya menemukan artikel ini sangat membantu untuk memahami perbedaan di antara mereka:

RUN - instruksi RUN memungkinkan Anda untuk menginstal aplikasi dan paket yang diperlukan untuk itu. Ini mengeksekusi perintah apa pun di atas gambar saat ini dan membuat layer baru dengan melakukan hasil. Seringkali Anda akan menemukan beberapa instruksi RUN di Dockerfile.

CMD - Instruksi CMD memungkinkan Anda untuk mengatur perintah default, yang akan dieksekusi hanya ketika Anda menjalankan kontainer tanpa menentukan perintah. Jika wadah Docker berjalan dengan perintah, perintah default akan diabaikan. Jika Dockerfile memiliki lebih dari satu instruksi CMD, semua
instruksi CMD terakhir kecuali diabaikan.

peri
sumber
13

RUN - Instal Python, wadah Anda sekarang memiliki python dibakar ke dalam gambar
CMD - python hello.py, jalankan skrip favorit Anda

Rohit Salecha
sumber
CMD - Instal Python, wadah saya sekarang jangan terburu-buru python dibakar ke dalam gambarnya?
Carlos Fontes
RUN akan membuat layer gambar python, CMD hanya akan mengeksekusi perintah tidak membuat gambar
Rohit Salecha
8

Perintah RUN: Perintah RUN pada dasarnya akan, menjalankan perintah default, ketika kita sedang membangun gambar. Ini juga akan melakukan perubahan gambar untuk langkah selanjutnya.

Mungkin ada lebih dari 1 perintah RUN, untuk membantu dalam proses membangun citra baru.

CMD Command: Perintah CMD hanya akan mengatur perintah default untuk wadah baru. Ini tidak akan dieksekusi pada waktu build.

Jika file buruh pelabuhan memiliki lebih dari 1 perintah CMD maka semuanya diabaikan kecuali yang terakhir. Karena perintah ini tidak akan menjalankan apa pun tetapi hanya mengatur perintah default.

Bir jahe
sumber
6

Catatan: Jangan bingung RUN dengan CMD. RUN sebenarnya menjalankan perintah dan melakukan hasilnya; CMD tidak mengeksekusi apa pun pada waktu build, tetapi menentukan perintah yang dimaksudkan untuk gambar.

dari referensi file buruh pelabuhan

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

Elsayed
sumber
4

RUN : Dapat banyak, dan digunakan dalam proses pembangunan , mis. Instal beberapa pustaka

CMD : Hanya dapat memiliki 1, yang merupakan titik awal eksekusi Anda (misalnya ["npm", "start"], ["node", "app.js"])

Xin
sumber
2

Jawaban yang ada mencakup sebagian besar apa yang dibutuhkan orang yang melihat pertanyaan ini. Jadi saya hanya akan membahas beberapa area khusus untuk CMD dan RUN.

CMD: Duplikat Diizinkan, tapi Boros

GingerBeer membuat poin penting: Anda tidak akan mendapatkan kesalahan jika Anda memasukkan lebih dari satu CMD - tetapi boros untuk melakukannya. Saya ingin menguraikan dengan contoh:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

Jika Anda membuat ini menjadi gambar dan menjalankan wadah di gambar ini, maka seperti yang dinyatakan GingerBeer, hanya CMD terakhir yang akan diperhatikan. Jadi output dari wadah itu adalah:

Menjalankan CMD 2

Cara saya memikirkannya adalah bahwa "CMD" sedang mengatur variabel global tunggal untuk seluruh gambar yang sedang dibangun, sehingga pernyataan "CMD" berturut-turut cukup menimpa setiap tulisan sebelumnya ke variabel global itu, dan pada gambar akhir yang membangun yang terakhir untuk menulis kemenangan. Karena Dockerfile dijalankan secara berurutan dari atas ke bawah, kita tahu bahwa CMD paling bawah adalah yang mendapatkan "tulis" terakhir ini (secara metaforis).

RUN: Perintah Mungkin tidak Jalankan jika Gambar di-cache

Poin halus yang perlu diperhatikan tentang RUN adalah bahwa itu diperlakukan sebagai fungsi murni bahkan jika ada efek samping, dan karenanya di-cache. Artinya, jika RUN memiliki beberapa efek samping yang tidak mengubah gambar yang dihasilkan, dan gambar tersebut telah di-cache, RUN tidak akan dieksekusi lagi sehingga efek samping tidak akan terjadi pada pembuatan berikutnya. Misalnya, ambil Dockerfile ini:

FROM busybox
RUN echo "Just echo while you work"

Pertama kali Anda menjalankannya, Anda akan mendapatkan output seperti ini, dengan ID alfanumerik yang berbeda:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

Perhatikan bahwa pernyataan gema dieksekusi di atas. Kedua kali Anda menjalankannya, ia menggunakan cache, dan Anda tidak akan melihat gema di output build:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Colm Bhandal
sumber
1

Sudah ada cukup jawaban untuk RUN dan CMD . Saya hanya ingin menambahkan beberapa kata di ENTRYPOINT . Argumen CMD dapat ditimpa oleh argumen baris perintah, sedangkan argumen ENTRYPOINT selalu digunakan.

Artikel ini adalah sumber informasi yang bagus.

Milo Lu
sumber