or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compose-files.mdcompose-project.mdconsole-commands.mddevservices-processing.mdindex.md

compose-files.mddocs/

0

# Compose File Processing

1

2

Docker Compose file parsing, validation, and service definition extraction with support for multiple compose files and project naming.

3

4

## Capabilities

5

6

### ComposeFiles

7

8

Manages multiple compose files and aggregates their service definitions while handling project naming and service conflicts.

9

10

```java { .api }

11

/**

12

* Container for multiple compose files with aggregated service definitions

13

*/

14

public class ComposeFiles {

15

16

/**

17

* Creates a ComposeFiles instance from a list of compose files

18

* @param composeFiles List of compose file objects to process

19

* @throws IllegalArgumentException If service name conflicts exist

20

*/

21

public ComposeFiles(List<File> composeFiles);

22

23

/**

24

* Gets all service names across all compose files

25

* @return Set of unique service names

26

*/

27

public Set<String> getAllServiceNames();

28

29

/**

30

* Gets all service definitions from all compose files

31

* @return Map of service name to service definition

32

*/

33

public Map<String, ComposeServiceDefinition> getServiceDefinitions();

34

35

/**

36

* Gets the project name from the compose files

37

* @return Project name or null if not specified

38

*/

39

public String getProjectName();

40

41

/**

42

* Gets the list of compose files

43

* @return List of File objects

44

*/

45

public List<File> getFiles();

46

}

47

```

48

49

**Usage Examples:**

50

51

```java

52

import io.quarkus.devservices.deployment.compose.*;

53

import java.io.File;

54

import java.util.List;

55

56

// Process multiple compose files

57

List<File> files = List.of(

58

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

59

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

60

new File("compose-dev-services.yml")

61

);

62

63

ComposeFiles composeFiles = new ComposeFiles(files);

64

65

// Get aggregated information

66

Set<String> allServices = composeFiles.getAllServiceNames();

67

Map<String, ComposeServiceDefinition> definitions = composeFiles.getServiceDefinitions();

68

String projectName = composeFiles.getProjectName();

69

70

// Process each service

71

for (String serviceName : allServices) {

72

ComposeServiceDefinition definition = definitions.get(serviceName);

73

74

System.out.println("Service: " + serviceName);

75

System.out.println("Container: " + definition.getContainerName());

76

System.out.println("Ports: " + definition.getPorts());

77

System.out.println("Labels: " + definition.getLabels());

78

System.out.println("Profiles: " + definition.getProfiles());

79

}

80

81

// Use in ComposeProject

82

ComposeProject project = new ComposeProject.Builder(composeFiles, "docker")

83

.withProject(projectName != null ? projectName : "default-project")

84

.build();

85

```

86

87

### ComposeFile

88

89

Parses and validates individual Docker Compose files, extracting service definitions and project metadata.

90

91

```java { .api }

92

/**

93

* Representation of a docker-compose file with parsing and validation

94

*/

95

public class ComposeFile {

96

97

/**

98

* Creates a ComposeFile by parsing the given file

99

* @param composeFile File object pointing to compose file

100

* @throws IllegalArgumentException If file cannot be parsed

101

*/

102

public ComposeFile(File composeFile);

103

104

/**

105

* Gets the project name specified in the compose file

106

* @return Project name or null if not specified

107

*/

108

public String getProjectName();

109

110

/**

111

* Gets all service definitions from this compose file

112

* @return Map of service name to service definition

113

*/

114

public Map<String, ComposeServiceDefinition> getServiceDefinitions();

115

}

116

```

117

118

**Usage Examples:**

119

120

