実践編:Docker を使用した本番環境向け Redis のデプロイ(永続化 + セキュリティ設定 + 高可用性)

Redis のコンテナ化によるデプロイは一見簡単そうに見え、docker run redis という 1 行のコマンドで動作させることができます。しかし、本番環境になると、問題が次々と浮上します。データが失われたらどうするか?ポートスキャンによるマイニング攻撃からどう防御するか?メモリが不足したらどう対処するか?マスター・スレーブやセンチネルをどう構築するか?

この記事では、最も基本的な docker run から始まり、Docker Compose、永続化戦略、セキュリティ強化、マスター・スレーブレプリケーション、Sentinelによる高可用性までを網羅し、本番環境での Docker による Redis デプロイの全プロセスを徹底解説します。
この記事から得られるもの:

  • 3つのデプロイ方法の完全なコマンド。コピーするだけで利用可能

  • RDB + AOFによる永続化設定で、データ損失を防止

  • 本番環境レベルのセキュリティ強化策:マイニングや侵入を防止

  • マスター・スレーブレプリケーション + センチネルモードによる高可用性デプロイ

  • よく使う運用コマンド + よくある問題のトラブルシューティングチェックリスト
    こんな方に最適:

  • RedisをDockerで稼働させたい初心者

  • これまで物理サーバーにRedisをインストールしてきたが、コンテナ化への移行を検討している運用担当者

  • 基本的な使い方は理解しているが、本番環境でのベストプラクティスを把握したい開発者

前置きは省き、すぐに本題に入ります。

一、環境の準備

1.1 システム要件

# Dockerのバージョンを確認
docker --version
# Docker version 24.0.7, build afdd53b

# Docker Composeのバージョンを確認
docker compose version
# Docker Compose version v2.21.0

1.2 事前チェック

# ポート 6379 が使用されていないことを確認
netstat -tlnp | grep 6379
# または
ss -tlnp | grep 6379

# ホストマシンのメモリが十分であることを確認(Redis はインメモリデータベースです)
free -h

注意:Redis の永続化時に子プロセスを fork するため、追加のメモリが必要です。メモリの少なくとも 50% を余剰として確保することを推奨します。


II. 方法 1:docker run によるクイック起動(テストに適しています)

2.1 公式イメージの取得

# 最新の安定版を取得
docker pull redis:latest

# 推奨:具体的なバージョンを指定
docker pull redis:7.2-alpine

# ローカルのイメージを確認
docker images | grep redis

推奨構成

  • redis:alpine --- サイズが小さい(約30MB)、本番環境での使用を推奨
  • redis:latest --- Debianベース、サイズが大きい(約130MB)、デバッグツールが充実
  • redis:7.2 --- メジャーバージョンを指定、本番環境でのバージョン固定

2.2 最小限の起動

docker run -d \\
  --name redis \\
  -p 6379:6379 \\
  --restart=always \\
  
redis:7.2-alpine

2.3 パスワード付きでの起動

docker run -d \\
  --name redis \\
  -p 6379:6379 \\
  --restart=always \\
  
redis:7.2-alpine \\
  redis-server --requirepass 「your_strong_password」

2.4 接続の確認

# コンテナ内に移動し、redis-cli を使用してテスト
docker exec -it redis redis-cli

# パスワードが必要な場合
docker exec -it redis redis-cli -a 「your_strong_password」
# または、コンテナ内に入ってから認証を行う
127.0.0.1:6379> AUTH your_strong_password
OK

# 読み書きのテスト
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
「world」

3. 方法2:外部設定 + データボリュームによる永続化(本番環境基準)

最もシンプルな起動方法ではデフォルト設定しか使用できず、データはコンテナ内に保存されるため、コンテナを削除するとデータも消えてしまいます。本番環境では、外部設定とデータの永続化を必ず設定する必要があります。

3.1 ディレクトリ構造の計画

# Redis 関連のディレクトリを作成
mkdir -p /data/redis/{conf,data,logs}

ディレクトリ 用途
/data/redis/conf 設定ファイル redis.conf
/data/redis/data データの永続化(RDB + AOF)
/data/redis/logs ログファイル

