How-to guides/Cloud & Serverless

Run PDFluent in a Docker container

PDFluent has no native dependencies. The Docker image is small and requires no additional apt packages.

rust
# Dockerfile
FROM rust:1.78-slim AS builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/pdf-processor /usr/local/bin/
ENTRYPOINT ["pdf-processor"]
Install:cargo add pdfluentDownload SDK →

Step by step

1

Create a minimal Rust project

Your binary reads PDF bytes from stdin or a file path passed as an argument and writes results to stdout.

rust
# Cargo.toml
[package]
name = "pdf-processor"
version = "0.1.0"
edition = "2021"

[dependencies]
pdfluent = "0.9"
2

Write a simple PDF processing binary

Accept the file path as a command-line argument. Process the document and print results to stdout.

rust
// src/main.rs
use pdfluent::PdfDocument;
use std::env;

fn main() -> pdfluent::Result<()> {
    let path = env::args().nth(1).expect("usage: pdf-processor <file.pdf>");
    let doc = PdfDocument::open(&path)?;

    println!("pages: {}", doc.page_count());
    println!("title: {:?}", doc.metadata().title());
    println!("chars: {}", doc.extract_text()?.len());

    Ok(())
}
3

Write a multi-stage Dockerfile

The builder stage compiles the binary. The final stage copies only the binary into a minimal debian image. No Rust toolchain ships in the final image.

rust
# Dockerfile
FROM rust:1.78-slim AS builder
WORKDIR /app

# Cache dependencies first
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main(){}" > src/main.rs
RUN cargo build --release
RUN rm -f target/release/deps/pdf_processor*

# Build the real binary
COPY src ./src
RUN cargo build --release

# Final image
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends     ca-certificates && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/target/release/pdf-processor /usr/local/bin/
ENTRYPOINT ["pdf-processor"]
4

Build and test the image locally

Build the image and run it with a test PDF mounted as a volume.

rust
docker build -t pdf-processor:latest .

# Run with a local PDF
docker run --rm   -v "$(pwd)/samples:/data"   pdf-processor:latest   /data/test.pdf
5

Use a musl target for a fully static binary

If your final base image is scratch or alpine, build a statically linked musl binary. This eliminates the glibc version dependency.

rust
# Dockerfile (scratch variant)
FROM rust:1.78-slim AS builder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt-get update && apt-get install -y musl-tools
WORKDIR /app
COPY . .
RUN cargo build --release --target x86_64-unknown-linux-musl

FROM scratch
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/pdf-processor /
ENTRYPOINT ["/pdf-processor"]

Notes and tips

  • The debian:bookworm-slim final image is about 80 MB. The scratch variant is about 5 MB (binary only).
  • PDFluent does not call fontconfig, freetype, or any system font libraries. Font data is embedded in the crate.
  • For processing PDFs that require CJK fonts, ensure the font bytes are compiled into the binary or mounted as a volume.
  • Use COPY --chown in the Dockerfile to run the binary as a non-root user in production.

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions