Three stack variables are set on the QA stack that the compose file never references:
QA_SMTP_HOST
QA_SMTP_PORT
QA_SMTP_SECURE
docker-compose.qa.yml hardcoded all three (smtp-relay.brevo.com, 587, false), so setting them in Portainer had no effect and nothing said so. The credentials beside them — QA_SMTP_USER, QA_SMTP_PASSWORD, QA_SMTP_FROM — do interpolate, which makes the inert three easy to mistake for working configuration.
Fixed by interpolating them like the rest, each keeping its Brevo value as a default:
The defaults matter. The mailer's own fallbacks are Gmail's — smtp.gmail.com, 465, implicit TLS — and Brevo is STARTTLS on 587. Interpolating with no default would mean an unset variable silently aims QA at Gmail and fails at send time rather than at boot, which is the exact failure the original hardcoding was there to prevent. :- applies only when the variable is unset or empty, so setting one still wins.
Verified with docker compose config in both directions, and the #107 compose guard still passes.
Production is left alone. It hardcodes the same three, nobody has asked to vary them there, and a needless change to the production stack is not worth the deploy. Worth revisiting only if QA and production configuration drifting apart becomes a problem.
Three stack variables are set on the QA stack that the compose file never references:
- `QA_SMTP_HOST`
- `QA_SMTP_PORT`
- `QA_SMTP_SECURE`
`docker-compose.qa.yml` hardcoded all three (`smtp-relay.brevo.com`, `587`, `false`), so setting them in Portainer had no effect and nothing said so. The credentials beside them — `QA_SMTP_USER`, `QA_SMTP_PASSWORD`, `QA_SMTP_FROM` — do interpolate, which makes the inert three easy to mistake for working configuration.
Fixed by interpolating them like the rest, each keeping its Brevo value as a default:
```yaml
- SMTP_HOST=${QA_SMTP_HOST:-smtp-relay.brevo.com}
- SMTP_PORT=${QA_SMTP_PORT:-587}
- SMTP_SECURE=${QA_SMTP_SECURE:-false}
```
The defaults matter. The mailer's own fallbacks are Gmail's — `smtp.gmail.com`, 465, implicit TLS — and Brevo is STARTTLS on 587. Interpolating with no default would mean an unset variable silently aims QA at Gmail and fails at send time rather than at boot, which is the exact failure the original hardcoding was there to prevent. `:-` applies only when the variable is unset or empty, so setting one still wins.
Verified with `docker compose config` in both directions, and the #107 compose guard still passes.
Production is left alone. It hardcodes the same three, nobody has asked to vary them there, and a needless change to the production stack is not worth the deploy. Worth revisiting only if QA and production configuration drifting apart becomes a problem.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Three stack variables are set on the QA stack that the compose file never references:
QA_SMTP_HOSTQA_SMTP_PORTQA_SMTP_SECUREdocker-compose.qa.ymlhardcoded all three (smtp-relay.brevo.com,587,false), so setting them in Portainer had no effect and nothing said so. The credentials beside them —QA_SMTP_USER,QA_SMTP_PASSWORD,QA_SMTP_FROM— do interpolate, which makes the inert three easy to mistake for working configuration.Fixed by interpolating them like the rest, each keeping its Brevo value as a default:
The defaults matter. The mailer's own fallbacks are Gmail's —
smtp.gmail.com, 465, implicit TLS — and Brevo is STARTTLS on 587. Interpolating with no default would mean an unset variable silently aims QA at Gmail and fails at send time rather than at boot, which is the exact failure the original hardcoding was there to prevent.:-applies only when the variable is unset or empty, so setting one still wins.Verified with
docker compose configin both directions, and the #107 compose guard still passes.Production is left alone. It hardcodes the same three, nobody has asked to vary them there, and a needless change to the production stack is not worth the deploy. Worth revisiting only if QA and production configuration drifting apart becomes a problem.