You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker本地开发Django Cookie-Cutter容器遇错崩溃的解决方法

问题描述

我在Docker中搭建了本地开发用的Django Cookie-Cutter环境,搭配VSCode devcontainer使用时,代码修改能被追踪并自动重载,但出现语法或其他错误时,整个容器会以代码1退出,导致其他存活容器引发连锁错误,Django容器直接停止。

这是基础的Django Cookie-Cutter安装环境,仅做了两处修改:

  • 修改compose/local/django/start脚本为:
exec python manage.py runserver_plus --reloader-interval 3
--reloader-type stat 0.0.0.0:8000
  • 移除本地依赖中的watchdog,替换为:
Werkzeug==3.0.3

需要实现:代码修改自动重载、错误日志记录,同时保持容器和服务器持续运行。

容器日志参考:

2024-07-10 13:57:55 Operations to perform:
2024-07-10 13:57:55   Apply all migrations: account, admin, auth, contenttypes, django_celery_beat, mfa, sessions, sites, socialaccount, users
2024-07-10 13:57:55 Running migrations:
2024-07-10 13:57:55   No migrations to apply.
2024-07-10 13:57:55   Your models in app(s): 'core' have changes that are not yet reflected in a migration, and so won't be applied.
2024-07-10 13:57:55   Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
2024-07-10 13:58:01 Performing system checks...
2024-07-10 13:58:01 
2024-07-10 13:58:01 System check identified no issues (0 silenced).
2024-07-10 13:58:01 
2024-07-10 13:58:01 Django version 4.2.13, using settings 'config.settings.local'
2024-07-10 13:58:01 Development server is running at http://0.0.0.0:8000/
2024-07-10 13:58:01 Using the Werkzeug debugger (https://werkzeug.palletsprojects.com/)
2024-07-10 13:58:01 Quit the server with CONTROL-C.
2024-07-10 13:57:42 PostgreSQL is available
2024-07-10 13:57:42 /start: line 1: local: can only be used in a function
2024-07-10 13:57:59 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
2024-07-10 13:57:59  * Running on all addresses (0.0.0.0)
2024-07-10 13:57:59  * Running on http://127.0.0.1:8000
2024-07-10 13:57:59  * Running on http://172.18.0.7:8000
2024-07-10 13:57:59 Press CTRL+C to quit
2024-07-10 13:57:59  * Restarting with stat
2024-07-10 13:58:02  * Debugger is active!
2024-07-10 13:58:02  * Debugger PIN: 146-133-257
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /test HTTP/1.1" 200 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/css/project.css HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/debug_toolbar/js/toolbar.js HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/debug_toolbar/css/print.css HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/debug_toolbar/css/toolbar.css HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/js/project.js HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/debug_toolbar/js/utils.js HTTP/1.1" 304 -
2024-07-10 13:58:37 172.18.0.1 - - [10/Jul/2024 13:58:37] "GET /static/images/favicons/favicon.ico HTTP/1.1" 304 -
2024-07-10 13:58:50  * Detected change in '/app/core/templates/core/idx.html', reset template loaders
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /test HTTP/1.1" 200 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/debug_toolbar/js/toolbar.js HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/debug_toolbar/css/toolbar.css HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/debug_toolbar/css/print.css HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/css/project.css HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/js/project.js HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/debug_toolbar/js/utils.js HTTP/1.1" 304 -
2024-07-10 13:59:03 172.18.0.1 - - [10/Jul/2024 13:59:03] "GET /static/images/favicons/favicon.ico HTTP/1.1" 304 -
2024-07-10 13:59:27  * Detected change in '/app/core/models.py', reloading
2024-07-10 13:59:27  * Restarting with stat
2024-07-10 13:59:31 Traceback (most recent call last):
2024-07-10 13:59:31   File "/app/manage.py", line 32, in <module>
2024-07-10 13:59:31     execute_from_command_line(sys.argv)
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
2024-07-10 13:59:31     utility.execute()
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/site-packages/django/core/management/__init__.py", line 416, in execute
2024-07-10 13:59:31     django.setup()
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/site-packages/django/__init__.py", line 24, in setup
2024-07-10 13:59:31     apps.populate(settings.INSTALLED_APPS)
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/site-packages/django/apps/registry.py", line 116, in populate
2024-07-10 13:59:31     app_config.import_models()
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/site-packages/django/apps/config.py", line 269, in import_models
2024-07-10 13:59:31     self.models_module = import_module(models_module_name)
2024-07-10 13:59:31                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-07-10 13:59:31   File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
2024-07-10 13:59:31     return _bootstrap._gcd_import(name[level:], package, level)
2024-07-10 13:59:31            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-07-10 13:59:31   File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
2024-07-10 13:59:31   File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
2024-07-10 13:59:31   File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
2024-07-10 13:59:31   File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
2024-07-10 13:59:31   File "<frozen importlib._bootstrap_external>", line 995, in exec_module
2024-07-10 13:59:31   File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
2024-07-10 13:59:31   File "/app/core/models.py", line 8, in <module>
2024-07-10 13:59:31     dksfj
2024-07-10 13:59:31 NameError: name 'dksfj' is not defined
解决方案

1. 给启动脚本添加循环重启逻辑

直接用循环包裹runserver_plus命令,确保进程因错误退出后自动重启,容器保持存活状态:
修改compose/local/django/start脚本为:

#!/usr/bin/env bash

set -o errexit
set -o pipefail
set -o nounset

while true; do
    python manage.py runserver_plus --reloader-interval 3 --reloader-type stat 0.0.0.0:8000
    echo "服务器意外退出,5秒后尝试重启..."
    sleep 5
done

这样即使代码错误导致进程崩溃,容器也会持续运行,自动重试直到错误修复。

2. 恢复watchdog依赖,使用更可靠的重载器

stat类型重载器对错误的容忍度较低,恢复watchdog后改用它的重载器,能更精准监听文件变化,且遇到非致命错误时不会直接终止进程:

  • 在本地依赖文件中恢复:
watchdog>=3.0.0
Werkzeug==3.0.3
  • 修改启动脚本的重载器参数:
python manage.py runserver_plus --reloader-interval 3 --reloader-type watchdog 0.0.0.0:8000

3. 配置Docker容器自动重启策略

在docker-compose.yml中给Django服务添加重启规则,让Docker在容器意外退出时自动重启:

services:
  django:
    # 其他配置保持不变
    restart: unless-stopped

4. 增强Django日志记录

在config/settings/local.py中配置详细日志,确保错误信息完整输出到容器日志,方便排查:

import os

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'DEBUG',
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': False,
        },
    },
}

内容的提问来源于stack exchange,提问作者dedepene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:59:50