diff --git a/container.go b/container.go index fef32aece1..0f0ca1686b 100644 --- a/container.go +++ b/container.go @@ -67,6 +67,7 @@ type ContainerRequest struct { Cmd []string Labels map[string]string BindMounts map[string]string + VolumeMounts map[string]string RegistryCred string WaitingFor wait.Strategy Name string // for specifying container name diff --git a/docker.go b/docker.go index aca0c0bc4d..12d1949885 100644 --- a/docker.go +++ b/docker.go @@ -424,18 +424,25 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque } // prepare mounts - bindMounts := []mount.Mount{} + mounts := []mount.Mount{} for hostPath, innerPath := range req.BindMounts { - bindMounts = append(bindMounts, mount.Mount{ + mounts = append(mounts, mount.Mount{ Type: mount.TypeBind, Source: hostPath, Target: innerPath, }) } + for volumeName, innerPath := range req.VolumeMounts { + mounts = append(mounts, mount.Mount{ + Type: mount.TypeVolume, + Source: volumeName, + Target: innerPath, + }) + } hostConfig := &container.HostConfig{ PortBindings: exposedPortMap, - Mounts: bindMounts, + Mounts: mounts, AutoRemove: true, Privileged: req.Privileged, } diff --git a/docker_test.go b/docker_test.go index af601fd7b1..cbd58dad46 100644 --- a/docker_test.go +++ b/docker_test.go @@ -3,7 +3,9 @@ package testcontainers import ( "context" "fmt" + "github.com/docker/docker/api/types/volume" "net/http" + "path/filepath" "testing" "time" @@ -886,3 +888,56 @@ func ExampleContainer_MappedPort() { port, _ := nginxC.MappedPort(ctx, "80") http.Get(fmt.Sprintf("http://%s:%s", ip, port.Port())) } + +func TestContainerCreationWithBindAndVolume(t *testing.T) { + absPath, err := filepath.Abs("./testresources/hello.sh") + if err != nil { + t.Fatal(err) + } + ctx, cnl := context.WithTimeout(context.Background(), 30*time.Second) + defer cnl() + // Create a Docker client. + dockerCli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + t.Fatal(err) + } + dockerCli.NegotiateAPIVersion(ctx) + // Create the volume. + vol, err := dockerCli.VolumeCreate(ctx, volume.VolumeCreateBody{ + Driver: "local", + }) + if err != nil { + t.Fatal(err) + } + volumeName := vol.Name + defer func() { + ctx, cnl := context.WithTimeout(context.Background(), 5*time.Second) + defer cnl() + err := dockerCli.VolumeRemove(ctx, volumeName, true) + if err != nil { + t.Fatal(err) + } + }() + // Create the container that writes into the mounted volume. + bashC, err := GenericContainer(ctx, GenericContainerRequest{ + ContainerRequest: ContainerRequest{ + Image: "bash", + BindMounts: map[string]string{absPath: "/hello.sh"}, + VolumeMounts: map[string]string{volumeName: "/data"}, + Cmd: []string{"bash", "/hello.sh"}, + WaitingFor: wait.ForLog("done"), + }, + Started: true, + }) + if err != nil { + t.Fatal(err) + } + defer func() { + ctx, cnl := context.WithTimeout(context.Background(), 5*time.Second) + defer cnl() + err := bashC.Terminate(ctx) + if err != nil { + t.Fatal(err) + } + }() +} diff --git a/testresources/hello.sh b/testresources/hello.sh new file mode 100644 index 0000000000..cc6381d33a --- /dev/null +++ b/testresources/hello.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +echo "hello world" > /data/hello.txt +echo "done"