Skip to content

Conversation

@sergeytimoshin
Copy link
Contributor

@sergeytimoshin sergeytimoshin commented Dec 12, 2025

…rm-slim

Summary by CodeRabbit

  • Chores
    • Updated build and runtime dependencies for improved compatibility and security.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

The Dockerfile was updated to use newer base images: Rust 1.92-bookworm for the builder stage and Debian bookworm-slim for the runtime stage. SSL dependencies were transitioned from libssl-dev to libssl3, and the build context was modified to copy from the current directory with an added cargo clean step.

Changes

Cohort / File(s) Summary
Dockerfile image and dependency updates
forester/Dockerfile
Updated builder image to rust:1.92-bookworm (from rust:1.79), runtime image to debian:bookworm-slim (from debian:12-slim). Changed build context from parent directory (..) to current directory (.), added cargo clean before build. Replaced libssl-dev with libssl3 for runtime SSL support.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Rust version compatibility: Verify that Rust 1.92 compiles the Forester project without issues and doesn't introduce MSRV (Minimum Supported Rust Version) concerns.
  • SSL library transition: Confirm that libssl3 provides sufficient functionality compared to libssl-dev and that no build-time SSL headers are needed.
  • Build context change: Understand why the COPY directive moved from .. to . and ensure this aligns with the repository structure and CI/CD context.
  • Debian bookworm variant: Validate that bookworm-slim has all required runtime dependencies and is production-ready for the deployment environment.

Suggested labels

ai-review

Suggested reviewers

  • SwenSchaeferjohann

Poem

📦 Rust ascends from seventy-nine to ninety-two,
Debian bookworm arrives in slim debut,
SSL threads retune their ancient song,
Docker foundations grow fresh and strong! 🐳✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating the Dockerfile to use Rust 1.92, which is the primary modification across builder image, dependencies, and base image versions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sergey/forester-dockerfile-1.92

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2953172 and 9b74c56.