3.2 設定ファイル redis.conf

/data/redis/conf/redis.confを作成します:

# ========== 基本設定 ==========
# バインド先アドレス。0.0.0.0 はすべての IP からのアクセスを許可することを意味します(本番環境では内部 IP をバインドすることを推奨します)
bind 0.0.0.0

# ポート
port 6379

# パスワード(本番環境では強固なパスワードを設定する必要があります)
requirepass your_strong_password_here

# データベース数
databases 16

# クライアント接続数の上限
maxclients 10000

# ========== メモリ設定 ==========
# 最大メモリ(サーバーの実情に応じて設定、例:2GB)
maxmemory 2gb

# メモリエジェクションポリシー
# allkeys-lru:すべてのキーの中から、最近最も使用頻度の低いキーを優先的に削除
# allkeys-lfu:すべてのキーの中から、使用頻度が最も低いキーを優先的に削除
# volatile-lru:有効期限が設定されているキーの中から、最近最も使用頻度の低いキーを優先的に削除
# noeviction:エジェクションを行わず、容量がいっぱいになると直接エラーを返す
maxmemory-policy allkeys-lru

# ========== 永続化 - RDB ==========
# RDB 永続化を有効化
save 900 1 # 900 秒以内に少なくとも 1 つのキーが変更される
save 300 10 # 300 秒以内に少なくとも 10 つのキーが変更される
save 60 10000 # 60秒以内に少なくとも10000個のキーに変更があった場合

# RDBファイル名
dbfilename dump.rdb

# データディレクトリ
dir /data

# RDB圧縮
rdbcompression yes

# ========== 永続化 - AOF ==========
# AOF 永続化を有効化(本番環境では RDB+AOF のハイブリッドモードを推奨)
appendonly yes

# AOF ファイル名
appendfilename 「appendonly.aof」

# AOF のディスク書き込みポリシー
# always:書き込み操作のたびにディスクに書き込む(最も安全、パフォーマンスが最も低い)
# everysec:毎秒ディスクに書き込み(推奨、安全性とパフォーマンスのバランスが取れている)
# no:OSが書き込みタイミングを決定(最速、最も安全ではない)
appendfsync everysec

# AOF書き換えのトリガー設定
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# ========== ログ設定 ==========
# ログレベル:debug、verbose、notice、warning
loglevel notice

# ログファイル
logfile 「/data/redis.log」

# ========== スロークエリ ==========
# スロークエリの閾値(マイクロ秒)
slowlog-log-slower-than 10000

# スロークエリの最大レコード数
slowlog-max-len 128

# ========== セキュリティ強化 ==========
# 危険なコマンドの名前変更(本番環境では強く推奨)
rename-command FLUSHDB 「」
rename-command FLUSHALL 「」
rename-command KEYS 『』
rename-command CONFIG 「CONFIG_mysecret」
rename-command SHUTDOWN 「SHUTDOWN_mysecret」

# 危険なコマンドの無効化(空に設定すると無効化されます)
# rename-command DEBUG 「」

# ========== その他 ==========
# バックグラウンド実行(Docker 展開時は有効にしないでください。有効にするとコンテナが終了します)
# daemonize no

# PID ファイル
pidfile /var/run/redis.pid

重要 :DockerでRedisをデプロイする際、daemonize は必ず no に設定する必要があります(デフォルトはnoです)。そうしないと、コンテナが起動後すぐに終了してしまいます。

3.3 コンテナの起動

docker run -d \\
  
--name redis \\
  -p 6379:6379 \\
  --restart=always \\
  -v /data/redis/conf/redis.conf:/etc/redis/redis.conf:ro \\
  -v /data/redis/data:/data \\
  -v /data/redis/logs:/var/log/redis \\
  
--sysctl net.core.somaxconn=1024 \\
  redis:7.2-alpine \\
  redis-server /etc/redis/redis.conf

パラメータの詳細:

