I’m having trouble with email delivery in my Django app deployed on Heroku. The emails work fine when I test locally, but I keep getting a connection timeout error on the production server.
My email configuration:
EMAIL_HOST = "smtp.mailgun.org"
EMAIL_PORT = 587
EMAIL_HOST_USER = os.environ["MAILGUN_USER"]
EMAIL_HOST_PASSWORD = os.environ["MAILGUN_PASS"]
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
View function that handles registration:
import re
import os
from django.http import HttpResponse
from django.contrib.auth.hashers import make_password
import secrets
from .models import Account, VerificationToken
from django.core.mail import send_mail
from threading import Thread
sender_email = re.sub(".*@", "support@", os.environ["MAILGUN_USER"])
def send_email_async(title, content, sender, recipients):
send_mail(
subject=title,
message=content,
from_email=sender,
recipient_list=recipients
)
def register_user(request):
if request.method == "POST":
user_password = request.POST["password"]
user_email = request.POST["email"]
if not re.match(r"[^@]+@[^@]+\.[^@]+", user_email):
return HttpResponse("Invalid email format")
if Account.objects.filter(email=user_email).exists():
return HttpResponse("User already registered")
new_account = Account.objects.create(
email=user_email,
password=make_password(user_password),
is_verified=False
)
token = secrets.token_hex(16)
VerificationToken.objects.create(user=new_account, token=token)
confirm_url = request.get_host() + "/verify/" + str(token)
Thread(target=send_email_async, args=(
"Account Verification",
confirm_url,
sender_email,
[user_email]
)).start()
return HttpResponse("Registration successful")
The error I’m getting:
TimeoutError: [Errno 110] Connection timed out
The weird thing is this works perfectly on my local machine but fails on Heroku. The form submission works and returns the success message, but the email sending fails in the background thread after about a minute. Has anyone encountered this before?