CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-devservices-deployment

Quarkus deployment module that provides automatic configuration and orchestration of development services using Docker Compose

Pending
Overview
Eval results
Files

compose-project.mddocs/

Compose Project Management

Complete Docker Compose project lifecycle management including service discovery, startup orchestration, health checking, and configuration extraction.

Capabilities

ComposeProject

Core class that wraps Docker Compose functionality and manages the complete lifecycle of compose-based services including startup, health checking, and shutdown.

/**
 * A wrapper around compose that starts and stops services defined in a set of compose files
 */
public class ComposeProject {
    
    /**
     * Constructor for ComposeProject with full configuration
     * @param dockerClient Docker client for container operations
     * @param composeFiles Compose files to manage
     * @param executable Compose executable name (docker or podman)
     * @param project Project name for compose services
     * @param startupTimeout Maximum time to wait for service startup
     * @param stopTimeout Maximum time to wait for service shutdown
     * @param stopContainers Whether to stop containers on shutdown
     * @param ryukEnabled Whether to enable Ryuk for cleanup
     * @param followContainerLogs Whether to follow container logs
     * @param removeVolumes Whether to remove volumes on shutdown
     * @param removeImages Image removal strategy
     * @param build Whether to build images before starting
     * @param options Additional compose command options
     * @param profiles Compose profiles to activate
     * @param scalingPreferences Service scaling configuration
     * @param env Environment variables
     */
    public ComposeProject(
        DockerClient dockerClient,
        ComposeFiles composeFiles,
        String executable,
        String project,
        Duration startupTimeout,
        Duration stopTimeout,
        boolean stopContainers,
        boolean ryukEnabled,
        boolean followContainerLogs,
        boolean removeVolumes,
        String removeImages,
        Boolean build,
        List<String> options,
        List<String> profiles,
        Map<String, Integer> scalingPreferences,
        Map<String, String> env);
    
    /**
     * Gets the project name
     * @return Project name
     */
    public String getProject();
    
    /**
     * Starts all services defined in the compose files
     */
    public synchronized void start();
    
    /**
     * Waits until all services are ready according to their wait strategies
     * @param waitOn Executor for parallel waiting, null for default
     */
    public void waitUntilServicesReady(Executor waitOn);
    
    /**
     * Combines start and wait operations
     * @param waitOn Executor for parallel waiting
     */
    public void startAndWaitUntilServicesReady(Executor waitOn);
    
    /**
     * Stops all services and cleans up resources
     */
    public synchronized void stop();
    
    /**
     * Discovers running service instances
     * @param checkForRequiredServices Whether to validate required services are running
     */
    public synchronized void discoverServiceInstances(boolean checkForRequiredServices);
    
    /**
     * Runs a compose command with environment variables
     * @param cmd Command to execute
     * @param env Environment variables
     */
    public void runWithCompose(String cmd, Map<String, String> env);
    
    /**
     * Gets list of running service instances
     * @return List of service wait strategy targets
     */
    public List<ComposeServiceWaitStrategyTarget> getServices();
    
    /**
     * Gets environment variable configuration from services
     * @return Map of environment variable names to values
     */
    public Map<String, String> getEnvVarConfig();
    
    /**
     * Gets exposed port configuration from services
     * @return Map of configuration keys to port values
     */
    public Map<String, String> getExposedPortConfig();
    
    /**
     * Gets list of Docker networks created by compose
     * @return List of networks
     */
    public List<Network> getNetworks();
    
    /**
     * Gets the default network ID for service communication
     * @return Default network ID or fallback name
     */
    public String getDefaultNetworkId();
}

Usage Examples:

import io.quarkus.devservices.deployment.compose.*;
import java.time.Duration;
import java.util.concurrent.Executors;

// Create and start a compose project
List<File> composeFiles = List.of(new File("docker-compose.yml"));
ComposeFiles files = new ComposeFiles(composeFiles);

ComposeProject project = new ComposeProject.Builder(files, "docker")
    .withProject("my-dev-services")
    .withStartupTimeout(Duration.ofMinutes(2))
    .withStopContainers(true)
    .withRyukEnabled(true)
    .withFollowContainerLogs(true)
    .withEnv(Map.of("POSTGRES_PASSWORD", "secret"))
    .build();

// Start services and wait for readiness
project.start();
project.waitUntilServicesReady(Executors.newCachedThreadPool());

