Подтвердить что ты не робот

Как настроить файл конфигурации официального изображения PostgreSQL Docker?

Я использую официальный образ Postgres Docker, пытаясь настроить его конфигурацию. Для этой цели я использую команду sed для изменения max_connections, например:

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

Я попробовал два метода для применения этой конфигурации. Первый заключается в добавлении команд в script и копировании его в папку инициализации "/docker-entrypoint-initdb.d". Второй способ - запустить их непосредственно в моем файле Docker с командой "RUN" (этот метод отлично работал с неофициальным изображением Postgresql с другим путем к файлу конфигурации "/etc/postgres/..." ). В обоих случаях изменения терпят неудачу, потому что отсутствует файл конфигурации (я думаю, что он еще не создан).

Как мне изменить конфигурацию?

Изменить 1:

Вот файл Docker, используемый для создания изображения:

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

FROM postgres:9.4
MAINTAINER Sabbane <[email protected]>

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\%[email protected]\%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

4b9b3361

Ответ 1

Изображение postgres:9.4 вы унаследовали, объявляет том в /var/lib/postgresql/data. По сути, это означает, что вы не можете копировать файлы по этому пути в вашем изображении; изменения будут отменены.

У вас есть несколько вариантов:

  • Вы можете просто добавить свои собственные файлы конфигурации как том во время выполнения с помощью docker run -v postgresql.conf: /var/lib/postgresql/data/postgresql.conf... Однако я не уверен, как именно это будет взаимодействовать с существующим томом.

  • Вы можете скопировать файл при запуске контейнера. Для этого скопируйте файл в сборку в месте, которое не находится под томом, затем вызовите сценарий из точки входа или cmd, который скопирует файл в правильное местоположение и запустит postgres.

  • Клонируйте проект за официальным изображением Postgres и отредактируйте Dockerfile, чтобы добавить свой собственный файл конфигурации до объявления VOLUME (все, что было добавлено до того, как инструкция VOLUME будет автоматически скопирована во время выполнения).

  • Передайте все изменения конфигурации в опции команды в файле docker-compose

лайк:

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

Ответ 2

С Docker Compose

При работе с 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
       - 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 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 data will be in the Docker VM
# (e.g., MobyLinuxVM) in /var/lib/docker/volumes/
volumes:
  postgresVolume:

Разрешение на запись в каталог журналов

Обратите внимание, что в Linux каталог журналов на хосте должен иметь необходимые разрешения. В противном случае вы получите слегка вводящую в заблуждение ошибку

FATAL: не удалось открыть файл журнала "/logs/postgresql-2017-02-04_115222.log": разрешение отклонено

Я говорю, что вводит в заблуждение, поскольку сообщение об ошибке предполагает, что каталог в контейнере имеет неправильное разрешение, хотя в действительности каталог на хосте не разрешает запись.

Чтобы это исправить, я установил правильные разрешения на хосте, используя

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

Ответ 3

Ввести пользовательский postgresql.conf в postgres Контейнер докеров

Файл postgresql.conf по умолчанию находится в каталоге PGDATA dir (/var/lib/postgresql/data), что усложняет работу, особенно при запуске контейнера postgres в первый раз, поскольку обертка docker-entrypoint.sh вызывает шаг initdb для PGDATA инициализация dir.

Чтобы настроить конфигурацию PostgreSQL в Docker последовательно, я предлагаю использовать параметр config_file postgres вместе с томами Docker следующим образом:

Производственная база данных (PGDATA dir как постоянный объем)

docker run -d \
-v $CUSTOM_CONFIG:/etc/postgresql.conf \
-v $CUSTOM_DATADIR:/var/lib/postgresql/data \
-e POSTGRES_USER=postgres \
-p 5432:5432 \
--name postgres \
postgres:9.6 postgres -c config_file=/etc/postgresql.conf

База данных тестирования (каталог PGDATA будет отброшен после docker rm)

docker run -d \
-v $CUSTOM_CONFIG:/etc/postgresql.conf \
-e POSTGRES_USER=postgres \
--name postgres \
postgres:9.6 postgres -c config_file=/etc/postgresql.conf

Отладка

  • Удалите параметр -d (отсоединить) из docker run, чтобы просмотреть журналы сервера напрямую.
  • Подключитесь к серверу postgres с клиентом psql и запросите конфигурацию:

    docker run -it --rm --link postgres:postgres postgres:9.6 sh -c 'exec psql -h $POSTGRES_PORT_5432_TCP_ADDR -p $POSTGRES_PORT_5432_TCP_PORT -U postgres'
    
    psql (9.6.0)
    Type "help" for help.
    
    postgres=# SHOW all;
    

Ответ 4

Когда вы запускаете официальную точку входа (A.K.A. при запуске контейнера), она запускает initdb в $PGDATA (/var/lib/postgresql/data по умолчанию), а затем сохраняет в этом каталоге эти 2 файла:

  • postgresql.conf с настройками по умолчанию вручную.
  • postgresql.auto.conf, когда настройки автоматически переопределяются с помощью ALTER SYSTEM.

