Django 如何避免使用Supervisor启动芹菜时出现密钥错误?

Django 如何避免使用Supervisor启动芹菜时出现密钥错误?,django,celery,supervisord,celeryd,Django,Celery,Supervisord,Celeryd,我有一个Django 1.62应用程序在Debian 7.8上运行,Nginx 1.2.1作为我的代理服务器,Gunicorn 19.1.1作为我的应用服务器。我已经安装了芹菜3.1.7和RabbitMQ 2.8.4来处理异步任务。我正在尝试使用Supervisor3.0a8管理我的各种应用程序,尤其是芹菜。问题是,当我试图通过主管启动芹菜时,我会出现以下错误: ImproperlyConfigured: The SECRET_KEY setting must not be empty. (我

我有一个Django 1.62应用程序在Debian 7.8上运行,Nginx 1.2.1作为我的代理服务器,Gunicorn 19.1.1作为我的应用服务器。我已经安装了芹菜3.1.7和RabbitMQ 2.8.4来处理异步任务。我正在尝试使用Supervisor3.0a8管理我的各种应用程序,尤其是芹菜。问题是,当我试图通过主管启动芹菜时,我会出现以下错误:

ImproperlyConfigured: The SECRET_KEY setting must not be empty.
(我在底部显示了整个stacktrace。)

我的所有配置文件都保存在“conf”目录中,该目录位于我的“myproj”项目目录的正下方,如下所示:

conf
├── celeryconfig.py
├── celeryconfig.pyc
├── celery.py
├── __init__.py
├── middleware.py
├── settings
│   ├── base.py
│   ├── dev.py
│   ├── __init__.py
│   ├── prod.py
├── urls.py
├── wsgi.py
我的生产Django设置保存在prod.py设置文件中,该文件继承了我的base.py基本设置。我将密钥保存在虚拟环境的postactivate文件中,并将其读取到生产设置中,如下所示。我已经通过Python解释器验证了密钥是否存在于我的生产设置中

# conf/settings/prod.py
from conf.settings.base import *
...
# get_env_variable is defined in base.py
SECRET_KEY = get_env_variable("SECRET_KEY")
这是get_env_变量函数,用于读取中的密钥:

# conf/settings/base.py
def get_env_variable(var_name):
    try:
        return os.environ[var_name]
    except KeyError:
        error_msg = "Set the %s environment variable" % var_name
        raise ImproperlyConfigured(error_msg)
这是我的主管配置文件。它基于中显示的示例文件:

下面是我如何使用Supervisor加载新芹菜配置的:

sudo service supervisor stop
sudo service supervisor start
这是我的芹菜申请文件:

# conf/celery.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
from conf import celeryconfig

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conf.settings')
app = Celery('conf')
app.config_from_object(celeryconfig)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# conf/celeryconfig.py
BROKER_URL = 'amqp://guest@localhost:5672//'
CELERY_RESULT_BACKEND = 'amqp'
CELERY_ACCEPT_CONTENT = ['json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_RESULT_EXPIRES = 3600
CELERY_SEND_TASK_ERROR_EMAILS = True
这是我的芹菜配置文件:

# conf/celery.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
from conf import celeryconfig

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conf.settings')
app = Celery('conf')
app.config_from_object(celeryconfig)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# conf/celeryconfig.py
BROKER_URL = 'amqp://guest@localhost:5672//'
CELERY_RESULT_BACKEND = 'amqp'
CELERY_ACCEPT_CONTENT = ['json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_RESULT_EXPIRES = 3600
CELERY_SEND_TASK_ERROR_EMAILS = True
根据芹菜文档,我修改了_init _uuuuy.py:

# conf/__init__.py
from __future__ import absolute_import
from .celery import app as celery_app
我可以使用以下命令手动启动芹菜,它启动得很好:

workon myproj  # Activate project's virtual environment
celery worker -A conf -l info
然而,当我试图通过主管启动它时,我得到了我描述的错误。考虑到主管可能无法访问Django密钥,因为它是一个环境变量,我尝试在prod.py设置文件中硬编码密钥(而不是通过get_env_variable函数读取密钥),但这并没有解决问题

我尝试将所有设置合并到包含实际密钥的prod.py设置文件中,但没有帮助

我还尝试将此环境参数添加到Supervisor配置文件中,如下所示,但这并没有解决问题:

# /etc/supervisor/conf.d/myproj.conf
...
[program:celery]
environment=SECRET_KEY="(my secret key)"
directory=/www/myproj
command=/home/myproj/venv/myproj/bin/celery worker --app=conf -l debug
user=nobody
...
我尝试将“用户”设置为我启动网站的用户的名称,但也没有帮助

# /etc/supervisor/conf.d/myproj.conf
...
[program:celery]
environment=SECRET_KEY="(my secret key)"
directory=/www/myproj
command=/home/myproj/venv/myproj/bin/celery worker --app=conf -l debug
user=myproj
...
我读到一个名为的库,它应该可以简化Django和Supervisor之间的集成,但是如果我使用该库,我会遇到同样的错误

最后我读到,如果您的密钥包含“%”符号,主管将不喜欢它。我注意到我的密钥确实包含一个“%”符号,所以我像这样转义了“%”,但这也不能解决问题

有人能看出我做错了什么吗?我在这里看到了在不同情况下遇到相同错误的用户提出的其他问题,但我尝试实施了讨论过的各种解决方案,但没有一个解决了问题

非常感谢你的想法。很抱歉问了这么长的问题,但这个问题有很多活动部件

以下是整个stacktrace:

Traceback (most recent call last):
  File "/home/myproj/venv/myproj/bin/celery", line 11, in <module>
    sys.exit(main())
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/__main__.py", line 30, in main
    main()
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 81, in main
    cmd.execute_from_commandline(argv)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 769, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/base.py", line 307, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 761, in handle_argv
    return self.execute(command, argv)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/celery.py", line 693, in execute
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/worker.py", line 179, in run_from_argv
    return self(*args, **options)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/base.py", line 270, in __call__
    ret = self.run(*args, **kwargs)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/bin/worker.py", line 212, in run
    state_db=self.node_format(state_db, hostname), **kwargs
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/worker/__init__.py", line 95, in __init__
    self.app.loader.init_worker()
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/loaders/base.py", line 128, in init_worker
    self.import_default_modules()
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/loaders/base.py", line 116, in import_default_modules
    signals.import_modules.send(sender=self.app)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/utils/dispatch/signal.py", line 166, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 69, in on_import_modules
    self.worker_fixup.validate_models()
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/kombu/utils/__init__.py", line 322, in __get__
    value = obj.__dict__[self.__name__] = self.__get(obj)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 64, in worker_fixup
    self._worker_fixup = DjangoWorkerFixup(self.app)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/celery/fixups/django.py", line 99, in __init__
    self._cache = import_module('django.core.cache')
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/core/cache/__init__.py", line 69, in <module>
    if DEFAULT_CACHE_ALIAS not in settings.CACHES:
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 54, in __getattr__
    self._setup(name)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 49, in _setup
    self._wrapped = Settings(settings_module)
  File "/home/myproj/venv/myproj/local/lib/python2.7/site-packages/django/conf/__init__.py", line 151, in __init__
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
回溯(最近一次呼叫最后一次):
文件“/home/myproj/venv/myproj/bin/芹菜”,第11行,在
sys.exit(main())
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/cellery/_main__.py”,第30行,在main中
main()
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/cellery/bin/cellery.py”,第81行,主文件
cmd.从命令行(argv)执行命令
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/celery/bin/celery.py”,第769行,从命令行执行
超级(CeleryCommand,self)。从命令行(argv)执行命令)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/bin/base.py”,第307行,从命令行执行
返回self.handle_argv(self.prog_名称,argv[1:])
handle_argv中的文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/celery/bin/celery.py”,第761行
返回self.execute(命令,argv)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/celery/bin/celery.py”,第693行,在execute中
).run_from_argv(self.prog_name,argv[1:],command=argv[0])
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/cellery/bin/worker.py”,第179行,运行时从
返回自我(*参数,**选项)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/bin/base.py”,第270行,在调用中__
ret=self.run(*args,**kwargs)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/cellery/bin/worker.py”,第212行,运行中
state\u db=self.node\u格式(state\u db,主机名),**kwargs
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/worker/_init___;.py”,第95行,在__init中__
self.app.loader.init_worker()
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/loaders/base.py”,第128行,在init_中
self.import\u默认\u模块()
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/loaders/base.py”,第116行,在导入默认模块中
signals.import\u modules.send(sender=self.app)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/utils/dispatch/signal.py”,第166行,在send中
响应=接收方(信号=自身,发送方=发送方,**已命名)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/fixups/django.py”,第69行,在线导入模块
self.worker\u fixup.validate\u models()
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/kombu/utils/__init____;.py”,第322行,在__
value=obj.\uuuu dict\uuuu[self.\uuuuuu name\uuuuu]=self.\uuuuu get(obj)
worker_fixup中的文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/fixups/django.py”,第64行
self.\u worker\u fixup=djangowerfixup(self.app)
文件“/home/myproj/venv/myproj/local/lib/python2.7/site packages/芹菜/fixups/django.py”,第99行,在__
self.\u cache=import\u模块('django.core.cache'))
文件“/usr/lib/python2.7/importlib/_init_uuu.py”,第37行,在导入模块中
__导入(名称)
文件“/home/myproj/venv/myproj/local/lib/py