Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 44 additions & 33 deletions docs/features/files_and_mounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,6 @@

Copying data of any type into a container is a very common practice when working with containers. This section will show you how to do it using _Testcontainers for Go_.

## Volume mapping

It is possible to map a Docker volume into the container using the `Mounts` attribute at the `ContainerRequest` struct. For that, please pass an instance of the `GenericVolumeMountSource` type, which allows you to specify the name of the volume to be mapped, and the path inside the container where it should be mounted:

<!--codeinclude-->
[Volume mounts](../../mounts_test.go) inside_block:volumeMounts
<!--/codeinclude-->

!!!tip
This ability of creating volumes is also available for remote Docker hosts.

!!!warning
Bind mounts are not supported, as it could not work with remote Docker hosts.

!!!tip
It is recommended to copy data from your local host machine to a test container using the file copy API
described below, as it is much more portable.

## Mounting images

Since Docker v28, it is possible to mount the file system of an image into a container using the `Mounts` attribute at the `ContainerRequest` struct. For that, use the `DockerImageMountSource` type, which allows you to specify the name of the image to be mounted, and the subpath inside the container where it should be mounted, or simply call the `ImageMount` function, which does exactly that:

<!--codeinclude-->
[Image mounts](../../lifecycle_test.go) inside_block:imageMounts
<!--/codeinclude-->

!!!warning
If the subpath is not a relative path, the creation of the container will fail.

!!!info
Mounting images fails the creation of the container if the underlying container runtime does not support the `image mount` feature, which is available since Docker v28.

## Copying files to a container

If you would like to copy a file to a container, you can do it in two different manners:
Expand Down Expand Up @@ -67,7 +35,7 @@ It's also possible to copy an entire directory to a container, and that can happ

It's important to notice that, when copying the directory to the container, the container path must exist in the Docker image. And this is a strong requirement for files to be copied _before_ the container is started, as we cannot create the full path at that time.

You can leverage the very same mechanism used for copying files to a container, but for directories.:
You can leverage the very same mechanism used for copying files to a container, but for directories:

1. The first way is using the `Files` field in the `ContainerRequest` struct, as shown in the previous section, but using the path of a directory as `HostFilePath`. Like so:

Expand All @@ -86,3 +54,46 @@ You can leverage the very same mechanism used for copying files to a container,
<!--codeinclude-->
[Copying a directory to a running container](../../docker_files_test.go) inside_block:copyDirectoryToRunningContainerAsDir
<!--/codeinclude-->

## Copying files from a container

It's also possible to copy files from a container to the host machine. This can be done by using the `CopyFileFromContainer` method on the `Container` type, which will return an error and an `io.ReadCloser` that you can use to read the file content.

<!--codeinclude-->
[Copying a file from a container](../../examples_test.go) inside_block:copyFileFromContainer
<!--/codeinclude-->

In the above example, we previously copied the file `/tmp/file.txt` to the container, and then we copied it back to the host machine, reading the content of the file.

## Volume mapping

It is possible to map a Docker volume into the container using the `Mounts` attribute at the `ContainerRequest` struct. For that, please pass an instance of the `GenericVolumeMountSource` type, which allows you to specify the name of the volume to be mapped, and the path inside the container where it should be mounted:

<!--codeinclude-->
[Volume mounts](../../mounts_test.go) inside_block:volumeMounts
<!--/codeinclude-->

!!!tip
This ability of creating volumes is also available for remote Docker hosts.

!!!warning
Bind mounts are not supported, as it could not work with remote Docker hosts.

!!!tip
It is recommended to copy data from your local host machine to a test container using the file copy API
described below, as it is much more portable.

## Mounting images

Since Docker v28, it is possible to mount the file system of an image into a container using the `Mounts` attribute at the `ContainerRequest` struct. For that, use the `DockerImageMountSource` type, which allows you to specify the name of the image to be mounted, and the subpath inside the container where it should be mounted, or simply call the `ImageMount` function, which does exactly that:

<!--codeinclude-->
[Image mounts](../../lifecycle_test.go) inside_block:imageMounts
<!--/codeinclude-->

!!!warning
If the subpath is not a relative path, the creation of the container will fail.

!!!info
Mounting images fails the creation of the container if the underlying container runtime does not support the `image mount` feature, which is available since Docker v28.

4 changes: 3 additions & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ func ExampleRun() {
fmt.Println(ctrResp.Config.Labels["testcontainers.label"])

// files
f, err := ctr.CopyFileFromContainer(ctx, "/tmp/file.txt")
// copyFileFromContainer {
f, err := ctr.CopyFileFromContainer(context.Background(), "/tmp/file.txt")
if err != nil {
log.Printf("failed to copy file from container: %s", err)
return
Expand All @@ -114,6 +115,7 @@ func ExampleRun() {
log.Printf("failed to read file: %s", err)
return
}
// }
fmt.Println(string(content))

// Output:
Expand Down
Loading