Точка входа также выполняет любые /docker-entrypoint-initdb.d/*.{sh,sql} файлы.

Все это означает, что вы можете предоставить оболочку /SQL script в этой папке, которая настраивает сервер для следующей загрузки (которая будет сразу после инициализации БД или в следующий раз, когда вы загрузите контейнер).

Пример:

conf.sql файл:

ALTER SYSTEM SET max_connections = 6;
ALTER SYSTEM RESET shared_buffers;

Dockerfile файл:

FROM posgres:9.6-alpine
COPY *.sql /docker-entrypoint-initdb.d/
RUN chmod a+r /docker-entrypoint-initdb.d/*

И тогда вам придется выполнять conf.sql вручную в уже существующих базах данных. Поскольку конфигурация хранится в томе, она будет пересоздана.


Другая альтернатива - передать флаг -c столько раз, сколько пожелаете:

docker container run -d postgres -c max_connections=6 -c log_lock_waits=on

Таким образом вам не нужно создавать новый образ, и вам не нужно заботиться о уже существующих или нет базах данных; все будет затронуто.

Ответ 5

Вы можете поместить свой пользовательский postgresql.conf во временный файл внутри контейнера и перезаписать конфигурацию по умолчанию во время выполнения.

Для этого:

  • Скопируйте свой собственный postgresql.conf внутри вашего контейнера
  • Скопируйте файл updateConfig.sh в /docker-entrypoint-initdb.d/

Dockerfile

FROM postgres:9.6

COPY postgresql.conf      /tmp/postgresql.conf
COPY updateConfig.sh      /docker-entrypoint-initdb.d/_updateConfig.sh

updateConfig.sh

#!/usr/bin/env bash

cat /tmp/postgresql.conf > /var/lib/postgresql/data/postgresql.conf

Во время выполнения контейнер выполнит script внутри /docker-entrypoint-initdb.d/ и перезапишет конфигурацию по умолчанию с вашей пользовательской.

Ответ 6

Я просмотрел все ответы и остался еще один вариант. Вы можете изменить значение CMD в файле Docker (это не самый лучший, но все же возможный способ достижения вашей цели).

В основном нам нужно

  • Скопируйте файл конфигурации в Docker-контейнер
  • Переопределить параметры запуска postgres

Пример файла Docker:

FROM postgres:9.6
USER postgres

# Copy postgres config file into container
COPY postgresql.conf /etc/postgresql

# Override default postgres config file
CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]

Хотя я думаю, что использование command: postgres -c config_file=/etc/postgresql/postgresql.conf в вашем docker-compose.yml файл docker-compose.yml предложенный Матиасом Брауном, является лучшим вариантом.

Ответ 7

Довольно низкотехнологичное решение этой проблемы состоит в том, чтобы объявить службу (я использую swarm на AWS и файл yaml) с файлами базы данных, установленными на постоянный том (здесь AWS EFS, обозначаемая облачной системой: спецификация драйвера aws).

  version: '3.3'
  services:
    database:
      image: postgres:latest
      volumes:
        - postgresql:/var/lib/postgresql
        - postgresql_data:/var/lib/postgresql/data
    volumes:
       postgresql:
         driver: "cloudstor:aws" 
       postgresql_data:
         driver: "cloudstor:aws"
  • db появляется как инициализированное настройками по умолчанию изображения.
  • Вы редактируете настройки conf внутри контейнера, например, если вы хотите увеличить максимальное количество одновременных подключений, требующих перезагрузки.
  • остановить запущенный контейнер (или масштабировать сервис до нуля, а затем вернуться к одному)
  • рой порождает новый контейнер, который на этот раз собирает ваши сохраненные настройки конфигурации и весело применяет их.

Приятным побочным эффектом сохранения вашей конфигурации является то, что она также сохраняет ваши базы данных (или наоборот);-)

Ответ 8

Мое решение для коллег, которым необходимо внести изменения в конфигурацию перед запуском docker-entrypoint-initdb.d

Мне нужно было изменить настройку shared_preload_libraries, чтобы во время работы postgres уже предварительно загружала новую библиотеку, и код в docker-entrypoint-initdb.d мог ее использовать.

Поэтому я просто пропатчил файл postgresql.conf.sample в Dockerfile:

RUN echo "shared_preload_libraries='citus,pg_cron'" >> /usr/share/postgresql/postgresql.conf.sample
RUN echo "cron.database_name='newbie'" >> /usr/share/postgresql/postgresql.conf.sample

И с этим патчем стало возможным добавить расширение в файл .sql в docker-entrypoint-initdb.d/:

CREATE EXTENSION pg_cron;

Ответ 9

Используя docker compose, вы можете смонтировать том с помощью postgresql.auto.conf. Пример:

version: '2'

services:
  db:
    image: postgres:10.9-alpine
    volumes:
      - postgres:/var/lib/postgresql/data:z
      - ./docker/postgres/postgresql.auto.conf:/var/lib/postgresql/data/postgresql.auto.conf
    ports:
      - 5432:5432