如何在 Docker 中运行 Aspose.Slides
概述
Aspose.Slides for Python via .NET 在 Linux 容器中运行,但该软件包是围绕打包的 .NET Core 3.1 运行时的 Python 包装器。该运行时需要三个原生库,而精简的 Python 镜像并未包含这些库,并且对它们的版本有特定要求。本文提供了可工作的 Dockerfile,解释每个依赖项的来源,并展示如何添加字体和许可证。
可工作的 Dockerfile
FROM python:3.11-slim-bullseye
RUN apt-get update && apt-get install -y --no-install-recommends \
libgdiplus \
libicu67 \
libfontconfig1 \
fonts-dejavu-core \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir aspose.slides
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
app.py:
import aspose.slides as slides
with slides.Presentation() as presentation:
slide = presentation.slides[0]
shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 400, 100)
shape.text_frame.text = "Created inside a Docker container"
presentation.save("output.pptx", slides.export.SaveFormat.PPTX)
presentation.save("output.pdf", slides.export.SaveFormat.PDF)
构建并运行:
docker build -t aspose-slides-python .
docker run --rm aspose-slides-python
为什么基础镜像是 Debian 11
aspose.slides wheel 打包了 .NET Core 3.1 运行时,而该运行时早于当前 Debian 发行版所提供的库版本。 在 Debian 12 和 13 上容器能够成功构建,但在第一次调用 Presentation() 时会失败:
Process terminated. Couldn't find a valid ICU package installed on the system.
该信息具有误导性——这些镜像中确实已安装 ICU,只是版本是 72 或 76,而 .NET Core 3.1 只能识别较旧的主版本。Debian 12 另外还提供 OpenSSL 3,导致第二个错误:
No usable version of libssl was found
python:3.11-slim-bullseye 是基于 Debian 11 的镜像,提供了捆绑运行时所期待的两个版本:
| 包 | Debian 11 上的版本 | 需要原因 |
|---|---|---|
libgdiplus |
6.0.4 | 用于渲染形状、文本和图像的 GDI+ 实现 |
libicu67 |
67.1 | 区域化数据。更新的主版本 .NET Core 3.1 不识别 |
libssl1.1 |
1.1.1w | 加密库。已预装在 Debian 11 上,Debian 12 及以上缺失 |
libfontconfig1 |
— | 字体发现 |
libssl1.1 已在基础镜像中存在,因此不需要在 apt-get install 中列出。
如果必须使用更新的基础镜像,可设置 DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 以绕过 ICU 要求。此设置会禁用特定文化的格式化,但 不能 解决 OpenSSL 问题,所以 Debian 11 仍是更简单的选择。
字体
精简镜像根本不包含任何字体。若未安装至少一种字体,文本在 PDF、图像和 HTML 输出中会显示为空白框。fonts-dejavu-core 是一个小巧且通用的起点。
为了匹配演示文稿的预期外观,可将演示文稿使用的字体复制到镜像中,并让 Aspose.Slides 使用这些字体:
COPY fonts/ /usr/share/fonts/truetype/custom/
RUN fc-cache -f
import aspose.slides as slides
slides.FontsLoader.load_external_fonts(["/usr/share/fonts/truetype/custom/"])
容器内的许可证
不要将许可证文件构建进镜像——任何拉取镜像的人都能获得许可证。应在运行时挂载:
docker run --rm -v /path/on/host:/license aspose-slides-python
import aspose.slides as slides
license = slides.License()
license.set_license("/license/Aspose.Slides.Python.NET.lic")
未提供许可证时,库会以评估模式运行,在输出中添加水印并限制可处理的幻灯片数量。详情请参阅许可证。
内存
渲染为 PDF 或图像比读取文件更消耗内存。内存限制严格的容器可能在转换过程中被 OOM killer 终止,表现为进程消失且没有 Python 堆栈信息。如果出现这种情况,请先提升容器的内存限制,再调查代码。