testcontainers-go
testcontainers-go copied to clipboard
[Enhancement]: Reuse docker-compose stack started outside of Testcontainers
User Story
As a test developer with a docker-compose stack that take a while to start up, I want to be able to start my containers prior to running my integration tests and reuse them for many test runs, so that I can iterate faster because I don't need to wait for each test start and stabilize its containers.
There is a workaround by using ReuseByName on individual containers instead of docker-compose. But, the ergonomics aren't as good. The docker-compose configuration needs to be decomposed into individual containers in the test. It would be better to use docker-compose on the CLI and in the tests.
Testcontainers version
0.37.0
Using the latest Testcontainers version?
Yes
Host OS
MacOS
Host arch
ARM
Go version
1.23.8
Docker version
Client: Docker Engine - Community
Version: 28.1.1
API version: 1.47 (downgraded from 1.49)
Go version: go1.24.2
Git commit: 4eba377327
Built: Fri Apr 18 09:44:47 2025
OS/Arch: darwin/arm64
Context: default
Server: Docker Engine - Community
Engine:
Version: 27.4.0
API version: 1.47 (minimum version 1.24)
Go version: go1.22.10
Git commit: 92a8393
Built: Sat Dec 7 10:39:01 2024
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.7.24
GitCommit: 88bf19b2105c8b17560993bee28a01ddc2f97182
runc:
Version: 1.2.2
GitCommit: v1.2.2-0-g7cb3632
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker info
Client: Docker Engine - Community
Version: 28.1.1
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.23.0
Path: /Users/csoon/.docker/cli-plugins/docker-buildx
Server:
Containers: 28
Running: 13
Paused: 0
Stopped: 15
Images: 30
Server Version: 27.4.0
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 88bf19b2105c8b17560993bee28a01ddc2f97182
runc version: v1.2.2-0-g7cb3632
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.8.0-50-generic
Operating System: Ubuntu 24.04.1 LTS
OSType: linux
Architecture: aarch64
CPUs: 4
Total Memory: 11.66GiB
Name: colima
ID: 4425450c-be0d-4954-bb81-88622ce0ce16
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
What happened?
I expect testcontainers-go docker-compose module to be able to reuse a docker-compose stack when specifying RecreateNever/RecreateDiverged and StackIdentifier.
Run in isolation without a running docker-compose stack the test passes.
This scenario does not work:
docker-compose up -d
go test
For a running stack (started by docker-compose or a previous go test), the docker-compose module:
- uses the StackIdentifer
- attempts to restart services
- deletes original docker network and creates a new one
- fails because the services are still pointing at the original network
Note: I am using colima 0.8.1 to run docker.
Relevant log output
% docker-compose up -d
[+] Running 2/2
✔ Network nginx-compose_default Created 0.1s
✔ Container nginx-compose-nginx-1 Started 0.1s
% docker ps -a | grep nginx-compose-nginx-1
de37e713809d nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp nginx-compose-nginx-1
% docker network ls | grep nginx-compose_default
718ed86c15ab nginx-compose_default bridge local
% go test
[+] Running 1/2
⠙ Container nginx-compose-nginx-1 Starting 0.3s
✔ Network nginx-compose_default Created 0.1s
--- FAIL: TestDockerCompose (0.38s)
main_test.go:33: Failed to start stack: compose up: Error response from daemon: network 718ed86c15ab3328ccd260d6f8f529ed7e74c70f85cb602768dd056a9330cd20 not found
FAIL
exit status 1
FAIL example.com/testcontainers-go/compose 0.919s
% docker ps -a | grep nginx-compose-nginx-1
de37e713809d nginx "/docker-entrypoint.…" 2 minutes ago Exited (128) 13 seconds ago nginx-compose-nginx-1
% docker network ls | grep nginx-compose_default
c357dc5d5f97 nginx-compose_default bridge local
Additional information
go test
func TestDockerCompose(t *testing.T) {
ctx := context.Background()
dockerCompose, err := compose.NewDockerComposeWith(
compose.WithStackFiles("docker-compose.yml"),
compose.StackIdentifier("nginx-compose"),
)
if err != nil {
t.Logf("Failed to create stack: %v", err)
t.FailNow()
}
err = dockerCompose.
WaitForService("nginx", wait.NewHTTPStrategy("/").
WithPort(nat.Port("80/tcp")).
WithStartupTimeout(20*time.Second),
).
Up(ctx, compose.Wait(true), compose.WithRecreate(api.RecreateNever))
if err != nil {
t.Logf("Failed to start stack: %v", err)
t.FailNow()
}
// no cleanup
}
name: nginx-compose
services:
nginx:
image: nginx
ports:
- 8080:80