build(deps): bump github.com/testcontainers/testcontainers-go

Bumps [github.com/testcontainers/testcontainers-go](https://github.com/testcontainers/testcontainers-go) from 0.40.0 to 0.41.0.
- [Release notes](https://github.com/testcontainers/testcontainers-go/releases)
- [Commits](https://github.com/testcontainers/testcontainers-go/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: github.com/testcontainers/testcontainers-go
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2026-03-11 11:55:40 +01:00
committed by Ralf Haferkamp
parent fef601f104
commit de59bb63ad
195 changed files with 30918 additions and 2151 deletions
@@ -23,3 +23,6 @@ TEST-*.xml
# Coverage files
coverage.out
# Usage metrics script binary
usage-metrics/scripts/collect-metrics
+21
View File
@@ -23,6 +23,27 @@ linters:
- thelper
- usestdlibvars
exclusions:
rules:
- linters:
- revive
path: "^exec/"
text: "var-naming: avoid package names that conflict with Go standard library package names"
- linters:
- revive
path: "^log/"
text: "var-naming: avoid package names that conflict with Go standard library package names"
- linters:
- revive
path: "modulegen/internal/(context|template)/"
text: "var-naming: avoid package names that conflict with Go standard library package names"
- linters:
- revive
path: "internal/sdk/types/"
text: "var-naming: avoid meaningless package names"
- linters:
- revive
path: "gcloud/internal/shared/"
text: "var-naming: avoid meaningless package names"
presets:
- comments
- common-false-positives
+5 -5
View File
@@ -14,15 +14,15 @@ This is a **Go monorepo** containing:
## Environment Setup
### Go Version
- **Required**: Go 1.24.7
- **Required**: Go 1.25.7
- **Tool**: Use [gvm](https://github.com/andrewkroh/gvm) for version management
- **CRITICAL**: Always run this before ANY Go command:
```bash
# For Apple Silicon (M1/M2/M3)
eval "$(gvm 1.24.7 --arch=arm64)"
eval "$(gvm 1.25.7 --arch=arm64)"
# For Intel/AMD (x86_64)
eval "$(gvm 1.24.7 --arch=amd64)"
eval "$(gvm 1.25.7 --arch=amd64)"
```
### Project Structure
@@ -171,14 +171,14 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
### When Tests Fail
1. **Read the error message carefully** - it usually tells you exactly what's wrong
2. **Check if it's a lint issue** - run `make pre-commit` first
3. **Verify Go version** - ensure using Go 1.24.7
3. **Verify Go version** - ensure using Go 1.25.7
4. **Check Docker** - some tests require Docker daemon running
## Common Pitfalls to Avoid
### Code Issues
- ❌ Using interface types as return values
- ❌ Forgetting to run `eval "$(gvm 1.24.7 --arch=arm64)"`
- ❌ Forgetting to run `eval "$(gvm 1.25.7 --arch=arm64)"`
- ❌ Not handling errors from built-in options
- ❌ Using module-specific container names (`PostgresContainer`)
- ❌ Calling `.Customize()` method instead of direct function call
+2 -2
View File
@@ -46,7 +46,7 @@ serve-docs:
#
# - compose-clean: Clean the .build directory, and clean the go.mod and go.sum files in the testcontainers-go compose module.
# - compose-clone: Clone the compose and compose-go repositories into the .build directory.
# - compose-replace: Replace the docker/compose/v2 dependency in the testcontainers-go compose module with the local copy.
# - compose-replace: Replace the docker/compose/v5 dependency in the testcontainers-go compose module with the local copy.
# - compose-spec-replace: Replace the compose-spec/compose-go/v2 dependency in the testcontainers-go compose module with the local copy.
# - compose-tidy: Run "go mod tidy" in the testcontainers-go compose module.
# - compose-test-all-latest: Test the testcontainers-go compose module against the latest versions of the compose and compose-go repositories.
@@ -67,7 +67,7 @@ compose-clone: compose-clean
.PHONY: compose-replace
compose-replace:
cd modules/compose && echo "replace github.com/docker/compose/v2 => ../../.build/compose" >> go.mod
cd modules/compose && echo "replace github.com/docker/compose/v5 => ../../.build/compose" >> go.mod
.PHONY: compose-spec-replace
compose-spec-replace:
+2 -2
View File
@@ -7,8 +7,8 @@ verify_ssl = true
[packages]
mkdocs = "==1.5.3"
mkdocs-codeinclude-plugin = "==0.2.1"
mkdocs-include-markdown-plugin = "==7.2.0"
mkdocs-codeinclude-plugin = "==0.3.1"
mkdocs-include-markdown-plugin = "==7.2.1"
mkdocs-material = "==9.5.18"
mkdocs-markdownextradata-plugin = "==0.2.6"
+38 -36
View File
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "361ac26693514418dce9f92cca60528d549bd0b3f4710374cf77dafd399ae232"
"sha256": "c30436cdeb31baa333fdc82d0679532754a1ea51be468b4fd83da0de242b70cf"
},
"pipfile-spec": 6,
"requires": {
@@ -140,11 +140,11 @@
},
"click": {
"hashes": [
"sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc",
"sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"
"sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a",
"sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"
],
"markers": "python_version >= '3.10'",
"version": "==8.3.0"
"version": "==8.3.1"
},
"colorama": {
"hashes": [
@@ -187,11 +187,11 @@
},
"markdown": {
"hashes": [
"sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280",
"sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a"
"sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950",
"sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36"
],
"markers": "python_version >= '3.9'",
"version": "==3.9"
"markers": "python_version >= '3.10'",
"version": "==3.10.2"
},
"markupsafe": {
"hashes": [
@@ -307,21 +307,21 @@
},
"mkdocs-codeinclude-plugin": {
"hashes": [
"sha256:172a917c9b257fa62850b669336151f85d3cd40312b2b52520cbcceab557ea6c",
"sha256:305387f67a885f0e36ec1cf977324fe1fe50d31301147194b63631d0864601b1"
"sha256:06bbbf0d4ac7eccaec6e0d89ce76d644a197cfed34880f541516e722ded6512a",
"sha256:443f32c9e4412b84ec084bd2b454020c5bf06cb9a958682e08a528e62b45da4d"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==0.2.1"
"markers": "python_version >= '3.11'",
"version": "==0.3.1"
},
"mkdocs-include-markdown-plugin": {
"hashes": [
"sha256:4a67a91ade680dc0e15f608e5b6343bec03372ffa112c40a4254c1bfb10f42f3",
"sha256:d56cdaeb2d113fb66ed0fe4fb7af1da889926b0b9872032be24e19bbb09c9f5b"
"sha256:30da634c568ea5d5f9e5881d51f80ac30d8c5f891cec160344ad7a0fdaea6286",
"sha256:5d94db87b06cd303619dbaebba5f7f43a3ded7fd7709451d26f08c176376ffec"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==7.2.0"
"version": "==7.2.1"
},
"mkdocs-markdownextradata-plugin": {
"hashes": [
@@ -351,11 +351,11 @@
},
"packaging": {
"hashes": [
"sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484",
"sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"
"sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4",
"sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"
],
"markers": "python_version >= '3.8'",
"version": "==25.0"
"version": "==26.0"
},
"paginate": {
"hashes": [
@@ -365,35 +365,36 @@
},
"pathspec": {
"hashes": [
"sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08",
"sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"
"sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645",
"sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"
],
"markers": "python_version >= '3.8'",
"version": "==0.12.1"
"markers": "python_version >= '3.9'",
"version": "==1.0.4"
},
"platformdirs": {
"hashes": [
"sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312",
"sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"
"sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd",
"sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291"
],
"markers": "python_version >= '3.10'",
"version": "==4.5.0"
"version": "==4.9.2"
},
"pygments": {
"hashes": [
"sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
"sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
"sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887",
"sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"
],
"markers": "python_version >= '3.7'",
"version": "==2.17.2"
"markers": "python_version >= '3.8'",
"version": "==2.19.2"
},
"pymdown-extensions": {
"hashes": [
"sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940",
"sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"
"sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91",
"sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d"
],
"markers": "python_version >= '3.8'",
"version": "==10.8.1"
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==10.16.1"
},
"python-dateutil": {
"hashes": [
@@ -602,11 +603,12 @@
},
"urllib3": {
"hashes": [
"sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760",
"sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"
"sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed",
"sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==2.5.0"
"version": "==2.6.3"
},
"watchdog": {
"hashes": [
+1 -1
View File
@@ -6,7 +6,7 @@ define go_install
endef
$(GOBIN)/golangci-lint:
$(call go_install,github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.2)
$(call go_install,github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.9.0)
$(GOBIN)/gotestsum:
$(call go_install,gotest.tools/gotestsum@latest)
+2 -1
View File
@@ -28,8 +28,9 @@ import (
"github.com/testcontainers/testcontainers-go/wait"
)
// Deprecated: Use [Container]
//
// DeprecatedContainer shows methods that were supported before, but are now deprecated
// Deprecated: Use Container
type DeprecatedContainer interface {
GetHostEndpoint(ctx context.Context, port string) (string, string, error)
GetIPAddress(ctx context.Context) (string, error)
+1 -1
View File
@@ -54,7 +54,7 @@ const (
var (
// createContainerFailDueToNameConflictRegex is a regular expression that matches the container is already in use error.
createContainerFailDueToNameConflictRegex = regexp.MustCompile("Conflict. The container name .* is already in use by container .*")
createContainerFailDueToNameConflictRegex = regexp.MustCompile("[Tt]he container name .* is already in use by .*")
// minLogProductionTimeout is the minimum log production timeout.
minLogProductionTimeout = time.Duration(5 * time.Second)
+8
View File
@@ -10,6 +10,7 @@ import (
"fmt"
"net/url"
"os"
"strings"
"sync"
"github.com/cpuguy83/dockercfg"
@@ -42,6 +43,13 @@ func dockerImageAuth(ctx context.Context, image string, configs map[string]regis
defaultRegistry := defaultRegistryFn(ctx)
reg := core.ExtractRegistry(image, defaultRegistry)
// Normalize Docker Hub aliases for credential lookup
if strings.EqualFold(reg, "docker.io") ||
strings.EqualFold(reg, "registry.hub.docker.com") ||
strings.EqualFold(reg, "registry-1.docker.io") {
reg = defaultRegistry // This is https://index.docker.io/v1/
}
if cfg, ok := getRegistryAuth(reg, configs); ok {
return reg, cfg, nil
}
+4 -1
View File
@@ -3,6 +3,7 @@ package testcontainers
import (
"context"
"fmt"
"strings"
"sync"
"github.com/docker/docker/api/types"
@@ -69,9 +70,11 @@ func (c *DockerClient) Info(ctx context.Context) (system.Info, error) {
if len(dockerInfo.Labels) > 0 {
infoLabels = `
Labels:`
var infoLabelsSb72 strings.Builder
for _, lb := range dockerInfo.Labels {
infoLabels += "\n " + lb
infoLabelsSb72.WriteString("\n " + lb)
}
infoLabels += infoLabelsSb72.String()
}
log.Printf(infoMessage, packagePath,
@@ -100,6 +100,16 @@ func ExtractRegistry(image string, fallback string) string {
registry := exp[1]
// docker.io is an implicit reference, return fallback for normalization
if strings.EqualFold(registry, "docker.io") {
return fallback
}
// registry.hub.docker.com is an explicit registry reference, preserve it
if strings.EqualFold(registry, "registry.hub.docker.com") {
return "registry.hub.docker.com"
}
if IsURL(registry) {
return registry
}
+1 -1
View File
@@ -1,4 +1,4 @@
package internal
// Version is the next development version of the application
const Version = "0.40.0"
const Version = "0.41.0"
+10 -1
View File
@@ -19,6 +19,12 @@ theme:
extra_css:
- css/extra.css
- css/tc-header.css
- css/usage-metrics.css
extra_javascript:
- https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js
- https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js
- https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js
- js/usage-metrics.js
repo_name: testcontainers-go
repo_url: https://github.com/testcontainers/testcontainers-go
markdown_extensions:
@@ -86,6 +92,7 @@ nav:
- modules/dynamodb.md
- modules/elasticsearch.md
- modules/etcd.md
- modules/forgejo.md
- modules/gcloud.md
- modules/grafana-lgtm.md
- modules/inbucket.md
@@ -123,6 +130,7 @@ nav:
- modules/socat.md
- modules/solace.md
- modules/surrealdb.md
- modules/tidb.md
- modules/toxiproxy.md
- modules/valkey.md
- modules/vault.md
@@ -148,9 +156,10 @@ nav:
- system_requirements/using_colima.md
- system_requirements/using_podman.md
- system_requirements/rancher.md
- Usage Metrics: usage-metrics.md
- Dependabot: dependabot.md
- Contributing: contributing.md
- Getting help: getting_help.md
edit_uri: edit/main/docs/
extra:
latest_version: v0.40.0
latest_version: v0.41.0
+1 -1
View File
@@ -343,7 +343,7 @@ func WithStartupCommand(execs ...Executable) CustomizeRequestOption {
// is ready.
func WithAfterReadyCommand(execs ...Executable) CustomizeRequestOption {
return func(req *GenericContainerRequest) error {
postReadiesHook := []ContainerHook{}
postReadiesHook := make([]ContainerHook, 0, len(execs))
for _, exec := range execs {
execFn := func(ctx context.Context, c Container) error {
+3 -3
View File
@@ -177,12 +177,12 @@ func exposeHostPorts(ctx context.Context, req *ContainerRequest, ports ...int) (
// newSshdContainer creates a new SSHD container with the provided options.
func newSshdContainer(ctx context.Context, opts ...ContainerCustomizer) (*sshdContainer, error) {
moduleOpts := []ContainerCustomizer{
moduleOpts := make([]ContainerCustomizer, 0, 3+len(opts))
moduleOpts = append(moduleOpts,
WithExposedPorts(sshPort),
WithEnv(map[string]string{"PASSWORD": sshPassword}),
WithWaitStrategy(wait.ForListeningPort(sshPort)),
}
)
moduleOpts = append(moduleOpts, opts...)
c, err := Run(ctx, sshdImage, moduleOpts...)
+4 -2
View File
@@ -64,10 +64,11 @@ type ReaperProvider interface {
Config() TestcontainersConfig
}
// NewReaper creates a Reaper with a sessionID to identify containers and a provider to use
// Deprecated: it's not possible to create a reaper any more. Compose module uses this method
// to create a reaper for the compose stack.
//
// # NewReaper creates a Reaper with a sessionID to identify containers and a provider to use
//
// The caller must call Connect at least once on the returned Reaper and use the returned
// result otherwise the reaper will be kept open until the process exits.
func NewReaper(ctx context.Context, sessionID string, provider ReaperProvider, _ string) (*Reaper, error) {
@@ -568,8 +569,9 @@ func (r *Reaper) handshake(conn net.Conn) error {
return nil
}
// Labels returns the container labels to use so that this Reaper cleans them up
// Deprecated: internally replaced by core.DefaultLabels(sessionID)
//
// Labels returns the container labels to use so that this Reaper cleans them up
func (r *Reaper) Labels() map[string]string {
return GenericLabels()
}
+2 -2
View File
@@ -1,5 +1,5 @@
mkdocs==1.5.3
mkdocs-codeinclude-plugin==0.2.1
mkdocs-include-markdown-plugin==7.2.0
mkdocs-codeinclude-plugin==0.3.1
mkdocs-include-markdown-plugin==7.2.1
mkdocs-material==9.5.18
mkdocs-markdownextradata-plugin==0.2.6
-1
View File
@@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package wait