Compartir comentarios
Las respuestas se generan en base a la documentación.

Secretos de compilación

Un secreto de compilación es cualquier fragmento de información sensible, como una contraseña o un token de API, que se consume como parte del proceso de compilación de tu aplicación.

Los argumentos de compilación y las variables de entorno no son adecuados para pasar secretos a tu compilación porque persisten en la imagen final. En su lugar, debes utilizar montajes de secretos o montajes SSH, que exponen los secretos a tus compilaciones de forma segura.

Tipos de secretos de compilación

  • Los montajes de secretos son montajes de uso general para pasar secretos a tu compilación. Un montaje de secreto toma un secreto del cliente de compilación y lo hace disponible temporalmente dentro del contenedor de compilación, durante la duración de la instrucción de compilación. Esto es útil si, por ejemplo, tu compilación necesita comunicarse con un servidor de artefactos privado o una API.
  • Los montajes SSH son montajes de propósito especial para hacer que los sockets o claves SSH estén disponibles dentro de las compilaciones. Se utilizan comúnmente cuando necesitas descargar repositorios Git privados en tus compilaciones.
  • La autenticación Git para contextos remotos es un conjunto de secretos predefinidos para cuando compilas con un contexto Git remoto que también es un repositorio privado. Estos secretos son secretos previos (pre-flight): no se consumen dentro de tu instrucción de compilación, sino que se utilizan para proporcionar al builder las credenciales necesarias para descargar el contexto.

Usar secretos de compilación

Para los montajes de secretos y los montajes SSH, el uso de secretos de compilación es un proceso de dos pasos. Primero debes pasar el secreto al comando docker build, y luego debes consumir el secreto en tu Dockerfile.

Para pasar un secreto a una compilación, utiliza la opción docker build --secret, o las opciones equivalentes para Bake.

$ docker build --secret id=aws,src=$HOME/.aws/credentials .
variable "HOME" {
  default = null
}

target "default" {
  secret = [
    "id=aws,src=${HOME}/.aws/credentials"
  ]
}

Para consumir un secreto en una compilación y hacerlo accesible para la instrucción RUN, utiliza la opción --mount=type=secret en el Dockerfile.

RUN --mount=type=secret,id=aws \
    AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
    aws s3 cp ...

Montajes de secretos

Los montajes de secretos exponen secretos a los contenedores de compilación, como archivos o variables de entorno. Puedes usar montajes de secretos para pasar información confidencial a tus compilaciones, como tokens de API, contraseñas o claves SSH.

Orígenes

El origen de un secreto puede ser un archivo o una variable de entorno. Cuando utilizas la CLI o Bake, el tipo se puede detectar automáticamente. También puedes especificarlo explícitamente con type=file o type=env.

El siguiente ejemplo monta la variable de entorno KUBECONFIG con el ID de secreto kube, como un archivo en el contenedor de compilación en /run/secrets/kube.

$ docker build --secret id=kube,env=KUBECONFIG .

Cuando utilizas secretos de variables de entorno, puedes omitir el parámetro env para vincular el secreto a un archivo con el mismo nombre que la variable. En el siguiente ejemplo, el valor de la variable API_TOKEN se monta en /run/secrets/API_TOKEN en el contenedor de compilación.

$ docker build --secret id=API_TOKEN .

Destino

Al consumir un secreto en un Dockerfile, el secreto se monta en un archivo por defecto. La ruta de archivo predeterminada del secreto, dentro del contenedor de compilación, es /run/secrets/<id>. Puedes personalizar cómo se montan los secretos en el contenedor de compilación utilizando las opciones target y env para la opción RUN --mount en el Dockerfile.

El siguiente ejemplo toma el ID de secreto aws y lo monta en un archivo en /run/secrets/aws en el contenedor de compilación.

RUN --mount=type=secret,id=aws \
    AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
    aws s3 cp ...

Para montar un secreto como un archivo con un nombre diferente, utiliza la opción target en la opción --mount.

RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
    aws s3 cp ...

Para montar un secreto como una variable de entorno en lugar de un archivo, utiliza la opción env en la opción --mount.

RUN --mount=type=secret,id=aws-key-id,env=AWS_ACCESS_KEY_ID \
    --mount=type=secret,id=aws-secret-key,env=AWS_SECRET_ACCESS_KEY \
    --mount=type=secret,id=aws-session-token,env=AWS_SESSION_TOKEN \
    aws s3 cp ...

Es posible utilizar las opciones target y env juntas para montar un secreto tanto como archivo como variable de entorno.

Montajes SSH

Si la credencial que deseas utilizar en tu compilación es un socket de agente SSH o una clave, puedes utilizar el montaje SSH en lugar de un montaje de secreto. Clonar repositorios Git privados es un caso de uso común para los montajes SSH.

El siguiente ejemplo clona un repositorio privado de GitHub utilizando un montaje SSH de Dockerfile.

