Anda sering tidak ingin melakukan git clone
repo pribadi dari dalam bangunan buruh pelabuhan. Melakukan klon di sana melibatkan menempatkan kredensial ssh pribadi di dalam gambar di mana mereka kemudian dapat diekstraksi oleh siapa pun dengan akses ke gambar Anda.
Sebagai gantinya, praktik umum adalah mengkloning git repo dari luar docker di alat CI pilihan Anda, dan cukup COPY
file ke dalam gambar. Ini memiliki manfaat kedua: caching buruh pelabuhan. Caching Docker melihat perintah yang sedang dijalankan, variabel lingkungan yang dicakupnya, memasukkan file, dll, dan jika mereka identik dengan build sebelumnya dari langkah induk yang sama, ia menggunakan kembali cache sebelumnya. Dengan sebuah git clone
perintah, perintah itu sendiri identik, jadi buruh pelabuhan akan menggunakan kembali cache meskipun repo git eksternal diubah. Namun, sebuah COPY
perintah akan melihat file dalam konteks build dan dapat melihat apakah mereka identik atau telah diperbarui, dan menggunakan cache hanya ketika itu sesuai.
Jika Anda akan menambahkan kredensial ke dalam bangunan Anda, pertimbangkan untuk melakukannya dengan membangun multi-tahap, dan hanya menempatkan kredensial tersebut pada tahap awal yang tidak pernah ditandai dan didorong di luar host build Anda. Hasilnya terlihat seperti:
FROM ubuntu as clone
# Update aptitude with new repo
RUN apt-get update \
&& apt-get install -y git
# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
&& touch /root/.ssh/known_hosts \
&& ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
# Copy over private key, and set permissions
# Warning! Anyone who gets their hands on this image will be able
# to retrieve this private key file from the corresponding image layer
COPY id_rsa /root/.ssh/id_rsa
# Clone the conf files into the docker container
RUN git clone git@bitbucket.org:User/repo.git
FROM ubuntu as release
LABEL maintainer="Luke Crooks <luke@pumalo.org>"
COPY --from=clone /repo /repo
...
Baru-baru ini, BuildKit telah menguji beberapa fitur eksperimental yang memungkinkan Anda untuk meneruskan kunci ssh sebagai mount yang tidak pernah ditulis ke gambar:
# syntax=docker/dockerfile:experimental
FROM ubuntu as clone
LABEL maintainer="Luke Crooks <luke@pumalo.org>"
# Update aptitude with new repo
RUN apt-get update \
&& apt-get install -y git
# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
&& touch /root/.ssh/known_hosts \
&& ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
# Clone the conf files into the docker container
RUN --mount=type=secret,id=ssh_id,target=/root/.ssh/id_rsa \
git clone git@bitbucket.org:User/repo.git
Dan Anda dapat membangunnya dengan:
$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
--secret id=ssh_id,src=$(pwd)/id_rsa .
Perhatikan bahwa ini masih memerlukan kunci ssh Anda untuk tidak dilindungi kata sandi, tetapi Anda setidaknya dapat menjalankan build dalam satu tahap, menghapus perintah COPY, dan menghindari kredensial ssh agar tidak pernah menjadi bagian dari gambar.
BuildKit juga menambahkan fitur hanya untuk ssh yang memungkinkan Anda untuk tetap memiliki kunci ssh yang dilindungi kata sandi, hasilnya terlihat seperti:
# syntax=docker/dockerfile:experimental
FROM ubuntu as clone
LABEL maintainer="Luke Crooks <luke@pumalo.org>"
# Update aptitude with new repo
RUN apt-get update \
&& apt-get install -y git
# Make ssh dir
# Create known_hosts
# Add bitbuckets key
RUN mkdir /root/.ssh/ \
&& touch /root/.ssh/known_hosts \
&& ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
# Clone the conf files into the docker container
RUN --mount=type=ssh \
git clone git@bitbucket.org:User/repo.git
Dan Anda dapat membangunnya dengan:
$ eval $(ssh-agent)
$ ssh-add ~/.ssh/id_rsa
(Input your passphrase here)
$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
--ssh default=$SSH_AUTH_SOCK .
Sekali lagi, ini disuntikkan ke dalam bangunan tanpa pernah ditulis ke lapisan gambar, menghilangkan risiko bahwa kredensial bisa bocor secara tidak sengaja.
Untuk memaksa buruh pelabuhan untuk menjalankan git clone
bahkan ketika baris sebelumnya telah di-cache, Anda bisa menyuntikkan ARG build yang berubah dengan setiap build untuk memecahkan cache. Itu terlihat seperti:
# inject a datestamp arg which is treated as an environment variable and
# will break the cache for the next RUN command
ARG DATE_STAMP
# Clone the conf files into the docker container
RUN git clone git@bitbucket.org:User/repo.git
Kemudian Anda menyuntikkan itu mengubah arg di perintah membangun buruh pelabuhan:
date_stamp=$(date +%Y%m%d-%H%M%S)
docker build --build-arg DATE_STAMP=$date_stamp .