logo
github
cover-image

Docker の Redis イメージに初期データをロードするベストプラクティス

2021.11.12 - 2021.11.17

ローカル環境で動作を確認しながら開発していると、サクッとデータベースに接続したくなるタイミングが割とすぐに来ますよね。AWS などの PaaS で立ち上げても良いのですが、やはりローカル開発ならローカルで済むに越したことはありません。さらに、頻繁にデータを入れ替えたりする場合は AWS だと逆に手間やコストがかかる場合もあります。

私は使用したいデータベースの公式 Docker イメージが提供されている場合は、Docker で済ませてしまいます。今回は Docker コンテナで動作するデータベースに、初期データをロードする方法についてベストプラクティスを紹介します。

はじめに

公式 Docker イメージの多くは、コンテナを立ち上げた段階でデータベースに接続して利用できる状態になります。つまり、Docker コンテナを起動した後にデータロードの処理を実装する隙がないケースがほとんどです。これは Docker コンテナ起動後に、コンテナの外側からわざわざ接続して、データをロードする必要が有ることを意味しています。後述の説明では、Redis を例に Docker コンテナの内側から、コンテナの起動と同時にデータをロードする方法を紹介します。

ベストプラクティス

まずはディレクトリ構成です。 任意のディレクトリに後述の3つのファイルを作成します。

plain text
. ├ preload-data │ └ example.txt ├ docker-compose.yml └ startup.sh

起動処理をオーバーライドする

Redis の起動処理をオーバーライドする startup.sh を作成します。 このシェルを DockerfileCMD に指定すればデータのプリロードを実現できますが、今回は Dockerfile を作成せず、 docker-compose.yml のみで構成します。

startup.sh

bash
#!/bin/bash # ジョブコントロールを有効化 (最後の fg コマンドを利用するため) set -m # redis-server をバックグラウンドで起動して3秒待機 (秒数は適宜調整) redis-server & sleep 3 # データロード処理 # (1行目のように直接書いても良いが、2行目のファイルから読み込む方法がオススメ) redis-cli set test-data test-value redis-cli < ./preload-data/example.txt # バックグラウンドの redis-server をフォアグランドに戻す fg %1

プリロードデータを準備する

プリロードデータをシェルの外から読み込む場合に必要なファイルです。

example.txt

plain text
set batch-test-data1 batch-test-value1 hset batch-test-data2 key1 batch-test-value2-1 hset batch-test-data2 key2 batch-test-value2-2

Docker Compose で起動する

Dockerfile を作成しても良いのですが、データディレクトリのマウントやデータの入れ替えを考えると、最初から docker-compose.yml でデータディレクトリをマウントした状態で Docker コンテナを起動した方が捗るため、以下のファイルを作成します。

docker-compose.yml

yaml
version: "3.7" services: database: image: redis:6.2.6 command: /bin/bash /data/startup.sh ports: - 6379:6379 volumes: - ./startup.sh:/data/startup.sh - ./preload-data:/data/preload-data

データがロードされたか確認する

Docker コンテナを起動して、データがロードされるか確認します。 redis-cli の中で叩いた keys * に、想定通りのキーが出力されれば OK です。

plain text
% cd (docker-compose.ymd を配置したフォルダ) % docker-compose up -d Creating network "example_default" with the default driver Creating example_database_1 ... done % docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES (CONTAINER-ID) redis:6.2.6 "docker-entrypoint.s…" 14 seconds ago Up 13 seconds 6379/tcp example_database_1 % docker exec -it (CONTAINER-ID) bash xxxxx@(CONTAINER-ID):/data# redis-cli 127.0.0.1:6379>keys * 1) "batch-test-data2" 2) "test-data" 3) "batch-test-data1"

参考リンク

docker-examples/redis-data-preload at main · laziness-works/docker-examples · GitHub
Skip to content You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab...
No Image
Run multiple processes in a container | Docker Docs
{ const container = $el; // The div with overflow const item = document.getElementById('sidebar-current-page') if (item) { const containerTop = container.scrollTop; const containerBottom = containerT...
No Image

Related posts

Alpine Linux の Docker イメージで動的に環境変数を設定するベストプラクティス
Dockerfile を書いていると、「 aarch64 の場合だけ」のように特定の条件を満たす時に環境変数を設定したい場合がありますよね。しかし Dockerfile としてビルド時の分岐がそもそもサポートされていないので、今回はそのような場合に有効な Dockerfile の作成方法を紹介します
thumbnail
レベル別プログラマの特徴まとめ
独断と偏見で、プログラマをレベル付けして特徴をまとめました。
thumbnail
Alpine Linux の Docker イメージで動的に環境変数を設定するベストプラクティス
Dockerfile を書いていると、「 aarch64 の場合だけ」のように特定の条件を満たす時に環境変数を設定したい場合がありますよね。しかし Dockerfile としてビルド時の分岐がそもそもサポートされていないので、今回はそのような場合に有効な Dockerfile の作成方法を紹介します
thumbnail