パラメータ 機能
-d バックグラウンドで実行
--name redis コンテナ名の指定
-p 6379:6379 ポートマッピング
--restart=always Dockerの再起動後に自動起動
-v .../redis.conf:ro 設定ファイルを読み取り専用でマウント
-v .../data:/data データディレクトリをマウント。永続化データはここに保存
--sysctl net.core.somaxconn=1024 TCP接続キューのサイズを拡大し、Redis起動時の警告を解消
redis-server /etc/redis/redis.conf 指定した設定ファイルで起動

3.4 永続化の検証

# テストデータの書き込み
docker exec -it redis redis-cli -a 「your_password」
127.0.0.1:6379> set test_key test_value
OK
127.0.0.1:6379> save # 手動で RDB パーシスタンスをトリガー
OK
127.0.0.1:6379> exit

# データファイルを確認
ls -la /data/redis/data/
# dump.rdb および appendonly.aof ファイルが表示されるはず

# コンテナを再起動してデータが失われていないことを確認
docker restart redis
docker exec -it redis redis-cli -a 「your_password」 get test_key
# 「test_value」 --- データが残っていれば、永続化が機能していることを示しています

4. 方法3:Docker Compose によるデプロイ(推奨)

本番環境では、保守や移行の利便性を考慮し、Composeによる一元管理を採用しています。

4.1 docker-compose.yml

version: 『3.8』

services:
  redis:
    image: redis:7.2-alpine
    container_name: redis
    restart: always
    
ports:
      - 「6379:6379」
    volumes:
      - ./conf/redis.conf:/etc/redis/redis.conf:ro
      - ./data:/data
      - ./logs:/var/log/redis
    command: redis-server /etc/redis/redis.conf
    sysctls:
      
- net.core.somaxconn=1024
      - net.ipv4.tcp_max_syn_backlog=8192
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        
hard: 65535
    healthcheck:
      test: [「CMD」, 「redis-cli」, 「-a」, 『your_strong_password_here』, 「ping」]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 5s
    networks:
      - redis-network

networks:
  redis-network:
    driver: bridge

4.2 起動

# フォアグラウンドで起動し、ログを確認
docker compose up

# バックグラウンドで起動
docker compose up -d

# ステータスの確認
docker compose ps

# ログの確認
docker compose logs -f redis

5. 永続化戦略の詳細

Redis には RDB と AOF の 2 種類の永続化方式があり、本番環境では両方を有効にする(ハイブリッドモード)ことを推奨します。

5.1 RDB スナップショット

原理:一定間隔ごとに、メモリ内のデータのフルスナップショットをディスクに書き込みます。

利点

  • ファイルがコンパクトで、バックアップや災害復旧に適している
  • 復元が速く、RDB ファイルを直接読み込める
  • パフォーマンスへの影響が小さく、子プロセスをフォークして書き込みを行い、メインプロセスはサービスを継続する

デメリット

  • 間隔中にダウンするとデータが失われる
  • データ量が多い場合、forkに時間がかかり、一時的な遅延が発生する可能性がある

設定

save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data

5.2 AOF 追加ファイル

原理:各書き込みコマンドをファイルの末尾に追加する。MySQLのbinlogに類似している。

利点

  • データの安全性が高く、最大で1秒分のデータが失われる可能性がある
  • ファイルはテキスト形式であるため、読み取り可能で手動での修復が可能

デメリット

  • ファイルサイズがRDBよりも大きい
  • 復元速度がRDBよりも遅い
  • 書き込み操作が頻繁な場合、パフォーマンスに多少の影響がある

設定

appendonly yes
appendfsync everysec # 毎秒ディスクに書き込み、推奨
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

5.3 ハイブリッド永続化(Redis 4.0+)

Redis 4.0 以降では、RDB + AOF のハイブリッドモードがサポートされています。AOF の書き換え時には、RDB の内容が AOF ファイルの先頭に書き込まれ、その後の増分書き込みコマンドが追加されます。これにより、RDB の復元速度と AOF のデータ安全性の両方を兼ね備えています。

# ハイブリッド永続化を有効にする(Redis 5.0+ ではデフォルトで有効)
aof-use-rdb-preamble yes

