I am deploying my Django project to MS Azure App service.
When users try to sign up or reset their passwords, the confirmation/reset emails are not sent.
However, a management command I created to test the configuration works as expected when I run it from Azure SSH terminal (i.e. in the same environment as the webapp).
Here is the command:
# mysite > core > management > commands > test_smtp.py
# ... truncating imports ...
from django.conf import settings
from django.core import mail
# ColorCommand subclasses BaseCommand and provides colored stdout
class Command(ColorCommand):
help = "Sends a test email"
def add_arguments(self, parser):
parser.add_argument(
"-r", "--recipients",
nargs="+",
type=str,
help="""Comma-separated list of emails to send the message to""",
default=settings.DEFAULT_TEST_RECIPIENTS,
)
parser.add_argument(
"-m", "--message",
type=str,
help="""Message to write as content of the email""",
default="This is a text message sent by MyDomain.com dev team."
)
def handle(self, *args, **options):
recipients = options['recipients']
message = options['message']
print(message)
self.info(f'Sending email to {recipients}')
with mail.get_connection() as connection:
mail.EmailMessage(
'Test email',
message,
settings.DEFAULT_FROM_EMAIL,
recipients,
connection=connection,
).send()
self.success('Email sent. Check your inbox.')
My (truncated) configuration is displayed below:
# mysite > mysite > settings.py
import os
from pathlib import Path
# On Azure server, email settings come from os.environ, as you'll see below
try:
from . import settings_local as local_settings
print("Local settings loaded from local settings file.")
except (ModuleNotFoundError, ImportError):
print("Local settings loaded from environment variables.")
local_settings = None
# ... heavily truncated ...
# Email section
DEFAULT_EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_EMAIL_USE_TLS = True
DEFAULT_EMAIL_USE_SSL = False
DEFAULT_EMAIL_HOST = 'pro3.mail.something.net' # Where `something` is the registrar of the web domain. It offers smtp services as well
DEFAULT_EMAIL_PORT = 587
DEFAULT_EMAIL_HOST_USER = 'hello@mydomain.com'
DEFAULT_DEFAULT_FROM_EMAIL = DEFAULT_EMAIL_HOST_USER
DEFAULT_DEFAULT_TEST_RECIPIENTS = ['test@mydomain.com']
EMAIL_BACKEND = getattr(local_settings, 'EMAIL_BACKEND', DEFAULT_EMAIL_BACKEND)
if 'file' in EMAIL_BACKEND:
EMAIL_FILE_PATH = os.path.join(BASE_DIR, local_settings.EMAIL_FILE_PATH)
elif 'smtp' in EMAIL_BACKEND:
EMAIL_USE_TLS = getattr(local_settings, 'EMAIL_USE_TLS',
DEFAULT_EMAIL_USE_TLS)
EMAIL_USE_SSL = getattr(local_settings, 'EMAIL_USE_SSL',
DEFAULT_EMAIL_USE_SSL)
EMAIL_HOST = getattr(local_settings, 'EMAIL_HOST', DEFAULT_EMAIL_HOST)
EMAIL_PORT = getattr(local_settings, 'EMAIL_PORT', DEFAULT_EMAIL_PORT)
EMAIL_HOST_USER = getattr(local_settings, 'EMAIL_HOST_USER',
DEFAULT_EMAIL_HOST_USER)
EMAIL_HOST_PASSWORD = getattr(local_settings, 'EMAIL_HOST_PASSWORD',
os.environ.get('EMAIL_HOST_PASSWORD'))
DEFAULT_FROM_EMAIL = getattr(local_settings, 'DEFAULT_FROM_EMAIL',
DEFAULT_DEFAULT_FROM_EMAIL)
DEFAULT_TEST_RECIPIENTS = getattr(local_settings,
'DEFAULT_TEST_RECIPIENTS',
DEFAULT_DEFAULT_TEST_RECIPIENTS)
On Azure, there is no local_settings.py and I use environment variables, so this can be simplified as:
# Email section
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
EMAIL_HOST = 'pro3.mail.something.net'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'hello@mydomain.com'
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD') # I checked: this is correctly set
DEFAULT_FROM_EMAIL = 'hello@mydomain.com'
DEFAULT_TEST_RECIPIENTS = ['test@mydomain.com']
Does anyone have any lead about what may be happening?