Nodemailer 无法从 Docker 容器内发送电子邮件
Nodemailer cannot send email from within Docker container
我已经 searching/reading/trying 在 Internet 上到处转了大约 3 周,然后才发帖到这里...
上下文:
- 开发小网站应用程序
- 技术:
- 前端和后端 (Node) 的下一个 JS (ReactJs, HTML, CSS)
- Linux 作为主机(Ubuntu 20.04 LTS)
- Docker封装app的容器(基于node:alpine镜像)(Docker版本20.10.6)
- Nodemailer 节点发送邮件的模块
- 这是使用 Nodemailer 发送电子邮件的代码:
import type { NextApiRequest, NextApiResponse } from "next";
import * as nodemailer from "nodemailer";
export default async (req: NextApiRequest, res: NextApiResponse) => {
res.statusCode = 200;
let transporter = nodemailer.createTransport({
host: process.env.NM_HOST,
port: parseInt(process.env.NM_PORT),
secure: true,
auth: {
user: process.env.NM_USER,
pass: process.env.NM_PASS,
},
tls: {
rejectUnauthorized: false,
},
});
// console.log("User:");
// console.log(process.env.NM_USER);
let info = await transporter.sendMail({
from: "Website <xxx@xxx.com>",
to: "Website <xxx@xxx.com>",
subject: "New contact",
text: "NAME:\n" + req.body.data.name + "\n----------\nEMAIL:\n" + req.body.data.email + "\n----------\nBODY:\n" + req.body.data.body,
}, function (err, info) {
if (err) {
console.log(err)
} else {
console.log(info);
}
});
console.log("Message sent: %s", info);
res.json({
a: req.body.data.name,
b: req.body.data.email,
c: req.body.data.body,
});
};
问题:
- 当我尝试使用 Nodemailer 发送电子邮件时,从 Linux 主机以“npm 运行 start”或“npm 运行 dev”启动我的应用程序时,邮件已送达
- 当我尝试使用 Nodemailer 发送电子邮件并从 Docker 的容器启动我的应用程序时,出现以下错误(来自应用程序的输出本身)
Error: connect ECONNREFUSED 127.0.0.1:465
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16) {
errno: -111,
code: 'ESOCKET',
syscall: 'connect',
address: '127.0.0.1',
port: 465,
command: 'CONN'
}
我已经尝试过的和观察到的:
ping google.com
(以及许多其他)在容器内工作(使用 docker exec -ti container-name sh
命令)
- 用
docker run --dns 8.8.8.8 ...
启动容器 -> 相同的结果(上面的错误)
- container 和 host'
/etc/resolv.conf
不同(但我认为这可能不是重点,因为 ping
命令正确解析,但如果我错了请随意说我错了)
- 我不是系统管理员(我是开发人员),所以我不知道这个东西是否暗示了 iptables 或 ufw(防火墙)(顺便说一句,很难安装非预装包node:alpine)
- 电子邮件服务器身份验证正确(用户名、主机名、密码),因为当我以
npm run start
或 npm run dev
启动我的应用程序时它可以正常工作
- 在网桥(默认)网桥(使用 docker-compose 自定义)和主机之间切换容器的网络...同样的问题(上面的错误)
非常感谢任何愿意提供帮助的人。
找出不起作用的地方:我使用的是 docker-compose
没有 --env-file
选项。
这样我试图在我的应用程序中访问的所有 环境变量 (例如 PORT、HOST、PSWD、USR)都被保留 undefined
(这是因为这些环境变量在构建步骤中尚未内置 - 设计选择,而是在运行时使用 process.env
)
访问
解决方案(根据您的情况更改 .env
文件部分):
docker-compose --env-file ./.env.production
有用的官方资源(docker-compose)
Docker-compose using --env-file option
我已经 searching/reading/trying 在 Internet 上到处转了大约 3 周,然后才发帖到这里...
上下文:
- 开发小网站应用程序
- 技术:
- 前端和后端 (Node) 的下一个 JS (ReactJs, HTML, CSS)
- Linux 作为主机(Ubuntu 20.04 LTS)
- Docker封装app的容器(基于node:alpine镜像)(Docker版本20.10.6)
- Nodemailer 节点发送邮件的模块
- 这是使用 Nodemailer 发送电子邮件的代码:
import type { NextApiRequest, NextApiResponse } from "next";
import * as nodemailer from "nodemailer";
export default async (req: NextApiRequest, res: NextApiResponse) => {
res.statusCode = 200;
let transporter = nodemailer.createTransport({
host: process.env.NM_HOST,
port: parseInt(process.env.NM_PORT),
secure: true,
auth: {
user: process.env.NM_USER,
pass: process.env.NM_PASS,
},
tls: {
rejectUnauthorized: false,
},
});
// console.log("User:");
// console.log(process.env.NM_USER);
let info = await transporter.sendMail({
from: "Website <xxx@xxx.com>",
to: "Website <xxx@xxx.com>",
subject: "New contact",
text: "NAME:\n" + req.body.data.name + "\n----------\nEMAIL:\n" + req.body.data.email + "\n----------\nBODY:\n" + req.body.data.body,
}, function (err, info) {
if (err) {
console.log(err)
} else {
console.log(info);
}
});
console.log("Message sent: %s", info);
res.json({
a: req.body.data.name,
b: req.body.data.email,
c: req.body.data.body,
});
};
问题:
- 当我尝试使用 Nodemailer 发送电子邮件时,从 Linux 主机以“npm 运行 start”或“npm 运行 dev”启动我的应用程序时,邮件已送达
- 当我尝试使用 Nodemailer 发送电子邮件并从 Docker 的容器启动我的应用程序时,出现以下错误(来自应用程序的输出本身)
Error: connect ECONNREFUSED 127.0.0.1:465
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16) {
errno: -111,
code: 'ESOCKET',
syscall: 'connect',
address: '127.0.0.1',
port: 465,
command: 'CONN'
}
我已经尝试过的和观察到的:
ping google.com
(以及许多其他)在容器内工作(使用docker exec -ti container-name sh
命令)- 用
docker run --dns 8.8.8.8 ...
启动容器 -> 相同的结果(上面的错误) - container 和 host'
/etc/resolv.conf
不同(但我认为这可能不是重点,因为ping
命令正确解析,但如果我错了请随意说我错了) - 我不是系统管理员(我是开发人员),所以我不知道这个东西是否暗示了 iptables 或 ufw(防火墙)(顺便说一句,很难安装非预装包node:alpine)
- 电子邮件服务器身份验证正确(用户名、主机名、密码),因为当我以
npm run start
或npm run dev
启动我的应用程序时它可以正常工作
- 在网桥(默认)网桥(使用 docker-compose 自定义)和主机之间切换容器的网络...同样的问题(上面的错误)
非常感谢任何愿意提供帮助的人。
找出不起作用的地方:我使用的是 docker-compose
没有 --env-file
选项。
这样我试图在我的应用程序中访问的所有 环境变量 (例如 PORT、HOST、PSWD、USR)都被保留 undefined
(这是因为这些环境变量在构建步骤中尚未内置 - 设计选择,而是在运行时使用 process.env
)
解决方案(根据您的情况更改 .env
文件部分):
docker-compose --env-file ./.env.production
有用的官方资源(docker-compose) Docker-compose using --env-file option