A menudo no desea realizar un git clone
repositorio privado desde la compilación de la ventana acoplable. Hacer el clon allí implica colocar las credenciales ssh privadas dentro de la imagen para que luego puedan ser extraídas por cualquier persona con acceso a su imagen.
En cambio, la práctica común es clonar el repositorio git desde fuera de la ventana acoplable en la herramienta de CI que elija, y simplemente COPY
los archivos en la imagen. Esto tiene un segundo beneficio: el almacenamiento en caché de la ventana acoplable. El almacenamiento en caché de Docker analiza el comando que se ejecuta, las variables de entorno que incluye, los archivos de entrada, etc., y si son idénticos a una compilación anterior del mismo paso principal, reutiliza esa caché anterior. Con un git clone
comando, el comando en sí es idéntico, por lo que Docker reutilizará el caché incluso si se cambia el repositorio externo de git. Sin embargo, un COPY
comando mirará los archivos en el contexto de compilación y podrá ver si son idénticos o si se han actualizado, y usará la memoria caché solo cuando sea apropiado.
Si va a agregar credenciales a su compilación, considere hacerlo con una compilación de varias etapas, y solo coloque esas credenciales en una etapa temprana que nunca se etiquete y empuje fuera de su host de compilación. El resultado se ve así:
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
...
Más recientemente, BuildKit ha estado probando algunas características experimentales que le permiten pasar una clave ssh como una montura que nunca se escribe en la imagen:
# 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
Y puedes construir eso con:
$ DOCKER_BUILDKIT=1 docker build -t your_image_name \
--secret id=ssh_id,src=$(pwd)/id_rsa .
Tenga en cuenta que esto aún requiere que su clave ssh no esté protegida por contraseña, pero al menos puede ejecutar la compilación en una sola etapa, eliminando un comando COPY y evitando que la credencial ssh forme parte de una imagen.
BuildKit también agregó una característica solo para ssh que le permite tener sus claves ssh protegidas con contraseña, el resultado es el siguiente:
# 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
Y puedes construir eso con:
$ 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 .
Nuevamente, esto se inyecta en la compilación sin escribirse nunca en una capa de imagen, lo que elimina el riesgo de que la credencial se filtre accidentalmente.
Para forzar a Docker a ejecutar git clone
incluso cuando las líneas anteriores se han almacenado en caché, puede inyectar un ARG de compilación que cambia con cada compilación para romper el caché. Eso parece como:
# 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
Luego, inyecta ese cambio de arg en el comando de construcción docker:
date_stamp=$(date +%Y%m%d-%H%M%S)
docker build --build-arg DATE_STAMP=$date_stamp .