// Get service information
String projectName = project.getProject();
List<ComposeServiceWaitStrategyTarget> services = project.getServices();
Map<String, String> envConfig = project.getEnvVarConfig();
Map<String, String> portConfig = project.getExposedPortConfig();

// Use configuration
String dbUrl = portConfig.get("DATABASE_URL");
String dbUser = envConfig.get("DB_USER");

// Cleanup when done
project.stop();

ComposeProject.Builder

Fluent builder pattern for creating ComposeProject instances with extensive configuration options.

/**
 * Builder for ComposeProject with fluent configuration
 */
public static class Builder {
    
    /**
     * Creates a new builder with required parameters
     * @param files Compose files to manage
     * @param executable Compose executable name
     */
    public Builder(ComposeFiles files, String executable);
    
    /**
     * Sets the docker client to use
     * @param dockerClient Docker client instance
     * @return This builder
     */
    public Builder withDockerClient(DockerClient dockerClient);
    
    /**
     * Sets the project name
     * @param project Project name for compose services
     * @return This builder
     */
    public Builder withProject(String project);
    
    /**
     * Sets whether to stop containers on shutdown
     * @param stopContainers Stop containers flag
     * @return This builder
     */
    public Builder withStopContainers(boolean stopContainers);
    
    /**
     * Sets whether to enable Ryuk for cleanup
     * @param ryukEnabled Ryuk enabled flag
     * @return This builder
     */
    public Builder withRyukEnabled(boolean ryukEnabled);
    
    /**
     * Sets the startup timeout
     * @param duration Maximum startup time
     * @return This builder
     */
    public Builder withStartupTimeout(Duration duration);
    
    /**
     * Sets the stop timeout
     * @param duration Maximum stop time
     * @return This builder
     */
    public Builder withStopTimeout(Duration duration);
    
    /**
     * Sets whether to build images before starting
     * @param build Build images flag
     * @return This builder
     */
    public Builder withBuild(Boolean build);
    
    /**
     * Sets environment variables
     * @param envVariables Environment variable map
     * @return This builder
     */
    public Builder withEnv(Map<String, String> envVariables);
    
    /**
     * Sets compose command options
     * @param options List of command options
     * @return This builder
     */
    public Builder withOptions(List<String> options);
    
    /**
     * Sets compose profiles to activate
     * @param profiles List of profile names
     * @return This builder
     */
    public Builder withProfiles(List<String> profiles);
    
    /**
     * Sets service scaling preferences
     * @param scalingPreferences Map of service name to replica count
     * @return This builder
     */
    public Builder withScalingPreferences(Map<String, Integer> scalingPreferences);
    
    /**
     * Sets whether to follow container logs
     * @param followContainerLogs Follow logs flag
     * @return This builder
     */
    public Builder withFollowContainerLogs(boolean followContainerLogs);
    
    /**
     * Sets image removal strategy
     * @param removeImages Image removal option
     * @return This builder
     */
    public Builder withRemoveImages(String removeImages);
    
    /**
     * Sets whether to remove volumes on shutdown
     * @param removeVolumes Remove volumes flag
     * @return This builder
     */
    public Builder withRemoveVolumes(boolean removeVolumes);
    
    /**
     * Builds the ComposeProject instance
     * @return Configured ComposeProject
     */
    public ComposeProject build();
}

Usage Examples:

// Minimal configuration
ComposeProject minimal = new ComposeProject.Builder(composeFiles, "docker")
    .withProject("my-project")
    .build();

// Full configuration with all options
ComposeProject full = new ComposeProject.Builder(composeFiles, "podman")
    .withProject("full-config-project")
    .withStartupTimeout(Duration.ofMinutes(5))
    .withStopTimeout(Duration.ofSeconds(30))
    .withStopContainers(true)
    .withRyukEnabled(false)
    .withBuild(true)
    .withFollowContainerLogs(true)
    .withRemoveVolumes(true)
    .withRemoveImages("all")
    .withEnv(Map.of(
        "POSTGRES_DB", "testdb",
        "POSTGRES_USER", "test",
        "POSTGRES_PASSWORD", "secret"
    ))
    .withProfiles(List.of("development", "testing"))
    .withOptions(List.of("--compatibility", "--verbose"))
    .withScalingPreferences(Map.of("web", 2, "worker", 3))
    .build();