```java

121

// Parse a single compose file

122

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

123

ComposeFile compose = new ComposeFile(composeFile);

124

125

// Get project and service information

126

String projectName = compose.getProjectName();

127

Map<String, ComposeServiceDefinition> services = compose.getServiceDefinitions();

128

129

System.out.println("Project: " + (projectName != null ? projectName : "unnamed"));

130

System.out.println("Services found: " + services.size());

131

132

// Process each service

133

for (Map.Entry<String, ComposeServiceDefinition> entry : services.entrySet()) {

134

String serviceName = entry.getKey();

135

ComposeServiceDefinition definition = entry.getValue();

136

137

System.out.println("\nService: " + serviceName);

138

if (definition.getContainerName() != null) {

139

System.out.println(" Container: " + definition.getContainerName());

140

}

141

if (definition.hasHealthCheck()) {

142

System.out.println(" Has health check: true");

143

}

144

if (!definition.getPorts().isEmpty()) {

145

System.out.println(" Exposed ports: " + definition.getPorts());

146

}

147

if (!definition.getProfiles().isEmpty()) {

148

System.out.println(" Profiles: " + definition.getProfiles());

149

}

150

}

151

152

// Handle parsing errors

153

try {

154

ComposeFile invalidFile = new ComposeFile(new File("invalid.yml"));

155

} catch (IllegalArgumentException e) {

156

System.err.println("Failed to parse compose file: " + e.getMessage());

157

}

158

```

159

160

### ComposeServiceDefinition

161

162

Represents an individual service definition from a Docker Compose file with access to all service configuration.

163

164

```java { .api }

165

/**

166

* Represents a service definition in a docker-compose file

167

*/

168

public class ComposeServiceDefinition {

169

170

/**

171

* Creates a service definition from compose data

172

* @param serviceName Name of the service

173

* @param definitionMap Raw service definition data from YAML

174

*/

175

public ComposeServiceDefinition(String serviceName, Map<String, ?> definitionMap);

176

177

/**

178

* Gets the service name

179

* @return Service name

180

*/

181

public String getServiceName();

182

183

/**

184

* Gets the container name if specified

185

* @return Container name or null if using default naming

186

*/

187

public String getContainerName();

188

189

/**

190

* Gets the exposed ports for this service

191

* @return List of ExposedPort objects, empty if no ports exposed

192

*/

193

public List<ExposedPort> getPorts();

194

195

/**

196

* Checks if the service has a health check defined

197

* @return true if health check is configured

198

*/

199

public boolean hasHealthCheck();

200

201

/**

202

* Gets all labels defined for this service

203

* @return Map of label keys to values, empty if no labels

204

*/

205

public Map<String, Object> getLabels();

206

207

/**

208

* Gets the profiles this service belongs to

209

* @return List of profile names, empty if no profiles

210

*/

211

public List<String> getProfiles();

212

}

213

```

214

215

**Usage Examples:**

216

217

```java

218

// Working with service definitions

219

ComposeServiceDefinition webService = serviceDefinitions.get("web");

220

221

// Basic service information

222

String serviceName = webService.getServiceName(); // "web"

223

String containerName = webService.getContainerName(); // "my-web-app" or null

224

225

// Port configuration

226

List<ExposedPort> ports = webService.getPorts();

227

for (ExposedPort port : ports) {

228

System.out.println("Exposed port: " + port.getPort());

229

}

230

231

// Health check configuration

232

if (webService.hasHealthCheck()) {

233

System.out.println("Service has health check configured");

234

// Health check details are handled by wait strategies

235

}

236

237

// Labels for configuration and wait strategies

238

Map<String, Object> labels = webService.getLabels();

239

String waitForLogs = (String) labels.get("quarkus.compose.wait-for.logs");

240

String portTimeout = (String) labels.get("quarkus.compose.wait-for.ports.timeout");

241

String configPort = (String) labels.get("quarkus.compose.config.port.8080");

242

243

if (waitForLogs != null) {

244

System.out.println("Wait for log message: " + waitForLogs);

245

}

246

247

// Profile-based conditional logic

248

List<String> profiles = webService.getProfiles();

249

boolean isDevService = profiles.contains("development");

250

boolean isTestService = profiles.contains("testing");

251

252

if (isDevService) {

253

System.out.println("Service is part of development profile");

254

}

255

256

// Creating service definitions programmatically (for testing)

257

Map<String, Object> serviceData = Map.of(

258

"image", "postgres:13",

259

"container_name", "dev-postgres",

260

"ports", List.of("5432:5432"),

261

"environment", Map.of("POSTGRES_PASSWORD", "secret"),

262

"labels", Map.of(

263

"quarkus.compose.config.port.5432", "DATABASE_URL",

264

"quarkus.compose.wait-for.logs", "database system is ready to accept connections"

265

),

266

"profiles", List.of("development", "testing")

267

);

268

269

ComposeServiceDefinition dbService = new ComposeServiceDefinition("database", serviceData);

270

```

