用 Docker 玩轉 PostgreSQL
Posted on Jul 10, 2018 in 用 Docker 架設服務 by Amo Chen ‐ 2 min read
最近學著使用 PostgreSQL 做些小應用,過程主要利用 Docker 幫忙建立 PostgreSQL 的執行環境,可說是相當方便,本篇就記錄幾則使用 Docker 玩轉 PostgreSQL 的筆記。
Pull PostgreSQL
PostgreSQL 已經是 Official Image ,所以可以直接透過以下指令 Pull Postgres 的 Image :
docker pull postgres
各種版本的 PostgreSQL 可以參閱 docker store - postgres 。
啟動 PostgreSQL
Pull Image 結束後,可以使用以下指令將 PostgreSQL 在背景執行:
docker run --name mypostgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
其中 -e POSTGRES_PASSWORD=mysecretpassword
指的是設定環境變數 POSTGRES_PASSWORD
, PostgreSQL 在啟動時會讀取環境變數 POSTGRES_PASSWORD
的值,並將之設定為 postgres (PostgreSQL 預設的使用者帳號)的密碼。
Docker 提供的 PostgreSQL Image 同時也提供多個環境變數可供設定,例如 POSTGRES_USER
, POSTGRES_PASSWORD
等,詳閱 docker store - postgres 。
連線至 PostgreSQL
由於 PostgreSQL 正在背景執行,所以可以啟動另一個新的 PostgreSQL 然後將其與正在背景執行的 PostgreSQL 連結在一起(link),並利用新啟動的 PostgreSQL 裡的 psql
指令連線至鄭在背景執行的 PostgreSQL :
docker run -it --rm --link mypostgres:postgres postgres psql -h postgres -U postgres
上述指令會詢問 postgres 的密碼,輸入我們設置環境變數 POSTGRES_PASSWORD
的值即可。
除了上述提到的連結方式之外,其實也可以選擇 expose PostgreSQL 的 5432 port ,直接從 host 利用 psql 指令連線進去即可:
docker run --rm --name mypostgres -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres
結合 docker-compose.yaml
除了用 docker 指令玩玩 PostgreSQL 之外,開發應用時也經常會利用 docker-compose 連結多個 container ,也由於資料庫相關的應用在開發時會有儲存的需求,不太可能每次都要花費時間重新建立資料,所以就必須掛載 Volumes 來儲存資料庫的資料,避免 container 重啟之後資料就不見了。
Docker 提供的 PostgreSQL Image 可以透過掛載 /var/lib/postgresql/data
(預設,可以修改環境變數 PGDATA
來改變) 達到儲存資料的需求。
此外,Docker 的 PostgreSQL Image 也可以透過掛載 /docker-entrypoint-initdb.d
達到擴充的目的,該資料夾內的 *.sql
, .sql.gz
, *.sh
都會在 PostgreSQL 服務啟動之前執行,所以也很適合作為預先建立資料庫、設定使用者權限、安裝測試資料等等用途,例如官方提供的範例:
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
如果是針對 PostgreSQL 的設定檔變更的話,則可以掛載 /etc/postgresql/postgresql.conf
。
設定好掛載上述提及的 3 個 Volumes 的 docker-compose.yaml
範例如下:
db:
image: "postgres:10"
restart: always
ports:
- "5432:5432"
volumes:
- ./initdb.d:/docker-entrypoint-initdb.d
- ./pgdata:/var/lib/postgresql/data
- ./postgres.conf:/etc/postgresql/postgresql.conf
上述範例會將 ./initdb.d
, ./pgdata
與 ./postgres.conf
分別掛在 PostgreSQL container 裡的 /docker-entrypoint-initdb.d
, /var/lib/postgresql/data
與 /etc/postgresql/postgresql.conf
。
如此一來就能夠隨心所欲的利用 Docker 玩轉 PostgreSQL 了。
References
https://store.docker.com/images/postgres