Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions forester/Dockerfile
Original file line number Diff line number Diff line change
@@ -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.

WORKDIR /app

RUN apt-get update && apt-get install -y \
clang \
lld \
pkg-config \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*

COPY .. .
COPY . .
RUN cargo clean
RUN cargo build --release --package forester
Comment on lines +11 to 13
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.


FROM debian:12-slim
RUN apt-get update && apt-get install -y ca-certificates libssl-dev && rm -rf /var/lib/apt/lists/*
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
Comment on lines +15 to +16
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.

RUN mkdir -p /app/config
COPY --from=builder /app/target/release/forester /usr/local/bin/forester
WORKDIR /app

ENTRYPOINT ["/usr/local/bin/forester"]
CMD []
CMD []