Arm(aarch64)で mailcow-dockernized を動かした。
mailcow とは
rspamd/virtual hosting メール / imaps / smtp / WEBメール / ip-ban の必要なものがワンセットで、docker compose だけで簡単にメール環境を作ることができる。
arm 版
Raspiやオラクルクラウド(A1)でARM64のバイナリを動かせるが、mailcow のdocker 版はx86を前提としているので、自分でビルドして、いくつかの設定を見直す必要がある。
Raspi-ubuntuやオラクルクラウド(A1)でメールサーバーを作って置こうと思い立って稼働させたのでメモ。色々苦労した
docker は qemu に対応しているので、docker だけでもx86バイナリを動かすことができるが、phpがとにかく遅い。メール配送はバックグラウンドになるで気にならないが、WEB-UIはx86バイナリを動かすとモタつきがきになる。そこでphp/sogo/dovecot をarm64で動かすのが良いと思う。Solr と clamv はメモリ食うのでオフにしてもいいと思うんですけどね。
arm で docker を起動したらエラーになる例。
そのまま起動すると exec format エラーになる。
docker の準備
そこで、aarch64(arm 64)バイナリ版をビルドしてみた。
### Docker の準備 sudo curl -sSL https://get.docker.com/ | CHANNEL=stable sh sudo systemctl enable --now docker sudo apt update sudo apt install docker-compose-plugin sudo usermod -aG docker $USER ## iptables でポートを開放する sudo iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT sudo iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT sudo iptables-save | sudo tee /etc/iptables/rules.v4 ### ソースコードの準備 git clone https://github.com/mailcow/mailcow-dockerized cd mailcow-dockerized ### docker イメージの取得 docker compose pull
ipv6関連を切っていく。
v6関連があるとデバッグが煩雑になるので切っておく。
## mailcow の設定で、v6を切っていく ## 参考資料:https://docs.mailcow.email/post_installation/firststeps-disable_ipv6/ ### docker v6 networkで切る sed -i 's|enable_ipv6: true|enable_ipv6: false|' docker-compose.yml ## ipv6natを切る。 touch docker-compose.override.yml cat <<EOF | sudo tee docker-compose.override.yml version: '2.1' services: ipv6nat-mailcow: image: bash:latest restart: "no" entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"] EOF ### unboundにv6応答をやめさせる sed -i 's|do-ip6: yes|do-ip6: no|' data/conf/unbound/unbound.conf sed -i '/do-ip6/s/$/\n prefer-ip6: no/g' data/conf/unbound/unbound.conf sed -i '/ipsecmod-enabled/s/$/\n local-zone: ip6.arpa. refuse/g' data/conf/unbound/unbound.conf ### postfix にv6利用をやめさせる cat <<EOF | sudo tee -a data/conf/postfix/extra.cf smtp_address_preference = ipv4 inet_protocols = ipv4 EOF ### nginx /devecot / php-fpm にv6リッスンをやめさせる sed -i '\|\[::\]:8081;|d' data/conf/nginx/dynmaps.conf sed -i '\|::|d' data/conf/nginx/templates/listen* sed -i 's/,\[::\]//g' data/conf/dovecot/dovecot.conf sed -i 's/\[::\]://g' data/conf/phpfpm/php-fpm.d/pools.conf
ホスト側でも念のためにv6を切っておいた
docker ホスト側(Oracleインスタンス=docker ホスト) でもv6はオフにしておいた。
cat <<EOF | sudo tee -a /etc/sysctl.conf net.ipv6.conf.default.disable_ipv6=1 net.ipv6.conf.lo.disable_ipv6=1 net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.eth0.disable_ipv6=1 EOF cat <<EOF | sudo tee /etc/rc.local #!/bin/bash # /etc/rc.local /etc/sysctl.d /etc/init.d/procps restart exit 0 EOF sudo chmod 755 /etc/rc.local sudo /etc/rc.local
arm(aarch64)用にビルドする。
Arm用バイナリがapt/apk提供されているものは、docker buildだけでいける。
apt で済むもの
apk/apt が提供されているものは、docker build を実行すれば良い。
## ビルド ## sogo と dovecot と rspamd は公式レポジトリを使っている。ためビルドできない #### debianパッケージを使えば動くと思うが未検証 ## aarch64用にビルドする # sed -i '\|rspamd.com/apt-stable|d' data/Dockerfiles/rspamd/Dockerfile list=(" acme clamd dockerapi netfilter olefy phpfpm postfix solr unbound watchdog ") ## aarch64用にビルドし直す 5分くらい for service in $list; do echo $service docker build data/Dockerfiles/$service -t mailcow/$service:aarch64_build done ## aarch64用にビルドしたものを使う用に書き換え for service in $list; do echo $service grep "mailcow/$service" docker-compose.yml sed -i -E "s|mailcow/$service:[0-9.]+|mailcow/$service:aarch64_build|" docker-compose.yml grep "mailcow/$service" docker-compose.yml done
sogo/dovecot/rspamd
sogo/dovecot/rspamd は debian/ubuntu の配布パッケージを使っていない。sogoは sogo.nu のnightly を使っているが、sogo.nuがarmバイナリを未提供
パッケージ | mailcow指定 | Arm版 |
---|---|---|
sogo | packages.sogo.nu | ??? |
dovecot | repo.dovecot.org | なし |
rspamd | rspamd.com/apt-stable | なし |
それぞれ、Debian公式なら存在するので大体は出来る |パッケージ| Debian公式 | aarch64バイナリ | 特記事項 | |:---:|---:|:---:|:---| |sogo | debian/sid | あり | sogo-activesync/aarch64はsid のみ| |dovecot| debian/stable | あり |dovecot-lua がない| |rspamd | debian/stable |あり|sa-rulesが動かない。|
これらについては、インストール後に予期せぬ出来事に遭遇するかもしれないが、場当たり的な対応で動いた。
sogo は id:sogo の home ディレクトリが異なるので対応が必要。
dovecot は dovecot-lua が無いが、mailcowがluaを未使用なので問題なさそう。
rspamd は、sa-rule がエラーになって起動しなくなるので、消せば動くが、アチコチで segmentation fault がでて面倒くさいのでarmは諦めて、qemu 経由でx86を動かすことにした。
aarch64で動かないものは、qemu経由で動かす準備する。
aarch64でビルドできない、または、動かすのを諦めるときは、qemu 経由して動かせば良い。ユーザー空間でqemu を動かせるbinfmt-support
などを入れて上げるとx86バイナリでもArm64で強引に動かせる。
sudo apt-get install qemu binfmt-support qemu-user-static
これでqemu経由で起動する。
たとえば、次のように、プロセスを見るとqemu-binfmt 経由で起動してるのがわかる。
docker compose exec rspamd-mailcow ps s
root@rspamd:/# ps xf PID TTY STAT TIME COMMAND 728 pts/0 Ssl 0:00 /usr/libexec/qemu-binfmt/x86_64-binfmt-P /bin/bash bash 782 ? Rl+ 0:00 \_ ps xf 1 ? Ssl 0:00 /usr/libexec/qemu-binfmt/x86_64-binfmt-P /bin/bash /bin/bash /docker-entrypoint.sh /usr/bin/rspamd -f -u _rspamd -g _rspamd 779 ? Sl 0:00 /usr/libexec/qemu-binfmt/x86_64-binfmt-P /bin/sleep sleep 3
既存のボリュームを削除する
もし、起動するバイナリを変えたり、ビルドし直したたら、ボリュームも削除しておく。データ自体はホスト側に書かれるので問題がなさそう。ただしmysql のボリュームにメールデータが保存されるので、mysql を消すと完全に初期化される。
docker compose down --volumes
初期設定する
./generate_config.sh
が初期設定コマンドで、DBパスワードやPostfixのオレオレ証明書などを作ってくれる。
./generate_config.sh Found Docker Compose Plugin (native). Setting the DOCKER_COMPOSE_VERSION Variable to native Notice: You´ll have to update this Compose Version via your Package Manager manually! Press enter to confirm the detected value '[value]' where applicable or enter a custom value. Mail server hostname (FQDN) - this is not your mail domain, but your mail servers hostname:
起動
mailcow を起動する。
初回起動は、順番に初期化しながらで5分くらいかかる。rspamd が無事に起動したら終了。
docker compose up -d docker compose logs -f
失敗したりやり直したときは、docker compose down --volumes
でやり直す
起動状況のチェック
docker compose logs watchdog-mailcow -f
Rspamd,Postfix,Sogo,Dovecot
が起動してたら最低限は動くはず。
rspamd の起動チェック
docker compose logs -f rspamd-mailcow
次がでてたら、無事に起動しているはず。
skip writing pid in no-fork mode
私は、aarch64版のrspamdを使おうとしたとき、起動後に不安定(segmentation fault)だったので、色々苦労した。rspamd が動かない場合→ qemu で動かした。
aarch64版をビルドして使うとき
sed -i '\|rspamd.com/apt-stable|d' data/Dockerfiles/rspamd/Dockerfile docker build data/Dockerfiles/rspamd -t mailcow/rspamd:aarch64_build
起動時にのエラーに苦しんだので、このあたりを参考にすると動いた。
https://github.com/mailcow/mailcow-dockerized/issues/3106
#45(main) <sfcohf>; lua; spamassassin.lua:1714: loading SA rules from /etc/rspamd/custom/sa-rules Segmentation fault (core dumped)
動くには動くが気づかない間に再起動を繰り返すなど動作が不安定だったので、x86で良いかとなった。
ログインする
初期パスワードは admin/moohoo
で固定です。
メール受信テスト
DNSを設定する。
mail.example.com mx 25 vps.example.com vps.example.com a 192.168.100.5
ローカル実験の例 data/conf/unbound/unbound.conf
ローカルで実験する場合、DNS(名前解決)を上書きしなくちゃいけない。ローカル配送と外部Submissionを使ってメールを送信する。受信25ポートについては任意にやっておく。
ただしunbound-mailcow
が root-hint
(ルートネームサーバー)から名前解決をするので、上書き設定や通信設定を data/conf/unbound/unbound.conf
に記入する
local-data: 'mail.example.com mx 10 vps.example.com'
または、unboundに外部DNSを参照させる。 我が家では、DNS問い合わせは特定デバイスのみ許可している。なのでmailcow が直接root.hint から名前解決が出来ない。そこで名前解決サーバーを指定した。
data/conf/unbound/unbound.conf
forward-zone: name: "." forward-addr: 192.168.100.2
設定したら再起動しておく。
docker compose rm unbound-mailcow --volumes docker compose up -d unbound-mailcow
Virtual Domain の設定
設定は、次の場所にある。
mailcow -> right top -> configuration -> mailsetup
ドメインを追加して
ユーザを追加する。
追加したユーザ宛にメールを送る。
curl コマンドでサクッとメールを送る。
TO=test-user@example.com SMTP_SERVER=xxxx.sakura.ne.jp:587 USER=postmaster@xxxxx.sakura.ne.jp PASS=xxxxx echo "To: $TO From: $USER Subject: this is a test from 587/starttls this is a test using smtps " | curl -v \ --url "smtp://$SMTP_SERVER" \ --user "$USER:$PASS" \ --ssl -k \ --mail-rcpt $TO \ -T -
受信の確認
Sogo でサクッと見る。
Sogoは再起動しないと、ユーザ作成が反映されないので注意。
IMAPやPOPでアクセスしてもいいけどね・・・
送信の確認
送信の確認は、OP25Bがあって面倒くさいので、割愛。
ローカル配送の場合
mailcow のPostfix設定では、a_user@example.com
から b_user@example.com
へ配送する場合、毎回 mx を参照してしまう。
これは、mailcow のpostfix設定がローカル配送をする際に、いったんMXを経由する用に設定されているためで、ローカルはなく、すべて name virtual でやってるから。
これはNAT環境やクラウド環境(ElasticIP)などがあるときに、ループバック設定が、とてもめんどくさい。
ローカル配送をやらせる。
同一ドメイン内配送(ローカル配送)をする場合、mailcow で設定しても良いんだけど。 data/conf/unbound/unbound.confで postfix を指定してあげると楽だった。
local-data: 'mail.example.com mx 10 postfix'
レポジトリ
mailcow のarm64 のパッチとビルドをできるように、github にメモを残しておいた
https://github.com/takuya/mailcow-dockerized-aarch64
まとめ
mailcow は arm64 でも qemu 経由で動かせる。ただ、ある程度は aarch64でビルドした方が速くて快適。