UbuntuのDockerコンテナにPostfixをインストールする
課題
UbuntuベースのDockerコンテナにPostfixをインストールしたい。
PostfixからSMTPリレーでメールを送信したい。
解決策
コードを見たほうが早いと思うので、以下にコードとその説明を書きます。
ここに書いたコードと全く同じ実装例を、githubの私のリポジトリにあげておいたので、その方が見やすいという方は使って下さい。
また、SMTPリレーのメール送信のテストにはMailtrapを使いました。
ディレクトリ構成
┏docker-compose.yml
┣Dockerfile
┣entrypoint.sh
┗/configs
┣ main.cf
┗ sasl_passwd
docker-compose.yml
version: '3.8'
services:
docker-ubuntu-postfix-example:
build:
context: ./
dockerfile: Dockerfile
image: docker-ubuntu-postfix-example-image:latest
container_name: docker-ubuntu-postfix-example-container
volumes:
# Postfixの設定をマウントする
- type: bind
source: ./configs/main.cf
target: /etc/postfix/main.cf
# SASL認証のパスワードをマウントする
- type: bind
source: ./configs/sasl_passwd
target: /etc/postfix/sasl_passwd
Dockerfile
FROM ubuntu:20.04
# postfixをインストールする為に、パッケージを更新
RUN apt update && apt upgrade -y
# postfixをインストール
RUN DEBIAN_FRONTEND=noninteractive apt install postfix -y
# SMTPリレーにはSMTP AUTHが必要。
# SMTP AUTHの為のSASLにはCyrus SaslとCyrus IMAPを使う。
RUN apt install sasl2-bin -y
RUN DEBIAN_FRONTEND=noninteractive apt install cyrus-imapd -y
# コンテナ起動時のスクリプト
COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
DEBIAN_FRONTEND=noninteractiveについて
DEBIAN_FRONTEND=noninteractive
を指定することによって、対話型のインストールをスキップしています。これによりスクリプトとしてインストール出来ます。
ENV DEBIAN_FRONTEND=noninteractive
を指定せずに2箇所に独立して書いてあるのは、影響範囲を明示的にしたいからです。
Cyrus SaslとCyrus IMAPとは
SMTPリレーホストを使う場合、SMTP-AUTHが求められることが多いかと思います。
SMTP自体は認証機構を持たないプロトコルなので、SMTP-AUTHを用いなければ、迷惑メールの踏み台などにされてしまうからです。
SMTP-AUTHの認証方式としてSASL(Simple Authentication and Security Layer)があります。
SASLの方式でライブラリの一つとしてCyrus Saslがあります。
今回はCyrus SaslでSMTP-AUTHをしたいので、sasl2-bin
とcyrus-imapd
をインストールしています。
細かいことに関しては公式サイトや日本語サイトも是非ご覧ください。
entrypoint.sh
#!/bin/bash
# postfixの起動
postfix start
# Postfixは/var/spool/postfixにchrootするので、
# 名前解決に際して、/etc/resolv.confではなく/var/spool/postfix/etc/resolv.confを見に行く。
# 従って、/etc/resolv.confをコピーする。
cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
# SASL認証用のテーブル作成
chown root:root /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
# postfixの設定変更を反映させる
postfix reload
# コンテナの起動を維持するため
tail -f /dev/null
名前問題の解決
cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
を行わないと名前解決に失敗します。Postfixがchroot
するからです。
このサイトを参考にしました。
main.cf
利用するSMTPリレーホストに応じて設定して下さい。
Mailtrapに関しては、ログイン後のページにPostfixの設定例があります。設定例をそのままコピペすれば動くと思います。
# ログの出力設定
maillog_file = /var/log/mail.log
# SMTPリレーの設定
relayhost =
smtp_sasl_auth_enable =
smtp_sasl_mechanism_filter =
smtp_sasl_security_options =
smtp_sasl_password_maps =
sasl_passwd
利用するSMTPリレーホストに応じて認証情報を設定して下さい。
Mailtrapに関しては、ログイン後のページにPostfixの設定例があります。設定例をそのままコピペすれば動くと思います。
動かしてみる
コンテナにログインして、以下のようなコマンドを入れてみれば動作確認できるかと思います。
$ sendmail your-email@example.com
From:your-email@example.com
To:your-email@example.com
Subject:Hello World
Hello World
.
最後に
下記の二点に焦点をあてて記事を書きました。
- Debian系のDockerコンテナにPostfixをインストールする。
- SMTPリレーでメールを送信する。
そこに焦点をあてたので、それ以外の多くの部分を省いています。 1,2の目的を達成する最低限のコードしか書いていません。 必要に応じてmain.cfにコードを足してみて下さい。
Discussion