公式Postgres Dockerイメージ を使用して、構成をカスタマイズしようとしています。この目的のために、コマンドsed
を使用してmax_connections
を変更します。例:
sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /var/lib/postgresql/data/postgresql.conf
この構成を適用するために2つの方法を試しました。 1つ目は、コマンドをスクリプトに追加し、initフォルダー「/docker-entrypoint-initdb.d」内にコピーすることです。 2番目の方法は、「RUN」コマンドを使用してDockerfile内で直接実行することです(この方法は、構成ファイル「/ etc/postgres/...」へのパスが異なる非公式のPostgresqlイメージで正常に機能しました)。どちらの場合も、構成ファイルがないため、変更は失敗します(まだ作成されていないと思います)。
構成を変更するにはどうすればよいですか?
編集1:
イメージの作成に使用されるDockerfileは次のとおりです。
# 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\%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
でボリュームを宣言します。これは基本的に、画像内のそのパスにファイルをコピーできないことを意味します。変更は破棄されます。
いくつかの選択肢があります。
実行時に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を設定できます。
たとえば、これによりPostgresはファイルにログを記録します。
command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs
適応 Vojtech Vitek's answer 、使用できます
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
ファイルはPGDATA
dir(/var/lib/postgresql/data
)内にあります。これは、docker-entrypoint.sh
ラッパーがinitdb
PGDATA
dir初期化のステップ。
DockerのPostgreSQL設定を一貫してカスタマイズするには、config_file
postgresオプションとDockerボリュームを次のように併用することをお勧めします。
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
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;
公式のエントリポイントを実行すると(コンテナを起動するとA.K.A。)、$PGDATA
でinitdb
(デフォルトでは/var/lib/postgresql/data
)が実行され、そのディレクトリに次の2つのファイルが保存されます。
postgresql.conf
とデフォルトの手動設定。postgresql.auto.conf
コマンドで自動的にオーバーライドされる設定のALTER SYSTEM
。エントリポイントは、/docker-entrypoint-initdb.d/*.{sh,sql}
ファイルも実行します。
つまり、そのフォルダーにシェル/ 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
この方法では、新しいイメージを構築する必要がなく、既存のデータベースやデータベースではないことを気にする必要がありません。すべてが影響を受けます。
カスタム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
実行時に、コンテナは/docker-entrypoint-initdb.d/
内のスクリプトを実行し、デフォルトの設定をカスタム設定で上書きします。
すべての答えを調べたところ、別のオプションが残っています。 DockerファイルでCMD値を変更できます(これは最良の方法ではありませんが、目標を達成するための可能な方法です)。
基本的には
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"]
Matthias Braun が提案するcommand: postgres -c config_file=/etc/postgresql/postgresql.conf
ファイルでdocker-compose.yml
を使用するのが最良の選択肢だと思いますが。
この問題に対するかなりローテクな解決策は、永続的なボリューム(ここでは、cloudstor:awsドライバーで示されるAWS EFS)にデータベースファイルをマウントして、サービス(AWSでswarmと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"
構成を永続化することの好ましい副作用は、データベースを永続化することです(または、逆の場合もありました);-)
私のソリューションは、docker-entrypoint-initdb.dを起動する前に設定を変更する必要がある同僚向けです。
「shared_preload_libraries」の設定を変更する必要があったので、その作業中にpostgresには新しいライブラリがプリロードされており、docker-entrypoint-initdb.dのコードで使用できます。
そこで、Dockerfileの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;