使用Docker运行Cookiecutter时Jinja2模板无法渲染求助
核心原因
Cookiecutter的处理逻辑是先加载cookiecutter.json收集用户输入,再执行模板渲染。因此cookiecutter.json里的Jinja模板语法不会被解析,你定义的_project_name_snake_case会被当作纯字符串,导致后续目录名和文件里的模板无法正确替换。
解决方案
方案一:用预生成钩子动态生成变量
通过Cookiecutter的钩子机制,在模板渲染前自动生成蛇形命名变量:
- 在项目根目录新建
hooks文件夹,创建pre_gen_project.py文件:
import os # 获取用户输入的项目名称 project_name = os.environ.get('COOKIECUTTER_PROJECT_NAME') # 转换为蛇形命名 snake_case_name = project_name.lower().replace(' ', '_') # 将结果写入环境变量,供后续模板调用 os.environ['COOKIECUTTER__PROJECT_NAME_SNAKE_CASE'] = snake_case_name
- 简化
cookiecutter.json,只保留用户输入项:
{ "project_name": "My Awesome Project" }
- 项目结构更新为:
mldev_template/ ├── Dockerfile.cookiecutter ├── entrypoint.sh ├── cookiecutter.json ├── hooks/ │ └── pre_gen_project.py └── {{cookiecutter._project_name_snake_case}}/ └── Dockerfile
方案二:直接在模板中使用过滤器
放弃在cookiecutter.json里预定义变量,直接在目录名和文件中用Jinja过滤器实现转换:
- 保持原目录名
{{ cookiecutter.project_name | lower | replace(' ', '_') }}不变 - 修改目录内的Dockerfile:
FROM python:3.10-slim LABEL project="{{ cookiecutter.project_name | lower | replace(' ', '_') }}"
- 简化
cookiecutter.json:
{ "project_name": "My Awesome Project" }
Docker运行优化
你当前需要手动进入容器执行命令,可以修改entrypoint.sh自动执行,无需交互进入容器:
#!/bin/bash # 指定生成目录到挂载的/workspace下,方便本地查看 cookiecutter /workspace/mldev_template --output-dir /workspace/generated
运行容器时直接执行:
docker run -it --rm -v $(pwd)/..:/workspace cookiecutter-runner
输入项目名后,生成的模板会直接出现在本地../generated目录下。
验证步骤
- 重新构建镜像:
docker build --no-cache -f Dockerfile.cookiecutter -t cookiecutter-runner .
- 运行容器并输入项目名(例如
Test Project) - 检查本地
../generated目录,会生成test_project文件夹,内部Dockerfile的LABEL project值为test_project。
内容的提问来源于stack exchange,提问作者JRL
相关产品推荐
相关产品推荐

