DockerでRedisを使いこなす!コンテナでのデプロイ方法
はじめに
今日のソフトウェア開発において、スケーラビリティ、高速性、そして柔軟性は不可欠な要素です。インメモリデータストアの代表格であるRedisは、その高速なデータ処理能力と多様なデータ構造により、キャッシュ、セッション管理、リアルタイム分析、メッセージキューなど、多岐にわたるアプリケーションで活用されています。一方で、Dockerはアプリケーションのデプロイ、管理、実行を劇的に簡素化するコンテナ技術のデファクトスタンダードです。
この2つの強力なツールを組み合わせることで、開発者はRedisのポテンシャルを最大限に引き出しつつ、環境構築の複雑さから解放され、再現性の高い開発・運用環境を構築できます。本記事では、「DockerでRedisを使いこなす!」をテーマに、Redisコンテナの基本的な起動から、データの永続化、Docker Composeによる複数コンテナ管理、セキュリティ設定、さらには実際のアプリケーションとの連携まで、詳細かつ網羅的に解説します。
約5000語にわたるこのガイドを通して、あなたはRedisとDockerの連携に関する深い知識を習得し、堅牢で効率的なシステム構築のための強力な一歩を踏み出せるでしょう。初心者の方から、さらにスキルアップを目指す経験者の方まで、幅広く役立つ内容を目指します。
さあ、DockerとRedisの世界へ飛び込みましょう!
第1章: DockerとRedisの基本理解
DockerとRedisを効果的に連携させるためには、それぞれの技術の基本的な概念をしっかりと理解することが重要です。この章では、両者の核心に迫り、なぜこれらを組み合わせることが強力なのかを探ります。
1.1 Dockerの基本
Dockerは、コンテナという単位でアプリケーションとその依存関係をパッケージ化し、あらゆる環境で一貫した動作を可能にするプラットフォームです。
1.1.1 コンテナとは何か? 仮想マシンとの違い
- コンテナ: アプリケーションとその実行に必要なもの(コード、ランタイム、システムツール、ライブラリ、設定など)をすべて含んだ、軽量で独立した実行環境です。ホストOSのカーネルを共有するため、仮想マシンに比べて起動が速く、リソース消費も少ないのが特徴です。隔離性があり、アプリケーション間の競合を防ぎます。
- 仮想マシン (VM): ホストOSの上にハイパーバイザーを介してゲストOS(完全なOS)を起動し、その上でアプリケーションを実行するものです。各VMは独立したOSを持つため、リソース消費が大きく、起動もコンテナより遅いです。しかし、完全なOSレベルの隔離が保証されます。
主要な違い:
特徴 | コンテナ | 仮想マシン |
---|---|---|
隔離レベル | OSカーネルを共有、プロセスレベルの隔離 | 各VMが独自のOSを持つ、OSレベルの隔離 |
リソース | 軽量、効率的 | 重い、リソース消費が大きい |
起動時間 | 秒単位 | 分単位 |
ポータビリティ | イメージとして簡単に共有・移動可能 | VMイメージも共有可能だが、コンテナより重い |
用途 | マイクロサービス、CI/CD、開発環境 | サーバー仮想化、複数のOSを実行 |
1.1.2 Docker Engine, Docker Hub, Dockerfile, Docker Composeの概念
- Docker Engine: Dockerの中核をなすサービスで、コンテナのビルド、実行、管理を行います。クライアント(CLI)からのコマンドを受け取り、デーモンが実際の処理を実行します。
- Docker Hub: Dockerイメージを共有・公開するためのクラウドベースのレジストリサービスです。Redisのような公式イメージや、コミュニティが作成したイメージをダウンロード(
pull
)したり、自身のイメージをアップロード(push
)したりできます。 - Dockerfile: Dockerイメージを自動的に構築するための一連の命令を記述したテキストファイルです。これを使えば、アプリケーションの実行環境をコードとして定義し、バージョン管理することが可能です。
- Docker Compose: 複数のDockerコンテナで構成されるアプリケーションを、単一のYAMLファイル (
docker-compose.yml
) で定義し、まとめて管理するためのツールです。これにより、複雑なマルチコンテナアプリケーションの起動、停止、ビルドなどを簡単に行うことができます。
1.1.3 Dockerのインストール方法 (OS別概要)
Dockerは、Windows、macOS、Linuxの主要なOSにインストールできます。
- Windows / macOS: Docker Desktopをインストールするのが最も簡単です。これにはDocker Engine、Docker CLI、Docker Compose、Kubernetesなどの必要なツールがすべて含まれています。
- Linux: 各ディストリビューション(Ubuntu, CentOSなど)の公式パッケージマネージャーを通じてインストールする方法が推奨されます。
インストール方法の詳細については、Docker公式ドキュメントを参照してください。
1.2 Redisの基本
Redis (Remote Dictionary Server) は、高性能なオープンソースのインメモリデータ構造ストアです。一般的には「キーバリュー型データベース」に分類されますが、単なるキーバリュー以上の機能を持っています。
1.2.1 Redisとは何か? (概要、特徴、用途)
- 概要: データをメインメモリに保持することで、非常に高速な読み書きを実現します。データの永続化オプションも提供しており、障害時にもデータを復旧できます。
- 特徴:
- インメモリ: データの大部分をRAMに保持するため、HDDやSSDへのアクセスがボトルネックになる従来のデータベースよりも圧倒的に高速です。
- 多様なデータ構造: 単純な文字列(String)だけでなく、ハッシュ(Hash)、リスト(List)、セット(Set)、ソート済みセット(Sorted Set)など、様々なデータ構造をサポートしています。これにより、幅広いデータモデルに対応できます。
- 永続化: RDB(スナップショット)とAOF(追記ログ)の2種類の永続化メカニズムを提供し、メモリ上のデータをディスクに保存してデータ損失を防ぎます。
- Pub/Sub機能: パブリッシュ/サブスクライブモデルをサポートしており、リアルタイムなメッセージングシステムを構築できます。
- トランザクション: 複数のコマンドをアトミックに実行する機能があります。
- Luaスクリプト: サーバーサイドでアトミックなスクリプトを実行できます。
- 用途:
- キャッシュ: 最も一般的な用途。頻繁にアクセスされるデータをRedisに保存し、データベースへの負荷を軽減します。
- セッションストア: Webアプリケーションのユーザーセッション情報を保存し、分散環境でのセッション共有を可能にします。
- リアルタイムアナリティクス: 瞬時のデータ集計やランキング表示など。
- メッセージキュー/ブローカー: Producer/Consumerモデルでの非同期通信。
- レートリミッター: APIのアクセス制限など。
- リードボード/ランキング: ソート済みセットを利用。
1.2.2 Redisのデータ構造 (String, Hash, List, Set, Sorted Set)
Redisが提供する主要なデータ構造は以下の通りです。
- String: 最も基本的なデータ型。テキスト、数値、バイナリデータなどを保存できます。単一のキーに対して単一の値を関連付けます。
- 例:
SET user:1:name "Alice"
,GET user:1:name
- 例:
- Hash: オブジェクトを表現するのに適しています。単一のキーに対して複数のフィールドと値を関連付けます。
- 例:
HSET user:1 name "Alice" email "[email protected]"
,HGETALL user:1
- 例:
- List: 挿入順序が保持される文字列のコレクションです。キューやスタックとして使用できます。
- 例:
LPUSH messages "Hello"
,RPUSH messages "World"
,LRANGE messages 0 -1
- 例:
- Set: 順序を持たない、一意な文字列のコレクションです。集合演算(和集合、積集合、差集合)が可能です。
- 例:
SADD tags "web" "backend" "database"
,SMEMBERS tags
- 例:
- Sorted Set: セットと同様に一意な文字列のコレクションですが、各メンバーにスコア(浮動小数点数)が関連付けられ、そのスコアに基づいてソートされます。ランキングや優先度キューに最適です。
- 例:
ZADD leaderboard 100 "Alice" 150 "Bob"
,ZRANGE leaderboard 0 -1 WITHSCORES
- 例:
これらのデータ構造を使いこなすことで、Redisは多様なアプリケーションロジックを効率的にサポートします。
1.3 なぜDockerでRedisを使うのか?
DockerとRedisを組み合わせることで、開発者と運用者の双方に多くのメリットがもたらされます。
- 環境構築の容易さ: Dockerイメージを使えば、Redisを数秒で起動できます。OSの依存関係やライブラリのインストールに悩む必要がなくなります。
- 再現性と移植性: Dockerイメージはどこで実行しても同じ環境を提供します。開発、テスト、本番環境で全く同じRedisインスタンスが動作することを保証し、”私のマシンでは動いたのに…”という問題を解消します。
- 分離性: Redisを他のアプリケーションやサービスから分離されたコンテナ内で実行することで、互いの依存関係や設定の衝突を防ぎます。各サービスが独立して動作するため、システムの安定性が向上します。
- リソース管理: DockerはCPU、メモリ、ネットワーク帯域などのリソースをコンテナごとに制限・管理できます。これにより、Redisが必要とするリソースを適切に割り当て、他のサービスへの影響を最小限に抑えられます。
- スケーラビリティとマイクロサービスとの親和性: Docker ComposeやKubernetesのようなオーケストレーションツールと組み合わせることで、Redisコンテナのスケールアウトや、マイクロサービスアーキテクチャ内での動的なデプロイが容易になります。
- 開発・テスト環境の効率化: 開発者はローカルマシン上で本番に近いRedis環境を簡単に構築し、アプリケーションとの連携をテストできます。CI/CDパイプラインにも組み込みやすく、自動テストの信頼性を高めます。
- バージョン管理: 特定のRedisバージョンをピンポイントで利用でき、バージョンアップ時の影響を最小限に抑えながらテストを進めることができます。
これらの理由から、DockerコンテナでRedisを運用することは、現代のソフトウェア開発・運用におけるベストプラクティスの一つと言えるでしょう。
第2章: Redisコンテナの基本的な起動方法
この章では、Dockerを使ってRedisコンテナを起動し、操作する最も基本的な手順を学びます。
2.1 Docker HubからのRedisイメージの取得
Docker Hubには、Redisの公式イメージが公開されています。このイメージを使用することで、簡単にRedisサーバーを起動できます。
まず、Redisイメージをローカルにダウンロードします。
bash
docker pull redis
このコマンドは、redis:latest
、つまり利用可能な最新の安定版Redisイメージをダウンロードします。
タグの選択 (latest, stable, specific versions)
latest
タグは常に最新の安定版を指しますが、本番環境では特定のバージョンを指定することを強く推奨します。これにより、予期せぬバージョンアップによる互換性の問題を避けることができます。
- 特定のバージョンを指定する場合:
bash
docker pull redis:6.2.7 # Redis 6.2.7 をダウンロード
docker pull redis:alpine # 軽量版のRedisイメージ (Alpine Linuxベース)
alpine
バージョンはイメージサイズが非常に小さいため、ディスクスペースやネットワーク帯域が限られる環境で特に有用です。機能面での大きな違いはありません。
ダウンロードが完了したイメージは、以下のコマンドで確認できます。
bash
docker images
2.2 Redisコンテナの単体起動
イメージがダウンロードできたら、いよいよRedisコンテナを起動します。
docker run
コマンドの詳細解説
Redisコンテナを起動するには docker run
コマンドを使用します。このコマンドには様々なオプションがあり、コンテナの動作を細かく制御できます。
基本的な構文: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
主要なオプション:
-d
,--detach
: コンテナをバックグラウンドで実行します。これにより、ターミナルが占有されることなく、他の作業を続けることができます。-p
,--publish
: ホストOSとコンテナ間でポートをマッピングします。構文はホストポート:コンテナポート
です。Redisのデフォルトポートは6379です。--name
: コンテナにわかりやすい名前を付けます。名前を付けることで、docker ps
、docker stop
、docker rm
などのコマンドでコンテナを識別しやすくなります。-v
,--volume
: ホストOSのディレクトリやDockerボリュームをコンテナ内にマウントし、データの永続化を可能にします。このオプションについては次章で詳しく解説します。--rm
: コンテナが停止した際に自動的に削除します。一時的なテスト用途に適しています。本番環境での永続的なコンテナには使用しません。--network
: コンテナを特定のDockerネットワークに接続します。
例: 基本的なRedisコンテナの起動
それでは、Redisコンテナを起動してみましょう。
bash
docker run -d --name my-redis -p 6379:6379 redis
このコマンドの意味:
docker run
: Dockerコンテナを起動する。-d
: コンテナをデタッチモード(バックグラウンド)で実行する。--name my-redis
: このコンテナにmy-redis
という名前を付ける。-p 6379:6379
: ホストOSのポート6379を、コンテナ内部のポート6379にマッピングする。これにより、ホストOSからlocalhost:6379
でRedisにアクセスできるようになります。redis
: 起動するイメージ名(ここではredis:latest
がデフォルトで使われます)。
コンテナが正常に起動したか確認するには、以下のコマンドを実行します。
bash
docker ps
STATUS
列が Up
となっていれば、コンテナは正常に動作しています。
2.3 起動したRedisコンテナへの接続
Redisコンテナが起動したら、実際にデータを保存したり取得したりしてみましょう。
redis-cli
の利用
Redisにアクセスするためのクライアントツールとして redis-cli
があります。これをホストから直接、またはコンテナ内で使用できます。
A. ホストOSから redis-cli
を使って接続する
ホストOSに redis-cli
がインストールされている場合、先ほどポートマッピング (-p 6379:6379
) を行ったので、直接接続できます。
bash
redis-cli -h 127.0.0.1 -p 6379
もしホストOSに redis-cli
がインストールされていない場合、一時的に別のDockerコンテナを起動して接続することも可能です。
“`bash
docker run -it –rm –network host redis redis-cli # ホストネットワークを利用
または、コンテナ名で指定
docker run -it –rm –link my-redis:redis redis redis-cli -h redis -p 6379
``
–network host
*補足:は直接ホストのネットワークスタックに接続するため、ホストの
localhost:6379にアクセスできます。
–linkは古い機能ですが、Docker Composeを使う場合はサービス名で名前解決ができます。単体コンテナの場合はIPアドレスか、後述の
docker exec`がより一般的です。*
B. Redisコンテナ内部から redis-cli
を使って接続する
docker exec
コマンドを使うと、起動中のコンテナ内で任意のコマンドを実行できます。
bash
docker exec -it my-redis redis-cli
このコマンドの意味:
docker exec
: 起動中のコンテナ内でコマンドを実行する。-it
: インタラクティブモードで、擬似TTYを割り当てる。これにより、通常のターミナルセッションのように操作できます。my-redis
: コマンドを実行する対象のコンテナ名。redis-cli
: コンテナ内で実行するコマンド。
簡単なRedisコマンドの実行
redis-cli
プロンプトが表示されたら、いくつかのRedisコマンドを試してみましょう。
- 接続確認:
redis
PING
PONG - データの保存:
SET
コマンドでキーと値を保存します。
redis
SET mykey "Hello Docker Redis!"
OK - データの取得:
GET
コマンドでキーに対応する値を取得します。
redis
GET mykey
"Hello Docker Redis!" - 保存したキーの確認:
redis
KEYS *
1) "mykey" - 終了:
redis
exit
これで、Redisコンテナが正常に動作し、データの読み書きができることを確認できました。
2.4 コンテナの停止、再起動、削除
不要になったコンテナは適切に管理することが重要です。
-
コンテナの停止:
bash
docker stop my-redis
これはコンテナに終了シグナル (SIGTERM) を送信し、プロセスがクリーンに終了するのを待ちます。
もしすぐに停止したい場合はdocker kill my-redis
を使いますが、これはSIGKILLを送信するため、データが失われる可能性があります。 -
コンテナの再起動:
bash
docker restart my-redis
停止中のコンテナを再起動します。 -
コンテナの削除:
コンテナを削除する前に、必ず停止しておく必要があります。
bash
docker rm my-redis
もし起動中のコンテナを強制的に削除したい場合は、-f
(force) オプションを使用します。
bash
docker rm -f my-redis
コンテナを削除しても、イメージは残ります。イメージを削除するには docker rmi
コマンドを使用します。
bash
docker rmi redis # redisイメージを削除 (ただし、そのイメージを使っているコンテナが残っていると削除できない)
この章では、Redisコンテナの最も基本的な操作を学びました。次の章では、より実用的な「データの永続化」について深く掘り下げていきます。
第3章: Redisデータの永続化と管理
Dockerコンテナは本質的に揮発性です。つまり、コンテナが停止・削除されると、そのコンテナ内で保存されたデータは失われます。Redisのようなデータベースでは、データが失われることは許されません。この章では、Redisデータを永続化するためのDockerのメカニズムと、Redis自身の永続化オプションについて解説します。
3.1 なぜデータの永続化が必要なのか?
前述の通り、コンテナは一時的な実行環境であり、アプリケーションの実行に必要な最小限のファイルシステムを持ちます。コンテナを停止したり削除したりすると、コンテナ内のファイルシステムへの変更は失われます。これは開発やテスト環境では便利ですが、データベースのように永続的にデータを保持する必要がある場合は大きな問題となります。
Redisのデータはデフォルトでメモリ上に存在するため、コンテナがクラッシュしたり、停止されたりすると、メモリ上のデータは消えてしまいます。これを防ぐためには、データをディスクに保存する仕組みが必要です。Dockerは、ホストOSのファイルシステムとコンテナ内のファイルシステムをリンクさせることで、この問題を解決します。
3.2 Docker Volumeによる永続化
Dockerでは、データの永続化のために主に「Docker Volume (ボリューム)」と「Bind Mount (バインドマウント)」の2つの方法を提供しています。
3.2.1 名前付きボリューム (Named Volumes)
名前付きボリュームは、Docker自身が管理するボリュームです。ホストOS上の特定のパスに保存されますが、ユーザーがそのパスを直接意識する必要はありません。
メリット:
* Dockerによる管理: Dockerがボリュームの作成、管理、場所の決定を行うため、ユーザーは煩わしさから解放されます。
* ポータビリティ: ボリュームはDockerによって管理されるため、Windows、macOS、Linux間で同じように動作します。
* バックアップ・移植の容易さ: docker volume cp
(未実装) や外部ツールを使ってボリュームをバックアップしたり、別のホストに移動させたりするのが比較的容易です。
* データの共有: 複数のコンテナ間で同じボリュームを共有することも可能です。
名前付きボリュームの作成と使用:
- ボリュームの作成:
docker volume create
コマンドで名前付きボリュームを作成します。
bash
docker volume create my-redis-data -
Redisコンテナでの利用:
docker run -v
オプションを使って、作成したボリュームをRedisコンテナのデータディレクトリ (/data
) にマウントします。
bash
docker run -d --name my-redis-persistent -p 6379:6379 -v my-redis-data:/data redis
このコマンドを実行すると、Redisは/data
ディレクトリに永続化されたデータを保存するようになります。my-redis-data
ボリュームは、ホストOS上のDocker管理下の領域に保存されます。 -
ボリュームの確認:
- 既存のボリュームを一覧表示する:
bash
docker volume ls - 特定のボリュームの詳細情報を表示する:
bash
docker volume inspect my-redis-data
Mountpoint
フィールドが、ホストOS上の実際の保存パスを示します(例:/var/lib/docker/volumes/my-redis-data/_data
)。
- 既存のボリュームを一覧表示する:
-
ボリュームの削除:
ボリュームを削除する前に、そのボリュームを使用しているコンテナがすべて停止または削除されていることを確認してください。
bash
docker volume rm my-redis-data
3.2.2 バインドマウント (Bind Mounts)
バインドマウントは、ホストOS上の特定のディレクトリをコンテナ内のディレクトリに直接マッピングする方法です。
メリット:
* シンプルさ: ホストOS上の既存のディレクトリをそのまま利用できるため、設定が直感的です。
* 開発用途に便利: ホストOSで編集したファイルを、コンテナ内でリアルタイムに反映させたい場合(例: 設定ファイル、ソースコード)に非常に適しています。
注意点:
* 権限の問題: ホストOS上のディレクトリの権限が適切に設定されていないと、コンテナ内のプロセスがファイルにアクセスできない場合があります。
* OS依存性: ホストOSのファイルシステム構造に依存するため、移植性が名前付きボリュームより劣る場合があります。
バインドマウントの使用:
-
ホストOSにディレクトリを作成: まず、ホストOSの任意の場所にデータを保存するためのディレクトリを作成します。
bash
mkdir -p ~/docker-redis-data
(-p
オプションは、必要な親ディレクトリも作成します。) -
Redisコンテナでの利用:
docker run -v
オプションを使って、ホストOSのディレクトリをRedisコンテナのデータディレクトリ (/data
) にマウントします。
bash
docker run -d --name my-redis-bind-mount -p 6379:6379 -v ~/docker-redis-data:/data redis
このコマンドにより、Redisが/data
に書き込むデータは、ホストOSの~/docker-redis-data
ディレクトリに直接保存されます。
どちらを選ぶべきか?:
- 名前付きボリューム: データの永続化が必要な本番環境、複数のコンテナでデータを共有したい場合、ポータビリティを重視する場合に推奨されます。
- バインドマウント: 開発環境で設定ファイルを変更しながら試したい場合、ソースコードをコンテナと共有したい場合など、ホストOSから直接データにアクセス・管理したい場合に便利です。
Redisのデータ永続化には、名前付きボリュームが一般的に推奨されます。
3.3 Redisの永続化オプション
Dockerの永続化メカニズムに加えて、Redis自身もデータをディスクに保存する永続化機能を持っています。これらを適切に設定することで、より堅牢なデータ保護が可能になります。Redisは主に以下の2つの永続化方法を提供します。
3.3.1 RDB (Redis Database Backup): スナップショット
RDBは、ある時点でのRedisのメモリ上のデータをディスクにバイナリ形式でスナップショットとして保存する機能です。
- 特徴:
- 設定された時間間隔とキーの変更数に基づいて自動的に保存されます。
- 高速なリカバリが可能です(バイナリ形式のため読み込みが速い)。
- ファイルサイズが比較的小さいです。
- 直近のデータ変更が失われる可能性があります(スナップショット間隔の分)。
- 設定:
redis.conf
ファイルで設定します。
# 900秒(15分)以内に1回でもキーが変更されたら保存
save 900 1
# 300秒(5分)以内に10回以上キーが変更されたら保存
save 300 10
# 60秒(1分)以内に10000回以上キーが変更されたら保存
save 60 10000
これらの設定はデフォルトで有効になっています。スナップショットファイル (dump.rdb
) は/data
ディレクトリに保存されます。
3.3.2 AOF (Append Only File): コマンドログ
AOFは、Redisサーバーへの書き込みコマンドをすべてログとしてファイルに追記していく方式です。
- 特徴:
- RDBよりも高いデータ整合性を提供します(直近の書き込みまで保存されるため)。
- ファイルサイズは大きくなる傾向があります。
- リカバリに時間がかかることがあります(コマンドを再実行するため)。
- 設定により、書き込み頻度(毎秒、毎書き込みなど)を調整できます。
- 設定:
redis.conf
ファイルでAOFを有効にし、同期オプションを設定します。
appendonly yes
# appendfsync always # すべての書き込みを即座にディスクに同期(最も安全だが性能が低い)
appendfsync everysec # 毎秒同期(デフォルト、推奨)
# appendfsync no # 同期しない(OSに任せる、最も性能が良いが安全性が低い)
AOFファイル (appendonly.aof
) も/data
ディレクトリに保存されます。
RDBとAOFの選択:
- データ損失を最小限に抑えたい場合:
appendonly yes
とappendfsync everysec
でAOFを有効にするのが一般的です。 - 高速な起動とバックアップを重視する場合: RDBを利用します。
- 両方を組み合わせる: 多くのプロダクション環境では、両方の永続化メカニズムを有効にして、最大限のデータ保護とリカバリ速度のバランスを取ります。RedisはRDBとAOFの両方が有効な場合、AOFを優先してデータをロードします。
redis.conf
を利用した設定 (コンテナ内で設定ファイルをマウントする方法)
Redisの永続化オプションやその他の設定(認証パスワードなど)は、redis.conf
ファイルで制御します。このファイルをDockerコンテナに適用するには、バインドマウントを利用するのが一般的です。
-
ホストOSに
redis.conf
ファイルを作成:
例えば、以下のような内容でmy-redis.conf
ファイルを作成します。
“`conf
# my-redis.conf
# RDB永続化設定 (デフォルトで有効)
save 900 1
save 300 10
save 60 10000AOF永続化を有効化
appendonly yes
appendfsync everysecRedisのデフォルトポート
port 6379
認証パスワードを設定 (セキュリティの強化)
requirepass your_strong_password_here
最大メモリ制限 (例: 256MB)
maxmemory 256mb
maxmemory-policy noeviction
``
maxmemory
(と
maxmemory-policy` は、メモリが一杯になった際の挙動を定義します。本番環境では非常に重要です。) -
Redisコンテナ起動時に設定ファイルをマウント:
ホストOSのmy-redis.conf
をコンテナ内の/usr/local/etc/redis/redis.conf
にマウントし、その設定ファイルを使ってRedisを起動します。
bash
docker run -d --name my-redis-custom -p 6379:6379 \
-v ~/docker-redis-data:/data \
-v ~/my-redis.conf:/usr/local/etc/redis/redis.conf \
redis redis-server /usr/local/etc/redis/redis.conf-v ~/my-redis.conf:/usr/local/etc/redis/redis.conf
: ホストのmy-redis.conf
をコンテナ内の所定のパスにマウントします。redis-server /usr/local/etc/redis/redis.conf
: Redisコンテナの起動コマンドを上書きし、マウントした設定ファイルを指定してRedisサーバーを起動します。
これで、カスタマイズされた設定でRedisコンテナを起動し、データの永続化も適切に行うことができるようになりました。パスワード設定については、第5章でさらに詳しく解説します。
第4章: Docker Composeを使ったRedis環境の構築
単一のRedisコンテナを起動するだけなら docker run
で十分ですが、実際のアプリケーションではWebサーバー、アプリケーションサーバー、データベースなど、複数のサービスが連携して動作することがほとんどです。Docker Composeは、このようなマルチコンテナアプリケーションの定義と管理を劇的に簡素化します。
4.1 Docker Composeとは何か?
Docker Composeは、複数のDockerコンテナで構成されるアプリケーションを定義・実行するためのツールです。YAML形式のファイル (docker-compose.yml
) を使って、各サービスのイメージ、ポートマッピング、ボリューム、ネットワーク、依存関係などを一元的に記述できます。
Docker Composeの主な利点:
* 単一ファイルでの定義: アプリケーション全体の構成が docker-compose.yml
ファイルにまとまり、可読性と管理性が向上します。
* 一貫した環境: 同じ docker-compose.yml
ファイルを使えば、開発者間で全く同じ環境を簡単に共有・再現できます。
* 簡単な起動・停止: docker-compose up
コマンド一つで、定義されたすべてのサービスを起動し、サービス間のネットワーク接続も自動的に設定されます。docker-compose down
で全てのサービスを停止・削除できます。
* サービス間の名前解決: Docker Composeは独自のネットワークを構築し、サービス名を使って他のサービスにアクセスできます(例: アプリケーションコンテナから redis
というホスト名でRedisコンテナに接続)。
4.2 Docker Composeのインストール (概要)
Docker Desktopをインストールしている場合、Docker Composeはすでに含まれています。Linux環境では、別途インストールが必要になる場合がありますが、多くの場合は公式ドキュメントに従って簡単にインストールできます。
- 確認コマンド:
bash
docker compose version # 新しい構文
# または
docker-compose --version # 古い構文 (Pythonベース)
現在のDocker推奨はdocker compose
(Docker CLIプラグインとして統合されたもの) ですが、古いdocker-compose
も依然として広く使われています。本記事ではdocker compose
の構文を使用します。
4.3 基本的な docker-compose.yml
の作成
Redisサービスのみを含むシンプルな docker-compose.yml
ファイルを作成してみましょう。
-
プロジェクトディレクトリの作成:
bash
mkdir my-redis-compose
cd my-redis-compose -
docker-compose.yml
ファイルの作成:
my-redis-compose
ディレクトリ内にdocker-compose.yml
という名前のファイルを作成し、以下の内容を記述します。“`yaml
docker-compose.yml
version: ‘3.8’ # Docker Composeファイルのバージョン。最新の推奨バージョンを使用。
services:
# Redisサービスを定義
redis:
image: redis:6.2.7 # 使用するRedisイメージのバージョンを指定 (latestではなく特定バージョンを推奨)
container_name: my-redis-server # コンテナ名を指定 (任意)
ports:
– “6379:6379” # ホストの6379ポートをコンテナの6379ポートにマッピング
volumes:
# 名前付きボリューム ‘redis-data’ をコンテナの /data ディレクトリにマッピング
– redis-data:/data
restart: always # コンテナが終了した場合に常に再起動する設定 (本番環境向け)ボリュームの定義
volumes:
redis-data: # ‘redis-data’ という名前のボリュームを定義
driver: local # ローカルストレージを使用 (デフォルト)
“`
各セクションの解説:
version: '3.8'
: Docker Composeファイルの書式バージョンを指定します。新しい機能を利用するために最新版が推奨されます。services
: アプリケーションを構成する各サービスを定義するセクションです。redis
: サービス名です。この名前は、同じComposeファイル内の他のサービスからRedisにアクセスする際のホスト名として利用できます。image: redis:6.2.7
: このサービスで使用するDockerイメージを指定します。container_name: my-redis-server
: 生成されるコンテナのカスタム名を指定します。指定しない場合、Docker Composeが自動的に名前を生成します。ports: - "6379:6379"
: ホストOSのポートとコンテナのポートをマッピングします。volumes: - redis-data:/data
:redis-data
という名前付きボリュームを、コンテナ内の/data
ディレクトリにマウントします。Redisはこの/data
ディレクトリに永続化ファイルを保存します。restart: always
: コンテナが停止したり、Dockerデーモンが再起動されたりした場合に、常にコンテナを再起動するポリシーを設定します。本番環境で推奨される設定です。
volumes
:services
セクションで参照される名前付きボリュームを定義します。redis-data:
:redis-data
というボリュームを定義します。Dockerがこれを管理します。driver: local
: ボリュームのストレージドライバーを指定します。local
がデフォルトで、ホストのローカルファイルシステムに保存されます。
4.4 Docker Composeコマンド
docker-compose.yml
ファイルを作成したら、以下のコマンドを使ってサービスを管理します。
-
サービスを起動する:
docker-compose.yml
ファイルがあるディレクトリで実行します。
bash
docker compose up -dup
: 定義されたすべてのサービスを起動します。-d
: デタッチモードでバックグラウンドで実行します。
初回実行時には、指定されたRedisイメージがダウンロードされ、コンテナが作成・起動されます。永続化のために
redis-data
ボリュームも自動的に作成されます。 -
起動中のサービスを確認する:
bash
docker compose ps
これで、my-redis-server
コンテナがUp
状態であることを確認できます。 -
Redisに接続する:
ホストOSからredis-cli
を使って接続できます。
bash
redis-cli -h 127.0.0.1 -p 6379
または、Docker Composeで起動したRedisコンテナ内でredis-cli
を実行することもできます。
bash
docker compose exec redis redis-cliexec redis
:redis
サービス(コンテナ)内でコマンドを実行します。
-
サービスからのログを表示する:
bash
docker compose logs -f redis # redisサービスのログをリアルタイムで表示
docker compose logs
は、デフォルトですべてのサービスのログを表示します。-f
でフォローモードに、特定のサービス名でフィルターできます。 -
サービスを停止する:
bash
docker compose stop
定義されたすべてのサービスを停止します。 -
サービスを停止し、リソース(コンテナ、ネットワーク、ボリューム)を削除する:
bash
docker compose downdown
:up
コマンドで作成されたコンテナ、ネットワークを停止・削除します。- 重要: デフォルトでは名前付きボリューム(
redis-data
など)は削除されません。データを保持したままコンテナだけを再構築したい場合に便利です。 - ボリュームも削除したい場合は、
-v
オプションを付けます。
bash
docker compose down -v
このコマンドは、コンテナ、ネットワークに加えて、定義されたボリュームも削除します。永続化されたデータも失われるため、注意して使用してください。
4.5 アプリケーションとRedisの連携 (Docker Compose)
Docker Composeの最大の利点は、複数のサービスを連携させて単一のアプリケーションとして動作させられる点です。ここでは、ダミーのWebアプリケーションとRedisを連携させる例を考えます。
基本的な考え方:
Docker Composeは、デフォルトで定義されたすべてのサービスを共有のDockerネットワークに配置します。このネットワーク内で、各サービスは互いにそのサービス名(例: redis
)をホスト名として名前解決できます。
例: Webアプリケーション + Redis
my-web-app
というWebアプリケーションが redis
サービスに接続するシナリオを想定します。
-
docker-compose.yml
の更新:
my-redis-compose
ディレクトリ内に、以下のdocker-compose.yml
を作成または更新します。“`yaml
docker-compose.yml
version: ‘3.8’
services:
web:
build:
context: ./web_app # web_app ディレクトリ内の Dockerfile を参照
ports:
– “8000:80” # ホストの8000ポートをwebコンテナの80ポートにマッピング
environment:
# Redis接続情報を環境変数としてwebコンテナに渡す
REDIS_HOST: redis # サービス名 ‘redis’ をホスト名として指定
REDIS_PORT: 6379
depends_on:
– redis # webサービスはredisサービスに依存することを宣言 (起動順序を制御)
restart: on-failureredis:
image: redis:6.2.7
container_name: my-redis-server
ports:
– “6379:6379” # ホストからのアクセスも許可するためマッピング
volumes:
– redis-data:/data
restart: alwaysvolumes:
redis-data:
“` -
Webアプリケーションの準備:
my-redis-compose
ディレクトリ内にweb_app
という新しいディレクトリを作成し、その中にWebアプリケーションのコードとDockerfile
を配置します。-
web_app/Dockerfile
:
dockerfile
# web_app/Dockerfile
FROM alpine/git:latest # 適当な軽量イメージ、実際はPython, Node.jsなどのベースイメージ
# 実際にはここにアプリケーションのビルド・コピーコマンドが続く
# 例: COPY . /app
# WORKDIR /app
# CMD ["python", "app.py"] など
# 今回はデモのため、単純に起動するだけ
CMD ["sh", "-c", "echo 'Web App started, connecting to Redis at $REDIS_HOST:$REDIS_PORT' && sleep infinity"]
(注: これはダミーのDockerfileです。実際のWebアプリケーションのDockerfileは、使用する言語やフレームワークによって異なります。) -
web_app/app.py
やweb_app/index.js
など、実際のアプリケーションファイルもここに配置されますが、ここでは動作確認が目的のため省略します。
-
-
実行:
my-redis-compose
ディレクトリでdocker compose up -d
を実行します。
bash
docker compose up -d --build--build
:web
サービスでbuild
を指定しているので、イメージが存在しない場合はビルドします。
これで、web
サービスは redis
というホスト名でRedisコンテナに接続できるようになります。アプリケーションコード内で REDIS_HOST
環境変数から redis
を取得し、接続を試みることになります。
Docker Composeは、複数のコンテナからなる複雑なアプリケーションのローカル開発環境やステージング環境を構築する際に非常に強力なツールです。
第5章: Redisコンテナの高度な設定と運用
Redisコンテナを本番環境やより複雑なシナリオで利用する場合、セキュリティ、パフォーマンス、可用性に関する高度な設定と考慮事項が必要になります。
5.1 Redisの設定ファイル (redis.conf
) の適用
第3章で触れましたが、redis.conf
をバインドマウントしてRedisコンテナに適用することは、様々な設定をカスタマイズするための最も一般的な方法です。
カスタム設定ファイルをバインドマウントする方法
基本的なコマンドは以下の通りです。
bash
docker run -d --name my-redis-configured -p 6379:6379 \
-v /path/to/your/redis_data:/data \
-v /path/to/your/redis.conf:/usr/local/etc/redis/redis.conf \
redis redis-server /usr/local/etc/redis/redis.conf
Docker Composeを使用する場合は、volumes
セクションに設定ファイルを指定します。
“`yaml
docker-compose.yml
version: ‘3.8’
services:
redis:
image: redis:6.2.7
container_name: my-redis-server
ports:
– “6379:6379”
volumes:
– ./redis_data:/data # ホストの./redis_dataをコンテナの/dataにマッピング
– ./redis.conf:/usr/local/etc/redis/redis.conf # ホストの./redis.confをコンテナにマッピング
command: redis-server /usr/local/etc/redis/redis.conf # マウントした設定ファイルを指定して起動
restart: always
volumes:
# 名前付きボリュームは利用しないが、ここでは参考までにコメントアウト
# redis-data:
``
redis_data
この例では、プロジェクトディレクトリの直下にディレクトリと
redis.conf` ファイルがあることを想定しています。
主要なRedis設定オプション
redis.conf
で設定できる重要なオプションの一部を再確認し、さらに追加の説明を加えます。
-
認証 (
requirepass
):
Redisはデフォルトで認証なしで動作します。本番環境では絶対にパスワードを設定すべきです。
conf
requirepass your_strong_password_here
パスワードを設定すると、redis-cli
で接続する際にAUTH your_strong_password_here
またはredis-cli -a your_strong_password_here
で認証が必要です。
アプリケーションから接続する場合も、Redisクライアントライブラリでパスワードを指定する必要があります。 -
メモリ制限 (
maxmemory
,maxmemory-policy
):
Redisはインメモリデータベースであるため、使用可能なメモリ量を制限することが重要です。
conf
maxmemory 256mb # Redisが使用できるメモリの最大値を256MBに制限
maxmemory-policy allkeys-lru # メモリが上限に達した際の削除ポリシー
maxmemory-policy
は、メモリが上限に達したときに、どのキーを削除するかを決定します。noeviction
: デフォルト。キーの削除を行わず、書き込みコマンドに対してエラーを返す。データ損失を避けたい場合に有効。allkeys-lru
: 全てのキーの中から、最も最近使われていない(Least Recently Used)キーを削除。volatile-lru
:EXPIRE
コマンドで有効期限が設定されたキーの中から、最も最近使われていないキーを削除。- その他、
lfu
,random
,ttl
など。
-
永続化オプション (
save
,appendonly
,appendfsync
):
第3章で説明したRDBとAOFの設定です。
これらをredis.conf
で明示的に制御することで、データの安全性とパフォーマンスを調整できます。 -
ネットワーク設定 (
bind
,protected-mode
):bind 127.0.0.1
: RedisがリッスンするIPアドレスを指定します。デフォルトではすべてのインターフェースでリッスンします。Dockerコンテナでは、コンテナ内部のネットワークインターフェースにバインドされます。外部からのアクセスを制限する場合は、ファイアウォールやDockerのネットワーク設定と組み合わせて行います。protected-mode yes
: デフォルトで有効。外部からのアクセスを制限し、不正アクセスを防ぎます。リモートからパスワードなしで接続できないようにします。bind
を設定したり、パスワードを設定したりしない限り、リモートからの接続は拒否されます。
5.2 Redisセキュリティの考慮事項
DockerコンテナでRedisを運用する際のセキュリティは非常に重要です。
- パスワード認証 (
requirepass
) の設定:
これは最も基本的なセキュリティ対策です。推測されにくい強力なパスワードを設定し、定期的に変更することを検討してください。環境変数などでアプリケーションに渡す際は、secrets管理ツールを利用するのがベストプラクティスです。 - ネットワークアクセス制限 (Firewall, Dockerネットワーク):
- ホストOSのファイアウォール: ホストOSのファイアウォール(例:
ufw
on Linux, Windows Firewall)で、Redisがリッスンしているポート (6379) へのアクセスを、信頼できるIPアドレスのみに制限します。 - Dockerネットワーク: Docker Composeでサービス間連携をする場合、Redisポートをホストに公開 (
ports
マッピング) せずに、アプリケーションコンテナから内部ネットワーク経由でのみアクセスさせることを検討します。
yaml
# docker-compose.yml (WebアプリからのみRedisにアクセス)
version: '3.8'
services:
web:
# ...
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
depends_on:
- redis
redis:
image: redis:6.2.7
# ports:
# - "6379:6379" # ホストへのポート公開をコメントアウト/削除
volumes:
- redis-data:/data
# ...
volumes:
redis-data:
この設定では、web
サービスはredis
というサービス名でRedisにアクセスできますが、ホストOSからは直接6379ポートでRedisに接続できなくなります(Docker Composeの内部ネットワーク経由のみ)。これがより安全な構成です。
- ホストOSのファイアウォール: ホストOSのファイアウォール(例:
- TLS/SSL暗号化:
RedisはネイティブでTLS/SSLをサポートしていません(Redis 6以降で試験的にサポートされ始めましたが、まだ広く使われていません)。安全な通信が必要な場合は、StunnelのようなTLSプロキシをRedisの前に配置することを検討します。これにより、クライアントとStunnel間、StunnelとRedis間で通信を暗号化できます。これは複雑な設定になるため、必要に応じて専門的な知識が必要です。 - 最小権限の原則:
Redisコンテナをrootユーザーで実行しないようにします。Dockerイメージによってはデフォルトでredis
ユーザーで実行されるようになっていますが、カスタムイメージを作成する際は注意が必要です。
5.3 RedisクラスタとSentinel (概念のみ、具体的なデプロイは別章)
単一のRedisインスタンスは、高可用性やスケーラビリティの点で限界があります。本番環境では、以下のいずれかの方法で冗長化・分散化を検討します。
- Redis Sentinel: Redisの監視、高可用性、自動フェイルオーバーを提供するシステムです。複数のRedisインスタンス(マスターとレプリカ)を監視し、マスターに障害が発生した場合に自動的にレプリカを新しいマスターに昇格させます。主に高可用性を実現します。
- Redis Cluster: データを複数のRedisノードにシャーディング(分散)し、書き込み・読み込みのスケーラビリティと高可用性を同時に実現します。クラスタ内の各ノードは、どのデータがどのノードにあるかを知っています。
Dockerコンテナ上でRedis SentinelやRedis Clusterをデプロイすることは可能ですが、単一コンテナのデプロイよりもはるかに複雑になります。これは、複数のコンテナを協調動作させ、ネットワーク、データ共有、設定同期などを慎重に管理する必要があるためです。本記事の範囲を超えますが、大規模な本番環境を構築する際にはこれらの選択肢を検討する必要があります。
5.4 監視とロギング
Redisコンテナが健全に動作しているか、パフォーマンスは問題ないかを継続的に監視することは非常に重要です。
- Docker logs:
docker logs [container_name]
またはdocker compose logs [service_name]
で、Redisコンテナの標準出力/標準エラー出力に記録されたログを確認できます。Redisは、起動情報、永続化に関するイベント、エラーなどをログに出力します。 - Prometheus/Grafanaなど外部ツールとの連携:
より高度な監視のためには、Prometheus (メトリクス収集) やGrafana (ダッシュボード表示) といったツールと連携することが一般的です。RedisはINFO
コマンドで様々なメトリクスを提供しており、これらをPrometheusが収集し、Grafanaでグラフ化することができます。これには、Redis Exporterのような追加のコンテナが必要になる場合があります。 - Redisコマンド:
INFO
コマンドは、Redisの現在の状態、メモリ使用量、接続数、永続化情報など、詳細なメトリクスを提供します。
MONITOR
コマンドは、Redisサーバーで実行されているすべてのコマンドをリアルタイムで表示します(デバッグ目的で非常に役立ちますが、パフォーマンスに影響を与える可能性があります)。
適切な監視とロギングは、問題の早期発見と解決、そしてパフォーマンスの最適化に不可欠です。
第6章: Dockerfileを使ったカスタムRedisイメージの作成
Docker Hubから提供される公式のRedisイメージは多くのユースケースに対応できますが、特定のニーズに合わせてカスタマイズしたい場合があります。例えば、特定のRedisモジュールを組み込みたい、独自の設定ファイルをイメージに含めたい、あるいは特定のOS環境でビルドしたいといったケースです。
このような場合、Dockerfile
を使って独自のRedisイメージをビルドします。
6.1 なぜカスタムイメージが必要なのか?
- Redisモジュールの組み込み: RedisJSON, RediSearch, RedisGraph など、Redisの機能を拡張するモジュールをあらかじめイメージに含めておきたい場合。
- 特定の設定の組み込み:
redis.conf
ファイルをイメージ内に含めておき、コンテナ起動時にその設定が自動的に適用されるようにしたい場合。これにより、コンテナ起動時のコマンドがシンプルになります。 - 依存関係の解決: Redisが特定の外部ライブラリやツールに依存する場合、それらをイメージビルド時にインストールしておくことができます。
- 環境の標準化: 組織内の特定のセキュリティポリシーや構成要件を満たすようにイメージを標準化したい場合。
- イメージサイズの最適化: 不要なパッケージを削除したり、軽量なベースイメージ(例:
alpine
)を使用したりして、イメージサイズをさらに最適化したい場合。
6.2 Dockerfileの基本
Dockerfile
は、Dockerイメージを自動的にビルドするための一連の命令を記述したテキストファイルです。各命令は新しいレイヤーを作成し、最終的なイメージを構成します。
主要な命令:
FROM
: ベースとなるイメージを指定します。すべてのDockerfileはこの命令から始まります。- 例:
FROM redis:6.2.7-alpine
- 例:
LABEL
: イメージのメタデータ(作者、バージョンなど)を定義します。RUN
: イメージビルド時に実行するコマンドを指定します。通常、パッケージのインストールやファイルの準備などに使われます。- 例:
RUN apt-get update && apt-get install -y build-essential
- 例:
COPY
: ホストOSのファイルやディレクトリをイメージ内にコピーします。- 例:
COPY ./my-redis.conf /usr/local/etc/redis/redis.conf
- 例:
ADD
:COPY
と似ていますが、URLからのダウンロードや圧縮ファイルの自動展開もサポートします。EXPOSE
: コンテナがリッスンするポートを宣言します。これはドキュメント的な意味合いが強く、ポートマッピングはdocker run -p
または Docker Composeで行います。- 例:
EXPOSE 6379
- 例:
ENV
: 環境変数を設定します。WORKDIR
: 以降のRUN
,CMD
,ENTRYPOINT
コマンドが実行される作業ディレクトリを設定します。USER
: 以降のコマンドを実行するユーザーを設定します。セキュリティのためにルート以外のユーザーを指定することが推奨されます。VOLUME
: 永続化が必要なデータを保存するボリュームとしてマークするディレクトリを宣言します。CMD
: コンテナ起動時に実行されるデフォルトのコマンドを指定します。Dockerfileごとに1つだけ設定でき、docker run
のコマンドライン引数で上書き可能です。ENTRYPOINT
: コンテナ起動時に常に実行されるコマンドを指定します。CMD
と組み合わせて、実行可能ファイルと引数を分離するイディオムがよく使われます。
6.3 カスタムRedisイメージの例
ここでは、独自の redis.conf
を組み込み、RedisJSONモジュールを追加するカスタムイメージの例を示します。
-
ディレクトリ構造:
my-custom-redis/
├── Dockerfile
├── redis.conf # カスタム設定ファイル
└── redisjson.so # RedisJSONモジュールファイル (事前にダウンロードまたはビルドしておく) -
redis.conf
の内容 (例):
“`conf
# my-custom-redis/redis.conf
requirepass my_custom_password
appendonly yes
save 900 1
save 300 10
save 60 10000
maxmemory 256mb
maxmemory-policy allkeys-lruRedisモジュールをロード
loadmodule /usr/local/lib/redisjson.so
“` -
Dockerfile
の内容:
“`dockerfile
# my-custom-redis/DockerfileRedisの公式イメージをベースにする
FROM redis:6.2.7-alpine
イメージのメンテナ情報 (任意)
LABEL maintainer=”Your Name your.email@example.com“
必要なディレクトリを作成
RUN mkdir -p /usr/local/etc/redis/ \
/usr/local/lib/カスタム設定ファイルをコンテナ内にコピー
ホストの ./redis.conf をコンテナの /usr/local/etc/redis/redis.conf へ
COPY redis.conf /usr/local/etc/redis/redis.conf
RedisJSONモジュールをコンテナ内にコピー
ホストの ./redisjson.so をコンテナの /usr/local/lib/redisjson.so へ
COPY redisjson.so /usr/local/lib/redisjson.so
データ永続化ディレクトリ
VOLUME /data
Redisのデフォルトポート
EXPOSE 6379
コンテナ起動時にマウントした設定ファイルでRedisサーバーを起動
CMD は docker run のコマンドライン引数で上書きできる
CMD [“redis-server”, “/usr/local/etc/redis/redis.conf”]
``
redisjson.so` ファイルは、RedisJSONのGitHubリポジトリからダウンロードするか、自分でビルドする必要があります。ここではファイルが事前に用意されていることを前提としています。*
*注:
6.4 イメージのビルドと実行
-
イメージのビルド:
my-custom-redis
ディレクトリに移動し、以下のコマンドを実行します。
bash
cd my-custom-redis
docker build -t my-custom-redis:1.0.0 .docker build
: Dockerイメージをビルドするコマンド。-t my-custom-redis:1.0.0
: ビルドするイメージにmy-custom-redis
という名前と1.0.0
というタグを付ける。.
: Dockerfileが存在するカレントディレクトリをビルドコンテキストとして指定。
ビルドが成功すると、
docker images
でmy-custom-redis
イメージがリストされていることを確認できます。 -
カスタムイメージの実行:
ビルドしたカスタムイメージを使ってコンテナを起動します。
bash
docker run -d --name my-custom-redis-instance -p 6379:6379 -v redis_data_volume:/data my-custom-redis:1.0.0
このコンテナは、Dockerfile内で組み込まれたredis.conf
の設定(パスワードやメモリ制限、RedisJSONモジュールロードなど)を適用して起動します。 -
動作確認:
redis-cli
で接続し、パスワード認証を試したり、RedisJSONのコマンドを試したりして、カスタム設定が適用されているか確認できます。
bash
docker exec -it my-custom-redis-instance redis-cli -a my_custom_password
# パスワード認証後
PING
JSON.SET mydoc $ '{"name":"Alice", "age":30}'
JSON.GET mydoc
Dockerfileを使ったカスタムイメージの作成は、Redisの機能をより深くカスタマイズし、特定の要件を満たす環境を構築するために不可欠なスキルです。
第7章: 実践的なアプリケーション連携例
これまでの知識を活かし、実際のWebアプリケーションからDockerized Redisに接続する具体的な例を見ていきましょう。ここではPython FlaskとNode.js Expressの2つの例を扱います。どちらの例もDocker Composeを使用し、複数のサービスが連携する環境を構築します。
7.1 Python Flask + Redis (キャッシュ)
Python FlaskアプリケーションでRedisをシンプルにキャッシュとして利用する例です。
ディレクトリ構造:
flask-redis-example/
├── docker-compose.yml
└── app/
├── Dockerfile
├── requirements.txt
└── app.py
-
app/requirements.txt
:
アプリケーションに必要なPythonライブラリを定義します。
Flask
redis -
app/app.py
:
Flaskアプリケーションのコードです。Redisに接続し、簡単なキャッシュ操作を行います。
“`python
# app/app.py
import os
import time
from flask import Flask, jsonify
import redisapp = Flask(name)
環境変数からRedisの接続情報を取得
REDIS_HOST = os.getenv(‘REDIS_HOST’, ‘localhost’)
REDIS_PORT = int(os.getenv(‘REDIS_PORT’, 6379))
REDIS_PASSWORD = os.getenv(‘REDIS_PASSWORD’, None) # パスワードがない場合はNoneRedisクライアントの初期化
try:
if REDIS_PASSWORD:
redis_client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, decode_responses=True)
else:
redis_client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, decode_responses=True)
redis_client.ping() # Redisへの接続をテスト
print(f”Connected to Redis at {REDIS_HOST}:{REDIS_PORT}”)
except redis.exceptions.ConnectionError as e:
print(f”Could not connect to Redis: {e}”)
redis_client = None # 接続失敗時はクライアントをNoneに設定@app.route(‘/’)
def index():
return jsonify(message=”Welcome to Flask Redis Example!”)@app.route(‘/cache/
‘)
def get_cached_data(key):
if not redis_client:
return jsonify(error=”Redis not connected.”), 500cached_value = redis_client.get(key) if cached_value: print(f"Cache hit for key: {key}") return jsonify(key=key, value=cached_value, source="cache") else: print(f"Cache miss for key: {key}, fetching from 'database'...") # ダミーのデータ取得(データベースからの取得をシミュレート) time.sleep(1) # ネットワーク遅延をシミュレート data_from_db = f"data_from_db_for_{key}_{time.time()}" redis_client.setex(key, 60, data_from_db) # 60秒間キャッシュに保存 return jsonify(key=key, value=data_from_db, source="database")
@app.route(‘/clear_cache/
‘)
def clear_cache(key):
if not redis_client:
return jsonify(error=”Redis not connected.”), 500deleted_count = redis_client.delete(key) return jsonify(message=f"Cache for key '{key}' cleared.", deleted_count=deleted_count)
if name == ‘main‘:
app.run(host=’0.0.0.0’, port=5000)
“` -
app/Dockerfile
:
FlaskアプリケーションのDockerイメージをビルドするためのDockerfileです。
“`dockerfile
# app/Dockerfile
FROM python:3.9-slim-busterWORKDIR /app
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txtCOPY . .
EXPOSE 5000
CMD [“python”, “app.py”]
“` -
docker-compose.yml
:
FlaskアプリとRedisサービスを定義するDocker Composeファイルです。
“`yaml
# docker-compose.yml
version: ‘3.8’services:
web:
build:
context: ./app # appディレクトリにあるDockerfileを使用
ports:
– “5000:5000” # ホストの5000ポートをwebコンテナの5000ポートにマッピング
environment:
REDIS_HOST: redis # Redisサービスのホスト名
REDIS_PORT: 6379
# REDIS_PASSWORD: your_redis_password # Redisにパスワードを設定した場合に有効化
depends_on:
– redis # webサービスはredisサービスに依存
restart: on-failureredis:
image: redis:6.2.7-alpine # 軽量版Redisイメージ
container_name: flask_redis_server
# ports:
# – “6379:6379” # ホストからのRedis直接アクセスを不要とするためコメントアウト
volumes:
– redis-data:/data # Redisデータの永続化
# – ./redis.conf:/usr/local/etc/redis/redis.conf # カスタムRedis設定を使用する場合
# command: redis-server /usr/local/etc/redis/redis.conf # カスタム設定を使用する場合
# environment:
# REDIS_PASSWORD: your_redis_password # Redisパスワードを環境変数で設定する場合 (非推奨, secrets管理を推奨)
restart: alwaysvolumes:
redis-data: # 名前付きボリュームの定義
``
redis
*サービスから
portsマッピングを削除しました。これにより、ホストOSからはRedisに直接アクセスできなくなり、
webサービスからのみ内部ネットワーク経由でアクセスする、よりセキュアな構成になります。
REDIS_PASSWORD` はコメントアウトしています。本番環境ではDocker SecretsやKubernetes Secretsなどの安全な方法で管理すべきです。
* -
実行:
flask-redis-example
ディレクトリに移動し、Docker Composeを起動します。
bash
cd flask-redis-example
docker compose up -d --build -
動作確認:
ブラウザまたはcurl
でアクセスします。http://localhost:5000/cache/mydata
: 初回アクセス時は「database」からデータ取得し、Redisにキャッシュされます。http://localhost:5000/cache/mydata
: 2回目以降のアクセスは「cache」からデータ取得され、高速に応答します。http://localhost:5000/clear_cache/mydata
: キャッシュをクリアします。
Redisコンテナのログも確認できます。
bash
docker compose logs -f redis
docker compose logs -f web
7.2 Node.js Express + Redis (セッションストア)
Node.js ExpressアプリケーションでRedisをセッションストアとして利用する例です。
ディレクトリ構造:
express-redis-example/
├── docker-compose.yml
└── app/
├── Dockerfile
├── package.json
└── server.js
-
app/package.json
:
アプリケーションに必要なNode.jsパッケージを定義します。
json
{
"name": "express-redis-app",
"version": "1.0.0",
"description": "Express app with Redis session store",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2",
"express-session": "^1.17.3",
"connect-redis": "^7.1.0",
"redis": "^4.6.8"
}
} -
app/server.js
:
Expressアプリケーションのコードです。express-session
とconnect-redis
を使ってセッションをRedisに保存します。
“`javascript
// app/server.js
const express = require(‘express’);
const session = require(‘express-session’);
const redis = require(‘redis’);
const RedisStore = require(‘connect-redis’).default;const app = express();
const PORT = process.env.PORT || 3000;
const REDIS_HOST = process.env.REDIS_HOST || ‘localhost’;
const REDIS_PORT = parseInt(process.env.REDIS_PORT || ‘6379’);
const REDIS_PASSWORD = process.env.REDIS_PASSWORD || undefined; // undefinedだとパスワードなし// Redisクライアントの初期化
const redisClient = redis.createClient({
socket: {
host: REDIS_HOST,
port: REDIS_PORT
},
password: REDIS_PASSWORD
});redisClient.on(‘connect’, () => console.log(‘Connected to Redis!’));
redisClient.on(‘error’, (err) => console.log(‘Redis Client Error’, err));// Redisクライアントを接続
(async () => {
await redisClient.connect();
})();// RedisStoreの設定
const redisStore = new RedisStore({
client: redisClient,
prefix: “myapp:”, // Redisキーのプレフィックス
ttl: 3600 // セッションの有効期限 (秒)
});// セッションミドルウェアの設定
app.use(session({
store: redisStore,
secret: ‘your_super_secret_key_here’, // セッションIDを暗号化するための秘密鍵
resave: false, // セッションストアに未変更のセッションを再保存しない
saveUninitialized: false, // 初期化されていない(変更されていない)セッションを保存しない
cookie: {
secure: process.env.NODE_ENV === ‘production’, // HTTPSの場合にのみクッキーを送信
httpOnly: true, // JavaScriptからのアクセスを禁止
maxAge: 1000 * 60 * 60 * 24 // クッキーの有効期限 (ミリ秒, 24時間)
}
}));// ルートハンドラ
app.get(‘/’, (req, res) => {
// セッションにアクセス数を保存
if (req.session.views) {
req.session.views++;
} else {
req.session.views = 1;
}
res.send(Hello World! You have visited this page ${req.session.views} time(s). Session ID: ${req.session.id}
);
});app.get(‘/reset’, (req, res) => {
req.session.destroy((err) => {
if (err) {
return res.status(500).send(‘Could not destroy session’);
}
res.send(‘Session reset!’);
});
});app.listen(PORT, () => {
console.log(Server listening on port ${PORT}
);
});
``
secret
* **重要**:キーは推測されにくい強力な文字列に置き換え、本番環境では環境変数やSecretsマネージャーで管理してください。
redisClient.connect()` は非同期なので、即時実行関数でラップしています。
* -
app/Dockerfile
:
ExpressアプリケーションのDockerイメージをビルドするためのDockerfileです。
“`dockerfile
# app/Dockerfile
FROM node:18-alpineWORKDIR /app
COPY package*.json ./
RUN npm install –productionCOPY . .
EXPOSE 3000
CMD [“npm”, “start”]
“` -
docker-compose.yml
:
ExpressアプリとRedisサービスを定義するDocker Composeファイルです。
“`yaml
# docker-compose.yml
version: ‘3.8’services:
web:
build:
context: ./app
ports:
– “3000:3000”
environment:
PORT: 3000
REDIS_HOST: redis
REDIS_PORT: 6379
# REDIS_PASSWORD: your_redis_password # Redisにパスワードを設定した場合に有効化
NODE_ENV: development # development or production (cookie secure設定に影響)
depends_on:
– redis
restart: on-failureredis:
image: redis:6.2.7-alpine
container_name: express_redis_server
# ports:
# – “6379:6379” # ホストからのRedis直接アクセスを不要とするためコメントアウト
volumes:
– redis-data:/data
# – ./redis.conf:/usr/local/etc/redis/redis.conf
# command: redis-server /usr/local/etc/redis/redis.conf
# environment:
# REDIS_PASSWORD: your_redis_password
restart: alwaysvolumes:
redis-data:
“` -
実行:
express-redis-example
ディレクトリに移動し、Docker Composeを起動します。
bash
cd express-redis-example
docker compose up -d --build -
動作確認:
ブラウザでhttp://localhost:3000/
にアクセスし、ページをリロードすると訪問回数が増加することを確認します。これはRedisに保存されたセッションデータが利用されているためです。
http://localhost:3000/reset
でセッションをリセットできます。Redisコンテナ内部から
redis-cli
でセッションキーを確認することもできます。
“`bash
docker compose exec redis redis-cliredis-cliプロンプトで
KEYS myapp:*
出力例: 1) “myapp:YOUR_SESSION_ID”
HGETALL myapp:YOUR_SESSION_ID
セッションデータがハッシュとして保存されていることが確認できます
“`
これらの実践例を通して、Docker Composeがいかに複雑なマルチサービスアプリケーションのデプロイと管理を簡素化するか、そしてDockerized Redisがアプリケーションのバックエンドとしていかに強力であるかを理解できたはずです。
第8章: トラブルシューティングとよくある質問
DockerとRedisの連携は非常に強力ですが、時に問題に直面することもあります。ここでは、よくある問題とその解決策、および関連するヒントをまとめます。
8.1 ポート衝突
問題: docker run
や docker compose up
時に port is already allocated
あるいは bind: address already in use
のようなエラーが表示される。
原因: ホストOS上で、Redisが使用しようとしているポート(デフォルト6379)が、すでに別のプロセス(別のRedisインスタンス、別のDockerコンテナ、または他のアプリケーション)によって使用されている。
解決策:
* netstat -tuln | grep 6379
(Linux/macOS) または netstat -ano | findstr :6379
(Windows) で、どのプロセスが6379ポートを使用しているかを確認する。
* 使用しているプロセスを停止するか、Dockerのポートマッピングを変更して別のホストポートを使用する。
例: docker run -d -p 6380:6379 redis
(ホストの6380ポートを使用)
Docker Composeの場合:
yaml
ports:
- "6380:6379"
8.2 コンテナが起動しない (docker logs
)
問題: docker ps
でコンテナの STATUS
が Exited
になっている、または全く表示されない。
原因: コンテナ内のアプリケーション(この場合はRedis)が、起動直後にエラーで終了している。
解決策:
* ログの確認: まず docker logs [container_name]
または docker compose logs [service_name]
でログを確認する。エラーメッセージから原因を特定できることが多い。
例: docker logs my-redis
または docker compose logs redis
* 設定ファイルの問題: redis.conf
をマウントしている場合、設定ファイルの構文エラーや、Redisがアクセスできないパス(権限不足など)が原因で起動に失敗することがあります。
* メモリ不足: ホストOSのメモリが不足しているか、Redisの maxmemory
設定が低すぎる場合、Redisが起動できないことがあります。
* ボリュームの権限: バインドマウントを使用している場合、ホスト側のディレクトリの権限が適切でないと、Redisがデータファイルを作成・書き込みできずに起動に失敗することがあります。ホスト側のディレクトリの所有者と権限を確認し、Redisユーザー(通常は redis
)が書き込めるように設定する。
8.3 データ永続化の問題
問題: コンテナを停止・削除してから再起動すると、以前保存したデータが消えている。
原因: データの永続化設定が正しく行われていない。
解決策:
* Docker Volumeの確認:
* 名前付きボリュームを使用しているか? (docker volume ls
, docker volume inspect
)
* ボリュームがコンテナのRedisデータディレクトリ (/data
) に正しくマウントされているか? (-v my-redis-data:/data
)
* docker compose down -v
でボリュームごと削除してしまっていないか?
* Redis永続化設定の確認:
* redis.conf
でRDB (save
) またはAOF (appendonly yes
) が正しく有効になっているか?
* redis-server
起動時に redis.conf
が正しくロードされているか?
* Redisコンテナ内部の /data
ディレクトリに dump.rdb
や appendonly.aof
が存在するかを確認する (docker exec my-redis ls /data
)。
8.4 ネットワーク接続の問題 (Dockerネットワーク, ping
hostname)
問題: アプリケーションコンテナからRedisコンテナに接続できない。エラーメッセージに Connection refused
, Host not found
などが含まれる。
原因: ネットワーク設定の誤り、ポートの誤り、ファイアウォール、Redisの bind
設定など。
解決策:
* Docker Composeの場合:
* アプリケーションがRedisサービス名 (redis
) をホストとして正しく参照しているか確認する。
* docker compose networks ls
でComposeによって作成されたネットワークを確認し、両方のコンテナが同じネットワークに接続されているか確認する。
* アプリケーションコンテナからRedisコンテナへの疎通を確認する。
bash
docker compose exec web ping redis
docker compose exec web redis-cli -h redis -p 6379 PING # パスワードがあれば -a で指定
* ポート公開の有無:
* docker-compose.yml
でRedisの ports
マッピングを削除した場合、ホストOSからはRedisに直接アクセスできません。アプリケーションコンテナから内部ネットワーク経由で接続する必要があります。
* アプリケーションコンテナのDockerfileで、Redis接続に必要なポートが開かれていることを確認します(Redisへの接続自体にはアプリ側でEXPOSEは不要)。
* Redisの bind
設定:
redis.conf
で bind 127.0.0.1
のように特定のIPアドレスにバインドしている場合、Dockerコンテナの内部ネットワークからのアクセスが拒否される可能性があります。コンテナ内ではデフォルトで 0.0.0.0
(すべてのインターフェース) でリッスンするようにするか、またはバインドIPをコンテナのプライベートネットワークIPに変更する必要がありますが、通常はデフォルトの redis-server
コマンドで問題ありません。protected-mode no
に変更する必要がある場合もありますが、これはセキュリティリスクを伴います。パスワード設定とファイアウォールが推奨されます。
8.5 Redisメモリ不足 (maxmemory
設定)
問題: Redisにデータを書き込めない、あるいはデータが予期せず削除される。ログに OOM command not allowed when used memory > maxmemory
のようなエラーが表示される。
原因: Redisが設定された maxmemory
上限に達している。
解決策:
* redis.conf
の maxmemory
設定を増やす。
* maxmemory-policy
を適切に設定し、メモリ上限に達した際の挙動(LRUなどで古いデータを削除する)を制御する。
* ホストOSに十分なメモリがあるか確認し、Dockerコンテナに割り当てられたメモリ上限も確認する(docker run --memory
オプション)。
* Redisに保存されているデータを確認し、不要なデータを削除したり、データ構造を見直したりしてメモリ使用量を最適化する。
8.6 redis-cli
で接続できない
問題: redis-cli
で接続しようとすると Could not connect to Redis at 127.0.0.1:6379: Connection refused
などと表示される。
原因:
* Redisコンテナが起動していないか、ポートマッピングが正しくない。
* Redisにパスワードが設定されているが、redis-cli
で認証していない。
* Redisが特定のIPアドレスにバインドされている(bind
設定)。
* ファイアウォールが接続をブロックしている。
解決策:
* docker ps
でRedisコンテナが Up
状態であることを確認する。
* docker inspect [container_name]
でポートマッピングを確認する。
* パスワードが設定されている場合、redis-cli -a your_password
で接続する。
* redis.conf
の bind
設定を確認し、デフォルトに戻すか、protected-mode no
を試す(ただしセキュリティリスクあり)。
* ホストOSのファイアウォール設定を確認する。
8.7 権限の問題 (bind mounts
)
問題: バインドマウントしたホストのディレクトリに、Redisがファイルを書き込めない。ログに Permission denied
が表示される。
原因: ホストのディレクトリのファイルシステム権限が、コンテナ内でRedisプロセスが実行されるユーザー(通常は redis
ユーザー、UID/GIDが999など)に書き込みを許可していない。
解決策:
* ホスト側のディレクトリの権限を、Redisコンテナのユーザーが書き込めるように変更する。
例 (Linux): sudo chown -R 999:999 /path/to/your/redis_data
(RedisのUID/GIDが999の場合)
または、より広範な権限を与える: sudo chmod -R 777 /path/to/your/redis_data
(セキュリティリスクあり)
* Dockerコンテナを起動する際に、RedisユーザーのUID/GIDをホスト側のディレクトリの所有者と合わせるように指定する(複雑になる場合がある)。
* 可能であれば、バインドマウントの代わりにDocker Volumeを使用することを検討する。
これらのトラブルシューティングのヒントが、あなたが直面する可能性のある問題を解決する手助けとなることを願っています。重要なのは、常にまずログを確認し、エラーメッセージを注意深く読むことです。
まとめと次のステップ
本記事では、「DockerでRedisを使いこなす!」をテーマに、Redisコンテナのデプロイと管理に関する広範な知識を網羅的に解説しました。
学習したことの再確認:
- DockerとRedisの基本: コンテナ技術とインメモリデータストアRedisのそれぞれの特性と、両者を組み合わせるメリットを理解しました。
- 基本的なコンテナ操作:
docker pull
,docker run
,docker stop
,docker rm
といった基本的なコマンドを使って、Redisコンテナを起動・管理する方法を学びました。 - データの永続化: Docker Volume (名前付きボリューム、バインドマウント) を使ってRedisデータを永続化する方法、そしてRedis自身の永続化機能 (RDB, AOF) の重要性を理解しました。
- Docker Composeの活用:
docker-compose.yml
ファイルを使って複数のサービス(アプリケーションとRedis)を定義し、一元的に管理する方法を習得しました。 - 高度な設定と運用:
redis.conf
を使ったカスタム設定の適用(認証、メモリ制限など)や、セキュリティに関する考慮事項について理解を深めました。 - カスタムイメージの作成:
Dockerfile
を使って、特定の要件(モジュール組み込み、カスタム設定)に応じたRedisイメージをビルドする方法を学びました。 - 実践的なアプリケーション連携: Python FlaskとNode.js Expressの具体例を通して、実際のアプリケーションからRedisコンテナに接続し、キャッシュやセッションストアとして利用する実践的なスキルを習得しました。
- トラブルシューティング: よくある問題(ポート衝突、起動失敗、永続化問題など)とその解決策を学び、問題解決のための実践的なアプローチを身につけました。
あなたは今、Docker環境でRedisを効率的かつ堅牢にデプロイし、アプリケーションと連携させるための強力な基盤を築きました。
次のステップ:
本記事はRedisとDockerの基本的なデプロイに焦点を当てましたが、さらに深く学ぶべき分野は多岐にわたります。
- Redis Cluster / Sentinelの深掘り: 大規模な本番環境では、単一のRedisインスタンスでは不十分です。Redis Sentinelによる高可用性、またはRedis Clusterによるスケーラビリティと可用性を実現する方法について学習してください。これらはDocker SwarmやKubernetesといったコンテナオーケストレーションツールと組み合わせてデプロイされることが一般的です。
- Docker Swarm / Kubernetes: 複数のホストにわたってコンテナをデプロイ・管理するためのオーケストレーションツールです。本番環境での自動スケーリング、自己修復、負荷分散などを実現するために必須の知識となります。
- Redisモジュール: RedisJSON, RediSearch, RedisGraph, RedisTimeSeriesなど、Redisの機能をさらに拡張するモジュールを探索し、あなたのアプリケーションのニーズに合わせて活用することを検討してください。
- 監視とアラート: Prometheus, Grafana, ELK Stack (Elasticsearch, Logstash, Kibana) などのツールを使って、Redisのパフォーマンスを継続的に監視し、問題が発生した際に自動的に通知するシステムを構築してください。
- セキュリティの強化: Docker Secretsや環境変数管理ツール、VPNなどを用いて、よりセキュアなRedis接続と認証情報の管理を実践してください。
- CI/CDパイプラインへの組み込み: Dockerイメージの自動ビルド、テスト、デプロイをCI/CD (継続的インテグレーション/継続的デリバリー) パイプラインに組み込み、開発プロセスを自動化・効率化してください。
DockerとRedisは、現代のクラウドネイティブアプリケーション開発において不可欠なツールです。本記事で得た知識を基に、さらなる学習と実践を重ね、あなたの開発スキルを次のレベルへと引き上げていきましょう。
Happy Hacking!