Docker环境下Django中Celery无法连接RabbitMQ的解决咨询
Docker下Celery无法连接RabbitMQ的问题排查与解决
问题背景
我正在学习Docker,遇到Celery无法连接RabbitMQ的问题。已为RabbitMQ和Django创建两个镜像,相关配置如下:
docker-compose.yml配置
version: "3.0" services: # WEB django: build: . volumes: - media_volume:/website/journal_website/media - static_volume:/website/journal_website/static - database_volume:/website/journal_website/database ports: - "8000:8000" depends_on: - rabbit # RabbitMQ rabbit: hostname: rabbit container_name: rabbitmq image: rabbitmq:3.12-rc-management environment: - RABBITMQ_DEFAULT_USER=simple_user - RABBITMQ_DEFAULT_PASS=simple_password ports: # AMQP protocol port - "5672:5672" # HTTP management UI - "15672:15672" restart: always volumes: media_volume: static_volume: database_volume:
Django settings.py中的Broker配置
CELERY_BROKER_URL = 'amqp://localhost:5672'
celery.py文件
from __future__ import absolute_import, unicode_literals import os from celery import Celery os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") celery_application = Celery("website") celery_application.config_from_object("django.conf:settings", namespace="CELERY") celery_application.autodiscover_tasks()
entrypoint.sh脚本
#!/bin/bash # Start Celery celery -A website worker -l info # Run Django server python3.11 manage.py runserver 127.0.0.1:8000
Dockerfile内容
# Many many commands to install python and all dependencies in ubuntu 20.04 # Run Django server EXPOSE 8000 ENTRYPOINT ["/entrypoint.sh"]
错误现象
使用Windows 10的Docker Desktop,执行docker compose up或通过桌面应用运行容器时,出现错误:
[Date: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused.
已确认localhost指向127.0.0.1,请问如何正确运行Celery?
解决方案
1. 修正Broker地址:用Docker服务名替代localhost
在Docker Compose的默认网络中,每个服务可以直接通过服务名互相访问,容器内的localhost指向容器自身,而非宿主机或其他容器。你的RabbitMQ服务名为rabbit,同时要带上配置的账号密码(否则Celery会默认用guest/guest尝试连接,和你设置的RabbitMQ账号不匹配),修改settings.py中的配置:
CELERY_BROKER_URL = 'amqp://simple_user:simple_password@rabbit:5672//'
2. 修复entrypoint.sh脚本的执行逻辑
当前脚本中celery -A website worker -l info会阻塞进程,导致后面的Django启动命令永远无法执行。需要将Celery放到后台运行,同时修改Django的绑定地址为0.0.0.0(容器内的127.0.0.1仅能被容器内部访问,宿主机无法通过端口映射访问):
#!/bin/bash # 后台启动Celery worker celery -A website worker -l info & # 启动Django服务器,绑定所有网卡 python3.11 manage.py runserver 0.0.0.0:8000
3. 等待RabbitMQ服务就绪后再启动Celery
depends_on仅保证容器的启动顺序,不保证RabbitMQ服务完全就绪。可以在entrypoint.sh开头加入等待逻辑,确保RabbitMQ端口开放后再启动后续服务:
#!/bin/bash # 等待RabbitMQ服务就绪(需要容器内安装netcat,可在Dockerfile中添加apt-get install -y netcat-openbsd) until nc -z rabbit 5672; do echo "Waiting for RabbitMQ..." sleep 2 done # 后台启动Celery worker celery -A website worker -l info & # 启动Django服务器 python3.11 manage.py runserver 0.0.0.0:8000
4. 验证RabbitMQ账号配置
进入RabbitMQ容器,检查用户是否正确创建:
docker exec -it rabbitmq rabbitmqctl list_users
确认输出中存在simple_user,确保账号密码与settings.py中的配置一致。
内容的提问来源于stack exchange,提问作者WideWood
相关产品推荐
相关产品推荐