本番環境での推奨設定:RDB + AOF ハイブリッドモード。データの安全性と復旧速度の両立を図ります。


6. セキュリティ設定(本番環境では必須)

Redisはマイニング攻撃の標的となりやすく、セキュリティ対策が施されていない状態でインターネットに公開されているRedisは、瞬く間に侵入されてしまいます。以下のセキュリティ対策は必ず実施してください。

6.1 強力なパスワードの設定

requirepass YourStrongPassword!@#2024

パスワードは十分に長く、複雑なものにしてください。123456redisのような脆弱なパスワードは使用しないでください。

6.2 内部ネットワーク IP のバインド

内部ネットワークでのみ使用する場合は、0.0.0.0をバインドしないでください:

# 内部ネットワークからのアクセスのみを許可
bind 192.168.1.100

あるいは、ポートをマッピングせず、Dockerの内部ネットワーク経由でのみアクセスするようにします:

# docker-compose.yml から ports 設定を削除し、内部ネットワークのみに公開
# ports:
# - 「6379:6379」

6.3 危険なコマンドの名称変更/無効化

# 直接無効化
rename-command FLUSHDB 「」
rename-command FLUSHALL 「」
rename-command KEYS 『』
rename-command DEBUG 「」

# コマンド名を変更し、エイリアスを知っているユーザーのみが使用できるようにする
rename-command CONFIG 「CONFIG_yoursecret」
rename-command SHUTDOWN 『SHUTDOWN_yoursecret』
rename-command SAVE 「SAVE_yoursecret」

6.4 ファイアウォールによる制限

# 特定の IP からのみ 6379 へのアクセスを許可
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

6.5 コンテナを root 権限で実行しない

# docker-compose.yml でユーザーを指定
user: 「999:999」 # redis ユーザーの uid/gid

6.6 セキュリティチェックリスト

  • 強固なパスワードが設定されている
  • 0.0.0.0 がバインドされていない(またはパブリックポートがマッピングされていない)
  • 危険なコマンドが無効化されている/名前変更されている
  • ファイアウォールでアクセス元が制限されている
  • コンテナが root として実行されていない
  • Redis のバージョンが最新の安定版である

7. 高可用性ソリューション

7.1 マスター・スレーブレプリケーション

1つのマスターと複数のスレーブ構成。マスターノードで書き込み、スレーブノードで読み取りを行い、読み書きを分離します。

docker-compose.yml
version: 『3.8』

services:
  redis-master:
    image: redis:7.2-alpine
    container_name: redis-master
    restart: always
    ports:
      - 「6379:6379」
    
volumes:
      - ./master/conf:/etc/redis
      - ./master/data:/data
    command: redis-server /etc/redis/redis.conf
    networks:
      - redis-net

  redis-slave1:
    image: redis:7.2-alpine
    container_name: redis-slave1
    
restart: always
    ports:
      - 「6380:6379」
    volumes:
      - ./slave1/conf:/etc/redis
      - ./slave1/data:/data
    command: redis-server /etc/redis/redis.conf --replicaof redis-master 6379
    
depends_on:
      - redis-master
    networks:
      - redis-net

  redis-slave2:
    image: redis:7.2-alpine
    container_name: redis-slave2
    restart: always
    ports:      - 「6381:6379」    volumes:      - ./slave2/conf:/etc/redis      - ./slave2/data:/data    command: redis-server /etc/redis/redis.conf --replicaof redis-master 6379    depends_on:      - redis-master    networks:      - redis-netnetworks:  redis-net:    driver: bridge
マスター・スレーブの検証
# マスターノードからスレーブノードの情報を確認docker exec -it redis-master redis-cli info replication# マスターノードからデータを書き込みdocker exec -it redis-master redis-cli set master_key hello# スレーブノードからデータを読み取りdocker exec -it redis-slave1 redis-cli get master_key# 「hello」 --- 同期成功

7.2 センチネルモード(Sentinel)

マスター・スレーブレプリケーションの問題点は、マスターノードがダウンした場合に手動で切り替えが必要になることです。センチネルモードでは、自動フェイルオーバーが実現されます。

