使用 docker 内的 WeasyPrint 导出 PDF 中的字体 (FastAPI)

sth*_*eli 4 python docker weasyprint fastapi

我有一个在 Docker 容器内运行的应用程序。该服务是使用 FastAPI 框架编写的,用于生成报告。我们首先生成一个 HTML 报告,然后使用 Wea​​syprint 库将其转换为 PDF。当我在笔记本电脑上执行它时(我使用的是 Manjaro Linux),一切都运行良好。但是,当我在 docker 容器内使用 API 时,我注意到生成的 PDF 中的字体不同。在 CSS 文件中,我们使用 Helvetica 字体系列、无衬线字体。因此,当在容器内生成报告时,无衬线字体不起作用。

此外,我已将我的字体文件夹(从我的笔记本电脑)复制到 Docker 容器中,以检查它是否缺少某些字体;然而,无衬线字体仍然不起作用。

这是我的 Dockerfile:

FROM tiangolo/uvicorn-gunicorn-fastapi

RUN apt-get update && apt-get install -y build-essential unzip vim git curl locales orca
RUN apt install -y python3-cffi libcairo2 libcairo2-dev libpango-1.0-0 libpango1.0-dev libpangocairo-1.0-0 libgdk-pixbuf2.0-0 \
                   libgdk-pixbuf2.0-dev libffi-dev shared-mime-info libffi-dev fonts-font-awesome

RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
    locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

ARG RELEASE=main
RUN git clone <my_repo>
RUN cd ./<repo> && pip install -r requirements.txt

EXPOSE 80
WORKDIR /app/<repo>/app

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--workers", "4"]
Run Code Online (Sandbox Code Playgroud)

以及我安装的Python库(在requirements.txt中):

numpy==1.20.3
pandas==1.2.4
plotly==4.14.3
kaleido==0.2.1
weasyprint==52.5
Jinja2==3.0.1
fastapi==0.65.2
uvicorn==0.14.0
pydantic==1.8.2
psutil==5.8.0
python-multipart==0.0.5
aiofiles==0.7.0
SQLAlchemy==1.4.22
async-exit-stack==1.0.1
async-generator==1.10
mysqlclient==2.0.3
Run Code Online (Sandbox Code Playgroud)

因为我可以在我的笔记本电脑上很好地生成它,所以我假设缺少一些库(我也尝试安装 fonts-open-sans 和 libglib2.0-dev,但没有任何改变)或者有问题某个版本。例如,我检查了WeasyPrint文档,pango应该是1.44.0版本或更高版本,而在Debian 10(docker中的操作系统)中,包libpango-1.0-0使用pango 1.42.0版本。这可能是为什么 sans-serif 不起作用的问题,或者是我缺少什么的想法吗?

rzl*_*vmp 6

好的,我为你做了一些工作;)

我使用以下命令构建了映像并启动了 docker 容器:

FROM tiangolo/uvicorn-gunicorn-fastapi

RUN apt-get update && apt-get install -y build-essential unzip vim git curl locales orca
RUN apt install -y python3-cffi libcairo2 libcairo2-dev libpango-1.0-0 libpango1.0-dev libpangocairo-1.0-0 libgdk-pixbuf2.0-0 \
                   libgdk-pixbuf2.0-dev libffi-dev shared-mime-info libffi-dev fonts-font-awesome

RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
    locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

COPY app.py .
COPY template .
COPY requirements.txt .
RUN pip install -r requirements.txt

EXPOSE 80

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--workers", "4"]
Run Code Online (Sandbox Code Playgroud)

requirements.txt你的一样,template是直接从这里复制的。

并且app.py

FROM tiangolo/uvicorn-gunicorn-fastapi

RUN apt-get update && apt-get install -y build-essential unzip vim git curl locales orca
RUN apt install -y python3-cffi libcairo2 libcairo2-dev libpango-1.0-0 libpango1.0-dev libpangocairo-1.0-0 libgdk-pixbuf2.0-0 \
                   libgdk-pixbuf2.0-dev libffi-dev shared-mime-info libffi-dev fonts-font-awesome

RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
    locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

COPY app.py .
COPY template .
COPY requirements.txt .
RUN pip install -r requirements.txt

EXPOSE 80

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--workers", "4"]
Run Code Online (Sandbox Code Playgroud)

正如您在下面看到的(我将 pdf 重命名为 png 以便能够附加)所有字体都是不同的。您的容器中没有问题。

在此输入图像描述