Problem
OpenShip already supports custom SMTP and several send-only provider presets,
but Cloudflare Email Sending requires users to manually discover and enter its
fixed submission settings:
- host:
smtp.mx.cloudflare.net
- port:
465 (implicit TLS)
- username:
api_token
- password: a Cloudflare API token with Email Sending edit permission
In a self-hosted Docker deployment, that manual configuration currently cannot
complete a send. Nodemailer establishes TLS under Bun but never receives the
SMTP greeting and eventually reports ETIMEDOUT: Greeting never received. The
same Nodemailer version, host, machine, and configuration complete the
greeting/EHLO flow under Node.js 22. Bun 1.3.10 reproduces the timeout, so a Bun
version bump alone does not resolve it.
Proposed approach
- Add a Cloudflare send-only preset to the existing shared mail-provider list
so selecting it prefills the host, port, and fixed username, leaving only the
From address/domain and API token for the user.
- Run the production API container under Node.js 22 so Nodemailer uses Node's
TLS implementation.
- Retain Bun in the final image for existing operational commands, and use the
existing tsx loader because workspace packages ship TypeScript source with
extensionless imports.
- Keep the existing encrypted SMTP credential storage and test-email endpoint
unchanged.
This requires no new endpoint, database migration, dependency, or
Cloudflare-specific secret-storage path.
Scope question
Is switching only the production API container runner from Bun to Node (while
retaining Bun in the image) acceptable for this integration, or would
maintainers prefer the runtime fix and provider preset to be proposed
separately?
Verification plan
- Regression tests for the provider preset and Docker runtime contract
- API and dashboard workspace checks
- Full repository test suite
- Clean API Docker image build and health check
- Authenticated Nodemailer
verify() against a user-controlled Cloudflare
Email Sending domain
- User-controlled real test-email delivery
A working fork branch exists for local validation, but I will wait for agreement
on scope and approach before opening the upstream PR, per CONTRIBUTING.md.
Problem
OpenShip already supports custom SMTP and several send-only provider presets,
but Cloudflare Email Sending requires users to manually discover and enter its
fixed submission settings:
smtp.mx.cloudflare.net465(implicit TLS)api_tokenIn a self-hosted Docker deployment, that manual configuration currently cannot
complete a send. Nodemailer establishes TLS under Bun but never receives the
SMTP greeting and eventually reports
ETIMEDOUT: Greeting never received. Thesame Nodemailer version, host, machine, and configuration complete the
greeting/EHLO flow under Node.js 22. Bun 1.3.10 reproduces the timeout, so a Bun
version bump alone does not resolve it.
Proposed approach
so selecting it prefills the host, port, and fixed username, leaving only the
From address/domain and API token for the user.
TLS implementation.
existing
tsxloader because workspace packages ship TypeScript source withextensionless imports.
unchanged.
This requires no new endpoint, database migration, dependency, or
Cloudflare-specific secret-storage path.
Scope question
Is switching only the production API container runner from Bun to Node (while
retaining Bun in the image) acceptable for this integration, or would
maintainers prefer the runtime fix and provider preset to be proposed
separately?
Verification plan
verify()against a user-controlled CloudflareEmail Sending domain
A working fork branch exists for local validation, but I will wait for agreement
on scope and approach before opening the upstream PR, per
CONTRIBUTING.md.