Skip to content

chore: Pin image digest#1658

Merged
HofmeisterAn merged 1 commit intodevelopfrom
feature/pin-docker-image
Mar 11, 2026
Merged

chore: Pin image digest#1658
HofmeisterAn merged 1 commit intodevelopfrom
feature/pin-docker-image

Conversation

@HofmeisterAn
Copy link
Collaborator

@HofmeisterAn HofmeisterAn commented Mar 11, 2026

What does this PR do?

The PR pins container images using their digests. It specifically pins the images for Ryuk and SSHD provided by the Testcontainers library, along with most images used in our tests. Images tagged as latest, and some Dockerfiles required for specific tests are not pinned.

Why is it important?

Follow best practices to improve the library's security.

Related issues

-

Summary by CodeRabbit

  • Chores
    • Pinned all Docker base images with SHA256 digests across test containers and examples to ensure reproducible and deterministic builds.
    • Updated test configuration stage references to match new Docker image aliases for consistency.

@HofmeisterAn HofmeisterAn added the chore A change that doesn't impact the existing functionality, e.g. internal refactorings or cleanups label Mar 11, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Walkthrough

This pull request systematically pins Docker image digests across the test suite and library components. It updates approximately 60 test Dockerfiles by appending SHA256 digest hashes to image references, updates 7 test code files to reference new stage aliases, modifies 2 library constants with digest-pinned image references, and updates 1 example Dockerfile with full publish/build flow and digest pinning.

Changes

Cohort / File(s) Summary
Library Constants
src/Testcontainers/Containers/PortForwarding.cs, src/Testcontainers/Containers/ResourceReaper.cs
Updated public image constants with SHA256 digest pins: SshdImage and RyukImage now include immutable digest references instead of mutable tags.
Example Application
examples/WeatherForecast/Dockerfile
Added full publish/build flow with multi-stage setup: build-env stage with dotnet SDK, publish to out directory, and runtime container with aspnet base image pinned by digest; includes resource-reaper label, port 443 exposure, and ENTRYPOINT configuration.
Test Dockerfiles - Service Images
tests/Testcontainers.ActiveMq.Tests/Dockerfile, tests/Testcontainers.ArangoDb.Tests/Dockerfile, tests/Testcontainers.Azurite.Tests/Dockerfile, tests/Testcontainers.BigQuery.Tests/Dockerfile, tests/Testcontainers.Bigtable.Tests/Dockerfile, tests/Testcontainers.Cassandra.Tests/Dockerfile, tests/Testcontainers.ClickHouse.Tests/Dockerfile, tests/Testcontainers.CockroachDb.Tests/Dockerfile, tests/Testcontainers.Consul.Tests/Dockerfile, tests/Testcontainers.CouchDb.Tests/Dockerfile, tests/Testcontainers.Couchbase.Tests/Dockerfile, tests/Testcontainers.Db2.Tests/Dockerfile, tests/Testcontainers.DynamoDb.Tests/Dockerfile, tests/Testcontainers.Elasticsearch.Tests/Dockerfile, tests/Testcontainers.FakeGcsServer.Tests/Dockerfile, tests/Testcontainers.Firestore.Tests/Dockerfile, tests/Testcontainers.Grafana.Tests/Dockerfile, tests/Testcontainers.InfluxDb.Tests/Dockerfile, tests/Testcontainers.JanusGraph.Tests/Dockerfile, tests/Testcontainers.K3s.Tests/Dockerfile, tests/Testcontainers.KurrentDb.Tests/Dockerfile, tests/Testcontainers.LowkeyVault.Tests/Dockerfile, tests/Testcontainers.MariaDb.Tests/Dockerfile, tests/Testcontainers.Milvus.Tests/Dockerfile, tests/Testcontainers.Minio.Tests/Dockerfile, tests/Testcontainers.Mosquitto.Tests/Dockerfile, tests/Testcontainers.MsSql.Tests/Dockerfile, tests/Testcontainers.Nats.Tests/Dockerfile, tests/Testcontainers.Neo4j.Tests/Dockerfile, tests/Testcontainers.Ollama.Tests/Dockerfile, tests/Testcontainers.OpenSearch.Tests/Dockerfile, tests/Testcontainers.Oracle.Tests/Dockerfile, tests/Testcontainers.Papercut.Tests/Dockerfile, tests/Testcontainers.Playwright.Tests/Dockerfile, tests/Testcontainers.PostgreSql.Tests/Dockerfile, tests/Testcontainers.PubSub.Tests/Dockerfile, tests/Testcontainers.Qdrant.Tests/Dockerfile, tests/Testcontainers.RabbitMq.Tests/Dockerfile, tests/Testcontainers.Redis.Tests/Dockerfile, tests/Testcontainers.Redpanda.Tests/Dockerfile, tests/Testcontainers.Seq.Tests/Dockerfile, tests/Testcontainers.Temporal.Tests/Dockerfile, tests/Testcontainers.Tests/Assets/Dockerfile, tests/Testcontainers.Tests/Assets/healthWaitStrategy/Dockerfile, tests/Testcontainers.Toxiproxy.Tests/Dockerfile, tests/Testcontainers.Typesense.Tests/Dockerfile, tests/Testcontainers.Weaviate.Tests/Dockerfile, tests/Testcontainers.WebDriver.Tests/Dockerfile
Pins all base images with SHA256 digests (e.g., image:tagimage:tag@sha256:...) to ensure reproducible builds; updates image versions to more recent patch versions where applicable.
Test Dockerfiles - Multi-stage Images
tests/Testcontainers.FirebirdSql.Tests/Dockerfile, tests/Testcontainers.Kafka.Tests/Dockerfile, tests/Testcontainers.Keycloak.Tests/Dockerfile, tests/Testcontainers.LocalStack.Tests/Dockerfile, tests/Testcontainers.MongoDb.Tests/Dockerfile, tests/Testcontainers.MySql.Tests/Dockerfile, tests/Testcontainers.Pulsar.Tests/Dockerfile
Pins all stage images with SHA256 digests and introduces explicit stage aliases (e.g., kafka4.1.1apache-v4_1_1, mongo4.4v4_4_30); maintains multi-stage builds with digestified image references.
Test Code Stage Name Updates
tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs, tests/Testcontainers.Kafka.Tests/KafkaContainerTest.cs, tests/Testcontainers.Keycloak.Tests/KeycloakContainerTest.cs, tests/Testcontainers.LocalStack.Tests/LocalStackContainerTest.cs, tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs, tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs, tests/Testcontainers.Pulsar.Tests/PulsarContainerTest.cs
Updates Docker stage name references in test fixtures and configurations to match new aliases introduced in Dockerfiles (e.g., stage "mongo4.4" → "v4_4_32"); renames fixture classes for clarity (e.g., FirebirdSql30 → FirebirdSql3010).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~18 minutes