📒 Files selected for processing (1)
  • forester/Dockerfile (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-24T17:53:53.971Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: forester/README.md:0-0
Timestamp: 2025-11-24T17:53:53.971Z
Learning: Applies to forester/src/main.rs : Required configuration must include: `--rpc-url`, `--ws-rpc-url`, `--indexer-url`, `--prover-url`, `--payer`, and `--derivation` parameters

Applied to files:

  • forester/Dockerfile
📚 Learning: 2025-11-24T18:01:30.012Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:30.012Z
Learning: Run registry tests using `cargo test-sbf -p registry-test` to test protocol configuration and forester registration

Applied to files:

  • forester/Dockerfile
🪛 Checkov (3.2.334)
forester/Dockerfile

[low] 1-22: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-22: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
forester/Dockerfile

[warning] 4-4: Pin versions in apt get install. Instead of apt-get install <package> use apt-get install <package>=<version>

(DL3008)


[info] 4-4: Avoid additional packages by specifying --no-install-recommends

(DL3015)


[info] 13-13: Multiple consecutive RUN instructions. Consider consolidation.

(DL3059)


[warning] 16-16: Pin versions in apt get install. Instead of apt-get install <package> use apt-get install <package>=<version>

(DL3008)


[info] 16-16: Avoid additional packages by specifying --no-install-recommends

(DL3015)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Forester e2e test
  • GitHub Check: stateless-js-v2

@@ -1,20 +1,22 @@
FROM rust:1.79 AS builder
FROM rust:1.92-bookworm AS builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

rust:1.92-bookworm Docker Hub image tag digest

💡 Result:

I couldn't find an official Docker Hub tag named rust:1.92-bookworm. The official rust image tags listing shows bookworm tags for 1 and for 1.91, and the 1.92 variants appear only as beta/nightly (e.g., 1.92.0-beta-bookworm). [1][2]

If you need the digest for a specific existing tag, tell me the exact tag (or I can look up the tag digest if you want me to query the registry for a particular tag).

Sources:

  • Docker Hub rust tags. [1]
  • instrumentisto / rust tags (shows 1.92 as beta). [2]

🏁 Script executed:

find . -name "CLAUDE.md" -o -name "*.md" | head -20

Repository: Lightprotocol/light-protocol

Length of output: 649


🏁 Script executed:

cat -n ./CLAUDE.md

Repository: Lightprotocol/light-protocol

Length of output: 10032


The rust:1.92-bookworm tag does not exist on Docker Hub; the build will fail.

The stable Rust image tags available are rust:1.91-bookworm and rust:1-bookworm. The 1.92 variant exists only as beta/nightly (e.g., 1.92.0-beta-bookworm). Update the tag to a stable release. While you're at it, pin by digest rather than tag alone for reproducibility and incident response—digest pinning prevents unexpected base image updates if a tag is retagged.

🧰 Tools
🪛 Checkov (3.2.334)

[low] 1-22: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-22: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🤖 Prompt for AI Agents
In forester/Dockerfile around line 1 the base image references non-existent tag
rust:1.92-bookworm causing build failures; update the FROM to a stable tag such
as rust:1.91-bookworm or rust:1-bookworm and then pin that image by digest for
reproducibility (obtain the official sha256 digest from Docker Hub or by pulling
the chosen tag locally and using docker image inspect to get its RepoDigests)
and replace the FROM line with the digest-pinned reference; after updating,
rebuild the image to verify the change.

Comment on lines +11 to 13
COPY . .
RUN cargo clean
RUN cargo build --release --package forester
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, find and examine the Dockerfile
find . -name "Dockerfile" -type f | head -20

Repository: Lightprotocol/light-protocol

Length of output: 120


🏁 Script executed:

# Check for .dockerignore
find . -name ".dockerignore" -type f

Repository: Lightprotocol/light-protocol

Length of output: 96


🏁 Script executed:

# Look for Cargo workspace configuration
find . -name "Cargo.toml" -type f | head -20

Repository: Lightprotocol/light-protocol

Length of output: 850


🏁 Script executed:

# Check for CLAUDE.md
find . -name "CLAUDE.md" -type f

Repository: Lightprotocol/light-protocol

Length of output: 575


🏁 Script executed:

# Read the Dockerfile to see its full content
cat -n ./forester/Dockerfile

Repository: Lightprotocol/light-protocol

Length of output: 760


🏁 Script executed:

# Read the .dockerignore
cat -n ./forester/.dockerignore

Repository: Lightprotocol/light-protocol

Length of output: 265


🏁 Script executed:

# Check the root Cargo.toml for workspace structure
head -50 ./Cargo.toml 2>/dev/null || echo "No root Cargo.toml"

Repository: Lightprotocol/light-protocol

Length of output: 90


🏁 Script executed:

# Check forester's Cargo.toml
head -50 ./forester/Cargo.toml

Repository: Lightprotocol/light-protocol

Length of output: 1967


🏁 Script executed:

# Read CLAUDE.md for tone and style guidance
cat ./CLAUDE.md

Repository: Lightprotocol/light-protocol

Length of output: 8639


🏁 Script executed:

# Check for Cargo.lock file
find . -name "Cargo.lock" -type f

Repository: Lightprotocol/light-protocol

Length of output: 229


🏁 Script executed:

# Search for workspace configuration in all Cargo.toml files
rg "^\[workspace\]" -t toml

Repository: Lightprotocol/light-protocol

Length of output: 115


🏁 Script executed:

# Check if there's a Cargo.toml with workspace definition
find . -name "Cargo.toml" -type f -exec grep -l "\[workspace\]" {} \;

Repository: Lightprotocol/light-protocol

Length of output: 105


🏁 Script executed:

# Verify the exact structure - are there other workspace members that need their Cargo.toml copied?
# Check what the workspace actually contains
cat ./sdk-libs/macros/fuzz/Cargo.toml | head -20

Repository: Lightprotocol/light-protocol

Length of output: 409


🏁 Script executed:

# Look for any Cargo.toml files in forester directory itself
find ./forester -name "Cargo.toml" -type f

Repository: Lightprotocol/light-protocol

Length of output: 93


🏁 Script executed:

# Check if there are sibling workspace members in the actual structure
ls -la forester/Cargo* 2>/dev/null | head -10

Repository: Lightprotocol/light-protocol

Length of output: 213


🏁 Script executed:

# Check the structure - does forester depend on local workspace paths or just via workspace = true?
grep -A 5 "workspace = true" ./forester/Cargo.toml | head -20

Repository: Lightprotocol/light-protocol

Length of output: 1027


🏁 Script executed:

# Verify: when you `cargo fetch` with just forester's Cargo.toml, can it resolve workspace deps?
# This requires understanding if workspace = true can work with just one crate's manifest
# Let's check if there's a workspace.members definition anywhere
rg "members\s*=" -A 5 --type toml

Repository: Lightprotocol/light-protocol

Length of output: 54


🏁 Script executed:

# Search for workspace.package definitions
rg "workspace\.package" --type toml -A 2

Repository: Lightprotocol/light-protocol

Length of output: 54


🏁 Script executed:

# Also check what "workspace = true" actually means in this context
# Let's see if there's any parent Cargo.toml or workspace definition
rg "\[workspace\]" --type toml -B 2 -A 10

Repository: Lightprotocol/light-protocol

Length of output: 705


Remove cargo clean and implement layered Docker builds to optimize caching.

The combination of COPY . . followed by cargo clean defeats Docker's layer caching. In a fresh container, cargo clean is redundant and only adds build time. More importantly, COPY . . invalidates the cache layer whenever any file changes, forcing full rebuilds even when only source code changed.

For optimal caching with this Nx-managed monorepo, layer your COPY commands to separate dependency resolution from source changes:

 WORKDIR /app
 
 RUN apt-get update && apt-get install -y \
     clang \
     lld \
     pkg-config \
     libssl-dev \
     && rm -rf /var/lib/apt/lists/*
 
-COPY . .
-RUN cargo clean
-RUN cargo build --release --package forester
+# Copy workspace manifests to enable dependency resolution
+COPY Cargo.toml Cargo.lock ./
+RUN cargo fetch
+
+# Copy remaining source files
+COPY . .
+RUN cargo build --release --locked --package forester

The --locked flag ensures reproducible builds using exact dependency versions from Cargo.lock (which already exists in your repo). Since your .dockerignore already excludes target/ and .git/, these changes should significantly improve rebuild times for local development and CI pipelines—unchanged dependencies will reuse cached layers.

🧰 Tools
🪛 Hadolint (2.14.0)

[info] 13-13: Multiple consecutive RUN instructions. Consider consolidation.

(DL3059)

🤖 Prompt for AI Agents
In forester/Dockerfile around lines 11-13, remove the unnecessary cargo clean
and refactor to a layered build: copy only Cargo.toml and Cargo.lock (and any
workspace manifests) first, run cargo fetch/build of dependencies (using
--locked) to populate the dependency layer, then copy the rest of the source and
run cargo build --release --package forester; ensure .dockerignore excludes
target/ and .git/ so target artifacts are not copied, and keep --locked on cargo
commands to guarantee reproducible cached dependency layers.

Comment on lines +15 to +16
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Harden the runtime image: run as non-root + add --no-install-recommends (and ideally a HEALTHCHECK).
This is a nice move to bookworm-slim + libssl3, but it still runs as root and lacks a health signal.

 FROM debian:bookworm-slim
-RUN apt-get update && apt-get install -y ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends ca-certificates libssl3 \
+  && rm -rf /var/lib/apt/lists/*
+
+RUN useradd -r -u 10001 -g nogroup forester
 RUN mkdir -p /app/config
 COPY --from=builder /app/target/release/forester /usr/local/bin/forester
 WORKDIR /app
+USER forester
@@
 ENTRYPOINT ["/usr/local/bin/forester"]
 CMD []

If forester exposes an HTTP endpoint or has a lightweight self-check command, add a HEALTHCHECK (otherwise ignore this).

Also applies to: 17-22

🧰 Tools
🪛 Hadolint (2.14.0)

[warning] 16-16: Pin versions in apt get install. Instead of apt-get install <package> use apt-get install <package>=<version>

(DL3008)


[info] 16-16: Avoid additional packages by specifying --no-install-recommends

(DL3015)

🤖 Prompt for AI Agents
In forester/Dockerfile around lines 15-16 (and also apply same changes to lines
17-22), the image currently installs packages as root without using
--no-install-recommends and lacks a healthcheck and non-root runtime; update the
Dockerfile to use apt-get install -y --no-install-recommends, combine apt
update/install/cleanup into a single RUN to remove /var/lib/apt/lists/*, create
a non-root user/group (e.g., forester), chown the app files and switch to USER
that non-root account before CMD/ENTRYPOINT, and if the service exposes an HTTP
endpoint or has a self-check command add a HEALTHCHECK instruction calling that
endpoint or command with sensible intervals/retries.

@sergeytimoshin sergeytimoshin merged commit 815c26d into main Dec 12, 2025
17 checks passed
@sergeytimoshin sergeytimoshin deleted the sergey/forester-dockerfile-1.92 branch December 12, 2025 17:05
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.

3 participants