✉️

UbuntuのDockerコンテナにPostfixをインストールする

2021/12/23に公開

課題

UbuntuベースのDockerコンテナにPostfixをインストールしたい。
PostfixからSMTPリレーでメールを送信したい。

解決策

コードを見たほうが早いと思うので、以下にコードとその説明を書きます。

ここに書いたコードと全く同じ実装例を、githubの私のリポジトリにあげておいたので、その方が見やすいという方は使って下さい。

また、SMTPリレーのメール送信のテストにはMailtrapを使いました。

ディレクトリ構成

┏docker-compose.yml
┣Dockerfile
┣entrypoint.sh
┗/configs
  ┣ main.cf
  ┗ sasl_passwd

docker-compose.yml

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

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-bincyrus-imapdインストールしています。

細かいことに関しては公式サイト日本語サイトも是非ご覧ください。

entrypoint.sh

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の設定例があります。設定例をそのままコピペすれば動くと思います。

main.cf
# ログの出力設定
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の設定例があります。設定例をそのままコピペすれば動くと思います。

sasl_passwd

動かしてみる

コンテナにログインして、以下のようなコマンドを入れてみれば動作確認できるかと思います。

$ sendmail your-email@example.com
From:your-email@example.com
To:your-email@example.com
Subject:Hello World

Hello World

.

最後に

下記の二点に焦点をあてて記事を書きました。

  1. Debian系のDockerコンテナにPostfixをインストールする。
  2. SMTPリレーでメールを送信する。

そこに焦点をあてたので、それ以外の多くの部分を省いています。 1,2の目的を達成する最低限のコードしか書いていません。 必要に応じてmain.cfにコードを足してみて下さい。

Discussion