271

272

### ComposeServiceWaitStrategyTarget

273

274

Implements Testcontainers wait strategy interface for compose services, providing container inspection and port information.

275

276

```java { .api }

277

/**

278

* A WaitStrategyTarget that represents a container in a docker-compose file

279

*/

280

public class ComposeServiceWaitStrategyTarget implements WaitStrategyTarget, Supplier<InspectContainerResponse> {

281

282

/**

283

* Creates a wait strategy target for a compose service container

284

* @param dockerClient Docker client for container operations

285

* @param container Container information from Docker API

286

*/

287

public ComposeServiceWaitStrategyTarget(DockerClient dockerClient, Container container);

288

289

/**

290

* Gets the exposed ports for this container

291

* @return List of exposed port numbers

292

*/

293

@Override

294

public List<Integer> getExposedPorts();

295

296

/**

297

* Gets the container ID

298

* @return Full container ID

299

*/

300

@Override

301

public String getContainerId();

302

303

/**

304

* Gets the service name from compose labels

305

* @return Service name

306

*/

307

public String getServiceName();

308

309

/**

310

* Gets the container number within the service

311

* @return Container number (1-based)

312

*/

313

public int getContainerNumber();

314

315

/**

316

* Gets the formatted container name

317

* @return Container name in format "service-number"

318

*/

319

public String getContainerName();

320

321

/**

322

* Gets detailed container information

323

* @return Container inspection response

324

*/

325

@Override

326

public InspectContainerResponse getContainerInfo();

327

328

/**

329

* Supplier interface implementation

330

* @return Container inspection response

331

*/

332

@Override

333

public InspectContainerResponse get();

334

}

335

```

336

337

**Usage Examples:**

338

339

```java

340

// Working with service wait strategy targets

341

List<ComposeServiceWaitStrategyTarget> services = composeProject.getServices();

342

343

for (ComposeServiceWaitStrategyTarget service : services) {

344

// Basic service information

345

String serviceName = service.getServiceName();

346

String containerName = service.getContainerName();

347

String containerId = service.getContainerId();

348

int containerNumber = service.getContainerNumber();

349

350

System.out.println("Service: " + serviceName);

351

System.out.println("Container: " + containerName + " (" + containerId.substring(0, 12) + ")");

352

353

// Port information

354

List<Integer> exposedPorts = service.getExposedPorts();

355

System.out.println("Exposed ports: " + exposedPorts);

356

357

// Detailed container inspection

358

InspectContainerResponse containerInfo = service.getContainerInfo();

359

String imageName = containerInfo.getConfig().getImage();

360

String status = containerInfo.getState().getStatus();

361

362

System.out.println("Image: " + imageName);

363

System.out.println("Status: " + status);

364

365

// Network information

366

Map<String, NetworkSettings> networks = containerInfo.getNetworkSettings().getNetworks();

367

for (Map.Entry<String, NetworkSettings> network : networks.entrySet()) {

368

String networkName = network.getKey();

369

String ipAddress = network.getValue().getIpAddress();

370

System.out.println("Network: " + networkName + " -> " + ipAddress);

371

}

372

}

373

374

// Using as Testcontainers wait strategy target

375

WaitStrategy healthCheck = Wait.forHealthcheck();

376

WaitStrategy logMessage = Wait.forLogMessage("Server started", 1);

377

WaitStrategy httpEndpoint = Wait.forHttp("/health").forStatusCode(200);

378

379

for (ComposeServiceWaitStrategyTarget service : services) {

380

if (service.getServiceName().equals("web-api")) {

381

// Apply wait strategy

382

try {

383

httpEndpoint.waitUntilReady(service);

384

System.out.println("Web API service is ready");

385

} catch (Exception e) {

386

System.err.println("Web API failed to become ready: " + e.getMessage());

387

}

388

}

389

}

390

```