PostgreSQLを起動するためのdocker-compose.yml

この docker-compose.yml を書く:

version: "3.8"

services:
  db:
    image: postgres:12.3
    restart: always
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

volumes:
  db-data:

いまさら何をという感じだが、上記の docker-compose.yml を先日書こうとして、いつもフンイキで触っている Docker だけどそろそろドキュメントを読んでおくかと思い立ち、ドキュメントを頭から(飛ばし飛ばし)読んだのでメモを残したくなりました。

環境

% docker --version
Docker version 19.03.12, build 48a66213fe
% docker-compose --version 
docker-compose version 1.26.2, build eefe0d31

Docker のアーキテクチャ

https://docs.docker.com/get-started/overview/#docker-architecture

Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers.

Docker はクライアント-サーバモデルで動いており、 Docker クライアントが Docker デーモンと会話する。Docker デーモンが Docker コンテナたちをビルドしたり実行したり配布したりといった何やかんや大変な仕事をやってくれる。

Docker デーモン

The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes.

Docker デーモンは Docker API リクエストを listen して、イメージ、コンテナ、ネットワーク、ボリュームといった Docker オブジェクトたちの面倒を見る。

イメージ

An image is a read-only template with instructions for creating a Docker container.

イメージはコンテナを作るための指示が書かれた読み取り専用のテンプレート。 ubuntu イメージとか redis イメージとか。

コンテナ

A container is a runnable instance of an image.

コンテナはイメージの実行可能なインスタンス

When a container is removed, any changes to its state that are not stored in persistent storage disappear.

コンテナが remove されると、コンテナの状態に対して成された変更のうち永続ストレージに保存されていないものは消滅する。

サービス

Services allow you to scale containers across multiple Docker daemons, which all work together as a swarm with multiple managers and workers.

サービスにより複数の Docker デーモンにわたってコンテナをスケールできるようになる。 Docker デーモンたちは複数のマネージャとワーカーからなる1つの群れとして協働する。

データの永続化について

上で引用したように

When a container is removed, any changes to its state that are not stored in persistent storage disappear.

となっているわけで、コンテナがいなくなった後でも消えてほしくないアプリケーションデータはどう保持しておけば良いのかと思うのだが、ドキュメントを読んでいくと volumes を作りなさいと書かれている (というか volumes を使うことが推奨されている。他にも bind mounts と tmpfs mounts という手段があるがここでは割愛する)。

例えば https://docs.docker.com/develop/dev-best-practices/#where-and-how-to-persist-application-data に書かれているように:

  • Avoid storing application data in your container’s writable layer using storage drivers. This increases the size of your container and is less efficient from an I/O perspective than using volumes or bind mounts.
  • Instead, store data using volumes.

詳しくは https://docs.docker.com/storage/ 以下のドキュメントを読むとよい。

Docker Compose

https://docs.docker.com/compose/

Compose is a tool for defining and running multi-container Docker applications.

Docker Compose は複数コンテナからなる Docker アプリを定義して実行するためのツールである。

docker-compose.yml の中で services: というトップレベルのキーの下に各サービスを定義する。

version について

https://docs.docker.com/compose/compose-file/compose-versioning/#versioning

docker-compose.yml の書式のバージョンを指定することができる。

There are currently three versions of the Compose file format:

  • Version 1, the legacy format. This is specified by omitting a version key at the root of the YAML.
  • Version 2.x. This is specified with a version: '2' or version: '2.1', etc., entry at the root of the YAML.
  • Version 3.x, the latest and recommended version, designed to be cross-compatible between Compose and the Docker Engine’s swarm mode. This is specified with a version: '3' or version: '3.1', etc., entry at the root of the YAML.

ファイルの先頭に version キーを 書かない ことでバージョン1を指定したことになる。 バージョン 2.x と 3.x の指定はファイルの先頭に version: '2'vesion: '2.1'version: '3'vesion: '3.1' などと書くことで指定できる。

推奨バージョンは現行の 3.x である。

また Note が書かれていて

Note: When specifying the Compose file version to use, make sure to specify both the major and minor numbers. If no minor version is given, 0 is used by default and not the latest minor version.

利用する Compose ファイルのバージョンを指定する際は、メジャー ナンバーと マイナー ナンバーの両方を忘れずに指定すること。マイナーバージョンが指定されないと、最新のマイナーバージョンではなく 0 がデフォルトで使われる。

