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

Heroku部署Django项目时找不到pdflatex生成的PDF文件

问题根因

报错的核心原因是pdflatex进程根本没在指定路径生成texput.pdf,本地能跑通但线上失败的差异来自Heroku平台的固有特性,和你列的三个猜测方向完全对应:

  • Heroku基础运行镜像默认不带LaTeX发行版,本地能跑是因为本地安装了TeX环境,线上直接调用pdflatex会触发命令不存在的错误,你的代码没有捕获进程返回值和错误流,完全感知不到执行失败。
  • Heroku dyno的文件系统是临时分层结构,除/tmp目录外,其余项目目录在运行时是只读的,往templates、media这类目录写文件会直接触发权限错误;就算写入成功,dyno重启、重新部署、扩缩容时所有本地文件都会被清空,且多dyno实例之间文件完全不共享。另外你通过heroku run bash登录的是全新的一次性dyno,和处理请求的业务dyno文件系统完全隔离,自然找不到业务进程生成的文件。
  • 你调用pdflatex时没有指定固定任务名,本地默认生成texput.pdf不代表线上环境默认输出文件名一致,工作目录、环境变量差异都可能导致输出文件名/路径偏移。

修复&排查步骤

1. 先补全进程错误捕获,定位具体失败点

不要静默执行subprocess命令,把标准输出、错误流、返回码都打在日志里,一眼就能看到失败原因:

import os
import subprocess
from subprocess import PIPE
from pathlib import Path

def createPDF(name):
    # 临时文件统一用/tmp目录,这是Heroku运行时唯一可写的临时路径
    tmp_dir = '/tmp'
    template = get_template('src.tex')
    context = {'content': name}
    rendered_tpl = template.render(context).encode('utf-8')

    process = subprocess.Popen(
        # 加-jobname固定输出文件名,强制指定输出目录到/tmp
        ['pdflatex', '-output-directory', tmp_dir, '-jobname', 'cv_output'],
        stdin=PIPE,
        stdout=PIPE,
        stderr=PIPE,
        cwd=tmp_dir
    )
    # 加超时避免进程卡死
    stdout, stderr = process.communicate(rendered_tpl, timeout=30)
    # 打印调试信息,直接看Heroku日志即可
    print(f"pdflatex执行返回码: {process.returncode}")
    print(f"pdflatex标准输出: {stdout.decode('utf-8', errors='ignore')}")
    print(f"pdflatex错误输出: {stderr.decode('utf-8', errors='ignore')}")

    # 遍历/tmp下的pdf文件,确认生成结果
    for f in os.listdir(tmp_dir):
        if f.endswith('.pdf'):
            pdf_path = os.path.join(tmp_dir, f)
            print(f"找到生成的PDF文件: {f}, 文件大小: {os.path.getsize(pdf_path)}字节")

部署后触发一次函数,看Heroku日志:如果返回码是127,就是环境里没有pdflatex;如果是权限错误,就是之前写的目录不可写。

2. 补全线上LaTeX运行环境

Heroku基础镜像不带pdflatex,需要在应用中添加TeX环境对应的buildpack,确保运行时可以正常调用pdflatex命令。

3. 修正文件存储逻辑

绝对不要在Heroku本地磁盘存持久化文件:

  • 临时生成的PDF全部写到/tmp目录,不要往项目内置的templates、media目录写任何运行时生成的内容。
  • 如果需要持久保存PDF,生成后立刻把文件上传到外部对象存储服务,不要存在本地磁盘。
  • 如果只是需要把PDF返回给用户下载,直接读取/tmp下生成的PDF字节流返回HttpResponse即可,不用落盘到项目目录。

对你列出的三个猜测的明确答复
  • 关于PDF未创建:90%以上概率是这个原因,要么pdflatex命令不存在,要么目录无写入权限,用上面的错误捕获代码可以直接定位具体错误。
  • 关于文件名不符合预期:调用pdflatex时加上-jobname 固定名称参数,就能强制输出文件名为固定名称.pdf,不需要依赖默认命名规则。
  • 关于文件存储路径偏移:强制指定-output-directory为/tmp,同时设置进程工作目录为/tmp,就不会出现路径错乱的问题;不要通过bash找文件,因为登录的bash是独立dyno,和业务进程的文件系统不互通,直接看日志打印的文件遍历结果即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:06:29