// Configure for testing environment
ComposeProject testing = new ComposeProject.Builder(composeFiles, "docker")
    .withProject("test-services")
    .withStartupTimeout(Duration.ofMinutes(1))
    .withRyukEnabled(true)
    .withBuild(false)
    .withProfiles(List.of("test"))
    .build();

ComposeRunner

Executes Docker Compose commands with proper environment setup and error handling, providing a fluent interface for running arbitrary compose operations.

/**
 * A class that runs compose commands with proper environment setup
 */
public class ComposeRunner {
    
    /**
     * Creates a new compose runner
     * @param composeExecutable Executable name (docker, podman, etc.)
     * @param composeFiles List of compose files
     * @param projectName Project name for compose
     */
    public ComposeRunner(String composeExecutable, List<File> composeFiles, String projectName);
    
    /**
     * Sets the compose command to run
     * @param cmd Command string with arguments
     * @return This runner
     */
    public ComposeRunner withCommand(String cmd);
    
    /**
     * Sets environment variables for the command
     * @param env Environment variable map
     * @return This runner
     */
    public ComposeRunner withEnv(Map<String, String> env);
    
    /**
     * Sets compose profiles to use
     * @param profiles List of profile names
     * @return This runner
     */
    public ComposeRunner withProfiles(List<String> profiles);
    
    /**
     * Sets additional compose options
     * @param options List of command-line options
     * @return This runner
     */
    public ComposeRunner withOptions(List<String> options);
    
    /**
     * Executes the compose command
     * @throws RuntimeException If command fails or compose not found
     */
    public void run();
    
    /**
     * Executes the compose command and returns output
     * @return Command output as string
     * @throws RuntimeException If command fails or compose not found
     */
    public String runAndGetOutput();
    
    /**
     * Checks if the compose executable is available
     * @param executable Executable name to check
     * @return true if executable is found in PATH
     */
    public static boolean isComposeAvailable(String executable);
}

Usage Examples:

// Basic compose command execution
ComposeRunner runner = new ComposeRunner("docker", composeFiles, "my-project");
runner.withCommand("up -d")
      .withEnv(Map.of("POSTGRES_PASSWORD", "secret"))
      .run();

// Running with profiles and custom environment
new ComposeRunner("podman", composeFiles, "dev-project")
    .withCommand("up --build")
    .withProfiles(List.of("development", "debug"))
    .withEnv(Map.of(
        "API_KEY", "dev-key",
        "LOG_LEVEL", "debug",
        "REDIS_PASSWORD", "redis-secret"
    ))
    .run();

// Getting command output for inspection
String status = new ComposeRunner("docker", composeFiles, "status-check")
    .withCommand("ps --format json")
    .runAndGetOutput();
System.out.println("Service status: " + status);

// Using additional options with command
new ComposeRunner("docker", composeFiles, "advanced-project")
    .withCommand("up")
    .withOptions(List.of("--compatibility", "--abort-on-container-exit"))
    .withEnv(Map.of("COMPOSE_HTTP_TIMEOUT", "120"))
    .run();

// Check if compose is available before running
if (ComposeRunner.isComposeAvailable("docker")) {
    new ComposeRunner("docker", composeFiles, "my-project")
        .withCommand("up -d")
        .run();
} else if (ComposeRunner.isComposeAvailable("podman")) {
    new ComposeRunner("podman", composeFiles, "my-project")
        .withCommand("up -d")
        .run();
} else {
    throw new RuntimeException("No compatible compose executable found");
}

// Stopping services with cleanup
new ComposeRunner("docker", composeFiles, "test-project")
    .withCommand("down -v --rmi all")
    .run();

Constants

// Default network name
public static final String DEFAULT_NETWORK_NAME = "default";

// Environment variable names used by ComposeRunner
private static final String DOCKER_HOST_ENV = "DOCKER_HOST";
private static final String DOCKER_CERT_PATH_ENV = "DOCKER_CERT_PATH";
private static final String DOCKER_TLS_VERIFY_ENV = "DOCKER_TLS_VERIFY";
private static final String PROJECT_NAME_ENV = "COMPOSE_PROJECT_NAME";
private static final String COMPOSE_FILE_ENV = "COMPOSE_FILE";
private static final String COMPOSE_PROFILES_ENV = "COMPOSE_PROFILES";

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-devservices-deployment

docs

compose-files.md

compose-project.md

console-commands.md

devservices-processing.md

index.md

tile.json