从 postgres docker 容器中的环境变量中删除敏感信息

Shi*_*ish 8 postgresql docker dockerfile docker-compose docker-swarm

我想制作一个 postgres 数据库映像,但不想公开使用 docker-compose.yml 文件生成时存储为环境变量的密码和用户名。基本上,我不希望任何人执行容器并找出变量。

一种方法是使用 docker-secrets,但我不想使用 docker swarm,因为我的容器将在单个主机上运行。

我的 docker-compose 文件 -

    version: "3"
    services:
       db:
         image: postgres:10.0-alpine
      environment:
         POSTGRES_USER: 'user'
         POSTGRES_PASSWORD: 'pass'
         POSTGRES_DB: 'db'
Run Code Online (Sandbox Code Playgroud)

我尝试过的事情 -

1)在entrypoint-entrypoint.sh末尾取消设置环境变量

        for f in /docker-entrypoint-initdb.d/*; do
            case "$f" in
            *.sh)     echo "$0: running $f"; . "$f" ;;
            *.sql)    echo "$0: running $f"; "${psql[@]}" -f "$f"; echo ;;
            *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;;
            *)        echo "$0: ignoring $f" ;;
            esac
            echo
        done
        unset POSTGRES_USER
Run Code Online (Sandbox Code Playgroud)

不过什么也没发生。:(

2) docker-entrypoint-initdb.d中的init.sql,不使用env创建db、user和pass。我分享了音量,因为 -

```
   volumes:
       - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
```
Run Code Online (Sandbox Code Playgroud)

并且,在我的主机上,在 docker-entrypoint-initdb.d 中,我将 init.sql 保存为 -

CREATE DATABASE docker_db;CREATE USER docker_user with encrypted password 'pass';GRANT ALL PRIVILEGES ON DATABASE docker_db TO docker_user;

Run Code Online (Sandbox Code Playgroud)

我移动到正在运行的容器中,这个文件在那里,但是没有像文件中提到的那样创建用户或数据库。

过去两天我一直坚持这个,非常感谢任何帮助。

rar*_*iru 9

更新

在 Compose 中使用 docker Secrets 之前,请考虑这个SO 问题github 答案


您可以在 Compose 中使用 docker 机密

如docker postgresql 文档的相关部分所述:

作为通过环境变量传递敏感信息的替代方法,_FILE可以将其附加到之前列出的一些环境变量,从而使初始化脚本从容器中存在的文件加载这些变量的值。特别是,这可用于从存储在/run/secrets/<secret_name>文件中的 Docker 机密中加载密码。

因此您的撰写文件可以读取:

version: "3"
services:
  db:
    image: postgres:10.0-alpine
  environment:
    POSTGRES_USER_FILE: /run/secrets/user
    POSTGRES_PASSWORD_FILE: /run/secrets/pass
    POSTGRES_DB_FILE: /run/secrets/db
  secrets:
    - user
    - pass
    - db

secrets:
  user:
    file: user.txt
  pass:
    file: pass.txt
  db: 
    file: db.txt
Run Code Online (Sandbox Code Playgroud)


Lin*_*nPy 5

使用没有值的 args 在您的Dockerfile

ARG PASSWORD 
Run Code Online (Sandbox Code Playgroud)

并使用

export PASSWORD="MYPASS" && docker build ...
Run Code Online (Sandbox Code Playgroud)

以这种方式ARG运行时不存在container

这是一个完整的例子:

dockerfile

FROM postgres:10.0-alpine

ARG my_user
ARG my_pass
Run Code Online (Sandbox Code Playgroud)

Compose

version: "3"
services:
       db:
         build:
           context: .
           args:
            - my_user
            - my_pass       
         environment:
           - POSTGRES_USER=${my_user}
           - POSTGRES_PASSWORD=${my_pass}
           - POSTGRES_DB=db
Run Code Online (Sandbox Code Playgroud)

运行:

export my_user=test && export my_pass=test1cd && docker-compose up -d --build
Run Code Online (Sandbox Code Playgroud)

现在,如果您登录container并尝试echo $my_pass获得一个空字符串

结果 :

docker exec -ti 3b631d907153 bash

bash-4.3# psql -U test db
psql (10.0)
Type "help" for help.

db=#
Run Code Online (Sandbox Code Playgroud)


Shi*_*ish 1

对于任何其他环境变量,您可以检查@LinPy 的答案。它巧妙地使用 Docker 映像构建时变量来覆盖这些值。但至少,在这种情况下我无法受益,也许是因为这些是 postgres 的一些“特殊”变量,并且无法覆盖它们(欢迎在评论部分中进行任何解释)。

那么,现在来解决这个问题——

问题 - 不希望 postgres 的用户名/密码作为环境变量可见。

解决方案 - 不要在 compose 的环境变量部分指定它们。

相反,使用脚本创建用户/数据库。Postgres 的映像运行一个入门级脚本,该脚本依次在 docker-entrypoint-initdb.d 目录中查找任何 .sh/.sql 文件并运行它。

例子,

目录结构-

-docker-compose.yml
-docker-entrypoint-initdb.d
  -init.sql
Run Code Online (Sandbox Code Playgroud)

我的 docker-compose 文件 -

version: "3"

services:
    db:
      image: postgres:10.0-alpine
      ports:
        - 8765:5432
      volumes:
        - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
Run Code Online (Sandbox Code Playgroud)

初始化.sql 文件

CREATE DATABASE docker_db;CREATE USER docker_user with encrypted password 'pass';GRANT ALL PRIVILEGES ON DATABASE docker_db TO docker_user;
Run Code Online (Sandbox Code Playgroud)
docker-compose up
docker exec -it container-id bash
psql -U docker_user docker_db
psql (10.0)
Type "help" for help.

docker_db=>

Run Code Online (Sandbox Code Playgroud)

现在,从主机中删除 init.sql,因为它是共享卷,它也会从容器中删除。