アーキテクチャ
  • 3つのSentinelノード(奇数個、ブレインスプリットを防ぐため)
  • 1つのマスターと2つのスレーブ
  • Sentinelはマスターノードを監視し、マスターノードがダウンすると自動的に新しいマスターを選出します
sentinel.conf
# Sentinelのポートport 26379# 監視対象のマスターノード(名前、アドレス、ポート、選出に必要な票数)sentinel monitor mymaster redis-master 6379 2# マスターノードのパスワード(ある場合)sentinel auth-pass mymaster your_password# マスターノードのオフライン判定時間(ミリ秒)sentinel down-after-milliseconds mymaster 5000# フェイルオーバーのタイムアウト時間sentinel failover-timeout mymaster 10000# 新しいマスターノードを同期するスレーブノードの数sentinel parallel-syncs mymaster 1
docker-compose.yml(Sentinel セクション)
 sentinel1:    image: redis:7.2-alpine    container_name: sentinel1    restart: always    ports:      - 「26379:26379」    volumes:      - ./sentinel1/conf:/etc/redis    command: redis-sentinel /etc/redis/sentinel.conf    depends_on:      - redis-master      - redis-slave1      - redis-slave2    networks:      - redis-net  sentinel2:    image: redis:7.2-alpine    container_name: sentinel2    restart: always    ports:      - 「26380:26379」    volumes:      - ./sentinel2/conf:/etc/redis    command: redis-sentinel /etc/redis/sentinel.conf    depends_on:      - redis-master    networks:      - redis-net  sentinel3:
    image: redis:7.2-alpine    container_name: sentinel3    restart: always    ports:      - 「26381:26379」    volumes:      - ./sentinel3/conf:/etc/redis    command: redis-sentinel /etc/redis/sentinel.conf    depends_on:      - redis-master    networks:      - redis-net
センチネルの検証
# センチネルのステータスを確認docker exec -it sentinel1 redis-cli -p 26379 sentinel master mymaster# スレーブノードの一覧を表示docker exec -it sentinel1 redis-cli -p 26379 sentinel slaves mymaster# マスターノードの障害をシミュレートし、自動フェイルオーバーを確認docker stop redis-master# 数秒待ってから新しいマスターノードを確認docker exec -it sentinel1 redis-cli -p 26379 sentinel get-master-addr-by-name mymaster

7.3 クラスタモード(Cluster)

データ量が多く、水平スケーリングが必要な場合は Redis Cluster を使用します。データは複数のノードにシャード化されて格納されます。

注意:Redis Cluster には少なくとも 6 つのノード(マスター 3 台、スレーブ 3 台)が必要です。単一マシンでのデプロイはテスト用であり、本番環境では異なるマシンに分散させる必要があります。


8. よく使われる運用コマンド

8.1 コンテナ操作

# 起動/停止/再起動docker start redisdocker stop redisdocker restart redis# コンテナへのアクセスdocker exec -it redis sh# リアルタイムログの確認docker logs -f redisdocker logs -f --tail 100 redis# リソース使用状況の確認docker stats redis

8.2 Redis クライアントコマンド

# Redis への接続docker exec -it redis redis-cli# パスワード指定で接続docker exec -it redis redis-cli -a 「your_password」# 指定したホストのポートに接続docker exec -it redis redis-cli -h 127.0.0.1 -p 6379

8.3 情報の照会

# サーバー情報の確認127.0.0.1:6379> info# メモリ使用状況の確認127.0.0.1:6379> info memory# パーシステンス状態の確認127.0.0.1:6379> info persistence# レプリケーション情報の確認127.0.0.1:6379> info replication# スロークエリの確認127.0.0.1:6379> slowlog get 10# キー数の確認127.0.0.1:6379> dbsize

8.4 永続化操作

# RDB スナップショットを手動でトリガー(ブロッキング方式)127.0.0.1:6379> SAVE# バックグラウンドで RDB スナップショットをトリガー(非ブロッキング)127.0.0.1:6379> BGSAVE# AOF の書き換えを手動でトリガー127.0.0.1:6379> BGREWRITEAOF# 最後の永続化時刻を確認127.0.0.1:6379> LASTSAVE

