我正在尝试设置一个 docker-mailserver 实例以使用
nodemailer
模块从我的本地开发设置中发送电子邮件。这是我的 docker-compose.yml 文件的样子:
version: '3.1'
services:
postgres:
container_name: postgres
image: postgres
restart: always
volumes:
- $PWD/.dbData:/data/db
networks:
- skynet
environment:
POSTGRES_PASSWORD: <PASSWORD>
POSTGRES_USER: <USER>
POSTGRES_DB: <DB>
mailserver:
image: docker.io/mailserver/docker-mailserver:latest
env_file: $PWD/mailserver.env
hostname: mailserver
domainname: example.com
container_name: mailserver
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
volumes:
- $PWD/.mailData/maildata:/var/mail
- $PWD/.mailData/mailstate:/var/mail-state
- $PWD/.mailData/maillogs:/var/log/mail
- /etc/localtime:/etc/localtime:ro
- ./config/:/tmp/docker-mailserver/
environment:
- ENABLE_SPAMASSASSIN=1
- SPAMASSASSIN_SPAM_TO_INBOX=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ENABLE_SASLAUTHD=0
- ONE_DIR=1
- DMS_DEBUG=0
cap_add:
- NET_ADMIN
- SYS_PTRACE
restart: always
networks:
- skynet
adminer:
image: adminer
hostname: adminer
ports:
- '8080:8080'
depends_on:
- postgres
networks:
- skynet
app:
# ... app details
networks:
skynet:
根据 docs,我复制了示例
mailserver.env
文件和 setup.sh
管理脚本。当我尝试运行 docker-compose up -d
时,我在邮件服务器容器的 docker 日志中看到以下内容:
Jun 22 23:25:53 mailserver postfix/master[26133]: fatal: bind: private/proxywrite: Invalid argument
我认为这可能会导致问题,因为当我尝试使用nodemailer(在同一台机器上)发送一条简单的消息时,如下所示:
const nodemailer = require('nodemailer')
let transporter = nodemailer.createTransport({
host: 'localhost', // <--- defaults to this anyway
port: 587,
})
const message = {
from: 'foo@example.com',
to: '<MY_PERSONAL_EMAIL>@gmail.com',
subject: 'YOUR CARS EXTENDED WARRANTY',
text: 'WEVE BEEN TRYING TO REACH YOU ABOUT YOUR CARS EXTENDED WARRANTY',
html: '<p>WEVE BEEN TRYING TO REACH YOU ABOUT YOUR CARS EXTENDED WARRANTY</p>',
}
transporter.sendMail(message).then(
() => {
console.log('success!')
},
(err) => {
console.error('=========== error occurred', err)
},
)
我收到以下错误:
error occurred Error: Unexpected socket close
at Timeout._onTimeout (/path/to/nodemailer-test/node_modules/nodemailer/lib/smtp-transport/index.js:189:31)
at listOnTimeout (internal/timers.js:551:17)
at processTimers (internal/timers.js:494:7)
任何帮助将不胜感激。
我猜您正在
app
容器中运行节点代码。
您试图从那里与
localhost:587
通信,这将是您的 app
容器的端口 587,而不是服务 mailserver
上可用的端口(您也将其绑定到主机)。
您可能想与那里的主机交谈,但是在 docker 中获取主机 IP 并不简单。幸运的是,在这种情况下也不需要:由于两个容器都是同一个 docker-compose 项目的一部分,因此它们会通过服务名称在内部自动路由。
这将使您的
app
容器直接与 mailserver
容器对话:
let transporter = nodemailer.createTransport({
host: 'mailserver',
port: 587,
})
更多故障排除:
mailserver
只是skynet
网络的一部分。确保 app
也属于其中。 netcat
/telnet
/ping
可以帮助您排除故障:docker-compose exec -it app bash
- 然后在容器内:ping mailserver
mailserver
服务配置与 https://github.com/docker-mailserver/docker-mailserver/blob/v10.0.0/docker-compose.yml 进行比较 - 看来您使用了较旧的配置版本,但是 mailserver/docker-mailserver:latest
指 v10。看来他们来自 README.md
/docker hub 页面的示例配置尚未反映这一点。由于它是 v10 的第一个版本,您可能想尝试使用 mailserver/docker-mailserver:9
(无论如何,“固定”所用依赖项的主要版本是一个很好的做法)如果您在 MacOS 上运行 docker,请尝试删除
/var/log/mail
卷。
从
- $PWD/.mailData/maillogs:/var/log/mail
文件中删除 docker-compose.yml
行。
不知何故,该卷与 MacOS 文件系统不兼容。 相关链接就在这里。 https://github.com/docker-mailserver/docker-mailserver/issues/3530