【问题标题】:Library wkhtmltopdf is not working inside Docker库 wkhtmltopdf 在 Docker 中不起作用
【发布时间】:2021-07-20 20:12:26
【问题描述】:

我在 Python Flask 中有一个代码,我在其中使用 HTML 模板生成 pdf 文件。当我单独运行代码时,代码工作得很好,但是当我尝试在 Docker 容器中运行它时,只要我调用生成报告的端点,docker 就会崩溃并重置。它只是保持加载,然后返回一个错误(在我用来测试的 Postman 中)。

PDF的代码如下:

def create_report(download_uuid):
    transactions = get_transaction_for_report(download_uuid)
    config = pdfkit.configuration(wkhtmltopdf=environ.get('WKHTMLTOPDF'))

    file_obj = io.BytesIO()
    with zipfile.ZipFile(file_obj, 'w') as zip_file:
        for transaction in transactions:
            html = render_template("report.html", transaction=transaction)
            pdf = pdfkit.from_string(html, False, configuration=config)
            data = zipfile.ZipInfo('{}.pdf'.format(transaction['control_number']))
            data.compress_type = zipfile.ZIP_DEFLATED
            zip_file.writestr(data, pdf)
    file_obj.seek(0)
    return send_file(file_obj, attachment_filename="forms.zip", as_attachment=True)

它返回一个 zip 文件,但 zip 文件内是 pdf 文件。此外,如果我删除 pdf 生成部分,则 zip 文件返回就好了。这是我的 Dockerfile:

FROM madnight/docker-alpine-wkhtmltopdf as wkhtmltopdf_image
FROM python:3.9-alpine

RUN adduser -D custom

WORKDIR /home/Project

COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --upgrade pip
RUN apk add make automake gcc g++ subversion python3-dev jpeg-dev zlib-dev libffi-dev musl-dev openssl-dev freetype freetype-dev ttf-freefont libxrender qt5-qtbase-dev
RUN venv/bin/pip install -r requirements.txt
RUN venv/bin/pip install gunicorn

COPY Project Project
COPY boot.sh app.py .env run.py create_database.py config.py ./
COPY templates templates
COPY static static
COPY --from=wkhtmltopdf_image /bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
RUN chmod +x boot.sh

ENV FLASK_APP app.py

USER root
RUN chown -R custom ./
USER custom

EXPOSE 9001
ENTRYPOINT ["./boot.sh"]

我应该说这是许多尝试让它发挥作用的最后一次迭代。本质上,我尝试通过 curl 获取 wkhtmltox,我尝试将 wkhtmltopdf 放在不同的目录中。到目前为止,没有任何效果。我不知道我错过了什么。为了完成这个项目,这基本上是我需要解决的问题,所以任何帮助都将不胜感激。

编辑:docker-compose.yml

version: '2'
services:
  app:
    build: .
    networks:
      - custom
    ports:
      - "9001:9001"
    volumes:
      - "./static:/home/EventismedEquipmentAPI/static"
    external_links:
      - eventismed-equipment:db
networks:
  custom:
    external: true

【问题讨论】:

  • docker logs [your_container_name] 的输出是什么?
  • app_1 | [2021-04-27 13:32:24 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:23) app_1 | [2021-04-27 09:32:24 -0400] [23] [INFO] Worker exiting (pid: 23) app_1 | [2021-04-27 13:32:24 +0000] [24] [INFO] Booting worker with pid: 24 那,然后它重新启动。
  • 您还需要更多信息吗?请我有点急于解决这个问题。
  • gist.github.com/cornernote/09221c5896d36133c3f36ecc13c928aa 展示了一种在 docker 中使用 wkhtmltopdf 的方法。研究并尝试将其应用到您的项目中。您的问题中缺少几条数据,但我认为您可以先执行此操作。
  • 那么@plasmy 你做到了吗?

标签: docker flask wkhtmltopdf pdfkit


【解决方案1】:

让我们解决这个问题。

我已经成功地在一个 docker 容器上运行了wkhtmltopdf。

Dockerfile:

# https://stackoverflow.com/a/62737156/152016
# Create image based on the official openjdk 8-jre-alpine image from the dockerhub
FROM openjdk:8-jre-alpine

# Install wkhtmltopdf
# https://stackoverflow.com/a/56925361/152016
RUN apk add --no-cache wkhtmltopdf ttf-dejavu

ENTRYPOINT ["sh"]

docker-compose.yml:

version: '3.8'

services:
  wkhtmltopdf:
    image: wkhtmltopdf
    container_name: wkhtmltopdf
    build:
      dockerfile: Dockerfile
      context: .

然后:

docker-compose build
docker run -ti --rm -v /tmp:/tmp wkhtmltopdf

容器内:

$ cd /tmp
$ wkhtmltopdf https://www.google.com test.pdf

然后你会在你的 mac 上看到 pdf /tmp/test.pdf

首先让我知道这是否有效。

【讨论】:

  • 是的,这很完美:) 但是有什么办法可以将它与我的项目集成?
  • 你的 python docker 镜像也在 alpine 上运行。所以你可以去掉第一个FROM和COPY --from=wkhtmltopdf,在你原来的RUN apk add上添加2个包wkhtmltopdf ttf-dejavu,将入口点更改为ENTRYPOINT ["sh"]进行测试,然后运行docker run命令我告诉你,并在新图像中生成另一个 pdf 以测试孤立的 pdf 创建。
  • 所以我尝试了这个,我得到了以下结果:QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-eventismed' Loading page (1/2) Error compiling builtin: ] 30% Fatal error compiling builtin function 'apply': Segmentation fault 我还有一个我使用的 docker-compose 文件,我将其编辑为主要问题
  • 早上好@Niloct。首先,我要感谢您为我提供的一切帮助。我昨晚熬夜到很晚,我设法解决了它。问题从来不是 WKHTML,而是我使用的 html 文件。出于某种原因,我对静态图像或文件的任何引用都会导致进程崩溃。我在 jinja2 中使用标准方式,使用 url_for。我不得不改变它,一切都像一个魅力。我不敢相信我花了这么长时间才弄清楚这一点。但我非常感谢您的帮助和跟进。
  • 我愿意。我非常感谢你@Niloct。我很少在这个网站上找到像你这样乐于助人的人。希望我们可以在其他时间重合。你似乎是我可以从中学到很多东西的人。
猜你喜欢
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2017-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多