or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

containers.mddocker-compose.mdimages-files.mdindex.mdjunit-integration.mdnetworks.mdoutput-logging.mdtestcontainers-utility.mdwait-strategies.md

docker-compose.mddocs/

0

# Docker Compose Integration

1

2

Support for Docker Compose multi-container environments, enabling complex multi-service testing scenarios with service discovery, orchestration, and environment management using existing Docker Compose files.

3

4

## Capabilities

5

6

### DockerComposeContainer

7

8

Primary class for managing Docker Compose environments in tests, providing full lifecycle management and service discovery.

9

10

```java { .api }

11

/**

12

* Container for managing Docker Compose multi-service environments

13

* @param <SELF> Self-referencing type for fluent API

14

*/

15

public class DockerComposeContainer<SELF extends DockerComposeContainer<SELF>>

16

extends GenericContainer<SELF> {

17

18

/** Create from single compose file */

19

public DockerComposeContainer(File composeFile);

20

21

/** Create from multiple compose files */

22

public DockerComposeContainer(List<File> composeFiles);

23

24

/** Create from compose file resource */

25

public DockerComposeContainer(String composeFileResource);

26

27

/** Specify which services to start (default: all services) */

28

public SELF withServices(String... services);

29

30

/** Configure environment variables for compose */

31

public SELF withEnv(String key, String value);

32

public SELF withEnv(Map<String, String> env);

33

34

/** Configure compose file environment variable substitution */

35

public SELF withEnvFile(File envFile);

36

37

/** Configure Docker Compose profiles */

38

public SELF withProfiles(String... profiles);

39

40

/** Configure local Docker Compose binary */

41

public SELF withLocalCompose(boolean localCompose);

42

43

/** Configure compose options */

44

public SELF withOptions(String... options);

45

46

/** Configure build arguments */

47

public SELF withBuild(boolean build);

48

49

/** Configure pull policy */

50

public SELF withPull(boolean pull);

51

52

/** Configure remove orphans */

53

public SELF withRemoveOrphans(boolean removeOrphans);

54

55

/** Get service host address */

56

public String getServiceHost(String serviceName, int servicePort);

57

58

/** Get mapped port for service */

59

public Integer getServicePort(String serviceName, int servicePort);

60

61

/** Get service container by name */

62

public ContainerState getServiceContainer(String serviceName);

63

64

/** Get all service containers */

65

public Map<String, ContainerState> getServiceContainers();

66

67

/** Execute command in specific service */

68

public Container.ExecResult execInService(String serviceName, String... command)

69

throws IOException, InterruptedException;

70

71

/** Get logs from specific service */

72

public String getServiceLogs(String serviceName);

73

}

74

```

75

76

**Usage Examples:**

77

78

```java

79

import org.testcontainers.containers.DockerComposeContainer;

80

import java.io.File;

81

82

// Basic Docker Compose setup

83

DockerComposeContainer<?> compose = new DockerComposeContainer<>(

84

new File("src/test/resources/docker-compose.yml"))

85

.withServices("web", "database")

86

.withExposedService("web", 8080)

87

.withExposedService("database", 5432);

88

89

compose.start();

90

91

// Access services

92

String webHost = compose.getServiceHost("web", 8080);

93

Integer webPort = compose.getServicePort("web", 8080);

94

String webUrl = "http://" + webHost + ":" + webPort;

95

96

String dbHost = compose.getServiceHost("database", 5432);

97

Integer dbPort = compose.getServicePort("database", 5432);

98

```

99

100

### Compose File Management

101

102

Utilities for working with Docker Compose files and configurations.

103

104

```java { .api }

105

/**

106

* Utilities for Docker Compose file handling

107

*/

108

public class DockerComposeFiles {

109

110

/** Load compose file from classpath */

111

public static File fromClasspath(String resource);

112

113

/** Load multiple compose files */

114

public static List<File> fromClasspath(String... resources);

115

116

/** Create temporary compose file from content */

117

public static File fromContent(String composeContent);

118

119

/** Merge multiple compose configurations */

120

public static File merge(File... composeFiles);

121

}

122

123

/**

124

* Parsed Docker Compose file representation

125

*/

126

public class ParsedDockerComposeFile {

127

128

public ParsedDockerComposeFile(File composeFile);

129

130

/** Get all service names */

131

public Set<String> getServiceNames();

132

133

/** Get service configuration */

134

public Map<String, Object> getServiceConfig(String serviceName);

135

136

/** Get service ports */

137

public List<Integer> getServicePorts(String serviceName);

138

139

/** Get service environment variables */

140

public Map<String, String> getServiceEnv(String serviceName);

141

142

/** Check if service exists */

143

public boolean hasService(String serviceName);

144

145

/** Get compose file version */

146

public String getComposeVersion();

147

}

148

```

