testcontainers-go
testcontainers-go copied to clipboard
[Bug]: Interstitial images from builds are not cleaned up
Testcontainers version
v0.22.0
Using the latest Testcontainers version?
Yes
Host OS
Windows 11
Host arch
x64
Go version
1.19
Docker version
Client:
Cloud integration: v1.0.35-desktop+001
Version: 24.0.5
API version: 1.43
Go version: go1.20.6
Git commit: ced0996
Built: Fri Jul 21 20:36:24 2023
OS/Arch: windows/amd64
Context: default
Server: Docker Desktop 4.22.0 (117440)
Engine:
Version: 24.0.5
API version: 1.43 (minimum version 1.12)
Go version: go1.20.6
Git commit: a61e2b4
Built: Fri Jul 21 20:35:45 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.21
GitCommit: 3dce8eb055cbb6872793272b4f20ed16117344f8
runc:
Version: 1.1.7
GitCommit: v1.1.7-0-g860f061
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker info
Client:
Version: 24.0.5
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.11.2-desktop.1
Path: C:\Program Files\Docker\cli-plugins\docker-buildx.exe
compose: Docker Compose (Docker Inc.)
Version: v2.20.2-desktop.1
Path: C:\Program Files\Docker\cli-plugins\docker-compose.exe
dev: Docker Dev Environments (Docker Inc.)
Version: v0.1.0
Path: C:\Program Files\Docker\cli-plugins\docker-dev.exe
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.20
Path: C:\Program Files\Docker\cli-plugins\docker-extension.exe
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v0.1.0-beta.6
Path: C:\Program Files\Docker\cli-plugins\docker-init.exe
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
Version: 0.6.0
Path: C:\Program Files\Docker\cli-plugins\docker-sbom.exe
scan: Docker Scan (Docker Inc.)
Version: v0.26.0
Path: C:\Program Files\Docker\cli-plugins\docker-scan.exe
scout: Command line tool for Docker Scout (Docker Inc.)
Version: 0.20.0
Path: C:\Program Files\Docker\cli-plugins\docker-scout.exe
Server:
Containers: 16
Running: 2
Paused: 0
Stopped: 14
Images: 33
Server Version: 24.0.5
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: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 3dce8eb055cbb6872793272b4f20ed16117344f8
runc version: v1.1.7-0-g860f061
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
Kernel Version: 5.10.102.1-microsoft-standard-WSL2
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 16
Total Memory: 31.32GiB
Name: docker-desktop
ID: 332a094f-cdeb-479f-acfa-557d63f0d1a1
Docker Root Dir: /var/lib/docker
Debug Mode: false
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
No Proxy: hubproxy.docker.internal
Experimental: false
Insecure Registries:
172.16.0.111:5000
hubproxy.docker.internal:5555
127.0.0.0/8
Live Restore Enabled: false
WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
WARNING: daemon is not using the default seccomp profile
What happened?
When using a Dockerfile with a multi-stage build, the interstitial images are not cleaned up at the end of execution. I'm building the image with:
FromDockerfile: testcontainers.FromDockerfile{
Dockerfile: "Dockerfile",
Context: ".",
PrintBuildLog: true,
},
Which results in the following dangling images:
The first two are because I actually build the container twice, for reasons related to the project. test is an example build from docker build -t test . to see what it does. The remaining two are me trying to trick testcontainers into doing something it isn't really designed to do[^1], so I'll take responsibility for them ;)
Example (partial) dockerfile:
# ---- Stage 0 ----
# Builds media repo binaries
FROM golang:1.19-alpine AS builder
# ... commands ...
RUN ./build.sh
# ---- Stage 1 ----
# Final runtime stage.
FROM alpine
COPY --from=builder /opt/bin/media_repo /usr/local/bin/
# ... commands ...
CMD ./run.sh
Relevant log output
No response
Additional information
[^1]: To avoid building an image twice, I dig into the internals of testcontainers-go a bit. Specifically, I create (but don't start) a container directly on the provider then capture the image name for use in a future container start. This seems to leave behind the image (the UUID below test in the screenshot above) as well as the interstitial build.