Często nie chcesz wykonywać git clone
prywatnego repozytorium z kompilacji dokera. Wykonanie tam klonowania polega na umieszczeniu prywatnych poświadczeń ssh wewnątrz obrazu, gdzie mogą je później wyodrębnić dowolne osoby mające dostęp do twojego obrazu.
Zamiast tego powszechną praktyką jest klonowanie repozytorium git spoza dokera w wybranym narzędziu CI i po prostu COPY
pliki do obrazu. Ma to drugą zaletę: buforowanie dokerów. Buforowanie dokera sprawdza uruchamiane polecenie, zawarte w nim zmienne środowiskowe, pliki wejściowe itp. Jeśli są identyczne z poprzednią kompilacją z tego samego kroku nadrzędnego, ponownie wykorzystuje poprzednią pamięć podręczną. W git clone
przypadku polecenia samo polecenie jest identyczne, więc doker ponownie użyje pamięci podręcznej, nawet jeśli zmieni się zewnętrzne repozytorium git. Jednak COPY
polecenie sprawdzi pliki w kontekście kompilacji i zobaczy, czy są one identyczne lub zostały zaktualizowane, i użyje pamięci podręcznej tylko wtedy, gdy jest to właściwe.
Jeśli zamierzasz dodać poświadczenia do swojej kompilacji, rozważ zrobienie tego z kompilacją wieloetapową i umieszczaj te poświadczenia tylko na wczesnym etapie, który nigdy nie jest oznaczany i wypychany poza host kompilacji. Wynik wygląda następująco:
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
...
Ostatnio BuildKit testuje niektóre eksperymentalne funkcje, które pozwalają przekazać klucz ssh jako mount, który nigdy nie jest zapisywany na obrazie:
# 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
Możesz to zbudować za pomocą:
$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
--secret id=ssh_id,src=$(pwd)/id_rsa .
Należy pamiętać, że nadal wymaga to, aby klucz ssh nie był chroniony hasłem, ale można przynajmniej uruchomić kompilację w jednym etapie, usuwając polecenie KOPIUJ i unikając poświadczenia ssh, które nigdy nie będzie częścią obrazu.
BuildKit dodał także funkcję tylko dla ssh, która pozwala nadal mieć chronione hasłem klucze ssh, wynik wygląda następująco:
# 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
Możesz to zbudować za pomocą:
$ 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 .
Ponownie jest on wstrzykiwany do kompilacji bez zapisywania go w warstwie obrazu, co eliminuje ryzyko przypadkowego wycieku poświadczenia.
Aby zmusić okno dokowane do uruchomienia git clone
nawet wtedy, gdy wiersze zostały uprzednio zbuforowane, możesz wstrzyknąć ARG kompilacji, który zmienia się przy każdej kompilacji, aby przerwać bufor. To wygląda jak:
# 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
Następnie wstrzykujesz ten zmieniający się argument w poleceniu kompilacji dokera:
date_stamp=$(date +%Y%m%d-%H%M%S)
docker build --build-arg DATE_STAMP=$date_stamp .