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

如何让Flask容器从另一个Docker容器中渲染HTML页面?

解决方案

核心问题分析

你遇到的TemplateNotFound错误,本质是Flask默认从自身容器内的templates目录查找模板文件,但目标HTML文件存放在另一个流水线容器中,且Flask未配置正确的文件访问路径。要实现需求,需要完成容器间文件共享和Flask路由/模板路径配置两步。


步骤1:实现容器间文件共享

使用Docker卷(推荐)或绑定挂载,将流水线容器中存放HTML的training/metadata目录共享给Flask容器:

方式1:使用Docker卷(适合生产环境)

  1. 创建一个专用卷:
docker volume create html_shared_volume
  1. 启动流水线容器时,将training/metadata目录挂载到卷:
docker run -d -v html_shared_volume:/path/to/training/metadata your-pipeline-image

(替换/path/to/training/metadata为流水线容器内实际的目录路径)

  1. 启动Flask容器时,同样挂载该卷到容器内的指定目录(比如/app/shared_metadata):
docker run -d -v html_shared_volume:/app/shared_metadata -p 5002:5002 your-flask-image

方式2:使用绑定挂载(适合开发调试)

如果是本地开发,可直接将主机上的目录作为中间层共享(假设流水线容器的training/metadata目录映射到主机的./local_metadata):

# 启动流水线容器
docker run -d -v ./local_metadata:/path/to/training/metadata your-pipeline-image

# 启动Flask容器
docker run -d -v ./local_metadata:/app/shared_metadata -p 5002:5002 your-flask-image

步骤2:配置Flask应用访问共享文件

根据你的需求,有两种实现方式:直接返回静态HTML文件(推荐,因为HTML是预先生成的),或修改Flask模板搜索路径。

方式1:直接返回静态HTML文件(无需Jinja渲染)

这种方式更高效,适合预先生成的静态HTML:

from flask import Flask, send_from_directory, abort

app = Flask(__name__)
# 共享目录在Flask容器内的路径
SHARED_METADATA_DIR = '/app/shared_metadata'

@app.route('/<dir_type>/<num>/<file_name>')
def serve_html(dir_type, num, file_name):
    # 校验目录类型,防止路径遍历攻击
    if dir_type not in ['evaluation', 'validation']:
        abort(403, description="Invalid directory type")
    
    # 构造完整文件路径
    target_file = f"{dir_type}/{num}/{file_name}.html"
    try:
        return send_from_directory(SHARED_METADATA_DIR, target_file)
    except FileNotFoundError:
        abort(404, description="HTML file not found")

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5002)

方式2:修改Flask模板搜索路径(使用Jinja渲染)

如果需要Jinja模板的动态渲染能力(比如后续要添加变量),可以将共享目录添加到Flask的模板路径:

from flask import Flask, render_template, abort

app = Flask(__name__)
# 将共享目录设置为模板目录
app.template_folder = '/app/shared_metadata'

@app.route('/<dir_type>/<num>/<file_name>')
def render_html(dir_type, num, file_name):
    if dir_type not in ['evaluation', 'validation']:
        abort(403, description="Invalid directory type")
    
    template_path = f"{dir_type}/{num}/{file_name}.html"
    try:
        return render_template(template_path)
    except:
        abort(404, description="Template file not found")

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5002)

注意事项

  1. 权限问题:确保流水线容器生成的HTML文件和目录权限允许Flask容器读取。可以让两个容器使用相同的UID/GID运行,或在流水线容器中设置文件权限为644、目录权限为755。
  2. 路径遍历防护:路由中添加dir_type校验,避免恶意请求访问共享目录外的文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:38:21