使い捨てデータベース環境

Webアプリケーション開発において、データベースは必要不可欠であるといっても過言ではないでしょう。 そして、特に複数のWebアプリを一つのマシンで開発するとき、アプリケーションごとにデータベースの環境1を分けたくなります。

つまり、マシンにただ一つのDBサーバーが立っていてすべてのWebアプリケーションがこのDBを共有するという状態ではなく、それぞれのWebアプリケーションごとに一つDBサーバーが立っていてそれぞれのDBが独立しているという状態になってほしいという気持ちになります。

さらに言うと、Webアプリの開発を始めるタイミングで簡単に立ち上げることができて、その日の開発が終わったら簡単に消せるようなデータベースの環境が欲しくなるわけです。

そういうわけで、この記事では使い捨て可能なPostgreSQL環境の作り方について説明します。 以下では僕がよく使うPostgreSQLについて書きますが、MySQLでも同じようなことはできると思います。

Dockerによるソリューション

使い捨てPostgreSQL環境を手に入れる一つの方法は、Dockerのpostgresイメージを利用することです。具体的には、(Dockerをインストールした後に)以下のようなコマンドを入力することでPostgreSQLがポート5432で立ち上がります。

$ docker run --rm -v /var/lib/postgresql/data -e POSTGRES_USER=someusername -e POSTGRES_PASSWORD=somepassword -p 5432:5432 --name some-postgres -d postgres:11-alpine

上のコマンドを適当なシェルスクリプトに書いておけば、簡単にPostgreSQL環境が生成できるようになります。 また、このPostgreSQL環境は,docker kill $CONTAINER_ID とすることで消すことができます。

そういうわけで、 使い捨てPostgreSQL環境が実現されました。

素朴なソリューション

しかし、PostgreSQLを立てるためだけにDockerをインストールするというのはなんだか本末転倒というか、問題に対して使うツールが大きすぎるという感じがします。しかも、Docker for MacはLinuxの仮想マシン上で動くため、macOSでこれをやるとメモリを結構食います2。 もっと簡単な方法はないものでしょうか。

実はもっと簡単な方法があります。その方法というのは、ディレクトリを指定して PostgreSQLを起動するということです。

ディレクトリを指定してPostgreSQLを起動する

まず、PostgreSQLをbrewとかで入れます。そして、initdbコマンドで適当なディレクトリをPostgreSQLのデータベースクラスタとして初期化します。 このとき、スーパーユーザのパスワードを設定するように言われるので、適当に入力します。

$ initdb ./database --username=someuser -A md5 --pwprompt

パスワードをプロンプトから入力したくない場合は、--pwfileオプションが使えます。 この場合は、password.txtの最初の一行がパスワードとして設定されます。

$ initdb ./database --username=someuser -A md5 --pwfile=password.txt

もしくは、パスワード無しでログインしたいという場合は、-A md5 以降をつけなければよいです。

$ initdb ./database --username=someuser

このようにデータベースクラスタ(./database)を初期化した後、PostgreSQLを起動します。

$ postgres -D ./database

そして別のコンソールを立ち上げ、データベースを作成します。

$ createdb -U someuser testdb

ここまでやれば、先程設定したユーザー名とパスワード、データベース名でログインできるようになっています(パスワードはプロンプトで聞かれます)。

$ psql --user=someuser --dbname=testdb

あとはこの手順をシェルスクリプトに落とし込めば、コマンド一つでデータベースが立ち上がるようになります。 データベースを止めたいときはpostgresqlのプロセスをkillすればいいし、データごと消したいときはrm -rf ./databaseすればよいです。

このように、Dockerなしで使い捨てPostgreSQL環境を作成することができました。

まとめ

Web開発において使い捨てのPostgreSQL(というかデータベース)の環境が欲しくなることがよくあります。Dockerを使うとこれを実現することはできますが、欠点もあります。

Dockerを使わずに使い捨てPostgreSQL環境を作るには、適当なディレクトリをデータベースクラスタとして指定してpostgresコマンドを起動すれば良いです。 この方法で立てたPostgreSQLサーバーは普通のPostgreSQLサーバーなので、Docker for Macのようにメモリを食うこともないし、特別パフォーマンスが落ちるということもありません(多分)。

よかったですね。

余談

僕は物心ついたときからDockerでPostgreSQLを立てていたんですが、皆さんはどうやって立てていますか?

もしかしてこの記事で書いた方法が普通で、Dockerを使うほうが少数派だったりするんでしょうか…

参考文献

  1. 例えばデータそのものもそうだし、ユーザー名とかパスワードとかも当然分けたい。 

  2. また,Docker for Mac上で起動したPostgreSQLは非常に遅い。特に並列にクエリを投げたときに遅くなる気がする。