将自定义配置位置添加到 Docker Postgres 映像,保留其访问参数

Ghe*_*man 1 postgresql docker docker-compose

我写了一个这样的 Dockerfile:

FROM postgres:11.2-alpine
ADD ./db/postgresql.conf /etc/postgresql/postgresql.conf
CMD ["-c", "config_file=/etc/postgresql/postgresql.conf"]
Run Code Online (Sandbox Code Playgroud)

它只是将自定义配置位置添加到通用 Postgres 映像中。

现在我有以下docker-compose服务描述

db:
  build:
    context: .
    dockerfile: ./db/Dockerfile
  environment:
    POSTGRES_PASSWORD passwordhere
    POSTGRES_USER: user
    POSTGRES_DB: db_name
  ports:
    - 5432:5432
  volumes:
    - ./run/db-data:/var/lib/db/data
Run Code Online (Sandbox Code Playgroud)

问题是,如果添加此配置选项,我将无法再使用这些凭据远程连接到数据库。没有那条CMD线它就可以正常工作。

如果我"postgres"在它前面加上CMD它,由于底层脚本本身预先加上它,它会产生相同的效果。

Mik*_*sky 6

如果所有文件都位于它们需要的位置,我相信您的设置的唯一问题是您从CMD-- 中省略了实际的可执行文件,仅指定了选项。你需要实际运行 postgres:

CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
Run Code Online (Sandbox Code Playgroud)

那应该有效!

编辑以回应下面OP的第一条评论

首先,我确实确认无论“postgres”是否在其中,行为都不会改变CMD。正是如你所说。向前!

postgresql.conf后来我想一定是使用的具体有问题。如果我们能找出默认文件是什么......事实证明我们可以!

如何从 postgres 映像中获取现有的 postgres.conf

1. 创建docker-compose.yml以下内容:

version: "3"

services:
  db:
    image: postgres:11.2-alpine
    environment:
      - POSTGRES_PASSWORD=passwordhere
      - POSTGRES_USER=user
      - POSTGRES_DB=db_name
    ports:
      - 5432:5432
    volumes:
      - ./run/db-data:/var/lib/db/data
Run Code Online (Sandbox Code Playgroud)

2. 使用以下命令启动服务

$ docker-compose run --rm --name=postgres db
Run Code Online (Sandbox Code Playgroud)

3. 在另一个终端中获取此版本中使用的文件的位置:

$ docker exec -it postgres psql --dbname=db_name --username=user --command="SHOW config_file"
               config_file
------------------------------------------
 /var/lib/postgresql/data/postgresql.conf
(1 row)
Run Code Online (Sandbox Code Playgroud)

4、查看默认的postgresql.conf内容

$ docker exec -it postgres cat /var/lib/postgresql/data/postgresql.conf
Run Code Online (Sandbox Code Playgroud)

5. 替换本地配置文件

现在我们要做的就是用./db/postgresql.conf已知工作状态配置的内容替换本地配置文件,并根据需要进行修改。

数据库对象只创建一次!

数据库对象仅由 postgres 容器创建一次(source)。因此,在开发数据库参数时,我们必须删除它们以确保我们处于干净的状态。

这是一个核心(小心!)选项,用于
(1) 删除所有退出的 Docker 容器,然后
(2) 删除所有未附加到容器的 Docker 卷:

$ docker rm $(docker ps -a -q) -f && docker volume prune -f
Run Code Online (Sandbox Code Playgroud)

所以现在我们可以确定从干净的状态开始了!

最终设置

让我们将 Dockerfile 重新带入图片中(就像您在问题中所做的那样)。

docker-compose.yml

version: "3"

services:
  db:
    build:
      context: .
      dockerfile: ./db/Dockerfile
    environment:
      - POSTGRES_PASSWORD=passwordhere
      - POSTGRES_USER=user
      - POSTGRES_DB=db_name
    ports:
      - 5432:5432
    volumes:
      - ./run/db-data:/var/lib/db/data
Run Code Online (Sandbox Code Playgroud)

连接到数据库

现在我们要做的就是从干净的状态开始构建。

# ensure all volumes are deleted (see above)
$ docker-compose build
$ docker-compose run --rm --name=postgres db
Run Code Online (Sandbox Code Playgroud)

我们现在(仍然)可以连接到数据库:

$ docker exec -it postgres psql --dbname=db_name --username=user --command="SELECT COUNT(1) FROM pg_database WHERE datname='db_name'"
Run Code Online (Sandbox Code Playgroud)

最后,我们可以postgres.conf从已知的工作状态进行编辑。