Possibly related PRs

Poem

🐰 Digests pinned with purpose true,
No floating tags for me and you,
Reproducible builds, content-addressed,
Docker images now locked and blessed! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description covers both required sections: it explains what the PR does (pins container images using digests) and why it's important (security best practices). While the description is concise, it provides sufficient information about the changeset's scope and motivation.
Title check ✅ Passed The title 'chore: Pin image digest' accurately describes the main change in the pull request, which is pinning container images using their SHA256 digests across multiple Dockerfiles and source files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/pin-docker-image

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.

@netlify
Copy link

netlify bot commented Mar 11, 2026

Deploy Preview for testcontainers-dotnet ready!

Name Link
🔨 Latest commit abcf147
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-dotnet/deploys/69b1584d84ed2a41950568be
😎 Deploy Preview https://deploy-preview-1658--testcontainers-dotnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@HofmeisterAn HofmeisterAn marked this pull request as ready for review March 11, 2026 11:34
Copy link

@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: 1

🧹 Nitpick comments (1)
tests/Testcontainers.Bigtable.Tests/Dockerfile (1)

1-1: Add an explicit non-root USER directive to harden the image.

The base image gcr.io/google.com/cloudsdktool/google-cloud-cli:446.0.1-emulators defaults to running as root. While digest pinning improves supply-chain integrity, consider adding USER cloudsdk (or another non-root user) to complete the security hardening.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Testcontainers.Bigtable.Tests/Dockerfile` at line 1, The Dockerfile
currently uses the base image
gcr.io/google.com/cloudsdktool/google-cloud-cli:446.0.1-emulators which runs as
root; add an explicit non-root USER (for example USER cloudsdk) to harden the
image, ensuring any files or directories written at build or runtime are owned
or chown'd appropriately (use chown/chmod during build before switching users)
and verify that the chosen user (cloudsdk) exists in the base image so the
container runs as non-root.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Testcontainers.Ollama.Tests/Dockerfile`:
- Line 1: The Dockerfile pins Ollama image tag 0.17.7 which conflicts with the
library default in OllamaBuilder.cs (default image version 0.6.6); synchronize
them by either updating the Dockerfile to the 0.6.6 image (preferably pinning
its digest) or update OllamaBuilder.cs to default to 0.17.7 (and run
compatibility tests) — locate the default constant/setting in OllamaBuilder.cs
and change the version string to match the Dockerfile or update the Dockerfile
base image to the digest for 0.6.6 so both artifacts reference the same exact
Ollama version.

---

Nitpick comments:
In `@tests/Testcontainers.Bigtable.Tests/Dockerfile`:
- Line 1: The Dockerfile currently uses the base image
gcr.io/google.com/cloudsdktool/google-cloud-cli:446.0.1-emulators which runs as
root; add an explicit non-root USER (for example USER cloudsdk) to harden the
image, ensuring any files or directories written at build or runtime are owned
or chown'd appropriately (use chown/chmod during build before switching users)
and verify that the chosen user (cloudsdk) exists in the base image so the
container runs as non-root.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 898ec27e-63b4-41c7-992e-a3eac2907eb3

📥 Commits

Reviewing files that changed from the base of the PR and between 21e854c and abcf147.

