作成日: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
今回メールサーバーで使用するイメージは「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);
}
})();
コンテナを立ち上げるとメールが送信されます。
また、送信がうまくいかない場合は、mail/log/mail.logを確認してみてください。
docker-compose up -d