Dalam terjemahan bagian ketiga dari seri Docker, kami akan terus terinspirasi oleh kue kering, yaitu bagel. Topik utama kami hari ini adalah bekerja dengan Dockerfiles. Kami akan menganalisis instruksi yang digunakan dalam file-file ini.
β
Bagian 1: dasar-dasarnyaβ
Bagian 2: istilah dan konsepβ
Bagian 3: File Dockerfileβ
Bagian 4: mengurangi ukuran gambar dan mempercepat perakitannyaβ
Bagian 5: timβ
Bagian 6: bekerja dengan dataBagel adalah instruksi di Dockerfile.Gambar Docker
Ingatlah bahwa wadah Docker adalah gambar Docker yang hidup. Ini adalah sistem operasi mandiri di mana hanya ada kode aplikasi dan yang paling diperlukan.
Gambar Docker adalah hasil dari proses pembangunan, dan wadah Docker menjalankan gambar. Di jantung Docker adalah Dockerfiles. File seperti ini memberi tahu Docker cara merakit gambar dari mana wadah dibuat.
Setiap gambar Docker memiliki file yang disebut Dockerfile. Namanya ditulis seperti itu - tanpa ekstensi. Ketika Anda menjalankan
docker build
untuk membuat gambar baru, diasumsikan bahwa Dockerfile ada di direktori kerja saat ini. Jika file ini terletak di beberapa tempat lain, lokasinya dapat ditentukan menggunakan flag
-f
.
Wadah, seperti yang kami temukan di bahan pertama seri ini, terdiri dari lapisan. Setiap lapisan, kecuali yang terakhir, yang terletak di atas yang lain, adalah read-only. Dockerfile memberi tahu sistem Docker yang berlapis-lapis dan bagaimana agar ditambahkan ke gambar.
Setiap lapisan, pada kenyataannya, hanyalah sebuah file yang menjelaskan perubahan dalam keadaan gambar dibandingkan dengan keadaan di mana ia setelah menambahkan lapisan sebelumnya. Pada Unix, omong-omong, hampir semua hal adalah
file .
Gambar dasar adalah apa layer sumber (atau lapisan) dari gambar yang sedang dibuat. Gambar dasar juga disebut gambar induk.
Gambar dasar adalah tempat gambar Docker dimulai.Ketika gambar diunduh dari repositori jarak jauh ke komputer lokal, hanya lapisan yang tidak tersedia di komputer ini yang diunduh secara fisik. Docker bertujuan untuk menghemat ruang dan waktu dengan menggunakan kembali lapisan yang ada.
File Dockerfile
Dockerfiles berisi instruksi untuk membuat gambar. Dalam huruf kapital, baris file ini dimulai. Mengikuti instruksi adalah argumen mereka. Instruksi, ketika membangun gambar, diproses dari atas ke bawah. Begini tampilannya:
FROM ubuntu:18.04 COPY . /app
Lapisan pada gambar akhir hanya dibuat oleh
FROM
,
RUN
,
COPY
, dan
ADD
. Instruksi lain mengatur sesuatu, menjelaskan metadata, atau memberi tahu Docker bahwa Anda perlu melakukan sesuatu selama pelaksanaan wadah, misalnya, membuka beberapa port atau menjalankan beberapa perintah.
Di sini kita melanjutkan dari asumsi bahwa gambar Docker berdasarkan OS mirip Unix digunakan. Tentu saja, di sini Anda juga dapat menggunakan gambar berbasis Windows, tetapi menggunakan Windows adalah praktik yang kurang umum, bekerja dengan gambar seperti itu lebih sulit. Akibatnya, jika Anda memiliki kesempatan, gunakan Unix.
Untuk memulai, berikut adalah daftar instruksi Dockerfile dengan komentar singkat.
Instruksi Dozen Dockerfile
FROM
- mengatur gambar dasar (induk).LABEL
- menjelaskan metadata. Misalnya, informasi tentang siapa yang membuat dan memelihara gambar.ENV
- menetapkan variabel lingkungan persisten.RUN
- mengeksekusi perintah dan membuat layer gambar. Digunakan untuk menginstal paket dalam wadah.COPY
- menyalin file dan folder ke wadah.ADD
- menyalin file dan folder ke sebuah wadah, dapat membongkar file .tar lokal.CMD
- menguraikan perintah dengan argumen yang perlu dijalankan ketika wadah diluncurkan. Argumen dapat ditimpa ketika wadah dimulai. File hanya dapat berisi satu instruksi CMD
.WORKDIR
- mengatur direktori kerja untuk instruksi selanjutnya.ARG
- set variabel untuk melewati Docker selama pembuatan gambar.ENTRYPOINT
- Menyediakan perintah dengan argumen untuk dipanggil selama eksekusi kontainer. Argumen tidak ditimpa.EXPOSE
- menunjukkan perlunya membuka port.VOLUME
- membuat titik mount untuk bekerja dengan penyimpanan persisten.
Sekarang mari kita bicara tentang instruksi ini.
Instruksi dan contoh penggunaannya
DockSederhana Dockerfile
Dockerfile bisa sangat sederhana dan pendek. Misalnya - seperti ini:
FROM ubuntu:18.04
InstructionDari instruksi
Dockerfile harus dimulai dengan pernyataan
FROM
, atau dengan pernyataan
ARG
diikuti oleh pernyataan
FROM
.
Kata kunci
FROM memberi tahu Docker untuk menggunakan gambar dasar yang cocok dengan nama dan tag yang disediakan saat membuat gambar. Gambar dasar, di samping itu, juga disebut
gambar induk .
Dalam contoh ini, gambar dasar disimpan di repositori
ubuntu . Ubuntu adalah nama repositori Docker resmi, yang menyediakan versi dasar dari keluarga Linux yang populer dengan sistem operasi yang disebut Ubuntu.
Harap perhatikan bahwa Dockerfile yang dimaksud menyertakan tag
18.04
yang menentukan gambar dasar mana yang kami butuhkan. Gambar inilah yang akan dimuat saat membangun gambar kita. Jika tag tidak termasuk dalam instruksi, maka Docker melanjutkan dari asumsi bahwa gambar terbaru dari repositori diperlukan. Untuk mengekspresikan maksud mereka dengan lebih jelas, disarankan agar penulis Dockerfile menunjukkan gambar mana yang dia butuhkan.
Ketika Dockerfile di atas digunakan pada mesin lokal untuk membangun gambar untuk pertama kalinya, Docker akan memuat lapisan yang ditentukan oleh gambar
ubuntu
. Mereka dapat dibayangkan saling tumpang tindih. Setiap lapisan berikutnya adalah file yang menggambarkan perbedaan gambar dibandingkan dengan keadaan di mana ia setelah menambahkan lapisan sebelumnya.
Saat Anda membuat sebuah wadah, sebuah lapisan tempat Anda dapat membuat perubahan ditambahkan di atas semua lapisan lainnya. Data di lapisan yang tersisa hanya bisa dibaca.
Struktur wadah (diambil dari dokumentasi )Docker, demi efisiensi, menggunakan strategi copy-on-write. Jika lapisan dalam gambar ada di tingkat sebelumnya dan beberapa lapisan perlu membaca data darinya, Docker menggunakan file yang ada. Anda tidak perlu mengunduh apa pun.
Ketika gambar dieksekusi, jika layer perlu dimodifikasi dengan menggunakan wadah, maka file yang sesuai disalin ke lapisan paling atas, bisa berubah. Untuk mempelajari lebih lanjut tentang strategi copy-on-write, lihat materi
ini dari dokumentasi Docker.
Kami melanjutkan diskusi tentang instruksi yang digunakan di Dockerfile, memberikan contoh file seperti itu dengan struktur yang lebih kompleks.
βLebih banyak buruh pelabuhan yang canggih
Meskipun Dockerfile yang baru saja kami ulas ternyata rapi dan dapat dimengerti, itu terlalu sederhana, ia hanya menggunakan satu instruksi. Selain itu, tidak ada instruksi yang dipanggil selama eksekusi kontainer. Lihatlah file lain yang mengumpulkan gambar kecil. Ini memiliki mekanisme yang menentukan perintah yang dipanggil selama pelaksanaan wadah.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" ENV ADMIN="jeff" RUN apk update && apk upgrade && apk add bash COPY . ./app ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \ /my_app_directory RUN ["mkdir", "/a_directory"] CMD ["python", "./my_script.py"]
Mungkin sekilas file ini mungkin terlihat agak rumit. Karena itu, mari kita hadapi dia.
Basis gambar ini adalah gambar Python resmi dengan tag 3.7.2-alpine3.8. Setelah menganalisis kode
ini , Anda dapat melihat bahwa gambar dasar ini termasuk Linux, Python, dan pada umumnya, ini terbatas pada komposisinya. Gambar Alpine OS sangat populer di dunia Docker. Fakta bahwa mereka berukuran kecil, kecepatan tinggi dan aman. Namun, gambar Alpine tidak berbeda dalam kemampuan luas khas sistem operasi konvensional. Oleh karena itu, untuk mengumpulkan sesuatu yang berguna berdasarkan gambar seperti itu, pencipta gambar perlu menginstal paket yang dibutuhkannya.
β LABEL instruksi
TagPernyataan LABEL (label) memungkinkan Anda untuk menambahkan metadata ke gambar. Dalam kasus file yang sedang dipertimbangkan sekarang, itu termasuk informasi kontak pencipta gambar. Mendeklarasikan label tidak memperlambat proses perakitan gambar atau meningkatkan ukurannya. Mereka hanya berisi informasi berguna tentang gambar Docker, jadi disarankan agar mereka dimasukkan dalam file. Detail tentang bekerja dengan metadata di Dockerfile dapat ditemukan di
sini .
InstructionInv instruksi
LingkunganInstruksi
ENV memungkinkan Anda untuk mengatur variabel lingkungan konstan yang akan tersedia dalam wadah selama eksekusi. Pada contoh sebelumnya, setelah membuat wadah, Anda bisa menggunakan variabel
ADMIN
.
Instruksi
ENV
sangat cocok untuk menetapkan konstanta. Jika Anda menggunakan nilai tertentu di Dockerfile beberapa kali, katakanlah, ketika mendeskripsikan perintah yang dieksekusi dalam wadah, dan menduga bahwa suatu hari Anda mungkin harus mengubahnya ke yang lain, masuk akal untuk menulisnya ke konstanta yang sama.
Perlu dicatat bahwa dalam file Dockerfile sering ada berbagai cara untuk menyelesaikan masalah yang sama. Apa sebenarnya yang digunakan adalah pertanyaan, keputusan yang dipengaruhi oleh keinginan untuk mematuhi metode kerja yang diadopsi di lingkungan Docker, untuk memastikan transparansi solusi dan kinerjanya yang tinggi. Misalnya,
ENTRYPOINT
RUN
,
CMD
dan
ENTRYPOINT
melayani tujuan yang berbeda, tetapi semuanya digunakan untuk menjalankan perintah.
Instruksi βRUN
Instruksi RUNInstruksi
RUN memungkinkan Anda membuat layer selama pembuatan gambar. Setelah eksekusi, layer baru ditambahkan ke gambar, statusnya diperbaiki. Instruksi
RUN
sering digunakan untuk menginstal paket tambahan dalam gambar. Dalam contoh sebelumnya, pernyataan
RUN apk update && apk upgrade
pernyataan
RUN apk update && apk upgrade
memberitahu Docker bahwa sistem perlu memperbarui paket dari gambar dasar. Mengikuti kedua perintah ini adalah perintah
&& apk add bash
, yang menunjukkan bahwa bash perlu diinstal pada gambar.
Apa yang tampak seperti
apk
dalam tim adalah singkatan dari
manajer paket Alpine Linux . Jika Anda menggunakan gambar dasar dari beberapa OS keluarga Linux lainnya, maka, misalnya, ketika menggunakan Ubuntu, Anda mungkin memerlukan perintah dari form
RUN apt-get
untuk menginstal paket. Nanti kita akan berbicara tentang cara-cara lain untuk menginstal paket.
Instruksi
RUN
dan instruksi serupa, seperti
CMD
dan
ENTRYPOINT
, dapat digunakan baik dalam bentuk exec atau dalam bentuk shell. Bentuk exec menggunakan sintaks yang menyerupai deskripsi array JSON. Misalnya, mungkin terlihat seperti ini:
RUN ["my_executable", "my_first_param1", "my_second_param2"]
.
Pada contoh sebelumnya, kami menggunakan form shell dari instruksi RUN sebagai berikut:
RUN apk update && apk upgrade && apk add bash
.
Kemudian di Dockerfile kami, kami menggunakan formulir exec dari instruksi
RUN
, dalam bentuk
RUN ["mkdir", "/a_directory"]
untuk membuat direktori. Pada saat yang sama, menggunakan instruksi dalam formulir ini, Anda harus mengingat kebutuhan untuk memformat string dengan tanda kutip ganda, seperti yang biasa dalam format JSON.
β Instruksi SALINAN
Instruksi COPYInstruksi
COPY disajikan dalam file kami seperti ini:
COPY . ./app
COPY . ./app
. Dia memberi tahu Docker bahwa dia harus mengambil file dan folder dari konteks lokal perakitan dan menambahkannya ke direktori kerja gambar saat ini. Jika direktori tujuan tidak ada, instruksi ini akan membuatnya.
β Masukkan instruksi
Instruksi
ADD memungkinkan Anda untuk memecahkan masalah yang sama seperti
COPY
, tetapi beberapa
COPY
penggunaan lebih terkait dengan itu. Jadi, dengan menggunakan instruksi ini, Anda dapat menambahkan file yang diunduh dari sumber jarak jauh ke wadah, serta membongkar file .tar lokal.
Dalam contoh ini, instruksi
ADD
digunakan untuk menyalin file yang dapat diakses URL ke
my_app_directory
wadah
my_app_directory
. Perlu dicatat, bagaimanapun, bahwa
dokumentasi Docker tidak merekomendasikan penggunaan file-file tersebut yang diperoleh dengan URL, karena mereka tidak dapat dihapus, dan karena mereka meningkatkan ukuran gambar.
Selain itu,
dokumentasi menyarankan, sedapat mungkin, bahwa Anda menggunakan pernyataan
COPY
alih-alih pernyataan
ADD
untuk membuat Dockerfile lebih mudah dimengerti. Saya percaya tim pengembangan Docker harus menggabungkan
ADD
dan
COPY
menjadi satu instruksi sehingga mereka yang membuat gambar tidak harus mengingat terlalu banyak instruksi.
Perhatikan bahwa pernyataan
ADD
berisi karakter pemisah baris -
\
. Karakter tersebut digunakan untuk meningkatkan keterbacaan perintah panjang dengan memecahnya menjadi beberapa baris.
β instruksi CMD
Instruksi CMDInstruksi
CMD menyediakan Docker dengan perintah untuk mengeksekusi ketika wadah dimulai. Hasil dari perintah ini tidak ditambahkan ke gambar selama perakitannya. Dalam contoh kita, perintah ini meluncurkan skrip
my_script.py
saat runtime.
Berikut ini hal lain yang perlu Anda ketahui tentang instruksi
CMD
:
- Hanya satu instruksi
CMD
dapat hadir dalam satu Dockerfile. Jika ada beberapa instruksi seperti itu dalam file, sistem akan mengabaikan semuanya kecuali yang terakhir. - Instruksi
CMD
mungkin memiliki formulir exec. Jika instruksi tidak menyertakan referensi ke file yang dapat dieksekusi, maka instruksi ENTRYPOINT
harus ada dalam file. Dalam hal ini, kedua instruksi ini harus dalam JSON
. - Argumen baris perintah yang diteruskan ke
docker run
menimpa argumen yang disediakan oleh pernyataan CMD
di Dockerfile.
Dock Dockerfile yang lebih kompleks
Pertimbangkan Dockerfile lain, di mana beberapa perintah baru akan digunakan.
FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" # RUN apk add --update git # WORKDIR /usr/src/my_app_directory # COPY . . # ARG my_var=my_default_value # , ENTRYPOINT ["python", "./app/my_script.py", "my_var"] # EXPOSE 8000 # VOLUME /my_volume
Dalam contoh ini, antara lain, Anda dapat melihat komentar yang dimulai dengan karakter
#
.
Salah satu hal utama yang dilakukan Dockerfile adalah menginstal paket. Seperti yang telah disebutkan, ada berbagai cara untuk menginstal paket menggunakan instruksi
RUN
.
Paket dalam gambar Alpine Docker dapat diinstal menggunakan
apk
. Untuk ini, seperti yang telah kami katakan, perintah dari form
RUN apk update && apk upgrade && apk add bash
.
Selain itu, paket Python dalam gambar dapat diinstal menggunakan
pip ,
wheel, dan
conda . Jika kita tidak berbicara tentang Python, tetapi tentang bahasa pemrograman lain, maka manajer paket lain dapat digunakan untuk menyiapkan gambar yang sesuai.
Pada saat yang sama, agar instalasi dimungkinkan, lapisan yang mendasarinya harus menyediakan manajer paket dengan manajer paket yang sesuai. Oleh karena itu, jika Anda mengalami masalah dalam menginstal paket, pastikan bahwa manajer paket diinstal sebelum Anda mencoba menggunakannya.
Misalnya, Anda dapat menggunakan pernyataan
RUN
di Dockerfile untuk menginstal daftar paket menggunakan
pip
. Jika Anda melakukan ini, gabungkan semua perintah menjadi satu instruksi dan pisahkan dengan karakter pemisah baris menggunakan
\
karakter. Berkat pendekatan ini, file-file akan terlihat rapi dan ini akan menyebabkan penambahan lebih sedikit layer pada gambar daripada yang akan ditambahkan menggunakan beberapa instruksi
RUN
.
Selain itu, Anda dapat melakukan berbagai hal untuk menginstal beberapa paket. Anda dapat mencantumkannya dalam file dan mentransfer file ini ke manajer paket menggunakan
RUN
. Biasanya, file-file ini disebut
requirements.txt
.
β Instruksi WORKDIR
Direktori kerjaInstruksi
WORKDIR memungkinkan
Anda untuk mengubah direktori kerja wadah.
ENTRYPOINT
COPY
,
ADD
,
RUN
,
CMD
dan
ENTRYPOINT
yang mengikuti
WORKDIR
bekerja dengan direktori ini. Berikut adalah beberapa fitur yang terkait dengan instruksi ini:
- Lebih baik untuk menetapkan path absolut ke folder dengan
WORKDIR
daripada menavigasi sistem file menggunakan perintah cd
di Dockerfile. - Instruksi
WORKDIR
secara otomatis membuat direktori jika tidak ada. - Anda dapat menggunakan beberapa instruksi
WORKDIR
. Jika instruksi relatif disediakan untuk instruksi tersebut, maka masing-masing dari mereka mengubah direktori kerja saat ini.
βPanduan ARG
Instruksi
ARG memungkinkan Anda untuk mengatur variabel yang nilainya dapat diteruskan dari baris perintah ke gambar selama perakitannya. Nilai untuk variabel default dapat direpresentasikan dalam Dockerfile. Sebagai contoh:
ARG my_var=my_default_value
.
Tidak seperti variabel
ENV
, variabel
ARG
tidak tersedia saat runtime. Namun, variabel
ARG
dapat digunakan untuk menetapkan nilai default untuk variabel
ENV
dari baris perintah selama pembuatan gambar. Dan variabel
ENV
akan sudah tersedia dalam wadah selama eksekusi. Rincian tentang teknik ini bekerja dengan variabel dapat ditemukan di
sini .
β ENTRYPOINT Instruksi
Titik transisi ke suatu tempatPernyataan ENTRYPOINT memungkinkan
Anda untuk menentukan perintah dengan argumen yang harus dieksekusi ketika wadah dimulai. Ini mirip dengan perintah
CMD
, tetapi parameter yang ditentukan dalam
ENTRYPOINT
tidak ditimpa jika wadah dimulai dengan parameter baris perintah.
Sebagai gantinya, argumen baris perintah yang diteruskan dalam konstruksi form
docker run my_image_name
ditambahkan ke argumen yang ditentukan oleh
ENTRYPOINT
. Misalnya, setelah menjalankan perintah dari
docker run my_image bash
formulir
docker run my_image bash
argumen
docker run my_image bash
akan ditambahkan ke akhir daftar argumen yang ditentukan oleh
ENTRYPOINT
. Saat menyiapkan Dockerfile Anda, jangan lupa
ENTRYPOINT
CMD
atau
ENTRYPOINT
.
Ada beberapa rekomendasi dalam dokumentasi untuk Docker mengenai instruksi mana,
CMD
atau
ENTRYPOINT
, harus dipilih sebagai alat untuk mengeksekusi perintah ketika wadah mulai:
- Jika Anda perlu menjalankan perintah yang sama setiap kali Anda memulai wadah, gunakan
ENTRYPOINT
. - Jika wadah akan digunakan sebagai aplikasi, gunakan
ENTRYPOINT
. - Jika Anda tahu bahwa ketika Anda memulai wadah, Anda harus memberikan argumen kepadanya yang dapat menimpa argumen yang ditentukan dalam Dockerfile, gunakan
CMD
.
Dalam contoh kami, menggunakan instruksi
ENTRYPOINT ["python", "my_script.py", "my_var"]
menyebabkan wadah, ketika dimulai, untuk menjalankan skrip Python
my_script.py
dengan argumen
my_var
. Nilai yang diwakili oleh
my_var
kemudian dapat digunakan dalam skrip menggunakan
argparse . , Dockerfile
my_var
, ,
ARG
. , , .
Docker exec-
ENTRYPOINT
:
ENTRYPOINT ["executable", "param1", "param2"]
.
β EXPOSE
EXPOSEEXPOSE , , . . , , , , , , .
( ) ,
docker run
-p
.
-P
(
P
), ,
EXPOSE
.
β VOLUME
VOLUMEVOLUME , . .
Ringkasan
, Dockerfile. . , ,
USER
,
ONBUILD
,
STOPSIGNAL
,
SHELL
HEALTHCHECK
.
Dockerfile.
, Dockerfile β Docker, , . , .
Pembaca yang budiman! Docker , , Docker-.
