Environment
- OpenProject 17 Community Edition
- Official Docker Compose deployment
- Debian 12 LXC
- Internal SMTP relay with STARTTLS
- FreeIPA internal CA
Observed behavior
The outbound email documentation implies SMTP settings can be configured through:
.env
- Docker Compose environment variables
- or the Administration UI
However, in practice:
-
SMTP variables defined only in .env are NOT injected into containers unless explicitly mapped into x-op-app -> environment (or override files).
-
The SMTP configuration UI is hidden even when SMTP runtime settings are not actually active.
-
Rails silently falls back to:
localhost:25
-
Existing database-backed settings prevent environment-seeded SMTP settings from being applied after initial bootstrap.
-
The documentation does not clearly explain:
- precedence order
- bootstrap-only behavior
- DB persistence behavior
- requirement for explicit environment injection
Evidence
Running:
bundle exec rails runner "pp ActionMailer::Base.smtp_settings"
continued to show:
{address: "localhost", port: 25}
despite SMTP variables existing in .env.
Additional findings
The Docker Compose deployment required explicit environment injection through docker-compose.override.yml such as:
OPENPROJECT_SMTP__ADDRESS
OPENPROJECT_SMTP__PORT
OPENPROJECT_SMTP__USER__NAME
OPENPROJECT_SMTP__PASSWORD
OPENPROJECT_EMAIL__DELIVERY__METHOD
Otherwise the application never consumed the SMTP configuration.
Additionally, internal SMTP over STARTTLS with private/internal PKI required manual CA injection into the containers because container trust stores do not inherit host trust stores automatically.
Resolution required
The deployment only partially functioned after:
- explicit environment injection in compose override
- container recreation
- SSRF allowlist overrides
- container CA trust injection
- repeated DB/settings resets
Even after these steps, SMTP configuration persistence behavior remained unclear because existing DB settings continued overriding environment-provided values.
Documentation concerns
This behavior was extremely difficult to diagnose because the documentation strongly suggests .env is sufficient.
The current documentation does not clearly communicate:
.env alone is not enough
- variables must be explicitly injected into service environment sections
- settings may persist in the DB after first initialization
- SMTP UI behavior changes depending on configuration mode
- configuration precedence order
Related issue
This appears closely related to:
#134
Environment
Observed behavior
The outbound email documentation implies SMTP settings can be configured through:
.envHowever, in practice:
SMTP variables defined only in
.envare NOT injected into containers unless explicitly mapped intox-op-app -> environment(or override files).The SMTP configuration UI is hidden even when SMTP runtime settings are not actually active.
Rails silently falls back to:
localhost:25Existing database-backed settings prevent environment-seeded SMTP settings from being applied after initial bootstrap.
The documentation does not clearly explain:
Evidence
Running:
bundle exec rails runner "pp ActionMailer::Base.smtp_settings"continued to show:
{address: "localhost", port: 25}despite SMTP variables existing in
.env.Additional findings
The Docker Compose deployment required explicit environment injection through
docker-compose.override.ymlsuch as:OPENPROJECT_SMTP__ADDRESSOPENPROJECT_SMTP__PORTOPENPROJECT_SMTP__USER__NAMEOPENPROJECT_SMTP__PASSWORDOPENPROJECT_EMAIL__DELIVERY__METHODOtherwise the application never consumed the SMTP configuration.
Additionally, internal SMTP over STARTTLS with private/internal PKI required manual CA injection into the containers because container trust stores do not inherit host trust stores automatically.
Resolution required
The deployment only partially functioned after:
Even after these steps, SMTP configuration persistence behavior remained unclear because existing DB settings continued overriding environment-provided values.
Documentation concerns
This behavior was extremely difficult to diagnose because the documentation strongly suggests
.envis sufficient.The current documentation does not clearly communicate:
.envalone is not enoughRelated issue
This appears closely related to:
#134