Skip to content

Commit 7107189

Browse files
authored
Add support for custom client options in DockerComposeEnvironment (#1044)
1 parent 0d6250c commit 7107189

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

docs/features/compose.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ const environment = await new DockerComposeEnvironment(composeFilePath, composeF
142142
.up();
143143
```
144144

145+
### With custom client options
146+
147+
See [docker-compose](https://github.com/PDMLab/docker-compose/) library.
148+
149+
```javascript
150+
const environment = await new DockerComposeEnvironment(composeFilePath, composeFile)
151+
.withClientOptions({ executable: { standalone: true, executablePath: "/path/to/docker-compose" } })
152+
.up();
153+
```
154+
155+
145156
## Downing a Docker compose environment
146157

147158
Testcontainers by default will not wait until the environment has downed. It will simply issue the down command and return immediately. This is to save time when running tests.

packages/testcontainers/src/container-runtime/clients/compose/default-compose-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ export function defaultComposeOptions(
2929
COMPOSE_PROJECT_NAME: options.projectName,
3030
...{ ...environment, ...options.environment },
3131
},
32+
executable: options.executable,
3233
};
3334
}

packages/testcontainers/src/container-runtime/clients/compose/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,21 @@ export type ComposeOptions = {
88
composeOptions?: string[];
99
environment?: NodeJS.ProcessEnv;
1010
logger?: Logger;
11+
executable?: ComposeExecutableOptions;
1112
};
1213

14+
export type ComposeExecutableOptions =
15+
| {
16+
executablePath: string;
17+
options?: string[] | (string | string[])[];
18+
standalone?: never;
19+
}
20+
| {
21+
executablePath?: string;
22+
options?: never;
23+
standalone: true;
24+
};
25+
1326
export type ComposeDownOptions = {
1427
timeout: number;
1528
removeVolumes: boolean;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export { getAuthConfig } from "./auth/get-auth-config";
22
export { ContainerRuntimeClient, getContainerRuntimeClient } from "./clients/client";
33
export { parseComposeContainerName } from "./clients/compose/parse-compose-container-name";
4-
export { ComposeDownOptions, ComposeOptions } from "./clients/compose/types";
4+
export { ComposeDownOptions, ComposeExecutableOptions, ComposeOptions } from "./clients/compose/types";
55
export { HostIp } from "./clients/types";
66
export { ImageName } from "./image-name";

packages/testcontainers/src/docker-compose-environment/docker-compose-environment.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ContainerInfo } from "dockerode";
22
import { containerLog, log, RandomUuid, Uuid } from "../common";
3-
import { getContainerRuntimeClient, parseComposeContainerName } from "../container-runtime";
3+
import { ComposeOptions, getContainerRuntimeClient, parseComposeContainerName } from "../container-runtime";
44
import { StartedGenericContainer } from "../generic-container/started-generic-container";
55
import { getReaper } from "../reaper/reaper";
66
import { Environment } from "../types";
@@ -26,6 +26,7 @@ export class DockerComposeEnvironment {
2626
private defaultWaitStrategy: WaitStrategy = Wait.forListeningPorts();
2727
private waitStrategy: { [containerName: string]: WaitStrategy } = {};
2828
private startupTimeoutMs?: number;
29+
private clientOptions: Partial<ComposeOptions> = {};
2930

3031
constructor(composeFilePath: string, composeFiles: string | string[], uuid: Uuid = new RandomUuid()) {
3132
this.composeFilePath = composeFilePath;
@@ -84,27 +85,41 @@ export class DockerComposeEnvironment {
8485
return this;
8586
}
8687

88+
public withClientOptions(
89+
options: Partial<Omit<ComposeOptions, "filePath" | "files" | "projectName" | "environment">>
90+
): this {
91+
this.clientOptions = { ...this.clientOptions, ...options };
92+
return this;
93+
}
94+
8795
public async up(services?: Array<string>): Promise<StartedDockerComposeEnvironment> {
8896
log.info(`Starting DockerCompose environment "${this.projectName}"...`);
8997
const client = await getContainerRuntimeClient();
9098
const reaper = await getReaper(client);
9199
reaper.addComposeProject(this.projectName);
92100

101+
const {
102+
composeOptions: clientComposeOptions = [],
103+
commandOptions: clientCommandOptions = [],
104+
...remainingClientOptions
105+
} = this.clientOptions;
106+
93107
const options = {
108+
...remainingClientOptions,
94109
filePath: this.composeFilePath,
95110
files: this.composeFiles,
96111
projectName: this.projectName,
97112
};
98113

99-
const commandOptions = [];
114+
const commandOptions = [...clientCommandOptions];
100115
if (this.build) {
101116
commandOptions.push("--build");
102117
}
103118
if (!this.recreate) {
104119
commandOptions.push("--no-recreate");
105120
}
106121

107-
const composeOptions: string[] = [];
122+
const composeOptions = [...clientComposeOptions];
108123
if (this.environmentFile) {
109124
composeOptions.push("--env-file", this.environmentFile);
110125
}

0 commit comments

Comments
 (0)