Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
12 changes: 6 additions & 6 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,25 +141,25 @@ type ContainerRequest struct {
Tmpfs map[string]string
RegistryCred string // Deprecated: Testcontainers will detect registry credentials automatically
WaitingFor wait.Strategy
Name string // for specifying container name
Hostname string
WorkingDir string // specify the working directory of the container
Name string // for specifying container name
Hostname string // Deprecated: Use [ConfigModifier] instead. S
WorkingDir string // Deprecated: Use [ConfigModifier] instead. Specify the working directory of the container
ExtraHosts []string // Deprecated: Use HostConfigModifier instead
Privileged bool // For starting privileged container
Privileged bool // Deprecated: Use [HostConfigModifier] instead. For starting privileged container
Networks []string // for specifying network names
NetworkAliases map[string][]string // for specifying network aliases
NetworkMode container.NetworkMode // Deprecated: Use HostConfigModifier instead
Resources container.Resources // Deprecated: Use HostConfigModifier instead
Files []ContainerFile // files which will be copied when container starts
User string // for specifying uid:gid
User string // Deprecated: Use [ConfigModifier] instead. For specifying uid:gid
SkipReaper bool // Deprecated: The reaper is globally controlled by the .testcontainers.properties file or the TESTCONTAINERS_RYUK_DISABLED environment variable
ReaperImage string // Deprecated: use WithImageName ContainerOption instead. Alternative reaper image
ReaperOptions []ContainerOption // Deprecated: the reaper is configured at the properties level, for an entire test session
AutoRemove bool // Deprecated: Use HostConfigModifier instead. If set to true, the container will be removed from the host when stopped
AlwaysPullImage bool // Always pull image
ImagePlatform string // ImagePlatform describes the platform which the image runs on.
Binds []string // Deprecated: Use HostConfigModifier instead
ShmSize int64 // Amount of memory shared with the host (in bytes)
ShmSize int64 // Deprecated: Use [HostConfigModifier] instead. Amount of memory shared with the host (in bytes)
CapAdd []string // Deprecated: Use HostConfigModifier instead. Add Linux capabilities
CapDrop []string // Deprecated: Use HostConfigModifier instead. Drop Linux capabilities
ConfigModifier func(*container.Config) // Modifier for the config before container creation
Expand Down
7 changes: 1 addition & 6 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1153,15 +1153,10 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque
Env: env,
Labels: req.Labels,
Cmd: req.Cmd,
Hostname: req.Hostname,
User: req.User,
WorkingDir: req.WorkingDir,
}

hostConfig := &container.HostConfig{
Privileged: req.Privileged,
ShmSize: req.ShmSize,
Tmpfs: req.Tmpfs,
Tmpfs: req.Tmpfs,
}

networkingConfig := &network.NetworkingConfig{}
Expand Down
26 changes: 18 additions & 8 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ func TestContainerWithHostNetworkOptions(t *testing.T) {
ExposedPorts: []string{
nginxHighPort,
},
Privileged: true,
WaitingFor: wait.ForHTTP("/").WithPort(nginxHighPort),
HostConfigModifier: func(hc *container.HostConfig) {
hc.NetworkMode = "host"
hc.Privileged = true
},
},
Started: true,
Expand All @@ -97,8 +97,10 @@ func TestContainerWithHostNetworkOptions_UseExposePortsFromImageConfigs(t *testi
gcr := GenericContainerRequest{
ContainerRequest: ContainerRequest{
Image: "nginx",
Privileged: true,
WaitingFor: wait.ForExposedPort(),
HostConfigModifier: func(hc *container.HostConfig) {
hc.Privileged = true
},
},
Started: true,
}
Expand Down Expand Up @@ -874,7 +876,9 @@ func TestWorkingDir(t *testing.T) {
wait.ForLog("/var/tmp/test"),
),
Entrypoint: []string{"pwd"},
WorkingDir: "/var/tmp/test",
ConfigModifier: func(c *container.Config) {
c.WorkingDir = "/var/tmp/test"
},
}

