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

Gestionar secretos de forma segura en Docker Compose

Un secreto es cualquier dato, como una contraseña, certificado o clave de API, que no debe transmitirse a través de una red ni almacenarse sin cifrar en un Dockerfile o en el código fuente de tu aplicación.

Docker Compose te ofrece una forma de usar secretos (secrets) sin tener que utilizar variables de entorno para almacenar información. Si inyectas contraseñas y claves de API como variables de entorno, te arriesgas a la exposición no intencionada de información. Los servicios solo pueden acceder a los secretos si se les concede acceso explícitamente mediante un atributo secrets dentro del elemento de nivel superior services.

Las variables de entorno a menudo están disponibles para todos los procesos y puede resultar difícil rastrear su acceso. También pueden imprimirse en los registros (logs) al depurar errores sin tu conocimiento. El uso de secretos mitiga estos riesgos.

Usar secretos

Los secretos se montan como un archivo en /run/secrets/<secret_name> dentro del contenedor.

Llevar un secreto a un contenedor es un proceso de dos pasos. Primero, define el secreto utilizando el elemento de nivel superior secrets en tu archivo de Compose. A continuación, actualiza las definiciones de tus servicios para hacer referencia a los secretos que requieren mediante el atributo secrets. Compose otorga acceso a los secretos por servicio.

A diferencia de otros métodos, esto permite un control de acceso granular dentro del contenedor de un servicio mediante los permisos estándar del sistema de archivos.

Ejemplos

Inyección de secretos en un solo servicio

En el siguiente ejemplo, al servicio frontend se le otorga acceso al secreto my_secret. En el contenedor, /run/secrets/my_secret se establece con el contenido del archivo ./my_secret.txt.

services:
  myapp:
    image: myapp:latest
    secrets:
      - my_secret
secrets:
  my_secret:
    file: ./my_secret.txt

Intercambio de secretos entre múltiples servicios y gestión de contraseñas

services:
  db:
    image: mysql:latest
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_root_password
      - db_password

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: db_password.txt
  db_root_password:
    file: db_root_password.txt

volumes:
  db_data:

En el ejemplo avanzado anterior:

  • El atributo secrets bajo cada servicio define los secretos que deseas inyectar en el contenedor específico.
  • La sección secrets a nivel superior define las variables db_password and db_root_password y proporciona el archivo (file) que aporta sus valores.
  • El despliegue de cada contenedor implica que Docker crea un montaje de vinculación (bind mount) bajo /run/secrets/<secret_name> con sus valores específicos.
Note

Las variables de entorno terminadas en _FILE que se muestran aquí son una convención utilizada por algunas imágenes, incluidas las Imágenes Oficiales de Docker (Docker Official Images) como mysql y postgres.

Secretos de compilación (Build secrets)

En el siguiente ejemplo, el secreto npm_token se pone a disposición en tiempo de compilación. Su valor se toma de la variable de entorno NPM_TOKEN.

services:
  myapp:
    build:
      secrets:
        - npm_token
      context: .

secrets:
  npm_token:
    environment: NPM_TOKEN

Recursos