背景
いろんなところに開発環境を作ってしまうと、データベースをいちいち引っ越しするのが面倒なので、/var/lib/postgresql
配下にあるポスグレの生データごとローカルに持ってきて、ローカルのDockerでそれを読み込んだ顛末
環境
訳あって(知識がなかったので)、VPSでは異なるバージョンのPostgresqlを併存させていたことがあり、ディレクトリ構成がその様になっていた。そのため以下の方法はその前提で書いてあることを了承いただきたい。
VPS側のOSはUbuntu。
移行先環境にWSLを使用している理由は、単に手元で手軽に確認したかったから(これは仕事用のデータとかではない趣味・勉強用のもの)。普段使っているPCがMacであれば、一部手順は不要になる。
方法
基本的に、PostgresのDockerイメージの、/var/lib/postgresql/data
ディレクトリを永続化させてbuildして、一旦stop
した上で中身をそのまま入れ替えてしまおうという作戦。しかし一筋縄ではいかないので、docker-compose logs -f
でエラーメッセージを見て、あれがないこれがない言われるのを補充していく。補充しよ
以下の方法でファイルが消失・上書きされていないという保証はできないので、バックアップはしておいてください。
結論から言うと、以下のようなdocker-compose.yml
を書いた。
version: '3'
services:
postgres:
image: postgres:10.21-alpine
user: '1000:1000'
volumes:
- ./etc/passwd:/etc/passwd:ro
- ./etc/group:/etc/group:ro
- ./data2:/var/lib/postgresql/data
- ./data:/var/lib/postgresql/10/main
- ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
- ./conf2:/etc/postgresql
- ./conf:/etc/postgresql/10/main
- ./etc/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
- ./etc/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key:ro
- ./tmp:/var/run/postgresql/10-main.pg_stat_tmp
ports:
- 5434:5432
environment:
POSTGRES_PASSWORD: postgres
command: -c 'config_file=/etc/postgresql/postgresql.conf'
で、ディレクトリ構成は以下のような感じにしておく。/conf
と/data
配下の色々なファイルはまるごとコピペ。その他ファイルは一つずつ探してきてコピペするような感じだった。方法は後述する。
.
├── conf
│ ├── conf.d
│ ├── environment
│ ├── pg_ctl.conf
│ ├── pg_hba.conf
│ ├── pg_ident.conf
│ ├── postgresql.conf
│ └── start.conf
├── conf2
│ ├── conf.d
│ ├── environment
│ ├── pg_ctl.conf
│ ├── pg_hba.conf
│ ├── pg_ident.conf
│ ├── postgresql.conf
│ └── start.conf
├── data
│ ├── PG_VERSION
│ ├── base
│ ├── global
│ ├── pg_commit_ts
│ ├── pg_dynshmem
│ ├── pg_logical
│ ├── pg_multixact
│ ├── pg_notify
│ ├── pg_replslot
│ ├── pg_serial
│ ├── pg_snapshots
│ ├── pg_stat
│ ├── pg_stat_tmp
│ ├── pg_subtrans
│ ├── pg_tblspc
│ ├── pg_twophase
│ ├── pg_wal
│ ├── pg_xact
│ ├── postgresql.auto.conf
│ ├── postmaster.opts
│ └── postmaster.pid
├── data2
├── docker-compose.yml
├── docker-entrypoint-initdb.d
├── etc
│ ├── group
│ ├── passwd
│ ├── ssl-cert-snakeoil.key
│ └── ssl-cert-snakeoil.pem
└── tmp
docker-compose.yml
について上から順番に説明
image: postgres:10.21-alpine
データを読み込むためにはpostgresqlのバージョンを移行前のものと合わせないといけない(と思う)。10.21だったので10.21のalpineのイメージを使用することにした
user: '1000:1000'
volumes:
- ./etc/passwd:/etc/passwd:ro
- ./etc/group:/etc/group:ro
この部分は以下のQiita記事の方法通りにやっている。こちらでの説明は省略
./etc/passwd
./etc/group
のファイルをリンクの説明に従って作成。内容は記事そのままコピペで動いた(一度alpineイメージを起動させてから./etc/passwd
を引っこ抜いてくる、みたいな手順は不要だった。)
- ./data2:/var/lib/postgresql/data
- ./data:/var/lib/postgresql/10/main
- ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
- ./conf2:/etc/postgresql
- ./conf:/etc/postgresql/10/main
データとconfファイル群を配置する。一行目は最初に起動したときに永続化用のデータがちゃんとWindows側に吐き出されてくるか確認したときに使っただけなので、不要かもしれない。
二行目の./data
に、VPSからコピーしてきたデータを置く。
三行目は初期に動かしたいSQLファイルを配置するディレクトリだが、今回は関係ないので何も配置していない。
四行目、ネット記事を参考にdocker-compose.yml
の最終行でcommand: -c 'config_file=/etc/postgresql/postgresql.conf'
と書いてしまったのでDockerイメージの方のポスグレがまずこのディレクトリにconfファイルがあるかどうかを読みに行ってしまうので、冗長だが、一応、./conf2
を、./conf
と同じファイル構成にして、この行を記述した。
5行目が最終的に読みに行くconfファイル群で、pg_hba.conf
とかもここのが読まれるため。localからのアクセスをtrustしたりするのはここでやる(後ほど行う)。
- ./etc/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
- ./etc/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key:ro
オレオレ証明書。VPSに生成されているものをコピペしてきた。何故かこれがないと動かないと言われてしまった。過去にした設定が原因かもしれないが、コピペで動いたのでとりあえずヨシ!
二行目の:ro
指定であるが、ファイルが0600
でないとだめと言われてしまったので指定したが、結果的にそうではなく、WSL(にインストールしているubuntuなどのOS)でchmod 0600
をしなければ動かなかった。
- ./tmp:/var/run/postgresql/10-main.pg_stat_tmp
なぜかtmpディレクトリは自動生成してくれなかった、alpineだからだろうか。何も考えずに上記行とtmpディレクトリを作成したら動いた。
以上を行ったら、docker-compose up -d --build
して、すかさずdocker-compose logs -f
する。
エラーが出てなかったら成功。
VPSではWebアプリを公開していたため、pg_hba.conf
にパスワード認証や、アクセスできるデータベースの制限などをしていたが、その部分は書き換える(conf2ではなくconfディレクトリのほう)。WSLのUbuntuにpsqlをいれて、port=5434(任意)にアクセスすれば中身の確認ができると思う。