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
相关产品推荐
相关产品推荐

