공식 PostgreSQL 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"내에 복사하는 것입니다. 두 번째 방법은 "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
postgres:9.4
당신이로부터 상속 한 이미지에 볼륨을 선언합니다 /var/lib/postgresql/data
. 이것은 본질적으로 이미지의 해당 경로에 파일을 복사 할 수 없음을 의미합니다. 변경 사항이 삭제됩니다.
몇 가지 선택이 있습니다.
.NET을 사용하여 런타임에 자체 구성 파일을 볼륨으로 추가 할 수 있습니다
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"
...
Docker Compose 사용
도커 작성 작업을 할 때 사용할 수있는 command: postgres -c option=value
당신의 docker-compose.yml
포스트 그레스를 구성 할 수 있습니다.
예를 들어 다음은 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'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
사용자 지정 postgresql.conf를 postgres Docker 컨테이너에 삽입
기본 postgresql.conf
파일은 PGDATA
dir ( /var/lib/postgresql/data
) 내에 있으며 , 이는 docker-entrypoint.sh
래퍼가 dir 초기화 initdb
단계를 호출하기 때문에 특히 postgres 컨테이너를 처음 실행할 때 상황을 더욱 복잡하게 만듭니다 PGDATA
.
Docker에서 PostgreSQL 구성을 일관되게 사용자 지정하려면 다음 config_file
과 같이 Docker 볼륨과 함께 postgres 옵션을 사용하는 것이 좋습니다 .
프로덕션 데이터베이스 (영구 볼륨으로서의 PGDATA 디렉토리)
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
. psql 클라이언트를 사용하여 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;
When you run the official entrypoint (A.K.A. when you launch the container), it runs initdb
in $PGDATA
(/var/lib/postgresql/data
by default), and then it stores in that directory these 2 files:
postgresql.conf
with default manual settings.postgresql.auto.conf
with settings overriden automatically withALTER SYSTEM
commands.
The entrypoint also executes any /docker-entrypoint-initdb.d/*.{sh,sql}
files.
All this means you can supply a shell/SQL script in that folder that configures the server for the next boot (which will be immediately after the DB initialization, or the next times you boot the container).
Example:
conf.sql
file:
ALTER SYSTEM SET max_connections = 6;
ALTER SYSTEM RESET shared_buffers;
Dockerfile
file:
FROM posgres:9.6-alpine
COPY *.sql /docker-entrypoint-initdb.d/
RUN chmod a+r /docker-entrypoint-initdb.d/*
And then you will have to execute conf.sql
manually in already-existing databases. Since configuration is stored in the volume, it will survive rebuilds.
Another alternative is to pass -c
flag as many times as you wish:
docker container run -d postgres -c max_connections=6 -c log_lock_waits=on
This way you don't need to build a new image, and you don't need to care about already-existing or not databases; all will be affected.
You can put your custom postgresql.conf
in a temporary file inside the container, and overwrite the default configuration at runtime.
To do that :
- Copy your custom
postgresql.conf
inside your container - Copy the
updateConfig.sh
file in/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
At runtime, the container will execute the script inside /docker-entrypoint-initdb.d/
and overwrite the default configuration with yout custom one.
I looked through all answers and there is another option left. You can change your CMD value in docker file (it is not the best one, but still possible way to achieve your goal).
Basically we need to
- Copy config file in docker container
- Override postgres start options
Docker file example:
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"]
Though I think using command: postgres -c config_file=/etc/postgresql/postgresql.conf
in your docker-compose.yml
file proposed by Matthias Braun is the best option.
A fairly low-tech solution to this problem seems to be to declare the service (I'm using swarm on AWS and a yaml file) with your database files mounted to a persisted volume (here AWS EFS as denoted by the cloudstor:aws driver specification).
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"
- The db comes up as initialized with the image default settings.
- You edit the conf settings inside the container, e.g if you want to increase the maximum number of concurrent connections that requires a restart
- stop the running container (or scale the service down to zero and then back to one)
- the swarm spawns a new container, which this time around picks up your persisted configuration settings and merrily applies them.
A pleasant side-effect of persisting your configuration is that it also persists your databases (or was it the other way around) ;-)
My solution is for colleagues who needs to make changes in config before launching docker-entrypoint-initdb.d
I was needed to change 'shared_preload_libraries' setting so during it's work postgres already has new library preloaded and code in docker-entrypoint-initdb.d can use it.
So I just patched postgresql.conf.sample file in 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
And with this patch it become possible to add extension in .sql file in docker-entrypoint-initdb.d/:
CREATE EXTENSION pg_cron;
'IT TIP' 카테고리의 다른 글
Pandas의 다른 값을 기반으로 한 값 변경 (0) | 2020.10.13 |
---|---|
AppCompat v21을 사용하여 Android에서 FAB (플로팅 작업 버튼)를 만드는 방법은 무엇입니까? (0) | 2020.10.13 |
프로그래밍 방식으로 Android 앱에서 Spinner를 열 수 있나요? (0) | 2020.10.13 |
둘 이상의 결과가있는 하위 쿼리를 사용하여 테이블에 값을 삽입하려면 어떻게해야합니까? (0) | 2020.10.13 |
Python에서 줄 바꿈 구분 기호를 사용하여 문자열 분할 (0) | 2020.10.13 |