つまり version: "3" と書くとこれは version: "3.0" と書いたのと等価である。このような仕様なので、しがらみが何もなければ常に最新のマイナーバージョンを明示的に指定するのが良いだろうと思う。

image

https://docs.docker.com/compose/compose-file/#image

Specify the image to start the container from. Can either be a repository/tag or a partial image ID.

コンテナを開始する起点となるイメージを指定する。

PostgreSQL なら image: postgres とか image: postgres:12.3 とかを指定する:

https://hub.docker.com/_/postgres

volumes

上でも書いたように volumes を作ってデータを永続化させないと DB としての役目を果たすことができない。

docker-compose.yml で volumes を定義する方法はこちらに載っている:

https://docs.docker.com/compose/compose-file/#volumes

Mount host paths or named volumes, specified as sub-options to a service.

volumes は各 service のサブオプションとして指定し、ホストの path または名前つき volumes (named volumes) をマウントする。

But, if you want to reuse a volume across multiple services, then define a named volume in the top-level volumes key.

ある volume を複数 service 間で使い回したかったら、トップレベルの volumes キーの下に名前付き volume を定義して使う。

(ドキュメントを読んでみてもこのトップレベvolumes 以外の場所で named volumes を定義できるのかどうかはよくわからなかった。)

トップレベvolumes の下の各エントリは、最初に載せた docker-compose.yml の例のように空っぽでも良いのだけど、オプションを指定することもできる(空っぽの場合はデフォルトの値が適用されるということ)。オプションについて詳しくはこちらを読むと良い:

https://docs.docker.com/compose/compose-file/#volume-configuration-reference

restart

postgres の docker image のREADME.md に載っていたのをそのまま書いたという以上の経験が無い。

ドキュメントへのリンクだけ載せておく: https://docs.docker.com/compose/compose-file/#restart

environment

https://docs.docker.com/compose/compose-file/#environment

環境変数を指定する。

ちなみに

Environment variables with only a key are resolved to their values on the machine Compose is running on, which can be helpful for secret or host-specific values.

キーだけの環境変数が書かれていると Compose が実行されたそのマシンのシェルの環境変数の値に解決される。これは秘匿情報やホストに特有の値を扱うときに便利。

この情報は Reference だけでなく Product Manuals でも紹介されている:

https://docs.docker.com/compose/environment-variables/#pass-environment-variables-to-containers

postgres

postgres の事情で言うと POSTGRES_PASSWORD の指定だけは必須である:

https://github.com/docker-library/docs/blob/6cbd2e9b436243e9dbcbc469c3a5142921dd88ab/postgres/README.md#environment-variables

POSTGRES_PASSWORD 環境変数PostgreSQL のスーパーユーザのパスワードとなる。

また POSTGRES_USER はスーパーユーザの名前を設定する環境変数で、特に指定されないとデフォルトでは postgres となる。 なので最初に載せた docker-compose.yml の例の中では書かなくても同じことだけど、個人的に明示的に書くほうが好きなので書いている。

おわりに

このようにして最初に挙げた docker-compose.yml が書けた。

たぶん適当に検索すれば数分で同じ内容が書けただろうとは思うけど一次情報にあたってアーキテクチャに対するメンタルモデルを醸成したり versionenvironment に関する tips を手に入れたりすることも大事ですね。

電子ピアノを買った

KORG の LP-380 という電子ピアノを 7/2 に購入して 7/4 の朝に届き、夕方組み立てました。

www.korg.com

僕の家族とピアノについてのありふれた話を唐突にしたいと思います。母親は幼少期にピアノを習っていてアップライトピアノを買い与えられ(それが今でも僕の実家に置かれている)、妹もヤマハ音楽教室に通ってぷらいまりーから始まり家でブルグミュラーを練習したり中学・高校生の頃は華麗なる大円舞曲とか幻想即興曲らへん(記憶が曖昧)を発表会に向けて練習していたり、夜遅くの練習のためにペラペラのキーボードが1台あった、そういう感じの環境でした。

実家のマンションでは他の家でも女の子のいる家庭からは同じような曲を練習している音がよく聞こえてきていたので、僕の実家も当時のよくある家庭の形の一つだったのかもしれません。

