jcompose is a JDK library for applications that need to load a Docker Compose project and manage its resources through the Docker Engine API. It keeps the project context explicit, reads Compose configuration in process, and scopes owned resources with the familiar com.docker.compose.* labels.
Docker Compose is jcompose's compatibility target. ComposeSharp is a sibling project maintained by the same author and the feature/documentation synchronization source: work developed there is subsequently ported here. Its API and implementation do not define compatibility; Compose's documentation and observable behavior do. jcompose is not a wrapper around the docker compose executable and does not claim full Docker Compose CLI or Compose Specification compatibility.
compose.yml + .env + env_file
│
▼
jcompose-loader
Java project model and validation
│
▼
jcompose-engine
Docker Engine resources and Compose labels
│
▼
IComposeService in your application
Project ownership is label-based. The project context carries the project name, working directory, Compose files, profiles, registry credentials, and Docker connection settings. Operations use these boundaries to find resources belonging to one project instead of scanning or removing unrelated Docker resources.
| Module | Responsibility |
|---|---|
jcompose-api |
Java project models, operation options and results, callbacks, and the asynchronous service contract |
jcompose-loader |
Compose YAML loading, interpolation, dotenv and env_file handling, validation, and multi-file merging |
jcompose-engine |
Docker Engine integration and project-scoped operations |
jcompose-spring-boot-starter |
Spring Boot auto-configuration for IComposeService, JComposeContextFactory, and jcompose.* defaults |
The public Java API uses CompletableFuture for finite operations and Flow.Publisher for streaming events and watch notifications. It targets JDK 21 or newer.
The Maven compiler targets Java 21 bytecode. The current local verification uses JDK 21.0.12 and Maven 3.9.16; a minimum Maven version and a supported Docker Engine version have not yet been established through a compatibility matrix.
Build the Maven reactor from a checkout:
mvn verifyAn application can construct the engine service directly and pass an explicit project context:
import io.github.gattgeng.jcompose.api.ComposeProjectContext;
import io.github.gattgeng.jcompose.engine.ComposeService;
import java.nio.file.Path;
var compose = new ComposeService();
var project = new ComposeProjectContext("inventory-dev", Path.of("C:/src/inventory"));
var config = compose.loadProject(project).join();
System.out.println(config.services().keySet());The API and engine modules are currently in active development. The sample shows the loading boundary; consult the operation documentation and support matrix before relying on a runtime operation or field.
Add jcompose-spring-boot-starter to a Spring Boot 3.5 application. The starter registers an IComposeService bean and a JComposeContextFactory:
@Service
class InventoryCompose {
private final IComposeService compose;
private final JComposeContextFactory contexts;
InventoryCompose(IComposeService compose, JComposeContextFactory contexts) {
this.compose = compose;
this.contexts = contexts;
}
void load(Path workingDirectory) {
var project = contexts.create("inventory-dev", workingDirectory);
compose.loadProject(project).join();
}
}Configure optional defaults with jcompose.default-project-name and jcompose.default-socket-path. The socket path accepts the Docker endpoint syntax supported by docker-java; leave it unset to use docker-java discovery. The project factory prefers Docker Compose's canonical compose.yaml filename and falls back to other conventional Compose filenames when it is absent. Each caller can provide profiles or a different Compose file.
The loader reads Compose YAML, .env, and service env_file inputs, performs variable interpolation, and creates project/service models. The current implementation is an incremental subset, not a complete Compose Specification parser. It retains raw service mappings for fields that do not yet have a fully typed Java representation or Docker Engine behavior.
The loader supports $NAME, ${NAME}, $$, and the :-, -, :?, ?, :+, and + interpolation operators. The process environment takes precedence over project .env values. Engine operations expose the project name from ComposeProjectContext as COMPOSE_PROJECT_NAME for interpolation, taking precedence over process and .env values. Service env_file values contribute to that service's container environment; they are not an interpolation source. Inline environment values take precedence over values from those files.
ComposeFileMerger.mergeWithEnv applies explicit environment overrides to that merge only, ahead of process environment and .env values. It does not modify process-wide environment variables, so concurrent merges remain isolated.
See loader compatibility for precedence, operator behavior, and current limits. For multi-file input, see merge semantics. These rules are documented as jcompose behavior and must be checked against Docker Compose; they are not inherited as compatible merely because ComposeSharp implements similar logic.
Service extends supports same-file and external-file references, recursive inheritance, and Compose-specific merge behavior, including the healthcheck.disable inheritance constraint. External inherited build, env-file, and bind paths are rebased to the project file. Dependencies and top-level resources still need to be declared by the project; see loader compatibility for the current boundary.
Local include files recursively import services, networks, volumes, secrets, and configs after multi-file overlays have been merged. An include path list is merged in order into one included project before import; collisions with other projects fail instead of merging. Relative build, env-file, bind, config, and secret file paths keep their included-project locations. Remote OCI/Git sources and the rest of the full Compose include schema are not supported. See loader compatibility and merge semantics for details.
The engine is being ported from the ComposeSharp feature scope, one documented and reviewable slice at a time. The current snapshot implements a subset of image builds and publishing, basic up/create reconciliation, one-off run, host/container copy, scale and wait, exec/attach, local build-context watch events, container filesystem export and image commit, selected label-scoped operations for existing Docker resources, project container queries, and a normalized configuration snapshot. These operations have explicit limitations and are not complete Docker Compose equivalents; see the compatibility matrix for current gaps.
| Area | Current boundary |
|---|---|
| Project lifecycle | Selected start, stop, restart, pause, unpause, kill, remove, and down operations act on existing resources carrying the project label. |
| Inspection | ps and list query project-labeled containers; list follows Docker's default container listing for project visibility, so paused or restarting projects may remain visible while stopped-only projects are omitted. all includes projects excluded by that listing. top, images, port, and volumes expose limited daemon-backed inspection. logsAsync streams container output to an ILogConsumer. A declared API method or options record alone does not imply complete implementation. |
| Generation | generateAsync renders a normalized YAML snapshot from configuration retained by the loader; it does not connect to Docker or write files. |
| Orchestration | Basic service reconciliation, one-off run, host/container copy, replica scaling, exit waiting, selected dependency conditions, health checks, declared network/volume resource definitions, project network attachments, DNS settings, CPU/memory limits, image builds/publishing, exec/attach, build-context watch events, container filesystem export, and image commit are implemented as subsets; full Compose lifecycle behavior is in progress. |
The Docker Compose field support matrix is the source of truth for field-level and operation status. For example, volumesAsync lists project-labeled Docker volumes and applies an explicit service selection across running and stopped project containers. The roadmap records the complete 3.0.0 synchronization scope and release criteria.
The compatibility target is Docker Compose file loading and project behavior within the subset explicitly documented in this repository. The ComposeSharp 3.0.0 baseline and later ComposeSharp development determine which feature work is synchronized; Docker Compose documentation and observable Docker Compose behavior determine whether jcompose's implementation is compatible.
For a compatibility report, include a minimal Compose file, expected behavior from Docker Compose, observed jcompose behavior, the jcompose commit, and Docker Engine/JDK versions. Update the field matrix and relevant operation contract alongside any behavior change. Do not treat a matching method name, model field, or ComposeSharp implementation as conformance evidence.
- Docker Compose field support matrix
- Loader compatibility
- Multi-file merge semantics
- Generate and watch contract
- Roadmap and completion criteria
- Maintainer release guide
- Contributing
- Code of Conduct
- Support
- Security policy
- Changelog
The repository is currently on 3.0.0-SNAPSHOT. This is not the completed 3.0.0 port and no JDK artifact has been published. The first JDK release is intentionally the last step, after the feature scope, compatibility evidence, repository configuration, CI, and release contents are complete and reviewed. See the maintainer release guide.
MIT. See LICENSE.