Невозможно отправить почту в докеризованном Django-приложении, если настройки почты заданы из среды docker

Я работаю над докеризованным проектом django store с Celery и Redis. Когда покупатель делает заказ, Celery отправляет ему письмо об этом. Когда я задаю настройки почты в django напрямую, все работает нормально:

EMAIL_USE_SSL = True
EMAIL_HOST = "smtp.yandex.ru"
EMAIL_HOST_USER = "mymail@yandex.ru"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST_PASSWORD = "password"
EMAIL_PORT = 465

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
EMAIL_ADMIN = EMAIL_HOST_USER

Но когда я устанавливаю те же переменные из окружения docker-compose:

EMAIL_USE_SSL = os.getenv("EMAIL_USER_SSL")
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_BACKEND = os.getenv("EMAIL_BACKEND")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
EMAIL_PORT = os.getenv("EMAIL_PORT")

DEFAULT_FROM_EMAIL = os.getenv("EMAIL_HOST_USER")
SERVER_EMAIL = os.getenv("EMAIL_HOST_USER")
EMAIL_ADMIN = os.getenv("EMAIL_HOST_USER")

Я получаю следующую ошибку от Celery:

celery-1  | [2024-09-23 12:48:48,816: ERROR/ForkPoolWorker-2] Task orders.tasks.send_order_email[243058c7-6fc2-47a2-9f36-7e0e1b00cd9d] raised unexpected: AttributeError("'NoneType' object has no attribute 'rsplit'")
celery-1  | Traceback (most recent call last):
celery-1  |   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 453, in trace_task
celery-1  |     R = retval = fun(*args, **kwargs)
celery-1  |                  ^^^^^^^^^^^^^^^^^^^^
celery-1  |   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 736, in __protected_call__
celery-1  |     return self.run(*args, **kwargs)
celery-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^
celery-1  |   File "/usr/src/bookstore/orders/tasks.py", line 7, in send_order_email
celery-1  |     send_mail(
celery-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/mail/__init__.py", line 77, in send_mail
celery-1  |     connection = connection or get_connection(
celery-1  |                                ^^^^^^^^^^^^^^^
celery-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/mail/__init__.py", line 51, in get_connection
celery-1  |     klass = import_string(backend or settings.EMAIL_BACKEND)
celery-1  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
celery-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/module_loading.py", line 25, in import_string
celery-1  |     module_path, class_name = dotted_path.rsplit(".", 1)
celery-1  |                               ^^^^^^^^^^^^^^^^^^
celery-1  | AttributeError: 'NoneType' object has no attribute 'rsplit'

docker-compose.yml

version: '3.8'

services:
  django:
    build: .
    container_name: django
    volumes:
      - .:/usr/src/bookstore/
    ports:
      - "8000:8000"
    command: >
      sh -c "python3 manage.py makemigrations
             python3 manage.py migrate
             python3 manage.py loaddata fixtures/books.json
             python3 manage.py loaddata fixtures/stores.json
             python3 manage.py runserver 0.0.0.0:8000"

    environment:
      - DEBUG=1
      - DJANGO_ALLOWED_HOSTS=localhost, 127.0.0.1
      - CELERY_BROKER=redis://redis:6379/0
      - CELERY_BACKEND=redis://redis:6379/0
      - DB_HOST=pgdb
      - DB_NAME=bookstore
      - DB_USER=bookstore
      - DB_PASS=bookstore

      - EMAIL_USE_SSL=True
      - EMAIL_HOST=smtp.yandex.ru
      - EMAIL_HOST_USER=mymail@yandex.ru
      - EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
      - EMAIL_HOST_PASSWORD=password
      - EMAIL_PORT=465

    depends_on:
      - pgdb
      - redis

  celery:
    build: .
    command: celery -A bookstore worker -l INFO
    volumes:
      - .:/usr/src/bookstore
    depends_on:
      - django
      - pgdb
      - redis
  
  pgdb:
    image: postgres
    environment:
      - POSTGRES_DB=bookstore
      - POSTGRES_USER=bookstore
      - POSTGRES_PASSWORD=bookstore
    volumes:
      - pgdata:/var/lib/postgresql/data/
    
  redis:
    image: "redis:alpine"

volumes:
  pgdata:

Celery в settings.py

CELERY_BROKER_URL = os.getenv("CELERY_BROKER", "redis://redis:6379/0")
CELERY_RESULT_BACKEND = os.getenv("CELERY_BACKEND", "redis://redis:6379/0")

tasks.py (задача сельдерея)

from django.core.mail import send_mail
from bookstore import celery_app


@celery_app.task
def send_order_email(email_host_user, user_email):
    send_mail(
        "New order",
        "You have successfully placed your order!",
        email_host_user,
        [user_email],
        fail_silently=False
    )

Вызов задачи

from .tasks import send_order_email
from django.conf import settings

def post(self, request):
    ...
    send_order_email.delay(settings.EMAIL_HOST_USER, request.user.email)

Я попытался добавить те же переменные окружения к сервису celery в файле docker-compose, ошибка исчезла, контейнер celery выводит:

celery-1  | [2024-09-23 12:24:43,178: INFO/MainProcess] Task orders.tasks.send_order_email[4663168e-08a6-44e0-b0e1-f75c01fd37cf] received

но сообщение электронной почты все еще не отправлено.

Вернуться на верх