Quarkus deployment module that provides automatic configuration and orchestration of development services using Docker Compose
npx @tessl/cli install tessl/maven-io-quarkus--quarkus-devservices-deployment@3.23.0Quarkus DevServices Deployment is a Maven deployment module that provides automatic configuration and orchestration of development services for Quarkus applications. It enables developers to automatically start and configure external services like databases, message brokers, and other containers during development and testing without manual setup through Docker Compose integration.
io.quarkus:quarkus-devservices-deployment:3.23.0import io.quarkus.devservices.deployment.DevServicesProcessor;
import io.quarkus.devservices.deployment.compose.ComposeDevServicesProcessor;
import io.quarkus.devservices.deployment.compose.ComposeProject;
import io.quarkus.devservices.deployment.compose.ComposeFiles;// Build step processor for DevServices
@BuildStep
public void configureDevServices(
BuildProducer<DevServicesResultBuildItem> devServicesProducer,
DockerStatusBuildItem dockerStatus) {
// DevServices will automatically handle service lifecycle
// No manual configuration needed for basic usage
}
// Creating a Compose project programmatically
ComposeFiles composeFiles = new ComposeFiles(List.of(composeFile));
ComposeProject project = new ComposeProject.Builder(composeFiles, "docker")
.withProject("my-project")
.withStartupTimeout(Duration.ofMinutes(2))
.withStopContainers(true)
.withFollowContainerLogs(true)
.build();
project.start();
project.waitUntilServicesReady(executor);DevServices Deployment handles various error conditions and provides clear error messages:
// Handle Docker availability issues
try {
ComposeProject project = createComposeProject();
project.start();
} catch (RuntimeException e) {
if (e.getMessage().contains("Docker not available")) {
// Handle Docker daemon not running
LOG.warn("Docker is not available, skipping DevServices");
return Optional.empty();
}
throw e;
}
// Handle compose file parsing errors
try {
ComposeFile composeFile = new ComposeFile(file);
} catch (IllegalArgumentException e) {
LOG.error("Failed to parse compose file: " + file.getName(), e);
// Continue with other files or fail gracefully
}
// Handle service startup failures
try {
project.waitUntilServicesReady(executor);
} catch (RuntimeException e) {
LOG.error("Services failed to start within timeout", e);
project.stop(); // Cleanup failed services
throw new RuntimeException("DevServices startup failed", e);
}Quarkus DevServices Deployment is organized around several key components:
Core build step processing that orchestrates the DevServices lifecycle, provides shared networking, and configures console commands for development-time service management.
@BuildStep
public DevServicesNetworkIdBuildItem networkId(
Optional<DevServicesLauncherConfigResultBuildItem> devServicesLauncherConfig,
Optional<DevServicesComposeProjectBuildItem> composeProjectBuildItem);
@BuildStep(onlyIf = { IsDevelopment.class })
public List<DevServiceDescriptionBuildItem> config(
DockerStatusBuildItem dockerStatusBuildItem,
BuildProducer<ConsoleCommandBuildItem> commandBuildItemBuildProducer,
BuildProducer<FooterLogBuildItem> footerLogProducer,
LaunchModeBuildItem launchModeBuildItem,
Optional<DevServicesLauncherConfigResultBuildItem> devServicesLauncherConfig,
List<DevServicesResultBuildItem> devServicesResults);Complete Docker Compose project lifecycle management including service discovery, startup orchestration, health checking, and configuration extraction.
public class ComposeProject {
public void start();
public void waitUntilServicesReady(Executor waitOn);
public void startAndWaitUntilServicesReady(Executor waitOn);
public void stop();
public void discoverServiceInstances(boolean checkForRequiredServices);
public String getProject();
public List<ComposeServiceWaitStrategyTarget> getServices();
public Map<String, String> getEnvVarConfig();
public Map<String, String> getExposedPortConfig();
public List<Network> getNetworks();
public String getDefaultNetworkId();
}
public static class Builder {
public Builder(ComposeFiles files, String executable);
public Builder withProject(String project);
public Builder withStartupTimeout(Duration duration);
public Builder withStopTimeout(Duration duration);
public ComposeProject build();
}Docker Compose file parsing, validation, and service definition extraction with support for multiple compose files and project naming.
public class ComposeFiles {
public ComposeFiles(List<File> composeFiles);
public Set<String> getAllServiceNames();
public Map<String, ComposeServiceDefinition> getServiceDefinitions();
public String getProjectName();
public List<File> getFiles();
}
public class ComposeFile {
public ComposeFile(File composeFile);
public String getProjectName();
public Map<String, ComposeServiceDefinition> getServiceDefinitions();
}Development-time CLI commands for listing DevServices, viewing logs, and managing container lifecycle during development.
@GroupCommandDefinition(name = "devservices", description = "Dev Service Commands")
public class DevServicesCommand implements GroupCommand {
public DevServicesCommand(List<DevServiceDescriptionBuildItem> serviceDescriptions);
public List<Command> getCommands();
public CommandResult execute(CommandInvocation commandInvocation);
}
@CommandDefinition(name = "list", description = "List of dev services")
public class DevServicesListCommand implements Command {
public CommandResult execute(CommandInvocation commandInvocation);
}
@CommandDefinition(name = "logs", description = "Print container logs")
public class DevServicesLogsCommand implements Command {
public CommandResult execute(CommandInvocation commandInvocation);
}// Build items used by DevServices processors
public class DevServicesNetworkIdBuildItem extends SimpleBuildItem {
public DevServicesNetworkIdBuildItem(String networkId);
public String getNetworkId();
}
public class DevServiceDescriptionBuildItem extends MultiBuildItem {
public DevServiceDescriptionBuildItem(String name, String description,
RunningDevService runningDevService);
public String getName();
public String getDescription();
public boolean hasContainerInfo();
public RunningDevService.ContainerInfo getContainerInfo();
public Map<String, String> getConfigs();
}
public class DevServicesComposeProjectBuildItem extends SimpleBuildItem {
public DevServicesComposeProjectBuildItem(ComposeProject project,
Map<String, List<RunningContainer>> composeServices,
String defaultNetworkId);
public ComposeProject getProject();
public Map<String, List<RunningContainer>> getComposeServices();
public String getDefaultNetworkId();
}
public class DevServicesResultBuildItem extends MultiBuildItem {
public DevServicesResultBuildItem(String name, String description,
String containerId, Map<String, String> configs);
public String getName();
public String getDescription();
public String getContainerId();
public Map<String, String> getConfigs();
}
// Port definition for Docker containers
public class ExposedPort {
public ExposedPort(int port);
public ExposedPort(int port, InternetProtocol protocol);
public int getPort();
public InternetProtocol getProtocol();
}
// Service definition from compose file
public class ComposeServiceDefinition {
public ComposeServiceDefinition(String serviceName, Map<String, ?> definitionMap);
public String getServiceName();
public String getContainerName();
public List<ExposedPort> getPorts();
public boolean hasHealthCheck();
public Map<String, Object> getLabels();
public List<String> getProfiles();
}
// Container wait strategy target
public class ComposeServiceWaitStrategyTarget implements WaitStrategyTarget, Supplier<InspectContainerResponse> {
public ComposeServiceWaitStrategyTarget(DockerClient dockerClient, Container container);
public String getContainerId();
public String getServiceName();
public int getContainerNumber();
public String getContainerName();
public InspectContainerResponse getContainerInfo();
}
// Log forwarding for containers
public class ContainerLogForwarder implements Closeable {
public ContainerLogForwarder(DevServiceDescriptionBuildItem devService);
public DevServiceDescriptionBuildItem getDevService();
public boolean isRunning();
public void start();
public void close();
}
// Running container information
public static class RunningContainer {
public RunningContainer(String containerId, String serviceName, String image,
Map<String, String> labels, Set<Integer> ports);
public String getId();
public String getServiceName();
public String getImage();
public Map<String, String> getLabels();
public Set<Integer> getPorts();
}
// Configuration enums
public enum InternetProtocol {
TCP, UDP
}