ロゴ

Dockerで簡単にメールサーバーを実装

作成日:2023年6月4日

目次

はじめに

DockerコンテナにpostfixのSMTPサーバーを実装します。
めんどくさいことは端折った超簡単な設定です。
リレー周りで少し詰まったので共有させていただきます。

フォルダ構成

メール送信用のアプリケーションもcomposeで立てることを想定しています。
今回、検証用にnodejsでメールを送信するので、composeでコンテナを立てます。

project/
 ├ app/
  │  ├ node_modules
  │  ├ package.json
  │ └ index.js 
 ├ mail/
  │  ├ config/
  │  | └ main.cf
  │ └ log/
  │    └ mail.log
 ├ docker/
 │ └ postfix/
 │   └ Dockerfile
 │ └ app/
 │   └ Dockerfile
  ├ .env
 └ docker-compose.yml


dockerの設定

今回メールサーバーで使用するイメージは「catatnight/postfix」です。

nodejsアプリケーションからのメール送信はホスト経由での送信になるので、
「networks」でIPを固定してあげます。
今回の設定だとコンテナ目線のホストマシンのIPは「172.21.0.1」で統一されます。
また、commandでコンテナ起動時にメールを送信します。

docker-compose.yml

version: '3.8'
services:
  postfix:
    build:
      context: .
      dockerfile: ./docker/postfix/Dockerfile
    hostname: postfix
    container_name: postfix
    ports:
      - "${SMTP_PORT}:25"
    volumes:
      - maildata:/var/mail
      - mailstate:/var/mail-state
      - ./mail/config/main.cf:/etc/postfix/main.cf
      - ./mail/log/mail.log:/var/log/mail.log
    environment:
      - maildomain=mail.example.com
      - smtp_user=${SMTP_USER}:${SMTP_PASS}
    networks:
      fixed_compose_network:
    restart: always
  node_app: 
    build: 
      context: .
      dockerfile: ./docker/app/Dockerfile
    hostname: app
    depends_on:
      - postfix
    container_name: node_app
    volumes:
      - ./app:/usr/app
      - node_modules:/usr/app/node_modules
    networks:
      fixed_compose_network:
    environment:
      - SMTP_USER=${SMTP_USER}
      - SMTP_PASS=${SMTP_PASS}
      - SMTP_HOST=${SMTP_HOST}
      - SMTP_PORT=${SMTP_PORT}
    command: sh -c 'npm install && node /usr/app/index.js'
volumes:
  node_modules:
  maildata:
  mailstate:
networks:
  fixed_compose_network:
    ipam:
      driver: default
      config:
        - subnet: 172.21.0.0/24

.env

SMTP_USER=user
SMTP_PASS=password
SMTP_HOST=172.21.0.1
SMTP_PORT=1025

app/Dockerfile

FROM node:alpine
WORKDIR /usr/app

postfix/Dockerfile

FROM  catatnight/postfix


メールサーバーの設定

main.cfを編集することでメールサーバーの設定が可能です。
基本的にはデフォルトの設定のままですが、
今回は「172.21.0.1」からのメールのリレーを許可する必要があります。
(私はこのリレーの設定でハマりました。)
リレーを許可するには、mynetworksにIPを追記します。

mynetworks =172.21.0.1


以下が僕の設定したmain.cfです(特にデフォルトから触っていません)。

main.cf


smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no


# appending .domain is the MUA's job.
append_dot_mydomain = no


# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h


readme_directory = no


# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=no
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache


# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.


smtpd_relay_restrictions = permit_mynetworks
myhostname = mail.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = dd40882ba0ea, localhost.localdomain, , localhost
relayhost = 
#↓ここにIPを追記
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128, 172.21.0.0/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination


メール送信用スクリプト

nodejsでのメールの送信は「nodemailer」を使用します。
optionsを指定して送信します。

const nodemailer = require('nodemailer');

// SMTP の設定
const options = {
  host:  process.env.SMTP_HOST, // メールサーバー
  port:  process.env.SMTP_PORT, // ポート番号 
};
// メールメッセージ
const mail = {
  from: {from}, // 送信元メールアドレス
  to: {to}, // 送信先メールアドレス
  subject: 'Testメール',
  text: `送信成功`,
};

// メールの送信
(async () => {
  try {
    const transport = nodemailer.createTransport(options);
    const result = await transport.sendMail(mail);
    console.log('+++ Sent +++');
    console.log(result);
  } catch (err) {
    console.log('--- Error ---');
    console.log(err);
  }
})();


Dockerで実行

コンテナを立ち上げるとメールが送信されます。
また、送信がうまくいかない場合は、mail/log/mail.logを確認してみてください。

docker-compose up -d


関連記事

記事画像

2022年7月1日

Yakan

田舎育ちのアナログ人間ですが、システム作ってます。
趣味の制作はWebアプリ中心です。
仕事は業務系なのでC#メインで書いてます。

Yakan

田舎育ちのアナログ人間ですが、システム作ってます。
趣味の制作はWebアプリ中心です。
仕事は業務系なのでC#メインで書いてます。

© 2022 - 2023 Yakan.