📒 Files selected for processing (65)
  • examples/WeatherForecast/Dockerfile
  • src/Testcontainers/Containers/PortForwarding.cs
  • src/Testcontainers/Containers/ResourceReaper.cs
  • tests/Testcontainers.ActiveMq.Tests/Dockerfile
  • tests/Testcontainers.ArangoDb.Tests/Dockerfile
  • tests/Testcontainers.Azurite.Tests/Dockerfile
  • tests/Testcontainers.BigQuery.Tests/Dockerfile
  • tests/Testcontainers.Bigtable.Tests/Dockerfile
  • tests/Testcontainers.Cassandra.Tests/Dockerfile
  • tests/Testcontainers.ClickHouse.Tests/Dockerfile
  • tests/Testcontainers.CockroachDb.Tests/Dockerfile
  • tests/Testcontainers.Consul.Tests/Dockerfile
  • tests/Testcontainers.CouchDb.Tests/Dockerfile
  • tests/Testcontainers.Couchbase.Tests/Dockerfile
  • tests/Testcontainers.Db2.Tests/Dockerfile
  • tests/Testcontainers.DynamoDb.Tests/Dockerfile
  • tests/Testcontainers.Elasticsearch.Tests/Dockerfile
  • tests/Testcontainers.FakeGcsServer.Tests/Dockerfile
  • tests/Testcontainers.FirebirdSql.Tests/Dockerfile
  • tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs
  • tests/Testcontainers.Firestore.Tests/Dockerfile
  • tests/Testcontainers.Grafana.Tests/Dockerfile
  • tests/Testcontainers.InfluxDb.Tests/Dockerfile
  • tests/Testcontainers.JanusGraph.Tests/Dockerfile
  • tests/Testcontainers.K3s.Tests/Dockerfile
  • tests/Testcontainers.Kafka.Tests/Dockerfile
  • tests/Testcontainers.Kafka.Tests/KafkaContainerTest.cs
  • tests/Testcontainers.Keycloak.Tests/Dockerfile
  • tests/Testcontainers.Keycloak.Tests/KeycloakContainerTest.cs
  • tests/Testcontainers.KurrentDb.Tests/Dockerfile
  • tests/Testcontainers.LocalStack.Tests/Dockerfile
  • tests/Testcontainers.LocalStack.Tests/LocalStackContainerTest.cs
  • tests/Testcontainers.LowkeyVault.Tests/Dockerfile
  • tests/Testcontainers.MariaDb.Tests/Dockerfile
  • tests/Testcontainers.Milvus.Tests/Dockerfile
  • tests/Testcontainers.Minio.Tests/Dockerfile
  • tests/Testcontainers.MongoDb.Tests/Dockerfile
  • tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs
  • tests/Testcontainers.Mosquitto.Tests/Dockerfile
  • tests/Testcontainers.MsSql.Tests/Dockerfile
  • tests/Testcontainers.MySql.Tests/Dockerfile
  • tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
  • tests/Testcontainers.Nats.Tests/Dockerfile
  • tests/Testcontainers.Neo4j.Tests/Dockerfile
  • tests/Testcontainers.Ollama.Tests/Dockerfile
  • tests/Testcontainers.OpenSearch.Tests/Dockerfile
  • tests/Testcontainers.Oracle.Tests/Dockerfile
  • tests/Testcontainers.Papercut.Tests/Dockerfile
  • tests/Testcontainers.Playwright.Tests/Dockerfile
  • tests/Testcontainers.PostgreSql.Tests/Dockerfile
  • tests/Testcontainers.PubSub.Tests/Dockerfile
  • tests/Testcontainers.Pulsar.Tests/Dockerfile
  • tests/Testcontainers.Pulsar.Tests/PulsarContainerTest.cs
  • tests/Testcontainers.Qdrant.Tests/Dockerfile
  • tests/Testcontainers.RabbitMq.Tests/Dockerfile
  • tests/Testcontainers.Redis.Tests/Dockerfile
  • tests/Testcontainers.Redpanda.Tests/Dockerfile
  • tests/Testcontainers.Seq.Tests/Dockerfile
  • tests/Testcontainers.Temporal.Tests/Dockerfile
  • tests/Testcontainers.Tests/Assets/Dockerfile
  • tests/Testcontainers.Tests/Assets/healthWaitStrategy/Dockerfile
  • tests/Testcontainers.Toxiproxy.Tests/Dockerfile
  • tests/Testcontainers.Typesense.Tests/Dockerfile
  • tests/Testcontainers.Weaviate.Tests/Dockerfile
  • tests/Testcontainers.WebDriver.Tests/Dockerfile

@HofmeisterAn HofmeisterAn changed the title feat: Pin image digest chore: Pin image digest Mar 11, 2026
@HofmeisterAn HofmeisterAn merged commit 4ea44aa into develop Mar 11, 2026
152 checks passed
@HofmeisterAn HofmeisterAn deleted the feature/pin-docker-image branch March 11, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore A change that doesn't impact the existing functionality, e.g. internal refactorings or cleanups

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant