dockerize smtp-proxy (#118)
This commit is contained in:
91
.github/workflows/publish.yml
vendored
91
.github/workflows/publish.yml
vendored
@@ -23,6 +23,13 @@ jobs:
|
||||
os:
|
||||
- warp-ubuntu-latest-x64-2x
|
||||
- warp-ubuntu-latest-arm64-2x
|
||||
app:
|
||||
- name: unsend
|
||||
dockerfile: ./docker/Dockerfile
|
||||
context: .
|
||||
- name: smtp-proxy
|
||||
dockerfile: ./Dockerfile
|
||||
context: ./apps/smtp-server
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -53,23 +60,23 @@ jobs:
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker build \
|
||||
-f ./docker/Dockerfile \
|
||||
-f ${{ matrix.app.dockerfile }} \
|
||||
--progress=plain \
|
||||
-t "unsend/unsend-$BUILD_PLATFORM:latest" \
|
||||
-t "unsend/unsend-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "unsend/unsend-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
-t "ghcr.io/unsend-dev/unsend-$BUILD_PLATFORM:latest" \
|
||||
-t "ghcr.io/unsend-dev/unsend-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "ghcr.io/unsend-dev/unsend-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
.
|
||||
-t "unsend/${{ matrix.app.name }}-$BUILD_PLATFORM:latest" \
|
||||
-t "unsend/${{ matrix.app.name }}-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "unsend/${{ matrix.app.name }}-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
-t "ghcr.io/unsend-dev/${{ matrix.app.name }}-$BUILD_PLATFORM:latest" \
|
||||
-t "ghcr.io/unsend-dev/${{ matrix.app.name }}-$BUILD_PLATFORM:$GIT_SHA" \
|
||||
-t "ghcr.io/unsend-dev/${{ matrix.app.name }}-$BUILD_PLATFORM:$APP_VERSION" \
|
||||
${{ matrix.app.context }}
|
||||
|
||||
- name: Push the docker image to DockerHub
|
||||
run: docker push --all-tags "unsend/unsend-$BUILD_PLATFORM"
|
||||
run: docker push --all-tags "unsend/${{ matrix.app.name }}-$BUILD_PLATFORM"
|
||||
env:
|
||||
BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-2x' && 'arm64' || 'amd64' }}
|
||||
|
||||
- name: Push the docker image to GitHub Container Registry
|
||||
run: docker push --all-tags "ghcr.io/unsend-dev/unsend-$BUILD_PLATFORM"
|
||||
run: docker push --all-tags "ghcr.io/unsend-dev/${{ matrix.app.name }}-$BUILD_PLATFORM"
|
||||
env:
|
||||
BUILD_PLATFORM: ${{ matrix.os == 'warp-ubuntu-latest-arm64-2x' && 'arm64' || 'amd64' }}
|
||||
|
||||
@@ -103,45 +110,49 @@ jobs:
|
||||
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker manifest create \
|
||||
unsend/unsend:latest \
|
||||
--amend unsend/unsend-amd64:latest \
|
||||
--amend unsend/unsend-arm64:latest \
|
||||
for APP_NAME in unsend smtp-proxy; do
|
||||
docker manifest create \
|
||||
unsend/$APP_NAME:latest \
|
||||
--amend unsend/$APP_NAME-amd64:latest \
|
||||
--amend unsend/$APP_NAME-arm64:latest
|
||||
|
||||
docker manifest create \
|
||||
unsend/unsend:$GIT_SHA \
|
||||
--amend unsend/unsend-amd64:$GIT_SHA \
|
||||
--amend unsend/unsend-arm64:$GIT_SHA \
|
||||
docker manifest create \
|
||||
unsend/$APP_NAME:$GIT_SHA \
|
||||
--amend unsend/$APP_NAME-amd64:$GIT_SHA \
|
||||
--amend unsend/$APP_NAME-arm64:$GIT_SHA
|
||||
|
||||
docker manifest create \
|
||||
unsend/unsend:$APP_VERSION \
|
||||
--amend unsend/unsend-amd64:$APP_VERSION \
|
||||
--amend unsend/unsend-arm64:$APP_VERSION \
|
||||
docker manifest create \
|
||||
unsend/$APP_NAME:$APP_VERSION \
|
||||
--amend unsend/$APP_NAME-amd64:$APP_VERSION \
|
||||
--amend unsend/$APP_NAME-arm64:$APP_VERSION
|
||||
|
||||
docker manifest push unsend/unsend:latest
|
||||
docker manifest push unsend/unsend:$GIT_SHA
|
||||
docker manifest push unsend/unsend:$APP_VERSION
|
||||
docker manifest push unsend/$APP_NAME:latest
|
||||
docker manifest push unsend/$APP_NAME:$GIT_SHA
|
||||
docker manifest push unsend/$APP_NAME:$APP_VERSION
|
||||
done
|
||||
|
||||
- name: Create and push Github Container Registry manifest
|
||||
run: |
|
||||
APP_VERSION="$(git name-rev --tags --name-only $(git rev-parse HEAD) | head -n 1 | sed 's/\^0//')"
|
||||
GIT_SHA="$(git rev-parse HEAD)"
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/unsend:latest \
|
||||
--amend ghcr.io/unsend-dev/unsend-amd64:latest \
|
||||
--amend ghcr.io/unsend-dev/unsend-arm64:latest \
|
||||
for APP_NAME in unsend smtp-proxy; do
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/$APP_NAME:latest \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-amd64:latest \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-arm64:latest
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/unsend:$GIT_SHA \
|
||||
--amend ghcr.io/unsend-dev/unsend-amd64:$GIT_SHA \
|
||||
--amend ghcr.io/unsend-dev/unsend-arm64:$GIT_SHA \
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/$APP_NAME:$GIT_SHA \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-amd64:$GIT_SHA \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-arm64:$GIT_SHA
|
||||
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/unsend:$APP_VERSION \
|
||||
--amend ghcr.io/unsend-dev/unsend-amd64:$APP_VERSION \
|
||||
--amend ghcr.io/unsend-dev/unsend-arm64:$APP_VERSION \
|
||||
docker manifest create \
|
||||
ghcr.io/unsend-dev/$APP_NAME:$APP_VERSION \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-amd64:$APP_VERSION \
|
||||
--amend ghcr.io/unsend-dev/$APP_NAME-arm64:$APP_VERSION
|
||||
|
||||
docker manifest push ghcr.io/unsend-dev/unsend:latest
|
||||
docker manifest push ghcr.io/unsend-dev/unsend:$GIT_SHA
|
||||
docker manifest push ghcr.io/unsend-dev/unsend:$APP_VERSION
|
||||
docker manifest push ghcr.io/unsend-dev/$APP_NAME:latest
|
||||
docker manifest push ghcr.io/unsend-dev/$APP_NAME:$GIT_SHA
|
||||
docker manifest push ghcr.io/unsend-dev/$APP_NAME:$APP_VERSION
|
||||
done
|
||||
|
45
apps/smtp-server/Dockerfile
Normal file
45
apps/smtp-server/Dockerfile
Normal file
@@ -0,0 +1,45 @@
|
||||
# Stage 1: Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Install pnpm (package manager) globally
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Set working directory for the application
|
||||
WORKDIR /app
|
||||
|
||||
# Copy configuration files first
|
||||
COPY package.json tsconfig.json tsup.config.ts ./
|
||||
|
||||
# Install dependencies (including devDependencies)
|
||||
RUN pnpm install
|
||||
|
||||
# Copy the source code
|
||||
COPY src/ ./src/
|
||||
|
||||
# Build the application
|
||||
RUN pnpm run build
|
||||
|
||||
|
||||
# Remove development dependencies to reduce size
|
||||
RUN pnpm prune --prod
|
||||
|
||||
# Stage 2: Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Set working directory in the final image
|
||||
WORKDIR /app
|
||||
|
||||
# Copy necessary files from the builder stage: production node_modules, build output, and package definition
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
|
||||
# Copy only the necessary files from builder
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
|
||||
|
||||
# Expose SMTP ports (standard SMTP, SMTPS, and alternative ports)
|
||||
EXPOSE 25 465 587 2465 2587
|
||||
|
||||
|
||||
# Run the SMTP server
|
||||
CMD ["node", "dist/server.js"]
|
29
apps/smtp-server/docker-compose.yml
Normal file
29
apps/smtp-server/docker-compose.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
name: unsend-smtp-server
|
||||
|
||||
services:
|
||||
smtp-server:
|
||||
container_name: unsend-smtp-server
|
||||
image: unsend/smtp-proxy:latest
|
||||
# Pass necessary environment variables
|
||||
environment:
|
||||
SMTP_AUTH_USERNAME: "unsend" # can be anything, just use the same while sending emails
|
||||
UNSEND_BASE_URL: "https://app.unsend.dev" # your self hosted unsend instance url
|
||||
|
||||
# Uncomment this if you have SSL certificates. port 465 and 2465 will be using SSL
|
||||
# UNSEND_API_KEY_PATH: "/certs/server.key"
|
||||
# UNSEND_API_CERT_PATH: "/certs/server.crt"
|
||||
# If you have SSL certificates, mount them here (read-only recommended)
|
||||
|
||||
# volumes:
|
||||
# - ./certs/server.key:/certs/server.key:ro
|
||||
# - ./certs/server.crt:/certs/server.crt:ro
|
||||
|
||||
# Expose the SMTP ports
|
||||
ports:
|
||||
- "25:25"
|
||||
- "587:587"
|
||||
- "2587:2587"
|
||||
- "465:465"
|
||||
- "2465:2465"
|
||||
# Restart always or on-failure, depending on preference
|
||||
restart: unless-stopped
|
@@ -81,10 +81,9 @@ const serverOptions: SMTPServerOptions = {
|
||||
replyTo: parsed.replyTo?.text,
|
||||
};
|
||||
|
||||
console.log("Parsed email data:", emailObject); // Debug statement
|
||||
|
||||
sendEmailToUnsend(emailObject, session.user)
|
||||
.then(() => callback())
|
||||
.then(() => console.log("Email sent successfully to: ", emailObject.to))
|
||||
.catch((error) => {
|
||||
console.error("Failed to send email:", error.message);
|
||||
callback(error);
|
||||
@@ -104,18 +103,22 @@ const serverOptions: SMTPServerOptions = {
|
||||
};
|
||||
|
||||
function startServers() {
|
||||
// Implicit SSL/TLS for ports 465 and 2465
|
||||
[465, 2465].forEach((port) => {
|
||||
const server = new SMTPServer({ ...serverOptions, secure: true });
|
||||
if (SSL_KEY_PATH && SSL_CERT_PATH) {
|
||||
// Implicit SSL/TLS for ports 465 and 2465
|
||||
[465, 2465].forEach((port) => {
|
||||
const server = new SMTPServer({ ...serverOptions, secure: true });
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(`Implicit SSL/TLS SMTP server is listening on port ${port}`);
|
||||
});
|
||||
server.listen(port, () => {
|
||||
console.log(
|
||||
`Implicit SSL/TLS SMTP server is listening on port ${port}`
|
||||
);
|
||||
});
|
||||
|
||||
server.on("error", (err) => {
|
||||
console.error(`Error occurred on port ${port}:`, err);
|
||||
server.on("error", (err) => {
|
||||
console.error(`Error occurred on port ${port}:`, err);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// STARTTLS for ports 25, 587, and 2587
|
||||
[25, 587, 2587].forEach((port) => {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: "smtp.unsend.dev",
|
||||
port: 2587,
|
||||
host: "localhost",
|
||||
port: 25,
|
||||
secure: false,
|
||||
auth: {
|
||||
user: "unsend",
|
||||
|
Reference in New Issue
Block a user