149

150

### Local Docker Compose

151

152

Support for using local Docker Compose binary instead of embedded compose functionality.

153

154

```java { .api }

155

/**

156

* Local Docker Compose execution support

157

*/

158

public class LocalDockerCompose {

159

160

public LocalDockerCompose(File... composeFiles);

161

public LocalDockerCompose(List<File> composeFiles);

162

163

/** Configure environment variables */

164

public LocalDockerCompose withEnv(String key, String value);

165

public LocalDockerCompose withEnv(Map<String, String> env);

166

167

/** Configure services to start */

168

public LocalDockerCompose withServices(String... services);

169

170

/** Configure Docker Compose command options */

171

public LocalDockerCompose withCommand(String... command);

172

173

/** Start services */

174

public LocalDockerCompose up();

175

176

/** Stop services */

177

public LocalDockerCompose down();

178

179

/** Execute compose command */

180

public LocalDockerCompose invoke(String... args);

181

182

/** Get service information */

183

public String getServiceHost(String serviceName, int servicePort);

184

public Integer getServicePort(String serviceName, int servicePort);

185

}

186

```

187

188

### Compose Container Extensions

189

190

Extended container functionality for compose environments.

191

192

```java { .api }

193

/**

194

* Enhanced compose container with additional service management

195

*/

196

public class ComposeContainer extends DockerComposeContainer<ComposeContainer> {

197

198

public ComposeContainer(File... composeFiles);

199

200

/** Wait for specific service to be ready */

201

public ComposeContainer waitingForService(String serviceName, WaitStrategy waitStrategy);

202

203

/** Configure service-specific wait strategies */

204

public ComposeContainer withServiceWaitStrategy(String serviceName, WaitStrategy waitStrategy);

205

206

/** Scale service to specific number of instances */

207

public ComposeContainer withServiceScale(String serviceName, int scale);

208

209

/** Get all instances of a scaled service */

210

public List<ContainerState> getServiceInstances(String serviceName);

211

212

/** Execute command across all service instances */

213

public List<Container.ExecResult> execInAllServiceInstances(String serviceName, String... command);

214

}

215

```

216

217

## Advanced Docker Compose Patterns

218

219

### Multi-File Compose Setup

220

221

Using multiple compose files for different environments and configurations:

222

223

```java

224

@Test

225

public void testWithMultipleComposeFiles() {

226

DockerComposeContainer<?> compose = new DockerComposeContainer<>(

227

Arrays.asList(

228

new File("docker-compose.base.yml"),

229

new File("docker-compose.test.yml"),

230

new File("docker-compose.override.yml")

231

))

232

.withServices("app", "database", "redis")

233

.withEnv("ENVIRONMENT", "test")

234

.withProfiles("testing");

235

236

compose.start();

237

238

// Test services

239

testApplication(compose.getServiceHost("app", 8080),

240

compose.getServicePort("app", 8080));

241

}

242

```

243

244

### Service Dependencies and Ordering

245

246

Managing service startup order and dependencies:

247

248

```java

249

@Test

250

public void testServiceDependencies() {

251

DockerComposeContainer<?> compose = new DockerComposeContainer<>(

252

new File("docker-compose.yml"))

253

// Database must be ready before application

254

.waitingForService("database", Wait.forListeningPort())

255

.waitingForService("redis", Wait.forListeningPort())

256

// Application waits for both database and redis

257

.waitingForService("app", Wait.forHttp("/health").forStatusCode(200))

258

.withStartupTimeout(Duration.ofMinutes(5));

259

260

compose.start();

261

262

// All services are now ready in correct order

263

}

264

```

265

266

### Environment-Specific Configuration

267

268

Using environment variables and profiles for different test scenarios:

269

270

