LoginSignup
3
3

PostgreSQL 9.6 on RHEL の Docker を作成する

Last updated at Posted at 2019-04-03

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 の環境が作れるようになります。

Dockerfile
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 はあなたのアカウントを設定してください。

subscribe_rhel.sh
#!/bin/sh

subscription-manager register --username 'FIXME' --password 'FIXME' --auto-attach

exit 0

さて setup_postgresql.sh ですが、CentOS 6/RHEL 6 では以下のようにしてセットアップできました。

setup_postgresql.sh
#!/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

問題となっているのは以下の箇所です。

/usr/pgsql-9.6/bin/postgresql96-setup
# 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 です。

/usr/lib/systemd/system/postgresql-9.6.service
# 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"

まとめると以下のようにしてセットアップが可能です。

setup_postgresql.sh
#!/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"
run.sh
#!/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 についての紹介でした。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3