---
title: "ElasticsearchのDocker構築｜単一ノードと3ノードのcompose定義・ホスト設定・永続化の実務"
url: "https://www.issoh.co.jp/tech/details/17015/"
published: 2026-08-26
updated: 2026-08-27
categories: ["データベース"]
publisher: "株式会社一創"
---

# ElasticsearchのDocker構築｜単一ノードと3ノードのcompose定義・ホスト設定・永続化の実務

Elasticsearchは公式のコンテナイメージが配布されているため、起動そのものは1行で済みます。詰まるのはその後です。ホスト側のカーネル設定でいきなり落ちる、メモリを割り当てたつもりが足りない、コンテナを作り直したらインデックスが消えている、という3つは構築の初日にほぼ必ず踏みます。ここでは2026年8月時点の9.5系を前提に、検証用の単一ノードから3ノードのクラスタまで、コンテナで動かすときだけ追加で必要になる設定を順に組み立てます。転置インデックスやシャード本数といった製品そのものの設計は[Elasticsearchの内部構造とシャード設計を扱った記事](https://www.issoh.co.jp/tech/details/17011/)が担当するため、この記事では触れません。

## まとめ：Docker構築で先に決める5点と結論

コマンドを打つ前に、決めておくと後戻りが減る値が5つあります。いずれも起動してから変えると、コンテナの作り直しやデータの入れ直しを伴います。

- **用途**：手元の検証だけか、ステージング以上か。前者ならセキュリティ設定を省いた構成でも構いませんが、後者では省けません
- **ノード数**：単一ノードは検証専用と割り切る。ノードが落ちた瞬間に読み書きが止まる構成であることを、先に受け入れておきます
- **ホスト側のカーネル設定**：`vm.max_map_count` はコンテナの中からは変更できません。ホストで通せない環境なら、そもそも構築が完了しません
- **コンテナのメモリ上限**：ヒープはここから自動で決まります。先に決めるのはヒープではなくコンテナに与えるメモリの方です
- **データの置き場所**：名前付きボリュームかバインドマウントか。バックアップの取り方まで含めて、起動前に決めておきます

結論から言えば、開発と検証はDockerで揃えるのが素直です。バージョンを固定した同じ環境をチーム全員に配れて、壊しても作り直せます。一方で本番は、単一ホストのcomposeで足りるのは停止しても数時間で復旧できることが許される用途に限られます。可用性の要件があるならオーケストレーション基盤かマネージドサービスへ寄せる方が、運用の総量を小さく抑えられる現実的な選択です。この線引きを曖昧にしたまま本番へ持ち込むと、ノード障害ではなくホスト障害で全滅する構成を、気づかないまま抱えることになります。

## 公式イメージで単一ノードを立てる｜検証環境を最短で用意する手順

まず押さえたいのは、8系以降のイメージは初回起動時にセキュリティ設定を自動生成するという点です。証明書が作られ、TLSが有効になり、`elastic`ユーザのパスワードが標準出力に一度だけ表示されます。この挙動を知らないと、起動したのにブラウザからつながらないという状態で止まります。つながらないのは正常で、接続先が暗号化された経路に変わっているからです。

### docker runでの起動｜初回に出るパスワードと証明書の受け取り方

公式ドキュメントが例示している起動コマンドは次の形です。専用ネットワークを作ってから、メモリ上限を明示して起動します。

```
docker network create elastic

docker run --name es01 --net elastic -p 9200:9200 -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:9.5.2
```

起動ログには、`elastic`ユーザのパスワードと、Kibanaを後からつなぐための登録トークンが出力されます。ここを取り逃すと再表示はできないため、ターミナルの内容は必ず控えてください。パスワードを控え損ねた場合は、コンテナ内の`elasticsearch-reset-password`で作り直す形になります。

次に必要なのが、認証局の証明書をホスト側へ取り出す操作です。TLSが有効なので、curlやクライアントライブラリから叩くにはこの証明書を渡す必要があります。

```
docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .

curl --cacert http_ca.crt -u elastic:PASSWORD https://localhost:9200
```

ここまでで単一ノードが動きます。`-m 1GB`はコンテナのメモリ上限で、この値からヒープが逆算されます。機械学習の機能まで触るなら公式は`-m 6GB`と自動割り当ての設定を例示しており、1GBでは足りません。

### start-localスクリプト｜手順を持たずに検証環境だけ用意する選択肢

検索の挙動を数時間だけ確かめたい、といった用途なら、公式が用意しているワンライナーの方が速く済みます。

```
curl -fsSL https://elastic.co/start-local | sh
```

これで9200番のElasticsearchと5601番のKibanaが立ち上がり、1か月の試用ライセンスが付きます。ただし公式ドキュメント自身が、本番デプロイにこの手順を使わないこと、安全ではないことを明記しています。手軽さと引き換えにセキュリティ設定を落としているためで、検証が終わったら消す前提の環境だと理解して使ってください。チームで共有する開発環境や、そのまま育てて本番にする可能性がある環境では選ばない方が無難です。

## ホスト側のカーネル設定｜vm.max\_map\_countで起動が止まる理由

Docker構築で最初につまずくのは、たいていこの設定です。Elasticsearchは索引ファイルをメモリマップで読むため、プロセスが持てるメモリマップ領域の数がカーネル既定値のままだと足りません。起動時のブートストラップチェックで弾かれ、コンテナが立ち上がらずに終了します。

### 1048576という現行値｜コンテナ内では変えられない設定をホストで通す

公式の本番向けドキュメントは、`vm.max_map_count`を`1048576`に設定するよう求めています。かつて広く引用されていた`262144`という値は下限側の目安で、現行の記述は一桁大きい値になっています。日本語の解説記事は`262144`のままのものが多く残っているため、コピー元の年代には注意してください。

```
sysctl -w vm.max_map_count=1048576
```

この指定は再起動で消えます。恒久化するにはカーネルパラメータの設定ファイルへ書き込みます。ここで押さえておきたいのは、これがホストのカーネルパラメータであってコンテナの設定ではないという点です。コンテナはホストのカーネルを共有するため、いくらcompose側に書き足しても、ホストで通っていなければ意味がありません。マネージドなコンテナ実行基盤でホストのカーネル設定に手が届かない場合、Elasticsearchをそこへ載せる選択そのものを見直す必要が出てきます。

### Docker Desktop・WSL2・macOSでの設定の入れ方の分岐

開発機はLinuxホストとは限りません。実行環境ごとに、設定を入れる先が変わります。

| 実行環境             | 設定を入れる先            | 注意点           |
| ---------------- | ------------------ | ------------- |
| Linuxホスト         | ホストのカーネル設定         | 設定ファイルで恒久化する  |
| Windows・WSL2     | docker-desktopのVM内 | WSL再起動で戻る場合あり |
| macOS            | Docker用VMの内側       | VM再作成でやり直し    |
| Docker Desktop全般 | 設定画面のリソース欄         | メモリは4GB以上を割く  |

WindowsでWSL2を使っている場合は、Windows側のシェルから`wsl -d docker-desktop sysctl -w vm.max_map_count=1048576`のように、Dockerが動いているディストリビューションへ直接指定します。macOSでは仮想マシンの内側に入る必要があり、Docker Desktopの版によって手順が変わります。いずれも共通しているのは、VMを作り直すと設定が飛ぶという点です。朝いちばんに起動しなくなったときは、まずこの値を疑ってください。

あわせて、Docker Desktopに割り当てるメモリも確認しておきます。公式のマルチノード手順が案内している最低ラインは4GBです。既定のままだと3ノード構成は起動途中で落ちます。

## docker composeで3ノードクラスタ｜公式定義の読み解きと変更範囲

単一ノードで挙動を確かめたら、次はクラスタです。公式リポジトリには環境変数ファイルとcompose定義の組が置かれており、3つのElasticsearchノードとKibanaが立ち上がります。composeそのものの書き方や`services`・`depends_on`といった構文は[docker-composeの仕組みを解説した記事](https://www.issoh.co.jp/tech/details/13282/)に譲り、ここでは製品固有の部分だけを読み解きます。

まず環境変数ファイルです。公開されている既定値は次のようになっています。パスワードは空で配布されるため、自分で埋めない限り起動しません。

```
ELASTIC_PASSWORD=
KIBANA_PASSWORD=
STACK_VERSION=9.5.2
CLUSTER_NAME=docker-cluster
LICENSE=basic
ES_PORT=9200
KIBANA_PORT=5601
MEM_LIMIT=1073741824
```

パスワードは6文字以上という制約があります。`LICENSE`を`trial`にすると30日の試用が始まり、有償階層の機能まで触れるようになります。`ES_PORT`をループバックアドレス付きで書けば、ホストの外へは公開されません。開発機でクラスタを立てるときは、この書き換えを既定にしておくと事故が減ります。

### setupサービスの役割｜証明書を先に作ってからノードを起動させる

公式定義でいちばん見落とされるのが、`setup`という名前の使い捨てサービスです。これは検索エンジンではなく、証明書を作るためだけに一度だけ動くコンテナになります。`elasticsearch-certutil`で認証局と各ノードの証明書を生成し、共有ボリュームへ置いてから終了します。

依存関係の作り方にも意味があります。`setup`のヘルスチェックは1台目のノードの証明書ファイルが存在するかどうかを見ており、各ノードは`service_healthy`という条件でその完了を待ちます。単に起動順を並べるのではなく、成果物ができたことを条件にしている点が肝です。`setup`はさらに、Elasticsearchが応答を返すまで待ってから`kibana_system`ユーザのパスワードを設定します。証明書生成と初期ユーザ設定という、クラスタの外から一度だけやるべき作業をここへ集めた構造だと読めます。

### ノード定義の要点｜seed\_hostsとinitial\_master\_nodesの関係

各ノードの環境変数のうち、クラスタの形を決めているのは2つです。`cluster.initial_master_nodes`は3ノードすべての名前を並べ、`discovery.seed_hosts`には自分を除いた残りを書きます。

```
- node.name=es01
- cluster.name=${CLUSTER_NAME}
- cluster.initial_master_nodes=es01,es02,es03
- discovery.seed_hosts=es02,es03
- bootstrap.memory_lock=true
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.transport.ssl.enabled=true
```

前者は初回のクラスタ形成でだけ使われる指定で、投票に参加するノードの初期集合を決めます。後者は他のノードを見つけるための連絡先です。ノードを増やすときは、composeのサービスを増やしたうえで両方の値を揃える必要があります。ここが片方だけになっていると、単独でクラスタを名乗るノードが並ぶ、いわゆる分断した状態を作ってしまいます。

なお、ノード名にはcomposeのサービス名がそのまま使われます。同じネットワーク内では名前解決が効くため、証明書のDNS名も`es01`のようなサービス名で発行されています。サービス名を変えるなら証明書の生成定義も直す、という対応関係を覚えておいてください。

### 公式サンプルのversion指定｜Compose V2でそのまま使うと出る警告

配布されているファイルの1行目には、いまも`version`キーが残っています。現行のCompose V2ではこのキーは不要になっており、そのまま実行すると廃止済みという趣旨の警告が出ます。動作自体は続くため放置しても構いませんが、ログを汚したくないなら削除してください。同様に、ドキュメント側はハイフンでつないだ古い呼び出し方で書かれています。CLIプラグインとして入っている環境では、空白で区切る現行の書き方に読み替えます。

公式サンプルは、そのまま動く最小構成であって本番の推奨構成ではありません。証明書の有効期限、ログドライバの指定、再起動ポリシー、リソース予約といった運用側の項目は入っていないため、ステージング以上で使うなら自分で足す前提で読んでください。

## メモリとヒープの決め方｜ES\_JAVA\_OPTSを書く前に確認する2点

日本語の解説記事の多くが`ES_JAVA_OPTS`でヒープを固定するよう案内しています。手元で動かすだけならそれで構いませんが、本番の作法として公式の記述とは一致しません。ここは差が出やすいところなので、順に確認します。

### コンテナのメモリ上限からヒープが自動で決まる仕組みと固定の判断

公式ドキュメントは、ヒープはノードの役割とコンテナに与えられたメモリ総量から自動で決まると説明しています。そのうえで`ES_JAVA_OPTS`については、他のJVMオプションをすべて上書きするため本番での使用は推奨しないと明記しています。つまり順序が逆で、先に決めるのはヒープではなく`mem_limit`や`-m`の方です。

実務としては、コンテナに与えるメモリを決め、ヒープは触らないのが既定の構えになります。どうしても固定したい事情があるなら、公式が案内する方法は、環境変数ではなくJVMオプションのファイルをマウントする形です。ヒープ上限そのものの考え方、たとえば物理メモリの半分までという目安や31GBの壁については[Elasticsearchのクラスタ設計を扱った記事](https://www.issoh.co.jp/tech/details/17011/)で扱っています。コンテナ側で追加になるのは、JVMが見ているのはホストの搭載メモリではなくコンテナの上限である、という一点だけです。

### memory\_lockとmemlockのulimit｜片方だけ入れると起動が落ちる

公式定義には`bootstrap.memory_lock=true`が入っています。ヒープをスワップさせないための指定で、検索の応答時間を安定させる効果があります。ただしこれは単独では成立しません。プロセスがメモリをロックする権限を持っていないと、ブートストラップチェックで失敗します。

```
ulimits:
  memlock:
    soft: -1
    hard: -1
```

composeではこの対で書きます。単体のコンテナ起動なら`--ulimit memlock=-1:-1`です。あわせて、ファイルディスクリプタの上限も公式は`65535`を案内しています。Dockerデーモンの既定値が十分なら省けますが、確認せずに省くと、インデックスが増えてから開けるファイルが尽きるという、遅れて出る障害になります。起動時に一度だけ確認しておく類の設定です。

## データ永続化の設計｜名前付きボリュームとバインドマウントの選択

コンテナを消したらデータも消えた、という事故はここで防ぎます。Elasticsearchのデータはコンテナ内の`data`ディレクトリに置かれ、このパスへボリュームを割り当てるのが公式の方針です。理由はデータ保護だけでなく、入出力性能の面もあります。

### dataディレクトリに何を割り当てるか｜名前付きボリュームが既定

公式定義はノードごとに名前付きボリュームを割り当てています。Dockerが管理する領域に置かれるため権限の問題が起きにくく、composeでコンテナを停止・削除してもボリュームが残る仕組みです。逆に言えば、まっさらな状態から試したいときはボリュームまで消す操作が別に要ります。この違いを知らないと、設定を変えたのに前のインデックスが残っている、という状態で悩みます。

バックアップは、ボリュームをそのままコピーするのではなく、製品側のスナップショット機能で取るのが定石です。稼働中のデータディレクトリをファイルとしてコピーしても、整合の取れた状態になる保証がありません。共有ファイルシステムやオブジェクトストレージをスナップショットの保存先として登録し、そこへ退避する形にします。

### バインドマウント時の権限｜UID 1000で書き込めなくなる典型例

ホスト上のディレクトリを直接見せたい場合はバインドマウントになりますが、ここで権限の壁に当たります。イメージ内のElasticsearchはUID 1000のユーザとして動くため、ホスト側のディレクトリがそのUIDで書き込めない所有権だと、起動直後に権限エラーで終了します。

```
mkdir -p ./esdata
chown -R 1000:0 ./esdata
```

所有者をUID 1000、グループをGID 0に合わせるのが公式の案内です。この作業を忘れると、ログには権限がないという趣旨のメッセージだけが出て、原因がホスト側にあることに気づきにくくなります。バインドマウントは中身を直接覗けるのが利点ですが、権限を自分で面倒みる分だけ手間が増えます。開発機で索引ファイルを直接見たい事情がなければ、名前付きボリュームを選んでおく方が単純です。

コンテナの外側でストレージをどう確保するかという設計は、オーケストレーション基盤へ載せる段階で本格的に効いてきます。その領域の考え方は[永続化ストレージの設計と運用を扱った記事](https://www.issoh.co.jp/tech/details/15294/)にまとめてあります。

## 本番環境でコンテナ運用してよい条件と、見送るべき場面の線引き

ここまでの設定が入れば、コンテナでElasticsearchを動かすこと自体は本番でも成立します。公式も、コンテナでの本番運用を前提にした注意点をすでに明文化済みです。問題は単一ホストのcomposeで足りるかという別の論点で、ここを混同すると判断を誤ります。

### 採用条件｜単一ホストのcompose構成で足りる規模と要件の線引き

次の条件がすべて揃うなら、composeのまま本番へ出して構いません。

- **停止許容時間が数時間ある**：ホストごと落ちたとき、別のホストで立て直すまで待てる業務であること
- **データ量が単一ホストに収まる**：ディスク増設で当面しのげる見込みがあり、ノードを横に足す計画が当面ないこと
- **正本が別にある**：検索用の索引が失われても、データベース側から作り直せる構造になっていること
- **スナップショットが自動で取れている**：復旧手順が書かれていて、実際に復元を試した記録があること

3つ目が特に効きます。検索索引を作り直せる構成にしておけば、コンテナ環境の障害をデータ損失ではなく再構築の時間として扱える設計です。逆に、Elasticsearchにしか存在しないデータを抱えている場合、単一ホスト構成は取ってはいけない選択になります。

### 見送る場面｜可用性が要るならオーケストレーションかマネージド

停止が業務を止める、あるいはデータ量が伸び続けるなら、composeのままでは支えきれません。3ノードをすべて同じホストに載せている構成は、ノード障害には耐えてもホスト障害には耐えないからです。冗長化の見た目だけが手に入り、実際の可用性は上がっていない状態になります。

この段階での選択肢は2つあります。ひとつはKubernetesのようなオーケストレーション基盤へ移し、ノードを物理的に別のホストへ分散させる方向です。もうひとつは、クラウド事業者のマネージドな検索サービスへ預ける方向で、系列の違いによる制約は[Elasticsearchと分岐した系列の違いを整理した記事](https://www.issoh.co.jp/tech/details/17013/)で確認できます。どちらを選ぶかは、運用に人手を割けるかどうかに左右される判断です。専任がいないなら預ける方が総コストは下がります。

なお、この判断は構築のあとに考えるものではありません。検証用のcomposeをそのまま育ててしまうと、移行のタイミングを逃します。検証はDocker、本番は別基盤、という前提を最初から持っておくのが安全です。構成の切り分けや移行の設計に迷う段階でしたら、[クラウドインフラの構築支援](https://www.issoh.co.jp/service/system/aws/)で要件から一緒に整理できます。

## よくある質問

### セキュリティ設定を無効にして起動してもよいですか？

手元の検証に限るなら構いません。ただしその環境をチームで共有したり、そのまま育てて本番にしたりするのは避けてください。無効化した構成では認証なしで全データが読み書きできます。ポートをホストの外へ公開していれば、同じネットワークにいる誰からでも触れる状態です。開発機で使う場合も、公開先をループバックアドレスに絞っておくと事故が減ります。

### 単一ノードのまま本番で使えますか？

使えますが、条件が限られます。レプリカを置けないため、ノードが落ちた瞬間に読み書きが止まる構造です。索引がデータベースから作り直せる構造で、数時間の停止が許されるなら選択肢に入ります。それ以外の場合は、最低3ノードを別々のホストへ分散させる構成を検討してください。同一ホスト上に3ノード並べても、ホスト障害には無力です。

### 日本語検索のプラグインはどう入れますか？

形態素解析のプラグインは、イメージにあらかじめ組み込んでおく形が扱いやすい方法です。公式イメージを親にしたDockerfileを書き、プラグイン導入コマンドを実行したイメージを自前で作ります。起動のたびにコンテナ内で入れる方式は、作り直しのたびに消えるうえ、ノードごとに版がずれる危険があります。プラグインの版はElasticsearch本体の版と一致する必要があるため、タグを固定して管理してください。

### バージョンを上げるときはタグを変えるだけでよいですか？

いいえ、それだけでは足りません。データの形式が版をまたいで変わることがあり、飛び級の更新は許されない場合があります。上げる前にスナップショットを取り、対象の版が直接の更新経路を持つかを確認してください。経路の制約と当日の手順は[Elasticsearchのバージョンアップと移行](https://www.issoh.co.jp/tech/details/17023/)で扱っています。クラスタ構成では、ノードを1台ずつ入れ替える手順を取ります。タグを一斉に書き換えて全体を再起動する操作は、全ノードが同時に止まるため避けます。

### コンテナ1つあたりのメモリはどれくらい必要ですか？

公式の単一ノードの例示は1GBですが、これは動作確認の水準です。実データを入れて検索するなら、少なくとも数GBは見込んでください。目安としては、扱う索引の容量とクエリの同時実行数から逆算します。ヒープはコンテナのメモリ上限から自動で決まるため、調整したいときはコンテナ側の上限を動かすのが先です。Docker Desktopを使う場合は、設定画面での割り当てが上限になる点にも注意してください。

## 関連記事

- [Elasticsearchとは？転置インデックスとシャード設計・ライセンス系列で決める採用可否](https://www.issoh.co.jp/tech/details/17011/)
- [ElasticsearchとOpenSearchの違い｜ライセンス・API互換・機能差から移行先を決める](https://www.issoh.co.jp/tech/details/17013/)
- [docker-composeとは？複数コンテナをymlで定義し一括管理する仕組みを解説](https://www.issoh.co.jp/tech/details/13282/)
- [Kubernetes永続化ストレージ入門｜PV・PVC・StorageClassの設計と運用の落とし穴](https://www.issoh.co.jp/tech/details/15294/)

---

出典: [ElasticsearchのDocker構築｜単一ノードと3ノードのcompose定義・ホスト設定・永続化の実務](<https://www.issoh.co.jp/tech/details/17015/>)（株式会社一創）