```java

271

@Test

272

public void testProductionLikeEnvironment() {

273

DockerComposeContainer<?> compose = new DockerComposeContainer<>(

274

new File("docker-compose.yml"))

275

.withEnv("DATABASE_URL", "postgresql://db:5432/prodlike")

276

.withEnv("REDIS_URL", "redis://cache:6379")

277

.withEnv("LOG_LEVEL", "DEBUG")

278

.withProfiles("production", "monitoring")

279

.withServices("app", "database", "redis", "monitoring");

280

281

compose.start();

282

283

// Test production-like configuration

284

}

285

```

286

287

### Service Scaling and Load Testing

288

289

Testing with multiple instances of services:

290

291

```java

292

@Test

293

public void testServiceScaling() {

294

ComposeContainer compose = new ComposeContainer(

295

new File("docker-compose.yml"))

296

.withServiceScale("worker", 3) // Scale worker service to 3 instances

297

.withServiceScale("app", 2) // Scale app service to 2 instances

298

.waitingForService("app", Wait.forHttp("/health"));

299

300

compose.start();

301

302

// Get all app instances

303

List<ContainerState> appInstances = compose.getServiceInstances("app");

304

assertEquals(2, appInstances.size());

305

306

// Test load balancing across instances

307

for (ContainerState instance : appInstances) {

308

String url = "http://" + instance.getHost() + ":" + instance.getMappedPort(8080);

309

// Test each instance

310

}

311

}

312

```

313

314

### Custom Compose File Generation

315

316

Generating compose files dynamically for test scenarios:

317

318

```java

319

@Test

320

public void testDynamicComposeFile() {

321

String composeContent = """

322

version: '3.8'

323

services:

324

app:

325

image: myapp:latest

326

ports:

327

- "8080"

328

environment:

329

- DATABASE_URL=postgresql://db:5432/testdb

330

- REDIS_URL=redis://cache:6379

331

depends_on:

332

- db

333

- cache

334

db:

335

image: postgres:13

336

environment:

337

POSTGRES_DB: testdb

338

POSTGRES_USER: test

339

POSTGRES_PASSWORD: test

340

ports:

341

- "5432"

342

cache:

343

image: redis:alpine

344

ports:

345

- "6379"

346

""";

347

348

File tempCompose = DockerComposeFiles.fromContent(composeContent);

349

350

DockerComposeContainer<?> compose = new DockerComposeContainer<>(tempCompose)

351

.withServices("app", "db", "cache");

352

353

compose.start();

354

355

// Test the dynamically created environment

356

}

357

```

358

359

### Integration with TestContainers Networks

360

361

Combining Docker Compose with TestContainers networks:

362

363

```java

364

@Test

365

public void testComposeWithCustomNetwork() {

366

try (Network testNetwork = Network.newNetwork()) {

367

368

DockerComposeContainer<?> compose = new DockerComposeContainer<>(

369

new File("docker-compose.yml"))

370

.withNetwork(testNetwork)

371

.withServices("app", "database");

372

373

// Additional container in same network

374

GenericContainer<?> monitor = new GenericContainer<>("monitoring:latest")

375

.withNetwork(testNetwork)

376

.withNetworkAliases("monitor")

377

.withExposedPorts(9090);

378

379

compose.start();

380

monitor.start();

381

382

// All containers can communicate within the network

383

}

384

}

385

```

386

387

### Compose File Validation and Debugging

388

389

```java

390

@Test

391

public void testComposeFileValidation() {

392

File composeFile = new File("docker-compose.yml");

393

ParsedDockerComposeFile parsed = new ParsedDockerComposeFile(composeFile);

394

395

// Validate compose file structure

396

assertTrue(parsed.hasService("app"));

397

assertTrue(parsed.hasService("database"));

398

399

// Check service configuration

400

List<Integer> appPorts = parsed.getServicePorts("app");

401

assertTrue(appPorts.contains(8080));

402

403

Map<String, String> dbEnv = parsed.getServiceEnv("database");

404

assertEquals("testdb", dbEnv.get("POSTGRES_DB"));

405

406

// Create container with validated configuration

407

DockerComposeContainer<?> compose = new DockerComposeContainer<>(composeFile)

408

.withServices(parsed.getServiceNames().toArray(new String[0]));

409

}

410

```