programing

공식 Postgre의 구성 파일을 사용자 정의하는 방법SQL Docker 이미지?

javamemo 2023. 5. 15. 20:59
반응형

공식 Postgre의 구성 파일을 사용자 정의하는 방법SQL Docker 이미지?

저는 공식 Postgres Docker 이미지를 사용하여 구성을 사용자 지정하려고 합니다.이를 위해 다음 명령을 사용합니다.sed 바꾸다max_connections예:

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

이 구성을 적용하기 위해 두 가지 방법을 시도했습니다.

  • 번째 하여 init하는 방법입니다./docker-entrypoint-initdb.d.
  • 은 "하여 내 이은 비공식 Postgre "RUN" ▁a▁with▁fine▁method▁worked▁the▁postofficial-this▁non다서▁is▁by). 파일에 가 다른 는 SQL 이미지입니다./etc/postgres/...).

두 경우 모두 구성 파일이 없기 때문에 변경이 실패합니다(아직 생성되지 않은 것 같습니다).

구성을 어떻게 변경해야 합니까?

이미지를 만드는 데 사용된 도커 파일은 다음과 같습니다.

# 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"]

이 도커 파일을 사용하면 빌드 프로세스에서 다음 오류가 발생합니다.

sed: /var/lib/postgresql/data/postgresql.conf를 읽을 수 없음: 해당 파일 또는 디렉토리 없음

도커 컴포지트

도커 컴포지트로 작업할 때 다음을 사용할 수 있습니다.command: postgres -c option=value의 신의에docker-compose.ymlPostgres를 구성합니다.

예를 들어 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.ymlPostgres를 구성하는 방법을 보여주는 내 응용 프로그램:

# 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의 경우 호스트의 로그 디렉토리에 올바른 사용 권한이 있어야 합니다.그렇지 않으면 약간 오해의 소지가 있는 오류가 발생합니다.

FATAL: "/logs/postgresql-2017-02-04_115222.log" 로그 파일을 열 수 없습니다. 권한이 거부되었습니다.

오류 메시지는 컨테이너의 디렉터리에 잘못된 권한이 있음을 시사하므로, 실제로는 호스트의 디렉터리가 쓰기를 허용하지 않습니다.

이 문제를 해결하기 위해 다음을 사용하여 호스트에 대한 올바른 사용 권한을 설정했습니다.

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

postgres:9.4을 서에상속이볼선언합니로 선언합니다./var/lib/postgresql/data이는 기본적으로 이미지의 해당 경로에 파일을 복사할 수 없음을 의미합니다. 변경 내용은 삭제됩니다.

몇 가지 선택사항이 있습니다.

  • 을 런타임에 할 수 .docker run -v postgresql.conf:/var/lib/postgresql/data/postgresql.conf ...하지만, 그것이 기존 볼륨과 어떻게 상호 작용할지는 정확히 모르겠습니다.

  • 컨테이너가 시작될 때 파일을 복사할 수 있습니다.을 복사한 에 " ▁the▁script▁a▁to다호니▁copy합출▁into▁at▁do,를▁that▁build▁then▁file▁which트▁call▁the립▁your이▁volume크스▁location▁a렇neath에서게▁the다음▁under▁isnentrypoint또는cmd그러면 파일이 올바른 위치에 복사되고 Postgres가 시작됩니다.

  • Postgres 공식 이미지 뒤에 있는 프로젝트를 복제하고 VOLUME이 선언되기 전에 Docker 파일을 편집하여 자체 구성 파일을 추가합니다(VOLUME 명령이 런타임에 자동으로 복사되기 전에 추가된 모든 항목).

  • 명령 옵션의 모든 구성 변경 사항을 도커 합성 파일로 전달

다음과 같이:

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

, 할 때)을는 공식진을즉때실할 (행, 컨를실때할)다행니실됩행점입너테이▁when▁runs가 실행됩니다.initdb$PGDATA(/var/lib/postgresql/data기본적으로), 두 개의 파일을 해당 디렉토리에 저장합니다.

  • postgresql.conf기본 수동 설정을 사용합니다.
  • postgresql.auto.conf명령을 사용하여 설정을 자동으로 재정의합니다.

