この記事は、「基礎・準備編」として、DBコンテナの使い方をまとめていこうと思います。
DB(データベース)の中でも、「PostgreSQL」を使う方法を紹介します。
その後の記事で、PostgreSQLコンテナとGO言語で作成したAPIをつなげて簡単なバックエンドAPIを作る予定です。
この記事では、「1」の方法をまとめます。
- データの永続化をせずに、一通りの動作をチェックしてみる
- コンテナ実行時のテーブルの自動作成、テスト用データの自動挿入
- データの永続化
- ユーザー名、パスワード、データベース名は外部(
.env
)に括りだす - Goサーバーと通信する
使用するDocker Imageは以下のリポジトリのものを使います
コンテナの実行
まずは、Dockerのコンテナを動かします。
使用するのはpostgres:14
という公式のイメージになります。
docker run --name my-postgres -e POSTGRES_USER=user -e POSTGRES_PASSWORD=pass -e POSTGRES_DB=my-db --rm -d postgres:14
- e : 環境変数を設定します。
- POSTGRES_USER : PostgreSQLのユーザー名を指定します。
- POSTGRES_PASSWORD : ユーザーのパスワードを指定します。
- POSTGRES_DB : データベース名を指定することでデータベースを生成します。
環境変数は、PostgreSQLコンテナが初回起動時にデータベースやユーザーの情報を自動的に設定するために使用されます。
Dockerで用意されているDBコンテナは「MySQL」や 「MongoDB」でも同じような仕組みのものが多いです。
その他の設定として、-d
でデタッチドモードとして実行しているので、exec
でコンテナ内に入ってbashを抜けてもデータベースは止まらないにようになっています。
デタッチモードで実行されているコンテナを止めるには、明示的にdocker contaienr stop my-postgres
コマンドを実行する必要があります。
(–rmをつけているので止めると同時にコンテナは削除されます。)
- 最低限必要な環境変数
POSTGRES_PASSWORD
だけで、残りはオプションです。
Dockerで指定している`POSTGRES_PASSWORDなどの環境変数は、データディレクトリが空の状態でコンテナを起動した場合にのみ効果があります。
ユーザー名のデフォルトはpostgres
が設定されます。
DBコンテナへの接続
DBコンテナへBashを通してpsqlを実行してDBにアクセスします。
接続に成功するとmy-db=#
という表示になり、my-db(データベース)にアクセスができていることが確認できます。
# コマンド
docker exec -it my-postgres psql -U user -d my-db
# 出力
psql (14.13 (Debian 14.13-1.pgdg120+1))
Type "help" for help.
my-db=#
psqlコマンド実行時にコンテナ実行時の-e
オプション(環境変数)で指定したユーザー名で作成を要求したデータベースにアクセスしています。
- U : ユーザー名を指定
- d : データベースを指定
ローカル(ホストOS上のDockerコンテナ)にあるデータベースへのアクセスにはパスワードは必要ないです。
ホストOSよりも外部のネットワークからのDBへのアクセスの場合にパスワードが必要になります。
データベースとテーブルの確認
まずは、データベースの一覧を確認してみます。
データベース一覧の出力は\l
を打つだけです。
# コマンド
my-db=# \l
# 出力
my-db | user | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | user | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | user | UTF8 | en_US.utf8 | en_US.utf8 | =c/user +
| | | | | user=CTc/user
template1 | user | UTF8 | en_US.utf8 | en_US.utf8 | =c/user +
| | | | | user=CTc/user
my-db
が確認できたら、次は、今いるデータベース(my-db
)のテーブルを確認してみます。
テーブルを確認するには、\dt
を打つだけです。
# コマンド
my-db=# \dt
# 出力
Did not find any relations.
出力結果から、my-db
にはテーブルが存在していないことが確認できます。
作っていないので当然の結果です。
PostgreSQLのpsql
のコマンドは以下が簡潔にまとまっていてわかりやすいです。
テーブルの作成
では、テーブルを作成してみます。
テーブルの作成は少し長くなりますが、コマンドラインでも、Enterを押しても;
が来るまでは改行になるので、CREATE TABLE
を使って以下のように入力します。
# コマンド
my-db=# CREATE TABLE users(
my-db(# id SERIAL PRIMARY KEY,
my-db(# name VARCHAR(100) NOT NULL,
my-db(# email VARCHAR(100) UNIQUE NOT NULL,
my-db(# created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
my-db(# );
# 出力
CREATE TABLE
テーブルが作成できたか\dt
を使って確認してみます。
# コマンド
my-db=# \dt
# 出力
public | users | table | user
テーブルの詳細を確認するには\d テーブル名
で確認できます。
# コマンド
my-db=# \d users
# 出力
id | integer | | not null | nextval('users_id_seq'::regclass)
name | character varying(100) | | not null |
email | character varying(100) | | not null |
created_at | timestamp without time zone | | | CURRENT_TIMESTAMP
データの挿入
では、テストデータを入れてみます。
データをテーブルに追加するには、INSERT INTO
を使います。
このコマンドも少し長くなりますが、;
が来るまでEnterを押しても改行になるだけなので大丈夫です。
# コマンド
my-db=# INSERT INTO users (name, email) VALUES
my-db-# ('山田 太郎', 'taro.yamada@example.com'),
my-db-# ('杉山 光一', 'sugiyama.kouiti@example.com')
my-db-# ;
# 出力
INSERT 0 2
データが追加できたか確認するには、SQL文
を使う必要があります。
my-db=# SELECT * FROM users;
1 | 山田 太郎 | taro.yamada@example.com | 2024-10-02 10:26:04.582033
2 | 杉山 光一 | sugiyama.kouiti@example.com | 2024-10-02 10:26:04.582033
my-db=# SELECT * FROM users WHERE name='山田 太郎';
1 | 山田 太郎 | taro.yamada@example.com | 2024-10-02 10:26:04.582033
以上でテーブルの作成とデータの挿入が完了したのでデータベースとしてそれっぽい形になりました。
締め作業
作業を終了したい場合は、一度、\q
でデータベースを抜けることができます。
コンテナ起動時にデタッチモードで起動したのでexec
の接続を終了しても、コンテナの動作(DBサーバー)は停止しません。
試しにdocker container ls
でDBコンテナが止まっていないか確認して、この章は終了になります。
# コマンド
my-db=# \q
# いつものコンソールに戻るのでコンテナの生存確認を行う
# コマンド
docker container ls
# 出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f258f6fd532 postgres:14 "docker-entrypoint.s…" 21 minutes ago Up 21 minutes 5432/tcp my-postgres
もし、今回の作ったデータが必要ない場合はdocker container stop my-postgres
で止めると、今頑張って作ったデータごと削除されます。
今回作ったコンテナは消しておきましょう。
docker container stop my-postgres
今回まとめた内容だけでは、DBコンテナを停止してしまうとデータがすべて飛んでしまいます。
これでは本来のデータベースとしての「データを保持する」という責任が果たせなくなるので、次回はDockerのvolume
にデータを退避させ、データの永続化を行い、更には今回たくさん打ち込んだデータベースの作成やデータの追加作業を自動でコンテナの初回起動時に行う仕組みを作ろうと思っています。