docassemble 1.10.15 排错FAQ
docassemble 1.10.15 排错 FAQ 合集:登录路径与密码策略、首启慢与安全关机数据回档、访谈 YAML 高频坑(mandatory/插值/current_datetime/person.name.first/event 块/错误态缓存/Exit 按钮取值)、Web 端点路径纠错、脚本化对接与备份权限,23 问全部来自实测踩坑记录。
docassemble 1.10.15 排错FAQ
目标:把 docassemble 1.10.15 单容器全栈部署上「真实踩过并解决」的坑整理成即查即用的问答。本文每一条现象、报错原文与处置命令均来自实测环境(Ubuntu 26.04.1 LTS 宿主,compose 项目
docassemble-1.10.15-stack,容器docassemble-1.10.15-web,端口 8139→80,docassemble 1.10.15),未实测的推断一律不收录。部署与运维主线见 《docassemble 1.10.15 Docker Compose 部署指南》 与 《docassemble 1.10.15 日常运维与升级指南》。
一、环境信息
- 应用:docassemble 1.10.15(
jhpyle/docassemble官方全栈镜像,supervisord 管理 Web/uwsgi/nginx/PostgreSQL 18.6/Redis 8.0.5/RabbitMQ 4.0.5/Celery 5.6.3) - Python:3.14.4,虚拟环境
/usr/share/docassemble/local3.14;Flask 3.1.3 - 主配置:
/usr/share/docassemble/config/config.yml(实测关键值:enable playground: true、allow log viewing: true、enable api: True、exitpage: https://docassemble.org) - 数据库:
PGPASSWORD=abc123 psql -U docassemble -d docassemble -h localhost(实测 public 模式 25 张表) - 应用日志:
/usr/share/docassemble/log/docassemble.log(排障第一现场) - 演示账号:
admin@example.com/Q1w2e3r4(出厂为password,首登强制改密;q1w2e3r4会被密码策略拒绝,见 Q3)
二、登录与账号
Q1: 访问登录页 404?
A: 本版本登录路径是 /user/sign-in(实测 GET 200)。/users/signin 是旧版 Rails 风格路径写法,实测 404。管理员后台各页路径以 /interviews、/config、/logs、/monitor 为准(见 Q17、Q18)。
Q2: 出厂账号登录后被强制跳转,进不去后台?
A: 正常行为。实测 admin@example.com / password 首登成功后系统 302 到 /user/change-password?next=/interviews,必须改密。改密成功回显:200 http://localhost/interviews?from_login=1,页面 <title>Interviews</title>。
Q3: 改密时提示密码不合规? A: 密码策略实测报错原文:
Password must be at least six characters long with at least one
lowercase letter, at least one uppercase letter...
常见弱口令形态 q1w2e3r4 因缺大写字母被拒;按策略补大写(如 Q1w2e3r4)实测通过。
三、部署与启动
Q4: 部署后访问 http://localhost:8139 一直显示 "Docassemble is starting"?
A: 首启正常现象,不是故障。initialize 要跑 apt-get update、pip 依赖与 NLTK 词库下载,实测总时长约 17 分钟。观察进度:
docker logs -f docassemble-1.10.15-web 2>&1 | grep -E 'success: .* entered RUNNING'
实测时序样例(节选):
2026-11-01 07:44:05,182 INFO success: rabbitmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2026-11-01 07:44:10,923 INFO success: celery entered RUNNING state, process has stayed up for > than 5 seconds (startsecs)
就绪判据:curl -s http://localhost:8139/ | grep -oE '<title>[^<]+</title>' 从 <title>Docassemble is starting</title> 变为 <title>Default interview</title>。
Q5: 重启后配置/访谈文件回档到旧版本,或开机日志出现 initialize: unsafe shutdown detected; will not restore from backup?
A: 上次停机被强杀(docker kill、docker stop -t 1 或宿主机断电),遗留 da_running 标记触发了保护逻辑(实测 initialize.sh 段):
RESTOREFROMBACKUP=true
if [ -f /var/run/docassemble/da_running ] || [ -f /var/run/docassemble/status-rabbitmq-running ]; then
echo "initialize: unsafe shutdown detected; will not restore from backup" >&2
RESTOREFROMBACKUP=false
fi
此时盘上是「强杀前的残局」,系统故意不用 backup 覆盖。处置:若确认要以备份为准,手动把 backup 卷内 config.yml、files/、postgres/ 拷回原位再 supervisorctl start reset;预防则是 compose 里 stop_grace_period: 600s(官方 docker stop -t 600 口径),停机一律 docker compose down。
Q6: 手动 pg_dump 到备份目录报 Permission denied?
A: 实测报错原文:
pg_dump: error: could not open output file "/usr/share/docassemble/backup/manual-test.pgd": Permission denied
backup 目录属 root,postgres 用户不可直接写。官方 cron 的写法是先落 postgres 属主临时目录、再由 root rsync:
docker exec docassemble-1.10.15-web bash -lc \
'D=$(mktemp -d); chown postgres:postgres $D; \
su postgres -c "cd /tmp; pg_dump -F c -f $D/docassemble docassemble"; \
ls -la $D'
-rw-rw-r-- 1 postgres postgres 98187 Nov 1 22:34 docassemble
Q7: docker pull jhpyle/docassemble 或查 Docker Hub tag 超时?
A: 本环境实测 hub.docker.com 直连超时(curl 无回显),改走代理 192.168.1.72:7897 后 HTTP 200 成功。镜像拉取本身走宿主 Docker 守护进程既有加速器/代理配置即可;GitHub API 同理。文档站 docassemble.org 实测可直连。
四、访谈创建与运行(YAML 高频坑)
Q8: 访谈打开报 501:Docassemble has finished executing all code blocks marked as initial or mandatory, and finished asking all questions marked as mandatory (if any). It is a best practice to end your interview with a question that says goodbye.?
A: 新手第一坑,实测踩中。docassemble 是拉取模型:引擎只执行标了 initial/mandatory 的代码块,并倒推回答未定义变量所需的问题。question 块既没 mandatory: True、也没有其他块引用它产生的变量,引擎就认为「无事可做」直接抛此错。处置:给入口问题加 mandatory: True。实测修复后同一访谈正常出题(见 Q14 运行序列)。
Q9: 页面把 { person.name.first } 原样显示,不替换成值?
A: 插值必须用 ${ }(dollar-brace),单花括号不渲染,实测原样输出。正确写法:您好,${ person.name.first }!。
Q10: 用 today_datetime() 报错?
A: 实测报错原文:
reference to a variable 'today_datetime' that could not be looked up in the question file (for language 'en') or in any of the files incorporated by reference into the question file
1.10.15 已移除 today_datetime(),取当前时间用 current_datetime();且所有引擎函数需要显式导入,YAML 顶部加:
---
modules:
- docassemble.base.util
不加 modules 导入时 current_datetime() 同样报 could not be looked up(实测)。
Q11: 定义了 objects: - person: Individual,写 { person.name }/${ person.name } 仍报错?
A: 实测报错原文:
reference to a variable 'person.name.first' that could not be looked up in the question file (for language 'en') or in any of the files incorporated by reference into the question file
Individual 对象的姓名是复合属性,提问/引用都要落到 person.name.first 层级(引擎倒推时也会把 person.name 展开成 person.name.first 去查找)。fields 写法实测通过形态:- 姓名: person.name.first。
Q12: event: 块配 content: 报 No question type could be determined for this section.?
A: 实测踩中。1.10.15 中 event 块若没有可判定的问题类型(无 question/buttons/fields 等)即报此句。退出类 event 页的实测可用写法是「question + buttons」形态:
---
id: greeting
question: 您好,${ person.name.first }!这是 docassemble 实测访谈。
subquestion: |
当前服务器时间:${ current_datetime() }
buttons:
- Exit: exit
mandatory: True
Q13: 修好了 YAML,重新打开访谈仍然显示旧错误页?
A: 错误状态按「用户+访谈 URL」持久化缓存在 PG userdict 表(实测:filename=访谈 URL、key=session 的行存有错误态),改文件不会自动清。实测处置:
docker exec docassemble-1.10.15-web bash -lc \
'echo "DELETE FROM userdict WHERE filename LIKE '"'"'%g25final%'"'"';" | PGPASSWORD=abc123 psql -U docassemble -d docassemble -h localhost'
# DELETE 1
删除后刷新访谈即干净重跑。注意 interviews 表不存在(实测),别去那张表找——访谈定义在 files/playground/ 磁盘文件里,库里只有会话与审计状态。
Q14: 脚本化跑访谈时,点 Exit 按钮报 int('exit') ValueError?
A: 实测日志原文(docassemble.log):
docassemble: ip=10.89.61.1 i=docassemble.playground1:g25final.yml uid=idJ6ZcaFkHNnHosBLP38lCWw2MXjAQ4D user=admin@example.com 2026-11-01 22:20:47 Tried to run _internal["answers"]['ID greeting'] = int('exit') and got error ValueError: invalid literal for int() with base 10: 'exit'
原因:buttons 提交时表单字段 _multiple_choice 的 value 是按钮索引(实测 "0"),不是动作字符串 exit。POST 时把 exit 改成 "0" 后实测走通:POST /interview?i=docassemble.playground1:g25final.yml → 302,Location: https://docassemble.org(config.yml exitpage 生效)。
Q15: 自动化提交答案时,POST 了但答案没保存、页面退回上一题?
A: 实测踩中:请求参数里带了 _back_one=1,docassemble 把它当作「返回上一题」导航操作,跳过答案存储。脚本化提交时剔除该参数即正常。
Q16: 脚本 POST 表单返回 400:flask_wtf.csrf.CSRFError: 400 Bad Request: The CSRF token is missing.?
A: 实测日志原文即此句。docassemble 所有 Web 表单(登录、playground 保存、访谈提交)都带 csrf_token 字段,脚本必须先 GET 同一页面取 token 与 Cookie,再随 POST 提交;直接裸 POST 必 400。登录流程实测形态:GET /user/sign-in 取 csrf_token → POST email/password/csrf_token → 302 即登录成功。
五、Web 端点与运维集成
Q17: 日志页/监控页 404?
A: 路径实测:/logs 200(<title>Logs</title>,受 allow log viewing: true 控制);/log 404。监控页是 /monitor 200(<title>Monitor</title>);/manage 实测 404。管理员侧栏入口以登录页实测链接为准:/config、/interviews、/playground、/user/sign-in。
Q18: 想脚本化新建 Playground 访谈,/playground/create-new 404?
A: 实测该路径不存在。Playground 页面(/playground?project=default,实测 <title>Playground</title>)的全部操作都 POST 回同一端点,表单字段实测为:playground_name(文件名)、playground_content(内容)、status、csrf_token、submit(按钮值,如 Save)。新建/保存成功后响应页仍是 <title>Playground</title>,文件落盘位置实测 /usr/share/docassemble/files/playground/1/<名字>.yml。
Q19: 容器里找不到 docassemble 命令行工具?
A: 设计如此,不是安装缺损。实测 docassemble --help 返回 executable file not found in $PATH(exit 127),venv bin/ 与 webapp 包均无 CLI 入口。管理面就是四件套:supervisorctl(进程)、psql(数据)、redis-cli(缓存)、Web 后台(/config、/logs、/monitor、/playgroundpackages?project=default)。
Q20: 听说 docassemble 全文检索要配 Elasticsearch,容器里找不到? A: 实测本镜像不含 Elasticsearch:supervisorctl 全单元清单(20 项)与进程列表均无 ES 相关条目。docassemble 的搜索走 PostgreSQL 自身,无需额外部署 ES。
Q21: 调 API 返回 404?
A: 实测 GET http://localhost:8139/api(不带密钥)直接返回 404 HTML 页而非 401/403 JSON——容易误判为「API 没开」。config.yml 实测 enable api: True 时 API 已启用,正确调用必须带 api_key 参数(密钥签发方式见官方 API 文档,本文「六、参考链接」),如 GET /api/interview?i=docassemble.playground1:g25final.yml&api_key=<密钥>。另外注意访谈页本身匿名可开(实测未登录 GET /interview?i=docassemble.playground1:g25final.yml 返回 200),这与 API 鉴权是两套体系。
Q22: curl 上传 YAML 到 playground,存进去的内容是字面量 @g25final.yml?
A: --data-urlencode 的文件展开语法是 field@file(没有等号)。写成 --data-urlencode 'playground_content=@g25final.yml' 会把 @g25final.yml 当字面量提交(实测踩中,playground 里存进的就是这串字符)。正确示例(端点与字段名实测见 Q18):
curl -s -b jar.txt \
--data-urlencode 'playground_content@g25final.yml' \
--data-urlencode 'playground_name=g25final.yml' \
--data-urlencode 'csrf_token=<TOKEN>' \
--data-urlencode 'submit=Save' \
'http://localhost:8139/playground?project=default'
Q23: 改了 config.yml 或装了扩展包,行为没变化?
A: 配置与包变更需要重载应用进程才生效。实测两种生效动作:轻量改动 supervisorctl restart uwsgi;涉及包/引擎行为 supervisorctl start reset(一次性程序,并行重启 uwsgi/websockets/celery/rabbitmq,实测回显 reset: started,随后 celery STARTING→RUNNING,uwsgi/nginx 进程号不变)。环境变量类(DAHOSTNAME 等)只在开机生成 config.yml 时生效,改它们要 docker compose up -d 重建容器。
六、参考链接
- 官方文档索引:https://docassemble.org/docs/functions.html
- 官方访谈编写文档(拉取模型说明):https://docassemble.org/docs/interviews.html
- 官方 Docker 文档:https://docassemble.org/docs/docker.html
- 官方配置文档:https://docassemble.org/docs/config.html
- 官方 API 文档:https://docassemble.org/docs/api.html
- GitHub 仓库(Issue 检索同类报错):https://github.com/jhpyle/docassemble/issues