c, err := GenericContainer(ctx, GenericContainerRequest{
Expand Down Expand Up @@ -1291,9 +1295,11 @@ func TestContainerWithCustomHostname(t *testing.T) {
name := fmt.Sprintf("some-nginx-%s-%d", t.Name(), rand.Int())
hostname := fmt.Sprintf("my-nginx-%s-%d", t.Name(), rand.Int())
req := ContainerRequest{
Name: name,
Image: nginxImage,
Hostname: hostname,
Name: name,
Image: nginxImage,
ConfigModifier: func(c *container.Config) {
c.Hostname = hostname
},
}
ctr, err := GenericContainer(ctx, GenericContainerRequest{
ProviderType: providerType,
Expand Down Expand Up @@ -1758,12 +1764,16 @@ func TestContainerRunningCheckingStatusCode(t *testing.T) {
}

func TestContainerWithUserID(t *testing.T) {
const expectedUserID = "60125"

ctx := context.Background()
req := ContainerRequest{
Image: "alpine:latest",
User: "60125",
Cmd: []string{"sh", "-c", "id -u"},
WaitingFor: wait.ForExit(),
ConfigModifier: func(c *container.Config) {
c.User = expectedUserID
},
}
ctr, err := GenericContainer(ctx, GenericContainerRequest{
ProviderType: providerType,
Expand All @@ -1779,7 +1789,7 @@ func TestContainerWithUserID(t *testing.T) {
b, err := io.ReadAll(r)
require.NoError(t, err)
actual := regexp.MustCompile(`\D+`).ReplaceAllString(string(b), "")
assert.Equal(t, req.User, actual)
require.Equal(t, expectedUserID, actual)
}

func TestContainerWithNoUserID(t *testing.T) {
Expand Down
123 changes: 119 additions & 4 deletions docs/features/common_functional_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,103 @@ Using the `WithImageSubstitutors` options, you could define your own substitutio
If you need to either pass additional environment variables to a container or override them, you can use `testcontainers.WithEnv` for example:

```golang
postgres, err = postgresModule.Run(ctx, "postgres:15-alpine", testcontainers.WithEnv(map[string]string{"POSTGRES_INITDB_ARGS": "--no-sync"}))
ctr, err = mymodule.Run(ctx, "docker.io/myservice:1.2.3", testcontainers.WithEnv(map[string]string{"FOO": "BAR"}))
```

#### WithExposedPorts

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to expose additional ports from the container, you can use `testcontainers.WithExposedPorts`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithExposedPorts("8080/tcp", "9090/tcp"))
```

#### WithEntrypoint

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to append commands to the container's entrypoint, you can use `testcontainers.WithEntrypoint`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithEntrypoint("/bin/sh", "-c", "echo hello"))
```

#### WithCmd

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to append commands to the container's command, you can use `testcontainers.WithCmd`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithCmd("echo", "hello"))
```

#### WithLabels

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to add Docker labels to the container, you can use `testcontainers.WithLabels`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithLabels(map[string]string{
"environment": "testing",
"project": "myapp",
}))
```

#### WithFiles

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to copy files into the container, you can use `testcontainers.WithFiles`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithFiles([]testcontainers.ContainerFile{
{
HostFilePath: "/path/to/local/file.txt",
ContainerFilePath: "/container/file.txt",
FileMode: 0o644,
},
}))
```

This option allows you to copy files from the host into the container at creation time.

#### WithMounts

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to add volume mounts to the container, you can use `testcontainers.WithMounts`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithMounts([]testcontainers.ContainerMount{
{
Source: testcontainers.GenericVolumeMountSource{Name: "appdata"},
Target: "/app/data",
},
}))
```

#### WithTmpfs

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

If you need to add tmpfs mounts to the container, you can use `testcontainers.WithTmpfs`. For example:

```golang
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
testcontainers.WithTmpfs(map[string]string{
"/tmp": "size=100m",
"/run": "size=100m",
}))
```

#### WithHostPortAccess
Expand All @@ -32,7 +128,7 @@ postgres, err = postgresModule.Run(ctx, "postgres:15-alpine", testcontainers.Wit
If you need to access a port that is already running in the host, you can use `testcontainers.WithHostPortAccess` for example:

```golang
postgres, err = postgresModule.Run(ctx, "postgres:15-alpine", testcontainers.WithHostPortAccess(8080))
ctr, err = mymodule.Run(ctx, "docker.io/myservice:1.2.3", testcontainers.WithHostPortAccess(8080))
```

To understand more about this feature, please read the [Exposing host ports to the container](/features/networking/#exposing-host-ports-to-the-container) documentation.
Expand Down Expand Up @@ -70,7 +166,7 @@ useful context instead of appearing out of band.
```golang
func TestHandler(t *testing.T) {
logger := log.TestLogger(t)
ctr, err := postgresModule.Run(ctx, "postgres:15-alpine", testcontainers.WithLogger(logger))
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3", testcontainers.WithLogger(logger))
CleanupContainer(t, ctr)
require.NoError(t, err)
// Do something with container.
Expand Down Expand Up @@ -117,6 +213,25 @@ It leverages the `Executable` interface to represent the command and positional

You could use this feature to run a custom script, or to run a command that is not supported by the module right after the container is ready.

#### Build from Dockerfile

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

Testcontainers exposes the `testcontainers.WithDockerfile` option to build a container from a Dockerfile.
The functional option receives a `testcontainers.FromDockerfile` struct that is applied to the container request before starting the container. As a result, the container is built and started in one go.

```golang
df := testcontainers.FromDockerfile{
Context: ".",
Dockerfile: "Dockerfile",
Repo: "testcontainers",
Tag: "latest",
BuildArgs: map[string]*string{"ARG1": nil, "ARG2": nil},
}

ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3", testcontainers.WithDockerfile(df))
```

#### WithNetwork

- Since testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go/releases/tag/v0.27.0"><span class="tc-version">:material-tag: v0.27.0</span></a>
Expand Down Expand Up @@ -151,7 +266,7 @@ Please read the [Create containers: Advanced Settings](/features/creating_contai
This option will merge the customized request into the module's own `ContainerRequest`.

```go
container, err := Run(ctx, "postgres:13-alpine",
ctr, err := mymodule.Run(ctx, "docker.io/myservice:1.2.3",
/* Other module options */
testcontainers.CustomizeRequest(testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Expand Down
42 changes: 36 additions & 6 deletions docs/features/creating_container.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,46 @@

Testcontainers are a wrapper around the Docker daemon designed for tests. Anything you can run in Docker, you can spin
up with Testcontainers and integrate into your tests:

* NoSQL databases or other data stores (e.g. Redis, ElasticSearch, MongoDB)
* Web servers/proxies (e.g. NGINX, Apache)
* Log services (e.g. Logstash, Kibana)
* Other services developed by your team/organization which are already dockerized

## Run

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

`testcontainers.Run` defines the container that should be run, similar to the `docker run` command.

```golang
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*DockerContainer, error)
```

- `context.Context`, the Go context.
- `string`, the Docker image to use.
- `testcontainers.ContainerCustomizer`, a variadic argument for passing options.

The following test creates an NGINX container on both the `bridge` (docker default
network) and the `foo` network and validates that it returns 200 for the status code.

It also demonstrates how to use `CleanupContainer`, that ensures that nginx container
is removed when the test ends even if the underlying container errored,
as well as the `CleanupNetwork` which does the same for networks.

The alternatives for these outside of tests as a `defer` are `TerminateContainer`
and `Network.Remove` which can be seen in the examples.

<!--codeinclude-->
[Creating a container](../../examples_test.go) inside_block:ExampleRun
<!--/codeinclude-->

## GenericContainer

!!!warning
`GenericContainer` is the old way to create a container, and we recommend using `Run` instead,
as it could be deprecated in the future.

`testcontainers.GenericContainer` defines the container that should be run, similar to the `docker run` command.

The following test creates an NGINX container on both the `bridge` (docker default
Expand Down Expand Up @@ -81,14 +114,11 @@ func TestIntegrationNginxLatestReturn(t *testing.T) {

ctx := context.Background()

networkName := "foo"
net, err := provider.CreateNetwork(ctx, NetworkRequest{
Name: networkName,
})
nw, err := network.New(ctx)
require.NoError(t, err)
CleanupNetwork(t, net)
testcontainers.CleanupNetwork(t, nw)

nginxC, err := setupNginx(ctx, networkName)
nginxC, err := setupNginx(ctx, nw.Name)
testcontainers.CleanupContainer(t, nginxC)
require.NoError(t, err)

Expand Down
10 changes: 9 additions & 1 deletion docs/modules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,26 @@ In order to simplify the creation of the container for a given module, `Testcont

- `testcontainers.WithImageSubstitutors`: a function that sets your own substitutions to the container images.
- `testcontainers.WithEnv`: a function that sets the environment variables for the container request.
- `testcontainers.WithExposedPorts`: a function that exposes additional ports from the container.
- `testcontainers.WithEntrypoint`: a function that appends commands to the container's entrypoint.
- `testcontainers.WithCmd`: a function that appends commands to the container's command.
- `testcontainers.WithLabels`: a function that adds Docker labels to the container.
- `testcontainers.WithFiles`: a function that copies files from the host into the container at creation time.
- `testcontainers.WithMounts`: a function that adds volume mounts to the container.
- `testcontainers.WithTmpfs`: a function that adds tmpfs mounts to the container.
- `testcontainers.WithHostPortAccess`: a function that enables the container to access a port that is already running in the host.
- `testcontainers.WithLogConsumers`: a function that sets the log consumers for the container request.
- `testcontainers.WithLogger`: a function that sets the logger for the container request.
- `testcontainers.WithWaitStrategy`: a function that sets the wait strategy for the container request.
- `testcontainers.WithWaitStrategyAndDeadline`: a function that sets the wait strategy for the container request with a deadline.
- `testcontainers.WithStartupCommand`: a function that sets the execution of a command when the container starts.
- `testcontainers.WithAfterReadyCommand`: a function that sets the execution of a command right after the container is ready (its wait strategy is satisfied).
- `testcontainers.WithDockerfile`: a function that sets the build from a Dockerfile for the container request.
- `testcontainers.WithNetwork`: a function that sets the network and the network aliases for the container request.
- `testcontainers.WithNewNetwork`: a function that sets the network aliases for a throw-away network for the container request.
- `testcontainers.WithConfigModifier`: a function that sets the config Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information.
- `testcontainers.WithEndpointSettingsModifier`: a function that sets the endpoint settings Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information.
- `testcontainers.WithHostConfigModifier`: a function that sets the host config Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information.
- `testcontainers.WithEndpointSettingsModifier`: a function that sets the endpoint settings Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information.
- `testcontainers.CustomizeRequest`: a function that merges the default options with the ones provided by the user. Recommended for completely customizing the container request.

### Update Go dependencies in the modules
Expand Down
Loading
Loading