# syntax=docker/dockerfile:1
FROM alpine
ADD [email protected]:me/myprivaterepo.git /src/

Para pasar un socket SSH a la compilación, utilizas la opción docker build --ssh, o las opciones equivalentes para Bake.

$ docker buildx build --ssh default .

Autenticación Git para contextos remotos

BuildKit admite dos secretos de compilación predefinidos, GIT_AUTH_TOKEN y GIT_AUTH_HEADER. Úsalos para especificar parámetros de autenticación HTTP al compilar con repositorios Git privados y remotos, incluyendo:

  • Compilar con un repositorio Git privado como contexto de compilación
  • Obtener repositorios Git privados en una compilación con ADD

Por ejemplo, supongamos que tienes un repositorio privado de GitHub en https://github.com/example/todo-app.git y deseas ejecutar una compilación utilizando ese repositorio como contexto de compilación. Un comando docker build sin autenticación fallará porque el builder no está autorizado para descargar el repositorio:

$ docker build https://github.com/example/todo-app.git
[+] Building 0.4s (1/1) FINISHED
 => ERROR [internal] load git source https://github.com/example/todo-app.git
------
 > [internal] load git source https://github.com/example/todo-app.git:
0.313 fatal: could not read Username for 'https://github.com': terminal prompts disabled
------

Para autenticar el builder en GitHub, establece la variable de entorno GIT_AUTH_TOKEN para que contenga un token de acceso válido de GitHub y pásala como un secreto a la compilación:

$ GIT_AUTH_TOKEN=$(gh auth token) docker build \
  --secret id=GIT_AUTH_TOKEN \
  https://github.com/example/todo-app.git

El secreto GIT_AUTH_TOKEN también funciona con ADD para obtener repositorios Git privados como parte de tu compilación:

FROM alpine
ADD https://github.com/example/todo-app.git /src

Esquema de autenticación HTTP

BuildKit admite dos secretos de autenticación Git:

  • GIT_AUTH_TOKEN: Utiliza autenticación básica (Basic auth) con un nombre de usuario fijo de x-access-token (el valor predeterminado al estilo de GitHub)
  • GIT_AUTH_HEADER: Utiliza el valor de cabecera de autorización sin procesar que proporciones (funciona con cualquier proveedor de Git)

Uso de GIT_AUTH_TOKEN (por ejemplo, GitHub)

Cuando usas GIT_AUTH_TOKEN, BuildKit construye una cabecera de autenticación básica utilizando x-access-token como usuario:

Authorization: Basic <base64("x-access-token:<GIT_AUTH_TOKEN>")>

Este método funciona para proveedores que aceptan el patrón de autenticación básica x-access-token, como GitHub. Ejemplo de uso:

$ export GIT_AUTH_TOKEN=$(gh auth token)
$ docker build \
  --secret id=GIT_AUTH_TOKEN \
  https://github.com/example/todo-app.git

Uso de GIT_AUTH_HEADER (cabecera de autorización personalizada)

Cuando usas GIT_AUTH_HEADER, BuildKit utiliza el valor exacto que proporcionas como cabecera Authorization:

Authorization: <GIT_AUTH_HEADER>

Ejemplo de uso con el token de GitLab CI/CD:

$ export GIT_AUTH_HEADER="Basic $(echo -n "gitlab-ci-token:${CI_JOB_TOKEN}" | base64)"
$ docker build \
  --secret id=GIT_AUTH_HEADER \
  https://gitlab.com/example/todo-app.git

Múltiples hosts

Puedes configurar los secretos GIT_AUTH_TOKEN y GIT_AUTH_HEADER en función de cada host, lo que te permite usar diferentes parámetros de autenticación para diferentes nombres de host. Para especificar un nombre de host, añade el nombre de host como sufijo al ID del secreto:

$ export GITHUB_TOKEN=$(gh auth token)
$ export GITLAB_AUTH_HEADER="Basic $(echo -n "gitlab-ci-token:${CI_JOB_TOKEN}" | base64)"
$ docker build \
  --secret id=GIT_AUTH_TOKEN.github.com,env=GITHUB_TOKEN \
  --secret id=GIT_AUTH_HEADER.gitlab.com,env=GITLAB_AUTH_HEADER \
  https://github.com/example/todo-app.git

Autenticación HTTP para COPY y ADD

Para usar secretos en los comandos COPY o ADD, puedes crear secretos HTTP_AUTH_TOKEN_<host> o HTTP_AUTH_HEADER_<host> para usarlos cuando accedas al host especificado. Por ejemplo, HTTP_AUTH_TOKEN_127.0.0.1=token hará que las solicitudes a 127.0.0.1 añadan una cabecera Authorization: Bearer token.

Estas variables siguen la misma convención que el manejo del esquema de autenticación Git HTTP.