Skip to content

feat(docker): add multi-stage CLI image and CI smoke test - #40

Open
nitishagar wants to merge 1 commit into
firecrawl:mainfrom
nitishagar:feat/issue-11-docker-cli
Open

feat(docker): add multi-stage CLI image and CI smoke test#40
nitishagar wants to merge 1 commit into
firecrawl:mainfrom
nitishagar:feat/issue-11-docker-cli

Conversation

@nitishagar

@nitishagar nitishagar commented Aug 6, 2026

Copy link
Copy Markdown

Closes #11.

Summary

Adds a minimal, multi-stage Docker image so docker run --rm -v "$PWD":/work anydoc convert <file> produces the same Markdown as the local cargo run --example convert. No bindings, no service, no registry push.

  • Builder rust:1.88-bookworm compiles examples/convert.rs with --release --locked (PDF support is included by default — pdf-inspector is a plain dependency, no feature flags exist in Cargo.toml).
  • Runtime debian:bookworm-slim carries only the convert binary + ca-certificates; WORKDIR /work, ENTRYPOINT ["convert"]. Documents are read from a mounted volume — nothing is baked in.
  • .dockerignore keeps target/, node_modules/, binding build artifacts, and agent scratch dirs out of the context.
  • CI adds a docker job that builds the image and runs one smoke conversion against tests/fixtures/docx/text.docx, so the Dockerfile cannot silently rot.

Why debian over alpine

pdf-inspector and its deps (lopdf, rayon, ttf-parser) are pure Rust — there are no native deps that block musl — but glibc matches the CI runner (ubuntu-2404) and a fully-static musl validation is deferred to a follow-up rather than shipped unvalidated for v1.

Verification

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo build --release --locked --example convert
  • docker build -t anydoc . ✅ on darwin/arm64
  • Image size: 33 MB (target was < 200 MB)
  • CLI parity: docker run … convert tests/fixtures/docx/text.docx output is byte-identical to local convert (1316 bytes both).
  • Negative paths: no-args → prints usage: + exit 1; missing file → clear error + exit 1.
  • Branch rebased on current main.

Scope / follow-ups (out of scope here)

  • No stdin (-) support: examples/convert.rs always reads a file path — it has no stdin branch. This is deferred to feat(cli): add a Rust anydoc binary for cargo install #29 (the standalone src/bin/anydoc.rs CLI), which owns real stdin. Documented as a spec gap, not silently dropped.
  • arm64 in CI: CI builds amd64 only (QEMU emulation is slow); the Dockerfile is arch-neutral, verified locally on arm64.
  • Registry publishing (GHCR/Docker Hub): maintainer decision, not included.
  • Non-root USER hardening: deferred to a follow-up (the plan calls this out).

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker support please

1 participant