対して僕はピアノのレッスンをほぼ受けたことがないのですが(幼稚園の頃1年間だけヤマハ音楽教室に通っていたが事情がありやめてしまった)、上記のような感じで鍵盤を弾いて音が鳴る環境が家にあったので気になった曲の耳コピをして遊んだり、大学でジャズサークルに一瞬だけ入った影響でコードの読み方とかいろんなスケールの存在をなんとなく知って、それで巷で流れる音楽で気になったやつのコード譜をインターネットで検索して見ながら押さえてみたりとか、そういうおもちゃみたいなピアノの触り方をしていました。

実家を出てからはピアノに触る機会は無くなり、他に優先して買うべき家具があったり、やりたいことが諸々あったり(僕は一度に複数の対象に注意を払うことがマジの苦手なのでそれらを順番に向き合っていくしかない)、そもそも家に置くスペースが無かったりといった理由によってピアノは買わなかったのですが、やっぱり気になった曲があったら鍵盤を押さえて音を取ったりコードを確かめたりしたいよなあとはずっと思っていて(なんじゃその用途って感じやが)、というかピアノを習っていた人なら誰でもやってるブルグミュラーってやつを僕も真面目に練習してみたいなという思いもあり、やっぱり電子ピアノが欲しいなあ(仕事が終わってから夜でもヘッドホンをつけて弾けるので)という思いが常に頭の片隅にあったのですね……

それで最近は五十嵐先生の「プログラミング言語の基礎概念」という本を読み終えて(めちゃめちゃ良い本でした)次にあの有名な「型システム入門」を読み始めたのですが、これは非常に分厚い本なので読み切るにはそれなりの時間がかかります。すると一つの対象について関心を持っている期間はそれ一つに向かって視野が非常に狭くなる傾向があるさすがの僕でもこれはある程度長い目で接していくべき本であるなと気が付きました。

そこで脳と気持ちに余裕が生まれたので最近ついに新しく棚を買って部屋を整理してスペースを作り出し、電子ピアノを様々探してこれにしようと決めて購入しました。

Amazon のレビューを見ていると、いつやめるかわからない娘のレッスンのためならこのくらいお手頃な機種で十分、というようなことも書かれていましたが、さっきちょっと実際に触ってみた限りでは僕はこの LP-380 という機種でも一生かかってもその表現の幅を使い切れないだろうと思ったのでまあ久しぶりに大きな良い買い物ができたなと思いました。そういうわけで今けっこう嬉しいです。

Auth0 入門

Auth0

Auth0 はアプリケーションのログイン・ログアウトやID管理といった認証システムを提供してくれるサービス。 認証部分のコーディングやセキュリティ周りの構築を丸投げできて便利。

無料プランでも7000アクティブユーザまで管理できて "Up to 2 social identity providers" 1 なので趣味で使うには十分かと思う。

テナント

Auth0 のアカウントを作成するとまずテナントと呼ばれるものを作ることを求められる。 テナントは各種 identity provider があなたのアプリの URL (の代わり)として認識するもので、要は各種 identity provider と実際のアプリとの間に入る抽象。 YOUR-TENANT-NAME.us.auth0.com みたいな名前で Auth0 全体でユニークである必要がある(たぶん)。

最初は pione30.us.auth0.com というテナント名にしてみたけど、後からドキュメント を読んでみると

You can create more than one tenant; in fact you are encouraged to do so for each environment you may have, such as development, staging, or production.

とあるので、なるべく粒度を細かくテナントを分けるのがベストプラクティスなのかなという感じがする。例えば awesomeapp-staging-pione30.us.auth0.com みたいな。

テナントを作成したら Quickstarts を読みながら自分の作りたいアプリに合った導入ガイドに従うと良い。例えば React で SPA 構築するぞという場合はこちら

コネクション

ユーザが入力するログイン情報の提供元と Auth0 との関連はコネクションと呼ばれる。

自分のアプリが使うように設定したコネクションは実際にはユーザの目に触れる「ログイン情報を入力してください」画面でユーザが選択可能なログイン手段として表示されることになる。 例えばユーザ名・パスワードによるログインはDatabase Connectionsと呼ばれている。

ソーシャルアカウントを使ったログインが主流[要出典]な現代、ご多分に漏れず Auth0 でも様々な Social Identity Providers が利用可能である(一覧はこちら)。

例えば「Twitter アカウントでログイン」機能をユーザに提供したいと思ったらこちらのドキュメントを読みながら設定していきましょう。事前にTwitter Developer accountの申請が必要です。

おわりに

便利な世の中です。情報を整理してまた何か追記するかも。