임의의 진점은다실행니다합음을을 합니다./docker-entrypoint-initdb.d/*.{sh,sql}files 파일

이 모든 것은 다음 부팅을 위해 서버를 구성하는 셸/SQL 스크립트를 해당 폴더에 제공할 수 있음을 의미합니다(DB 초기화 직후 또는 다음에 컨테이너를 부팅할 때).

예:

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

이렇게 하면 새 이미지를 작성할 필요가 없으며, 데이터베이스가 이미 존재하는지 여부에 대해 신경 쓸 필요가 없습니다. 모든 것이 영향을 받게 됩니다.

Postgres Docker 컨테이너에 사용자 지정 postgresql.conf 삽입

은 " " 입니다.postgresql.conf는 일파장 내에 .PGDATAdir)/var/lib/postgresql/data할 때 더. 이는 ), Postgres에서 시작된 입니다.docker-entrypoint.sh는 니다합호출래퍼를 합니다.initdb을 위한 조치.PGDATA initializationdir 파일입니다.

PostgrePostgre를 지정하려면 과 같이 .의 SQL 일관되게 합니다.config_file다음과 같은 도커 볼륨과 함께 Postgres 옵션:

프로덕션 데이터베이스(PGDATA dir as Persistent Volume)

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 dir는 다음 후에 폐기됩니다.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

디버깅

  1. 를 합니다.-d에서 (선택사항)docker run명령을 사용하여 서버 로그를 직접 확인할 수 있습니다.

  2. 클라이언트를 사용하여 Postgres 서버에 연결하고 구성을 쿼리합니다.

    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;
    

당신은 당신의 커스텀을 넣을 수 있습니다.postgresql.conf컨테이너 내부의 임시 파일에 저장하고 런타임에 기본 구성을 덮어씁니다.

실행 방법:

  • 정의 postgresql.conf의 컨테이너 에▁your안▁inside당.
  • 를 합니다.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

▁inside 안에서 합니다./docker-entrypoint-initdb.d/기본 구성을 사용자 지정 구성으로 덮어씁니다.

또 : 의 문제를 바꿀 수 있습니다.CMDDocker 파일의 값(최고의 파일은 아니지만 목표를 달성하기 위한 가능한 방법).

기본적으로 다음과 같은 작업이 필요합니다.

  • 구성 파일을 도커 컨테이너에 복사합니다.
  • Postgres 시작 옵션 재정의

도커 파일 예:

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마티아스 브라운이 제안한 파일이 최선의 선택입니다.

는 또한 이미지를.FROM postgres) 할 수 그리고 다음 명령을 실행하여 구성을 변경할 수 있었습니다.

첫 번째는 Postgre를 찾는 것입니다.SQL 구성 파일입니다.이 작업은 실행 중인 데이터베이스에서 이 명령을 실행하여 수행할 수 있습니다.

SHOW config_file;

나의 경우는 그것이 돌아옵니다./data/postgres/postgresql.conf.

다음 단계는 실행 중인 Postgre의 해시가 무엇인지 알아보는 것입니다.SQL 도커 컨테이너입니다.

docker ps -a

실행 중인 모든 컨테이너 목록이 반환됩니다.제 경우에는 이렇게 보입니다.

...
0ba35e5427d9    postgres    "docker-entrypoint.s…" ....
...

이제 다음을 실행하여 컨테이너 내부의 bash로 전환해야 합니다.

docker exec -it 0ba35e5427d9 /bin/bash

컨테이너 내부에서 구성이 올바른 경로에 있는지 확인하고 표시합니다.

cat /data/postgres/postgresql.conf

저는 최대 연결 수를 100에서 1000으로, 공유 버퍼를 128MB에서 3GB로 변경하고 싶었습니다.sed 명령을 사용하여 검색을 수행하고 구성에서 해당 변수로 대체할 수 있습니다.

sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /data/postgres/postgresql.conf
sed -i -e"s/^shared_buffers = 128MB.*$/shared_buffers = 3GB/" /data/postgres/postgresql.conf

우리가 마지막으로 해야 할 일은 컨테이너 내의 데이터베이스를 다시 시작하는 것입니다.사용 중인 PostGres 버전을 확인합니다.

cd /usr/lib/postgresql/
ls 

나의 경우에는.12이제 올바른 버전으로 다음 명령을 실행하여 데이터베이스를 다시 시작할 수 있습니다.

su - postgres -c "PGDATA=$PGDATA /usr/lib/postgresql/12/bin/pg_ctl -w restart"

이 문제에 대한 상당히 낮은 기술의 해결책은 데이터베이스 파일이 지속 볼륨(여기서는 Cloudstor:aws 드라이버 사양으로 표시된 AWS EFS)에 마운트된 상태로 서비스를 선언하는 것입니다(AWS 및 yaml 파일에서 스웜 사용).

  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"
  1. DB가 이미지 기본 설정으로 초기화된 상태로 나타납니다.
  2. 컨테이너 내부의 conf 설정을 편집합니다(예: 다시 시작해야 하는 최대 동시 연결 수를 늘리려는 경우).
  3. 실행 중인 컨테이너를 중지합니다(또는 서비스를 0으로 축소했다가 다시 1로 축소
  4. 떼가 새 컨테이너를 생성하고, 이번에는 지속적인 구성 설정을 선택하여 즐겁게 적용합니다.

구성을 유지할 때의 좋은 부작용은 데이터베이스도 유지한다는 것입니다(또는 그 반대의 경우도 마찬가지입니까);-).

내 솔루션은 도커-엔트리포인트-initdb.d를 시작하기 전에 구성을 변경해야 하는 동료를 위한 것입니다.

저는 'shared_preload_libraries' 설정을 변경하여 작업 중에 postgres에 이미 새 라이브러리가 사전 로드되어 있고 docker-entrypoint-initdb.d의 코드가 이를 사용할 수 있도록 해야 했습니다.

그래서 방금 도커 파일의 postgresql.conf.sample 파일을 패치했습니다.

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

그리고 이 패치를 통해 docker-entrypoint-initdb.d/:의 .sql 파일에 확장자를 추가할 수 있습니다.

CREATE EXTENSION pg_cron;

하면 도커포컴지트볼마수있다습니운할트륨을로 볼륨을 수 .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

언급URL : https://stackoverflow.com/questions/30848670/how-to-customize-the-configuration-file-of-the-official-postgresql-docker-image

반응형