Growi+PostfixをDockerで構築
背景
久々にWikiを構築する機会があったので、お気に入りのGrowiを使用して構築することにした。
手軽に使用できるSMTPサーバがないため、メールサーバ込みで構築する必要がある。
運用面を考えて全てコンテナで構築したいが、公式のdocker-composeではメールサーバまでカバーしていない。
また、最小限の認証機能付きDocker imageも見つからない。
上記の理由から自分で構築したが、意外と試行錯誤したため共有。
構築手順
growi-docker-composeのダウンロード
公式のGithubから、docker-composeをダウンロード。
$ git clone https://github.com/weseek/growi-docker-compose.git growi
Postfixの構築
$ cd growi $ mkdir postfix $ mkdir postfix/conf
postfix/Dockerfileの作成。Alpine Linuxで作成する。
FROM alpine:latest RUN apk add --update --no-cache postfix cyrus-sasl bash ADD conf/main.cf /etc/postfix/main.cf ADD conf/smtpd.conf /usr/lib/sasl2/smtpd.conf ADD entrypoint.sh /entrypoint.sh CMD /entrypoint.sh
postfix/conf/main.cfの作成。
mynetworks = 127.0.0.0/8
maillog_file = /dev/stdout
myhostname = # This will be overwritten in entrypoint.sh
smtp_relay_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
postfix/conf/smtpd.confの作成。今回は、sasldbプラグインを利用し、ファイルでパスワードを作成する。(参考サイト)
mech_listの行は、多分PLAIN LOGINだけで大丈夫。
pwcheck_method: auxprop auxprop_plugin: sasldb mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM
postfix/entrypointの作成。
#!/bin/bash # SASL Settings if [ ! -f /etc/sasl2/sasldb2 ]; then mkdir /etc/sasl2 echo $smtp_pw | saslpasswd2 -p -c -f /etc/sasl2/sasldb2 -u $ mail_domain $smtp_user chown postfix:postfix /etc/sasl2/sasldb2 fi # Execute newaliases postconf -e myhostname=$mail_domain newaliases # Start postfix postfix start-fg
docker-compose.ymlの編集
以下の通り編集。
version: '3' services: app: build: context: . dockerfile: ./Dockerfile ports: - 3000:3000 # localhost only by default links: - mongo:mongo - elasticsearch:elasticsearch depends_on: - mongo - elasticsearch environment: - MONGO_URI=mongodb://mongo:27017/growi - ELASTICSEARCH_URI=http://elasticsearch:9200/growi - PASSWORD_SEED=changeme - FILE_UPLOAD=mongodb # activate this line if you use MongoDB GridFS rather than AWS - MATHJAX=1 # activate this line if you want to use MathJax entrypoint: "dockerize -wait tcp://mongo:27017 -wait tcp://elasticsearch:9200 -timeout 60s /docker-entrypoint.sh" command: ["yarn migrate && node -r dotenv-flow/config --expose_gc dist/server/app.js"] restart: unless-stopped volumes: - growi_data:/data mongo: image: mongo:4.4 restart: unless-stopped volumes: - mongo_configdb:/data/configdb - mongo_db:/data/db elasticsearch: build: context: ./elasticsearch dockerfile: ./Dockerfile environment: - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms256m -Xmx256m" # increase amount if you have enough memory - LOG4J_FORMAT_MSG_NO_LOOKUPS=true # CVE-2021-44228 mitigation for Elasticsearch <= 6.8.20/7.16.0 ulimits: memlock: soft: -1 hard: -1 restart: unless-stopped volumes: - es_data:/usr/share/elasticsearch/data - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml postfix: build: context: ./postfix dockerfile: ./Dockerfile environment: - mail_domain=server.example.com - smtp_user=test - smtp_pw=testpass ports: - 127.0.0.1:25:25 restart: unless-stopped volumes: growi_data: mongo_configdb: mongo_db: es_data:
構築・テスト
コンテナ構築
$ docker-compose build
$ docker-compose up -d
ブラウザからアクセス。http://localhost:3000
管理者アカウント作成。
設定 > アプリ設定 > メール設定から、以下を設定する。
- Fromアドレス: 任意(ドメインは、$mail_domainのサーバ名を抜いたものにする。)
- 送信方法: SMTP
- ホスト: postfix
- ポート: 25
- ユーザ: test
- パスワード: testpw
SASLのデバッグ方法
Growiのメールテストがうまく動かない場合は、以下のようにデバッグする。
@Postfixコンテナ
docker-compose logs -f postfix
でpostfixのログを監視。
@Growiコンテナ
apt update && apt install telnet
でtelnetをインストール。
telnet postfix 25
でpostfixコンテナに接続。
以下のような感じで、認証が通るか確認。
220 server.example.com ESMTP Postfix EHLO client.example.com # 入力する 250-server.example.com 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-AUTH DIGEST-MD5 PLAIN CRAM-MD5 250 8BITMIME AUTH PLAIN dGVzdAB0ZXN0AHRlc3RwYXNz # 入力する。 235 Authentication successful
AUTH PLAINの後の文字は、"{認証ユーザ名}¥0{認証ユーザ名}¥0{認証パスワード}"をbase64エンコードした文字。
¥0はNULL文字。
test/testpassの場合は、dGVzdAB0ZXN0AHRlc3RwYXNzとなる。
認証が通らない場合には、postfixコンテナ側のlogを見ながらググる。