Graylog on Windows Docker構築Tips

Graylogを私有端末のWindows Docker上に構築した際のTipsメモです。
Windows端末でGraylogをサクッと試したい場合、Dockerは非常に役立ちます。
Graylogはv5以降、検索エンジンはElasticSerch、OpenSerchのどちらかを選べるようになっているので、その両パターン「docker-compose.yml」を使った構築Tipsを整理しました。
ちなみに[Graylog公式ページ](https://go2docs.graylog.org/5-0/downloading_and_installing_graylog/docker_installation.htm)記載の「docker-compose.yml」は構文に誤りがあり注意が必要。※2023/5/7執筆時点
※本記事は[こちら](https://github.com/Graylog2/docker-compose/blob/main/open-core/docker-compose.yml)を参考にしました。
※GraylogのチューニングTipsは[こちらの記事](https://qiita.com/khat/items/3ce34c169f03cc29e9f4)も参考にしてください。

# 前提条件
## 私有端末OS / Dockerバージョン
・Windows 11 Pro
・Docker : 23.0.5, build bc4487a
・Visual Studio Code : 1.77.3 ※「docker-compose.yml」編集＆保存で使用

## Graylog / Mongo DB / ElasticSerch / OpenSerch各バージョン
・Graylog : 5.0.6
・Mongo DB : 5.0.17
・ElasticSerch : 7.10.2
・OpenSerch : 2.4.0

# docker-compose.yml
①適当なディレクトリ「例：C:\docker_work\」に「docker-compose.yml」ファイルを作成。
②Visual Studio Codeで「docker-compose.yml」を開いて以下記載構文をコピペ。主な環境変数は以下の通り。
```
・GraylogログインURL：http://localhost:9000/
・GraylogログインID/PW：admin/admin
・Syslog受信ポート：Windows端末はudp/tcp514で受信してGraylogにudp/tcp1514で転送
・opensearch/ElasticSerchの使用メモリ：1GB
```
③「docker-compose.yml」格納ディレクトリ上で以下コマンド実行
```
>docker compose up
```
▼Docker実行後のステータス画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171475/dbf59b1f-a5a4-e348-29ee-8a522283bc9b.png)
▼Graylog画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171475/601d7de9-86c9-3696-dd54-9b14bfa0a706.png)


## docker-compose.yml構文：OpenSerch使用時
```yaml
version: '3'

services:
  mongodb:
    image: "mongo:5.0"
    volumes:
      - "mongodb_data:/data/db"
    restart: "on-failure"

  opensearch:
    image: "opensearchproject/opensearch:2.4.0"
    environment:
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "bootstrap.memory_lock=true"
      - "discovery.type=single-node"
      - "action.auto_create_index=false"
      - "plugins.security.ssl.http.enabled=false"
      - "plugins.security.disabled=true"
    ulimits:
      memlock:
        hard: -1
        soft: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "xsearch_data:/usr/share/opensearch/data"
    restart: "on-failure"

  graylog:
    image: "${GRAYLOG_IMAGE:-graylog/graylog:5.0}"
    depends_on:
      opensearch:
        condition: "service_started"
      mongodb:
        condition: "service_started"
    entrypoint: "/usr/bin/tini -- wait-for-it opensearch:9200 --  /docker-entrypoint.sh"
    environment:
      GRAYLOG_NODE_ID_FILE: "/usr/share/graylog/data/config/node-id"
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
      GRAYLOG_HTTP_EXTERNAL_URI: "http://localhost:9000/"
      GRAYLOG_ELASTICSEARCH_HOSTS: "http://opensearch:9200"
      GRAYLOG_MONGODB_URI: "mongodb://mongodb:27017/graylog"
    ports:
    - "514:1514/udp"     # Syslog
    - "514:1514/tcp"     # Syslog
    - "5044:5044/tcp"   # Beats
    - "5555:5555/tcp"   # RAW TCP
    - "5555:5555/udp"   # RAW TCP
    - "9000:9000/tcp"   # Server API
    - "12201:12201/tcp" # GELF TCP
    - "12201:12201/udp" # GELF UDP
    #- "10000:10000/tcp" # Custom TCP port
    #- "10000:10000/udp" # Custom UDP port
    - "13301:13301/tcp" # Forwarder data
    - "13302:13302/tcp" # Forwarder config
    volumes:
      - "graylog_data:/usr/share/graylog/data/data"
      - "graylog_journal:/usr/share/graylog/data/journal"
    restart: "on-failure"

volumes:
  mongodb_data:
  xsearch_data:
  graylog_data:
  graylog_journal:
```

## docker-compose.yml構文：ElasticSerch使用時
```yaml
version: '3'

services:
  mongodb:
    image: "mongo:5.0"
    volumes:
      - "mongodb_data:/data/db"
    restart: "on-failure"

  elasticsearch:
    image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
    environment:
      - "http.host=0.0.0.0"
      - "transport.host=localhost"
      - "network.host=0.0.0.0"
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        hard: -1
        soft: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "xsearch_data:/usr/share/elasticsearch/data"
    restart: "on-failure"

  graylog:
    image: "${GRAYLOG_IMAGE:-graylog/graylog:5.0}"
    depends_on:
      elasticsearch:
        condition: "service_started"
      mongodb:
        condition: "service_started"
    entrypoint: /usr/bin/tini -- wait-for-it elasticsearch:9200 --  /docker-entrypoint.sh
    environment:
      GRAYLOG_NODE_ID_FILE: "/usr/share/graylog/data/config/node-id"
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
      GRAYLOG_HTTP_EXTERNAL_URI: "http://localhost:9000/"
      GRAYLOG_ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
      GRAYLOG_MONGODB_URI: "mongodb://mongodb:27017/graylog"
    ports:
    - "514:1514/udp"     # Syslog
    - "514:1514/tcp"     # Syslog
    - "5044:5044/tcp"   # Beats
    - "5555:5555/tcp"   # RAW TCP
    - "5555:5555/udp"   # RAW TCP
    - "9000:9000/tcp"   # Server API
    - "12201:12201/tcp" # GELF TCP
    - "12201:12201/udp" # GELF UDP
    #- "10000:10000/tcp" # Custom TCP port
    #- "10000:10000/udp" # Custom UDP port
    - "13301:13301/tcp" # Forwarder data
    - "13302:13302/tcp" # Forwarder config
    volumes:
      - "graylog_data:/usr/share/graylog/data/data"
      - "graylog_journal:/usr/share/graylog/data/journal"
    restart: "on-failure"

volumes:
  mongodb_data:
  xsearch_data:
  graylog_data:
  graylog_journal:
```

## docker-compose.yml構文：Elasticsearch使用時の解説
※ChatGPTによる解析転載（私のdocker-compose.yml知識が乏しい為、ChatGPTの助けを借りました）

MongoDBサービスを定義しています。
```yaml
  mongodb:
    image: "mongo:5.0"
    volumes:
      - "mongodb_data:/data/db"
    restart: "on-failure"
```
- MongoDBのバージョン5.0の公式Dockerイメージを使用します。
- mongodb_dataボリュームに/data/dbディレクトリをマウントします。
- restart: "on-failure"を設定することで、コンテナがエラーで停止した場合に自動的に再起動するようになります。

ElasticsSearchサービスを定義しています。
```yaml
elasticsearch:
    image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
    environment:
      - "http.host=0.0.0.0"
      - "transport.host=localhost"
      - "network.host=0.0.0.0"
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        hard: -1
        soft: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "xsearch_data:/usr/share/elasticsearch/data"
    restart: "on-failure"
```
- elasticsearch.10.2の公式Dockerイメージを使用します。
- xsearch_dataボリュームに/usr/share/elasticsearch/dataディレクトリをマウントします。
- environmentを設定して、Java仮想マシンのメモリ設定を変更します。
- ulimitsを設定し、メモリーロックとファイルディスクリプタの数を制限しています。
- restart: "on-failure"を設定することで、コンテナがエラーで停止した場合に自動的に再起動するようになります。

Graylogサービスを定義しています。
```yaml
  graylog:
    image: "${GRAYLOG_IMAGE:-graylog/graylog:5.0}"
    depends_on:
      elasticsearch:
        condition: "service_started"
      mongodb:
        condition: "service_started"
    entrypoint: /usr/bin/tini -- wait-for-it elasticsearch:9200 --  /docker-entrypoint.sh
    environment:
      GRAYLOG_NODE_ID_FILE: "/usr/share/graylog/data/config/node-id"
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
      GRAYLOG_HTTP_EXTERNAL_URI: "http://localhost:9000/"
      GRAYLOG_ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
      GRAYLOG_MONGODB_URI: "mongodb://mongodb:27017/graylog"
    ports:
    - "514:1514/udp"     # Syslog
    - "514:1514/tcp"     # Syslog
    - "5044:5044/tcp"   # Beats
    - "5555:5555/tcp"   # RAW TCP
    - "5555:5555/udp"   # RAW TCP
    - "9000:9000/tcp"   # Server API
    - "12201:12201/tcp" # GELF TCP
    - "12201:12201/udp" # GELF UDP
    #- "10000:10000/tcp" # Custom TCP port
    #- "10000:10000/udp" # Custom UDP port
    - "13301:13301/tcp" # Forwarder data
    - "13302:13302/tcp" # Forwarder config
    volumes:
      - "graylog_data:/usr/share/graylog/data/data"
      - "graylog_journal:/usr/share/graylog/data/journal"
    restart: "on-failure"
```
- Graylogのバージョン5.0の公式Dockerイメージを使用します。
- /usr/share/graylog/data/dataディレクトリにgraylog_dataボリュームをマウントします。
- /usr/share/graylog/data/journalディレクトリにgraylog_journalボリュームをマウントします。
- depends_onを設定し、OpenSearchとMongoDBが起動した後にGraylogを開始するようにします。
- entrypointを設定して、コンテナが開始されるときにtiniを実行し、elasticsearchが起動するのを待ちます。
- environmentを設定して、Graylogの設定を変更します。
 ・GRAYLOG_HTTP_BIND_ADDRESS: Graylog HTTPサーバがバインドするIPアドレスとポート番号を指定します。
 ・GRAYLOG_HTTP_EXTERNAL_URI: Graylogが外部からアクセスされるURLを指定します。
 ・GRAYLOG_ELASTICSEARCH_HOSTS: Graylogが使用するElasticsearchのホスト名とポート番号を指定します。
 ・GRAYLOG_MONGODB_URI: Graylogが使用するMongoDBのURIを指定します
- portsを設定して、Graylog WebインターフェイスやSyslog、Beats、RAW TCPなどのポートをホストマシンにバインドします。例えば、514番ポートを使用するSyslog、5044番ポートを使用するBeats、9000番ポートを使用するServer APIなどが設定されています。コメントアウトされているカスタムポートの設定もあるため、必要に応じてコメントを外してポートを追加できます。
- restart: "on-failure"を設定することで、コンテナがエラーで停止した場合に自動的に再起動するようになります。

最後に、データを永続化するために、それぞれのサービス用に以下のボリュームが定義されています。
```yaml
volumes:
  mongodb_data:
  xsearch_data:
  graylog_data:
  graylog_journal:
```
- それぞれのサービスは、上記ボリュームを使用して永続化されたデータを格納します。mongodb_dataボリュームは mongodbサービスによって使用され、xsearch_dataボリュームは opensearch サービスによって使用されます。graylog_dataおよびgraylog_journalボリュームはgraylog サービスによって使用されます。