PostgreSQL on RHEL の Docker を作成します。
Red Hat Enterprise Linux は開発目的であれば無料で利用することができます。
https://redhat.sios.jp/red-hat-developer-program
これを利用して、RHEL 上に PostgreSQL をインストールした Docker イメージを作成したいと思います。
Developer Program への登録は上記記事を参照してください。
intra-mart の検証用として利用したいので、intra-mart が要求する設定をあらかじめ実施します。
これによって、docker run 後何も考えずにすぐに検証用として利用できるような PostgreSQL 9.6 の環境が作れるようになります。
FROM registry.access.redhat.com/rhel7.6
EXPOSE 22 5432
ENV DEBIAN_FRONTEND noninteractive
# subscription
COPY subscribe_rhel.sh /subscribe_rhel.sh
RUN chmod +x /subscribe_rhel.sh \
&& /subscribe_rhel.sh
# yum
RUN yum -y update \
&& yum provides -y '*/applydeltarpm' \
&& yum groupinstall -y 'Development Tools' \
&& yum install -y initscripts curl tar unzip mlocate openssh-server openssl-devel \
&& yum localinstall -y https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-redhat96-9.6-3.noarch.rpm \
&& yum install -y postgresql96-server epel-release multitail ncurses-devel ncurses-static ncurses-term \
&& rm -rf /var/cache/yum/* \
&& yum clean all
# locale
RUN yum reinstall -y glibc-common \
&& localedef -i ja_JP -f UTF-8 ja_JP.utf8 \
&& touch /etc/sysconfig/i18n \
&& echo 'LANG="ja_JP.UTF-8"' >> /etc/sysconfig/i18n \
&& echo 'LANG="ja_JP.UTF-8"' > /etc/locale.conf
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
# timezone
RUN yum install -y tzdata \
&& echo 'ZONE="Asia/Tokyo"' > /etc/sysconfig/clock \
&& echo 'UTC=false' >> /etc/sysconfig/clock \
&& ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# root passwd
RUN bash -c 'echo "root:password" | chpasswd'
# ssh
RUN sed -i -e "s/#PasswordAuthentication yes/PasswordAuthentication yes/g" /etc/ssh/sshd_config \
&& sed -i -e "s/#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config \
&& sed -i -e "s/UsePAM yes/UsePAM no/g" /etc/ssh/sshd_config
# PostgreSQL
COPY setup_postgresql.sh /setup_postgresql.sh
RUN chmod +x /setup_postgresql.sh \
&& /setup_postgresql.sh \
&& rm -f /setup_postgresql.sh
COPY run.sh /run.sh
RUN chmod +x /run.sh
RUN updatedb
CMD ["/run.sh"]
yum が使えないので subscription-manager register を実行します。
username と password はあなたのアカウントを設定してください。
#!/bin/sh
subscription-manager register --username 'FIXME' --password 'FIXME' --auto-attach
exit 0
さて setup_postgresql.sh ですが、CentOS 6/RHEL 6 では以下のようにしてセットアップできました。
#!/bin/bash
service postgresql-9.6 initdb
echo "listen_addresses = '*'" >> /var/lib/pgsql/9.6/data/postgresql.conf
sed -i -e "s/ident$/trust/g" /var/lib/pgsql/9.6/data/pg_hba.conf
sed -i -e "s/127\.0\.0\.1\/32/0\.0\.0\.0\/0/g" /var/lib/pgsql/9.6/data/pg_hba.conf
sed -i -e "s/max_connections = 100/max_connections = 200/g" /var/lib/pgsql/9.6/data/postgresql.conf
sed -i -e "s/shared_buffers = 128MB/shared_buffers = 512MB/g" /var/lib/pgsql/9.6/data/postgresql.conf
echo "postgres:postgres" | chpasswd
service postgresql-9.6 start
sleep 1
su postgres -c "psql -c \"ALTER USER postgres WITH PASSWORD 'postgres'\""
su postgres -c "psql -c \"CREATE ROLE imart WITH LOGIN PASSWORD 'imart'\""
su postgres -c "psql -c \"CREATE DATABASE imart OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -c \"CREATE DATABASE iap_db OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -c \"CREATE DATABASE \\\"default\\\" OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -d imart -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
su postgres -c "psql -d iap_db -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
su postgres -c "psql -d default -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
service postgresql-9.6 stop
ここで問題は、RHEL 7 では service ではなく systemctl を利用しますが、docker build では systemctl は利用できない事です。
# service postgresql-9.6 initdb
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, force-reload, status). For other actions, please try to use systemctl.
無理やり実行しようとしても、
# /usr/pgsql-9.6/bin/postgresql96-setup initdb
Failed to get D-Bus connection: Operation not permitted
failed to find PGDATA setting in postgresql-9.6.service
問題となっているのは以下の箇所です。
# this parsing technique fails for PGDATA pathnames containing spaces,
# but there's not much I can do about it given systemctl's output format...
PGDATA=`systemctl show -p Environment "${SERVICE_NAME}.service" |
sed 's/^Environment=//' | tr ' ' '\n' |
sed -n 's/^PGDATA=//p' | tail -n 1`
以下のようにして、
sed -i -e "s/if \[ x\"\$PGDATA\" = x \]; then/PGDATA=\/var\/lib\/pgsql\/9.6\/data\/\nif \[ x\"\$PGDATA\" = x \]; then/g" /usr/pgsql-9.6/bin/postgresql96-setup
if [ x"$PGDATA" = x ]; then
を
PGDATA=/var/lib/pgsql/9.6/data/
if [ x"$PGDATA" = x ]; then
に置き換えてから /usr/pgsql-9.6/bin/postgresql96-setup initdb をする方法もありますが、無理やり感がぬぐえません。
結論としては、以下のように pg_ctl を利用して initdb が可能です。
su postgres -c "/usr/pgsql-9.6/bin/pg_ctl -D /var/lib/pgsql/9.6/data initdb"
次に問題となるのは service start と service stop です。
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades. If you want to customize, the
# best way is to create a file "/etc/systemd/system/postgresql-9.6.service",
# containing
# .include /lib/systemd/system/postgresql-9.6.service
# ...make your changes here...
# For more info about custom unit files, see
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
# Note: changing PGDATA will typically require adjusting SELinux
# configuration as well.
# Note: do not use a PGDATA pathname containing spaces, or you will
# break postgresql-setup.
[Unit]
Description=PostgreSQL 9.6 database server
Documentation=https://www.postgresql.org/docs/9.6/static/
After=syslog.target
After=network.target
[Service]
Type=notify
User=postgres
Group=postgres
# Note: avoid inserting whitespace in these Environment= lines, or you may
# break postgresql-setup.
# Location of database directory
Environment=PGDATA=/var/lib/pgsql/9.6/data/
# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog
# Disable OOM kill on the postmaster
OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0
ExecStartPre=/usr/pgsql-9.6/bin/postgresql96-check-db-dir ${PGDATA}
ExecStart=/usr/pgsql-9.6/bin/postmaster -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
# Do not set any timeout value, so that systemd will not kill postmaster
# during crash recovery.
TimeoutSec=0
[Install]
WantedBy=multi-user.target
このようになっているため、以下のようにして起動/終了します。
# 起動
su postgres -c "PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj; PG_OOM_ADJUST_VALUE=0; /usr/pgsql-9.6/bin/pg_ctl -D /var/lib/pgsql/9.6/data -l /var/lib/pgsql/9.6/data/pg_log/postgresql.log start"
# 終了
su postgres -c "/usr/pgsql-9.6/bin/pg_ctl -D /var/lib/pgsql/9.6/data stop"
まとめると以下のようにしてセットアップが可能です。
#!/bin/bash
export PGSQL=/usr/pgsql-9.6
export PGDATA=/var/lib/pgsql/9.6/data
su postgres -c "${PGSQL}/bin/pg_ctl -D $PGDATA initdb"
echo "listen_addresses = '*'" >> ${PGDATA}/postgresql.conf
sed -i -e "s/ident$/trust/g" ${PGDATA}/pg_hba.conf
sed -i -e "s/127\.0\.0\.1\/32/0\.0\.0\.0\/0/g" ${PGDATA}/pg_hba.conf
sed -i -e "s/max_connections = 100/max_connections = 200/g" ${PGDATA}/postgresql.conf
sed -i -e "s/shared_buffers = 128MB/shared_buffers = 512MB/g" ${PGDATA}/postgresql.conf
echo "postgres:postgres" | chpasswd
su postgres -c "mkdir -p ${PGDATA}/pg_log"
su postgres -c "PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj; PG_OOM_ADJUST_VALUE=0; ${PGSQL}/bin/pg_ctl -D $PGDATA -l ${PGDATA}/pg_log/postgresql.log start"
sleep 2
su postgres -c "psql -c \"ALTER USER postgres WITH PASSWORD 'postgres'\""
su postgres -c "psql -c \"CREATE ROLE imart WITH LOGIN PASSWORD 'imart'\""
su postgres -c "psql -c \"CREATE DATABASE imart OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -c \"CREATE DATABASE iap_db OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -c \"CREATE DATABASE \\\"default\\\" OWNER=imart encoding 'utf8' TEMPLATE template0\""
su postgres -c "psql -d imart -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
su postgres -c "psql -d iap_db -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
su postgres -c "psql -d default -c \"CREATE SCHEMA acceldocuments AUTHORIZATION imart\""
su postgres -c "${PGSQL}/bin/pg_ctl -D $PGDATA stop"
#!/bin/bash
/subscribe_rhel.sh
/usr/sbin/sshd-keygen
/usr/sbin/sshd
su postgres -c "PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj; PG_OOM_ADJUST_VALUE=0; /usr/pgsql-9.6/bin/pg_ctl -D /var/lib/pgsql/9.6/data restart"
multitail -M 0 --follow-all --retry-all -q 1 "/var/lib/pgsql/9.6/data/pg_log/*.log"
ビルドします。
docker build -t mypostgresql:9.6 .
起動
docker run -itd -p 5432:5432 -p 2222:22 mypostgresql:9.6
ssh
ssh -p 2222 root@localhost
docker run 時に -p 2222:22 とした場合、2222 が ssh のポートです。
root/password でログインできます。
localhost の部分は、docker run しているマシンの IP アドレスに置き換えてください。
というわけで簡単にですが PostgreSQL 9.6 intra-mart 用構成済みの Docker についての紹介でした。