如何自定义官方PostgreSQL Docker镜像的配置文件?

新手上路,请多包涵

我正在使用 官方 Postgres Docker 映像 来尝试自定义其配置。为此,我使用命令 sed 来更改 max_connections 例如:

 sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /var/lib/postgresql/data/postgresql.conf

我尝试了两种方法来应用此配置。第一种是将命令添加到脚本并将其复制到初始化文件夹“/docker-entrypoint-initdb.d”中。第二种方法是使用“RUN”命令直接在我的 Dockerfile 中运行它们(此方法适用于配置文件“/etc/postgres/…”的路径不同的非官方 Postgresql 映像)。在这两种情况下,更改都失败了,因为缺少配置文件(我认为它尚未创建)。

我应该如何更改配置?

编辑1:

这是用于创建映像的 Dockerfile:

 # Database (http://www.cs3c.ma/)

FROM postgres:9.4
MAINTAINER Sabbane <contact@cs3c.ma>

ENV TERM=xterm

RUN apt-get update
RUN apt-get install -y nano

ADD scripts /scripts
# ADD scripts/setup-my-schema.sh /docker-entrypoint-initdb.d/

# Allow connections from anywhere.
RUN sed -i -e"s/^#listen_addresses =.*$/listen_addresses = '*'/" /var/lib/postgresql/data/postgresql.conf
RUN echo "host    all    all    0.0.0.0/0    md5" >> /var/lib/postgresql/data/pg_hba.conf

# Configure logs
RUN sed -i -e"s/^#logging_collector = off.*$/logging_collector = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_directory = 'pg_log'.*$/log_directory = '\/var\/log\/postgresql'/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_filename = 'postgresql-\%Y-\%m-\%d_\%H\%M\%S.log'.*$/log_filename = 'postgresql_\%a.log'/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_file_mode = 0600.*$/log_file_mode = 0644/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_truncate_on_rotation = off.*$/log_truncate_on_rotation = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_rotation_age = 1d.*$/log_rotation_age = 1d/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_min_duration_statement = -1.*$/log_min_duration_statement = 0/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_checkpoints = off.*$/log_checkpoints = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_connections = off.*$/log_connections = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_disconnections = off.*$/log_disconnections = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^log_line_prefix = '\%t \[\%p-\%l\] \%q\%u@\%d '.*$/log_line_prefix = '\%t \[\%p\]: \[\%l-1\] user=\%u,db=\%d'/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_lock_waits = off.*$/log_lock_waits = on/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#log_temp_files = -1.*$/log_temp_files = 0/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#statement_timeout = 0.*$/statement_timeout = 1800000        # in milliseconds, 0 is disabled (current 30min)/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^lc_messages = 'en_US.UTF-8'.*$/lc_messages = 'C'/" /var/lib/postgresql/data/postgresql.conf

# Performance Tuning
RUN sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^shared_buffers =.*$/shared_buffers = 16GB/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#effective_cache_size = 128MB.*$/effective_cache_size = 48GB/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#work_mem = 1MB.*$/work_mem = 16MB/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#maintenance_work_mem = 16MB.*$/maintenance_work_mem = 2GB/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#checkpoint_segments = .*$/checkpoint_segments = 32/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#checkpoint_completion_target = 0.5.*$/checkpoint_completion_target = 0.7/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#wal_buffers =.*$/wal_buffers = 16MB/" /var/lib/postgresql/data/postgresql.conf
RUN sed -i -e"s/^#default_statistics_target = 100.*$/default_statistics_target = 100/" /var/lib/postgresql/data/postgresql.conf

VOLUME ["/var/lib/postgresql/data", "/var/log/postgresql"]

CMD ["postgres"]

使用此 Dockerfile,构建过程会显示错误: sed: can't read /var/lib/postgresql/data/postgresql.conf: No such file or directory

原文由 Sabbane 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

您继承的 postgres:9.4 映像在 /var/lib/postgresql/data 声明了一个卷。这实质上意味着您不能将任何文件复制到图像中的该路径;更改将被丢弃。

你有几个选择:

  • 您可以在运行时使用 docker run -v postgresql.conf:/var/lib/postgresql/data/postgresql.conf ... 将自己的配置文件添加为卷。但是,我不确定这将如何与现有卷交互。

  • 您可以在容器启动时复制文件。为此,请将文件复制到不在卷下方的位置,然后从 entrypointcmd 调用脚本,这会将文件复制到正确的位置并启动 Postgres。

  • 克隆 Postgres 官方镜像后面的项目并编辑 Dockerfile 以在声明 VOLUME 之前添加您自己的配置文件(在运行时自动复制在 VOLUME 指令之前添加的任何内容)。

  • 在 docker-compose 文件中传递命令选项中的所有配置更改

像这样:

 services:
  postgres:
    ...
    command:
      - "postgres"
      - "-c"
      - "max_connections=1000"
      - "-c"
      - "shared_buffers=3GB"
      - "-c"
      ...

原文由 Adrian Mouat 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用 Docker 撰写

使用 Docker Compose 时,您可以在 command: postgres -c option=value docker-compose.yml 来配置 Postgres。

例如,这会使 Postgres 记录到文件中:

 command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs

改编 Vojtech Vitek 的答案,你可以使用

command: postgres -c config_file=/etc/postgresql.conf

更改 Postgres 将使用的配置文件。您将使用卷安装自定义配置文件:

 volumes:
   - ./customPostgresql.conf:/etc/postgresql.conf


这是我的应用程序的 docker-compose.yml ,展示了如何配置 Postgres:

 # Start the app using docker-compose pull && docker-compose up to make sure you have the latest image
version: '2.1'
services:
  myApp:
    image: registry.gitlab.com/bullbytes/myApp:latest
    networks:
      - myApp-network
  db:
     image: postgres:9.6.1
     # Make Postgres log to a file.
     # More on logging with Postgres: https://www.postgresql.org/docs/current/static/runtime-config-logging.html
     command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs
     environment:
       # Provide the password via an environment variable. If the variable is unset or empty, use a default password
       # Explanation of this shell feature: https://unix.stackexchange.com/questions/122845/using-a-b-for-variable-assignment-in-scripts/122848#122848
       - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-4WXUms893U6j4GE&Hvk3S*hqcqebFgo!vZi}
     # If on a non-Linux OS, make sure you share the drive used here. Go to Docker's settings -> Shared Drives
     volumes:
       # Persist the data between container invocations
       - postgresVolume:/var/lib/postgresql/data
       - ./logs:/logs
     networks:
       myApp-network:
         # Our application can communicate with the database using this hostname
         aliases:
           - postgresForMyApp
networks:
  myApp-network:
    driver: bridge
# Creates a named volume to persist our data. When on a non-Linux OS, the volume's data will be in the Docker VM
# (e.g., MobyLinuxVM) in /var/lib/docker/volumes/
volumes:
  postgresVolume:


写入日志目录的权限

请注意,在 Linux 上时,主机上的日志目录必须具有正确的权限。否则你会得到稍微误导的错误

致命:无法打开日志文件“/logs/postgresql-2017-02-04_115222.log”:权限被拒绝

我说的是误导,因为错误消息表明 容器 中的目录具有错误的权限,而实际上 主机上 的目录不允许写入。

为了解决这个问题,我在主机上设置了正确的权限,使用

chgroup ./logs docker && chmod 770 ./logs

原文由 Matthias Braun 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