8.5 ホット変更の設定

# 設定を確認127.0.0.1:6379> CONFIG GET maxmemory# 設定を変更(一時的に有効、再起動で無効化)127.0.0.1:6379> CONFIG SET maxmemory 4gb# 現在の設定を設定ファイルに書き込み127.0.0.1:6379> CONFIG REWRITE

9. よくある質問とトラブルシューティング

Q1:コンテナが起動後すぐに終了してしまう

設定ファイル内で daemonize yes と指定されている可能性が高いです。Docker コンテナはフォアグラウンドプロセスを必要とするため、no に変更してください。

# ログを確認して原因を特定するdocker logs redis

Q2:起動時に「WARNING overcommit_memory is set to 0」という警告が表示される

# 一時的な解決策sysctl vm.overcommit_memory=1# 恒久的な解決策(/etc/sysctl.confへの書き込み)echo 「vm.overcommit_memory=1」 >> /etc/sysctl.confsysctl -p

Q3:起動時の警告「WARNING you have Transparent Huge Pages (THP) support enabled」

# 一時的に無効化echo never > /sys/kernel/mm/transparent_hugepage/enabledecho never > /sys/kernel/mm/transparent_hugepage/defrag# 永続的に無効化し、rc.localに書き込むecho 『echo never > /sys/kernel/mm/transparent_hugepage/enabled』 >> /etc/rc.localecho 『echo never > /sys/kernel/mm/transparent_hugepage/defrag』 >> /etc/rc.local

Q4:起動時の警告「WARNING: The TCP backlog setting of 511 cannot be enforced」

# somaxconnの値を大きくするsysctl net.core.somaxconn=1024# docker run 実行時にパラメータを追加--sysctl net.core.somaxconn=1024

Q5:メモリが満杯になった場合の対処法

# メモリ使用状況の確認docker exec -it redis redis-cli info memory# 大きなキーを確認docker exec -it redis redis-cli --bigkeys# 期限切れのキーを削除127.0.0.1:6379> SCAN 0 MATCH * COUNT 1000# メモリのスワップアウトポリシーが適切か確認127.0.0.1:6379> CONFIG GET maxmemory-policy

Q6:RDBの永続化に失敗

データディレクトリの権限を確認し、redisユーザーに書き込み権限があることを確認:

chown -R 999:999 /data/redis/data

10. パフォーマンス最適化の推奨事項

  1. メモリ設定 :処理量に応じて maxmemory を設定し、Redisがスワップを使用しないようにする
  2. エジェクションポリシー:キャッシュ用途では allkeys-lru または allkeys-lfu を使用し、volatile-lru よりも安定しています
  3. 永続化ポリシー:RDB + AOF のハイブリッドモードで、データの安全性とパフォーマンスのバランスを取ります
  4. THPの無効化:透過的大ページ(THP)はRedisの遅延変動を引き起こすため、必ず無効化する必要があります
  5. メモリの巨大ページhugepageを有効にするとページテーブルのオーバーヘッドを削減できますが、THPとの区別に注意が必要です
  6. ネットワーク最適化somaxconn および tcp_backlog
  7. の値を大きくする

  8. スロークエリの監視:スロークエリログを有効化し、定期的に遅いコマンドを調査する
  9. 接続プール:クライアントで接続プールを使用し、接続の頻繁な作成・破棄を避ける
  10. パイプライン:バッチ処理にはパイプラインを使用し、ネットワークの往復回数を削減
  11. キーの設計:長いキーや頻繁にアクセスされるキーを避け、有効期限を適切に設定

まとめ

Docker による Redis デプロイの 3 ステップ:

  1. テスト環境docker run で素早く起動し、機能を検証
  2. 本番環境:外部設定 + データボリュームによる永続化 + セキュリティ強化
  3. 高可用性:マスター・スレーブレプリケーション+センチネルモードによる自動フェイルオーバーの実現

基本原則:データの永続化、パスワードの必須設定、危険なコマンドの無効化、パブリックネットワークへの無防備な公開禁止、メモリの上限設定