在 Docker Compose 中安全地管理秘密

秘密是任何不應透過網路傳輸或以未加密形式儲存在 Dockerfile 或應用程式原始碼中的資料,例如密碼、證書或 API 金鑰。

Docker Compose 提供了一種使用秘密而無需使用環境變數來儲存資訊的方法。如果您將密碼和 API 金鑰作為環境變數注入,則存在無意資訊洩露的風險。服務只能在頂層 services 元素中的 secrets 屬性明確授予訪問許可權時才能訪問秘密。

環境變數通常對所有程序都可用,並且可能難以跟蹤訪問。在除錯錯誤時,它們還可能在您不知情的情況下列印在日誌中。使用秘密可以緩解這些風險。

使用秘密

秘密以檔案形式掛載到容器內的 /run/secrets/<secret_name> 中。

將秘密匯入容器是一個兩步過程。首先,在 Compose 檔案中的頂層 secret 元素 中定義秘密。接下來,更新您的服務定義,以 secrets 屬性 引用它們所需的秘密。Compose 按服務授予秘密訪問許可權。

與其他方法不同,這允許透過標準檔案系統許可權在服務容器內進行精細的訪問控制。

示例

單服務秘密注入

在以下示例中,前端服務被授予訪問 my_secret 秘密的許可權。在容器中,/run/secrets/my_secret 設定為檔案 ./my_secret.txt 的內容。

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

多服務秘密共享和密碼管理

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:

在上面的高階示例中

  • 每個服務下的 secrets 屬性定義了您想要注入到特定容器中的秘密。
  • 頂層 secrets 部分定義了變數 db_passworddb_root_password,並提供了填充其值的 file
  • 每個容器的部署意味著 Docker 會在 /run/secrets/<secret_name> 下建立帶有其特定值的繫結掛載。
注意

這裡演示的 _FILE 環境變數是某些映象(包括 Docker 官方映象,如 mysqlpostgres)使用的一種約定。

構建機密

在以下示例中,npm_token 秘密在構建時可用。其值取自 NPM_TOKEN 環境變數。

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

secrets:
  npm_token:
    environment: NPM_TOKEN

資源