tomato·bazeldocs v0 · latest
Docs/Reference/Modules/rules_docker_compose

rules_docker_compose

rules_docker_compose is a Bazel ruleset published to the tomato-bazel registry.

MODULE.bazelstarlark
bazel_dep(name = "rules_docker_compose", version = "0.2.6")

View source & releases on GitHub ↗

Bazel rules that build a Docker Compose project from typed service / volume / network targets scattered across your code graph.

The user-facing Starlark surface mirrors the compose-spec exhaustively — every property the spec accepts is a typed Bazel attr.*. There’s no hand-curated subset and no allowlist of deferred fields. Drift is impossible by construction:

  • The canonical schema is fetched on-demand from compose-spec/compose-spec at a commit + sha256 pinned in compose/private/extensions.bzl.
  • rules_jsonschema’s jsonschema_rust_library emits a Rust library (compose_types) of typed bindings from that schema via typify.
  • The same repo’s jsonschema_starlark_codegen emits compose/compose_rules.bzl — one rule() per schema definition, typed attr.* per schema property.
  • The Rust compose-gen binary decodes per-target JSON shards into the typed Service/Volume/Network structs (#[serde(deny_unknown_fields)] rejects anything the schema doesn’t declare) and emits canonical YAML.

The hand-written part of the repo is small and scoped to things the schema can’t describe: graph aggregation, OCI digest resolution, and bazel run wrappers around docker compose. Both codegen passes go through rules_jsonschema’s plugin contract — see that repo’s plugin_contract.md if you want to swap a plugin for one of your own.

What ships

  • rules (re-exported by compose/defs.bzl):
    • docker_compose_service / _volume / _network — typed rules generated from the compose-spec; see docs/compose_rules.md for the full attr list.
    • docker_compose — collects shards from deps and renders one canonical compose.yaml.
    • docker_compose_oci_image_ref — resolves an OCI image layout to <repo>@sha256:<digest> at build time and overrides a service’s image: in the rendered output.
    • docker_compose_up / _downbazel run wrappers around docker compose -f <generated> {up,down}.
  • providers: ComposeServiceInfo, ComposeVolumeInfo, ComposeNetworkInfo, ComposeProjectInfo, ComposeServiceImageRefInfo.

Reference docs (docs/defs.md, docs/compose_rules.md) are stardoc-generated, committed to source, and diff_tested.

Install

.bazelrc:

common --registry=https://registry.fastverk.com/
common --registry=https://bcr.bazel.build/

MODULE.bazel:

bazel_dep(name = "rules_docker_compose", version = "0.1.0")

rules_jsonschema, rules_rust, and a Rust toolchain are pulled in transitively.

Quick start

load(
    "@rules_docker_compose//compose:defs.bzl",
    "docker_compose",
    "docker_compose_network",
    "docker_compose_service",
    "docker_compose_up",
    "docker_compose_volume",
)

docker_compose_network(name = "appnet", driver = "bridge")
docker_compose_volume(name = "cache")

docker_compose_service(
    name = "web",
    image = "nginx:1.27",
    ports = ["8080:80"],
    networks = ["appnet"],
    depends_on = ["redis"],
    restart = "unless-stopped",
    environment = {"NGINX_HOST": "example.local"},
)

docker_compose_service(
    name = "redis",
    image = "redis:7",
    networks = ["appnet"],
    volumes = ["cache:/data"],
    # Complex nested objects (build, healthcheck, deploy, …) are
    # JSON-encoded — the Rust shard reader parses them straight into
    # the typed schema model.
    healthcheck = json.encode({
        "test": ["CMD", "redis-cli", "ping"],
        "interval": "10s",
        "retries": 3,
    }),
)

docker_compose(
    name = "stack",
    project_name = "myapp",
    deps = [":appnet", ":cache", ":redis", ":web"],
    out = "compose.yaml",
)

docker_compose_up(name = "stack.up", project = ":stack")

bazel build //path:stack produces bazel-bin/path/compose.yaml. bazel run //path:stack.up -- -d cd’s to the workspace root and runs docker compose -f bazel-bin/path/compose.yaml up -d, so relative bind-mounts resolve against your source tree.

Attr ergonomics

Most compose-spec properties type cleanly:

Spec shapeBazel attrExample
stringattr.stringimage = "nginx:1.27"
enum of stringsattr.string(values=...)restart = "unless-stopped"
boolean (or [boolean, string, object] union)attr.boolinit = True, external = True
integer / numberattr.int
[number, string] unionattr.stringshm_size = "256m"
Array of strings (incl. oneOf [string, object] short-form)attr.string_listports = ["8080:80"]
Object with string-valued propsattr.string_dictlabels = {"k": "v"}
Compose-spec’s list_or_dict shapeattr.string_dictenvironment = {"FOO": "bar"}
Nested object (build, healthcheck, deploy, …)attr.string taking JSONbuild = json.encode({...})

docs/compose_rules.md lists every attr.

OCI integration

docker_compose_oci_image_ref resolves an OCI image layout to a digest-pinned reference at build time:

load("@rules_oci//oci:defs.bzl", "oci_image")
load(
    "@rules_docker_compose//compose:defs.bzl",
    "docker_compose_oci_image_ref",
    "docker_compose_service",
    "docker_compose",
)

oci_image(name = "worker_image", ...)

docker_compose_service(
    name = "worker",
    # image left unset — supplied at build time via image_ref below.
    command = ["./worker"],
)

docker_compose_oci_image_ref(
    name = "worker_image_ref",
    service_name = "worker",
    oci_image = ":worker_image",
    oci_repo = "ghcr.io/myorg/worker",
)

docker_compose(
    name = "stack",
    deps = [":worker", ":worker_image_ref"],
    out = "compose.yaml",
)

The rendered compose.yaml will pin worker.image to ghcr.io/myorg/worker@sha256:<digest>, where the digest is read from the OCI layout’s index.json at build time. Whoever runs docker compose up is guaranteed to pull exactly what Bazel built.

Push the image separately (e.g. via @rules_oci’s oci_push) so the registry actually has it at the resolved digest.

How drift is controlled

The schema is fetched by a Bazel module extension pinned in compose/private/extensions.bzl (commit SHA + sha256). Two codegen passes consume it on every build:

  1. typify (jsonschema_rust_library) generates typed Rust bindings. Removing a field upstream surfaces as a Rust compile error.
  2. schema_to_starlark (jsonschema_starlark_codegen) generates typed Bazel rule definitions. The generated .bzl is committed, and //compose:compose_rules_up_to_date re-runs codegen on every CI build to detect drift.

Adding a typed Bazel attr for a new spec field is zero code change beyond bumping the pin: typify picks up the new struct field, schema_to_starlark emits the new attr.*, and the diff_test fails until you commit the regenerated compose_rules.bzl.

To bump the spec:

# 1. Pick a commit from https://github.com/compose-spec/compose-spec
# 2. Edit _COMPOSE_SPEC_COMMIT + _COMPOSE_SPEC_SHA256 in
#    compose/private/extensions.bzl
#    (compute the sha256 with: curl -fsSL <url> | shasum -a 256)
# 3. Re-run codegen + docs:
bazel run //compose:update_compose_rules
bazel run //docs:update
bazel test //...

Both update targets are write_source_files instances — pure Starlark, no hand-written shell scripts.

The schema itself is never copied into this repo — Bazel fetches it from GitHub on first build and caches it like any other external dep.

Compatibility

  • Bazel: 7.4+, bzlmod required (tested on 9.1).
  • Rust: 1.88+ (transitive deps need stabilised let-chains).
  • docker compose: v2 plugin (docker compose, not docker-compose).

Cargo-direct builds

The compose-gen crate depends on compose_types, a rust_library materialised by Bazel’s jsonschema_rust_library rule at build time. Plain cargo build / cargo clippy from the workspace root cannot resolve that import — Cargo never sees the schema → Rust pipeline. Use Bazel for builds and tests; for IDE integration, generate a rust-analyzer project from Bazel via @rules_rust//tools/rust_analyzer:gen_rust_project.

rules_jsonschema’s own tools (schema_to_rust, schema_to_starlark) have no Bazel-only deps, so cargo works for those if you’re hacking on the codegen.

Testing

bazel test //...

Six tests, all hermetic:

TargetWhat it covers
//compose/private/compose_gen:compose_gen_test12 Rust unit tests — YAML normalisation, OCI image-ref resolution, service-image override, shard decoding
//compose:compose_rules_up_to_dateschema_to_starlark output is fresh against the committed .bzl
//docs:defs_doc_up_to_date + //docs:compose_rules_doc_up_to_datestardoc freshness
//examples/smoke:stack_yaml_up_to_dateend-to-end smoke golden
//examples/coverage:stack_yaml_up_to_dateend-to-end coverage golden (build, healthcheck, profiles, OCI refs, …)

License

MIT.

Usage#

Real usage, taken from the module’s examples/.

examples/configs_secrets/BUILD.bazel

load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
load(
    "@rules_docker_compose//compose:defs.bzl",
    "docker_compose",
    "docker_compose_config",
    "docker_compose_network",
    "docker_compose_secret",
    "docker_compose_service",
)

# Demonstrates the v0.2.0 top-level `configs:` + `secrets:` rules. Both
# replace the previous workaround of bind-mounting config files via the
# per-service `volumes:` block; compose-spec's `configs:` semantics
# (immutable, project-scoped, mountable into multiple services from a
# single source) are now first-class.

docker_compose_network(name = "appnet", driver = "bridge")

# Top-level config — file-backed. Referenced by `app` via the
# schema-derived `configs = ["prometheus"]` list.
docker_compose_config(
    name = "prometheus",
    src = "prometheus.yml",
)

# Top-level secret — file-backed. Referenced by `app` via `secrets`.
docker_compose_secret(
    name = "api_key",
    src = "api_key.txt",
)

# Top-level secret — environment-backed. Demonstrates the alternative
# source path; compose reads the env var's value at runtime.
docker_compose_secret(
    name = "session_key",
    environment = "SESSION_KEY",
)

docker_compose_service(
    name = "app",
    image = "nginx:1.27",
    configs = ["prometheus"],
    secrets = [
        "api_key",
        "session_key",
    ],
    networks = ["appnet"],
)

docker_compose(
    name = "stack",
    project_name = "configs_secrets",
    out = "compose.yaml",
    deps = [
        ":api_key",
        ":app",
        ":appnet",
        ":prometheus",
        ":session_key",
    ],
)

# Pin the rendered output so intentional rule changes show up in PR review.
diff_test(
    name = "stack_yaml_up_to_date",
    file1 = "expected.yaml",
    file2 = ":stack",
)

examples/coverage/BUILD.bazel

load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
load(
    "@rules_docker_compose//compose:defs.bzl",
    "docker_compose",
    "docker_compose_network",
    "docker_compose_service_raw",
    "docker_compose_volume",
)

# Exercises the schema-derived raw rule's long-tail attrs (build, labels,
# shm_size, stop_grace_period, cap_add, sysctls, …) that aren't lifted
# into the v0.2 public façade. Consumers needing these reach for
# `docker_compose_service_raw`; the façade `docker_compose_service`
# covers the high-traffic 80% of services without exposing the full
# 95-attr schema-derived surface.
docker_compose_service = docker_compose_service_raw

docker_compose_network(
    name = "internal",
    driver = "bridge",
    driver_opts = {"com.docker.network.bridge.name": "covnet0"},
    internal = True,
    attachable = True,
    labels = {"tier": "internal"},
)

docker_compose_network(
    name = "external_net",
    external = True,
    name_override = "shared_public",
)

docker_compose_volume(
    name = "shared",
    driver = "local",
    driver_opts = {
        "type": "none",
        "device": "/var/lib/cov/shared",
        "o": "bind",
    },
    labels = {"backup": "nightly"},
    name_override = "cov_shared",
)

docker_compose_volume(
    name = "ext",
    external = True,
)

docker_compose_service(
    name = "api",
    build = json.encode({
        "context": "./api",
        "dockerfile": "Dockerfile.api",
        "target": "runtime",
        "args": {
            "BUILD_VERSION": "1.2.3",
            "GIT_SHA": "abc123",
        },
    }),
    entrypoint = ["/bin/sh", "-c"],
    command = ["./bin/api --listen :8080"],
    environment = {"LOG_LEVEL": "info"},
    env_file = [".env", ".env.local"],
    working_dir = "/srv/api",
    user = "1000:1000",
    hostname = "api-host",
    labels = {
        "traefik.enable": "true",
        "traefik.http.routers.api.rule": "Host(`api.example.com`)",
    },
    profiles = ["dev", "prod"],
    # Networks/volumes are addressed by their *Starlark name* (which
    # becomes the top-level compose key), not by their `name_override`
    # — the override is the runtime resource name, not the lookup key.
    networks = [
        "internal",
        "external_net",
    ],
    volumes = ["shared:/srv/shared"],
    healthcheck = json.encode({
        "test": ["CMD-SHELL", "curl -fsS http://localhost:8080/healthz || exit 1"],
        "interval": "30s",
        "timeout": "5s",
        "retries": 5,
        "start_period": "20s",
    }),
    # These used to require `extra_config`; with v0.2 codegen they're
    # first-class typed Bazel attrs derived from the spec.
    init = True,
    shm_size = "256m",
    stop_grace_period = "1m30s",
    cap_add = ["NET_ADMIN", "SYS_TIME"],
    sysctls = {"net.core.somaxconn": "1024"},
)

docker_compose(
    name = "stack",
    project_name = "coverage",
    deps = [
        ":api",
        ":ext",
        ":external_net",
        ":internal",
        ":shared",
    ],
    out = "compose.yaml",
)

diff_test(
    name = "stack_yaml_up_to_date",
    file1 = "expected.yaml",
    file2 = ":stack",
)

examples/smoke/BUILD.bazel

load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
load(
    "@rules_docker_compose//compose:defs.bzl",
    "docker_compose",
    "docker_compose_command",
    "docker_compose_down",
    "docker_compose_exec",
    "docker_compose_network",
    "docker_compose_run",
    "docker_compose_service",
    "docker_compose_up",
    "docker_compose_volume",
)

# Two-service stack (nginx + redis) using one named volume and one
# private network. Plus a worker service whose image is supplied at
# build time from an OCI image layout label.
#
# This example exercises the v0.2 docker_compose_service façade:
#   * `deps`, `networks`, `named_volume_mounts` are label_lists / dicts.
#   * `oci_image` is a label that the façade resolves to
#     `<repo>@sha256:<digest>` at build time (replaces the separate
#     `docker_compose_oci_image_ref` target previously needed for that).
#   * `healthcheck` is JSON-encoded (no schema-derived typed attr exists
#     for the nested healthcheck object).

docker_compose_network(
    name = "appnet",
    driver = "bridge",
)

docker_compose_volume(name = "cache")

docker_compose_service(
    name = "redis",
    image = "redis:7",
    networks = [":appnet"],
    named_volume_mounts = {":cache": "/data"},
    healthcheck = json.encode({
        "test": ["CMD", "redis-cli", "ping"],
        "interval": "10s",
        "retries": 3,
    }),
)

docker_compose_service(
    name = "web",
    image = "nginx:1.27",
    ports = ["8080:80"],
    networks = [":appnet"],
    deps = [":redis"],
    restart = "unless-stopped",
    environment = {
        "NGINX_HOST": "example.local",
    },
)

# OCI image source — a real repo would point this at `oci_pull` or
# `oci_image`; the fixture keeps the test hermetic.
filegroup(
    name = "fake_alpine_layout",
    srcs = glob(["fake_oci_layout/**"]),
)

docker_compose_service(
    name = "worker",
    oci_image = ":fake_alpine_layout",
    oci_repo = "ghcr.io/fastverk/example-worker",
    command = ["echo", "hello from worker"],
    networks = [":appnet"],
)

docker_compose(
    name = "stack",
    project_name = "smoke",
    # Root services only — `_compose_transitive_aspect` walks each
    # service's `deps`/`networks`/`named_volume_mounts` to discover the
    # volume, network, and image-ref shards automatically.
    deps = [
        ":web",
        ":worker",
    ],
    out = "compose.yaml",
)

docker_compose_up(
    name = "stack.up",
    project = ":stack",
)

docker_compose_down(
    name = "stack.down",
    project = ":stack",
)

# `bazel run :redis.shell` -> docker compose -f <yml> exec -T redis redis-cli
docker_compose_exec(
    name = "redis.shell",
    project = ":stack",
    service = "redis",
    command = ["redis-cli"],
    no_tty = True,
)

# `bazel run :worker.once -- --extra-arg` -> docker compose -f <yml> run --rm
# worker echo "smoke run" --extra-arg
docker_compose_run(
    name = "worker.once",
    project = ":stack",
    service = "worker",
    command = ["echo", "smoke run"],
)

# `bazel run :stack.logs -- redis` -> docker compose -f <yml> logs -f redis
docker_compose_command(
    name = "stack.logs",
    project = ":stack",
    subcommand = "logs",
    args = ["-f"],
)

# Pins the entire end-to-end output. Refresh the committed
# `expected.yaml` after intentional rule changes with:
#   bazel build //examples/smoke:stack
#   cp bazel-bin/examples/smoke/compose.yaml examples/smoke/expected.yaml
diff_test(
    name = "stack_yaml_up_to_date",
    file1 = "expected.yaml",
    file2 = ":stack",
)

Rules & providers#

Generated with Stardoc from the module's .bzl sources.

from docs/compose_rules.md

docker_compose_network

load("@rules_docker_compose//compose:compose_rules.bzl", "docker_compose_network")

docker_compose_network(name, attachable, driver, driver_opts, enable_ipv4, enable_ipv6, external,
                       internal, ipam, labels, name_override, network_name)

Network configuration for the Compose application.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
attachableIf true, standalone containers can attach to this network.BooleanoptionalFalse
driverSpecify which driver should be used for this network. Default is ‘bridge’.Stringoptional""
driver_optsSpecify driver-specific options defined as key/value pairs.Dictionary: String -> Stringoptional{}
enable_ipv4Enable IPv4 networking.BooleanoptionalFalse
enable_ipv6Enable IPv6 networking.BooleanoptionalFalse
externalSpecifies that this network already exists and was created outside of Compose.BooleanoptionalFalse
internalCreate an externally isolated network.BooleanoptionalFalse
ipamCustom IP Address Management configuration for this network. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
labelsAdd metadata to the network using labels.Dictionary: String -> Stringoptional{}
name_overrideCustom name for this network.Stringoptional""
network_nameTop-level key for this network in the rendered project. Defaults to the rule name.Stringoptional""

docker_compose_service

load("@rules_docker_compose//compose:compose_rules.bzl", "docker_compose_service")

docker_compose_service(name, annotations, attach, blkio_config, build, cap_add, cap_drop, cgroup,
                       cgroup_parent, command, configs, container_name, cpu_count, cpu_percent,
                       cpu_period, cpu_quota, cpu_rt_period, cpu_rt_runtime, cpu_shares, cpus, cpuset,
                       credential_spec, depends_on, deploy, develop, device_cgroup_rules, devices,
                       dns, dns_opt, dns_search, domainname, entrypoint, env_file, environment,
                       expose, extends, external_links, extra_hosts, gpus, group_add, healthcheck,
                       hostname, image, init, ipc, isolation, label_file, labels, links, logging,
                       mac_address, mem_limit, mem_reservation, mem_swappiness, memswap_limit, models,
                       network_mode, networks, oom_kill_disable, oom_score_adj, pid, pids_limit,
                       platform, ports, post_start, pre_stop, privileged, profiles, provider,
                       pull_policy, pull_refresh_after, read_only, restart, runtime, scale, secrets,
                       security_opt, service_name, shm_size, stdin_open, stop_grace_period,
                       stop_signal, storage_opt, sysctls, tmpfs, tty, ulimits, use_api_socket, user,
                       userns_mode, uts, volumes, volumes_from, working_dir)

Configuration for a service.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
annotations-Dictionary: String -> Stringoptional{}
attach-BooleanoptionalFalse
blkio_configBlock IO configuration for the service. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
buildConfiguration options for building the service’s image. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cap_addAdd Linux capabilities. For example, ‘CAP_SYS_ADMIN’, ‘SYS_ADMIN’, or ‘NET_ADMIN’.List of stringsoptional[]
cap_dropDrop Linux capabilities. For example, ‘CAP_SYS_ADMIN’, ‘SYS_ADMIN’, or ‘NET_ADMIN’.List of stringsoptional[]
cgroupSpecify the cgroup namespace to join. Use ‘host’ to use the host’s cgroup namespace, or ‘private’ to use a private cgroup namespace.Stringoptional""
cgroup_parentSpecify an optional parent cgroup for the container.Stringoptional""
commandOverride the default command declared by the container image, for example ‘CMD’ in Dockerfile.List of stringsoptional[]
configsGrant access to Configs on a per-service basis.List of stringsoptional[]
container_nameSpecify a custom container name, rather than a generated default name.Stringoptional""
cpu_countNumber of usable CPUs. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cpu_percentPercentage of CPU resources to use. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cpu_periodLimit the CPU CFS (Completely Fair Scheduler) period.Stringoptional""
cpu_quotaLimit the CPU CFS (Completely Fair Scheduler) quota.Stringoptional""
cpu_rt_periodLimit the CPU real-time period in microseconds or a duration.Stringoptional""
cpu_rt_runtimeLimit the CPU real-time runtime in microseconds or a duration.Stringoptional""
cpu_sharesCPU shares (relative weight) for the container.Stringoptional""
cpusNumber of CPUs to use. A floating-point value is supported to request partial CPUs.Stringoptional""
cpusetCPUs in which to allow execution (0-3, 0,1).Stringoptional""
credential_specConfigure the credential spec for managed service account. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
depends_onExpress dependency between services. Service dependencies cause services to be started in dependency order. The dependent service will wait for the dependency to be ready before starting.List of stringsoptional[]
deployJSON-encoded value. The shard reader deserialises the parsed JSON straight into the typed schema model.Stringoptional""
developJSON-encoded value. The shard reader deserialises the parsed JSON straight into the typed schema model.Stringoptional""
device_cgroup_rulesAdd rules to the cgroup allowed devices list.List of stringsoptional[]
devicesList of device mappings for the container.List of stringsoptional[]
dnsCustom DNS servers to set for the service container.List of stringsoptional[]
dns_optCustom DNS options to be passed to the container’s DNS resolver.List of stringsoptional[]
dns_searchCustom DNS search domains to set on the service container.List of stringsoptional[]
domainnameCustom domain name to use for the service container.Stringoptional""
entrypointOverride the default entrypoint declared by the container image, for example ‘ENTRYPOINT’ in Dockerfile.List of stringsoptional[]
env_fileAdd environment variables from a file or multiple files. Can be a single file path or a list of file paths.List of stringsoptional[]
environmentAdd environment variables. You can use either an array or a list of KEY=VAL pairs.Dictionary: String -> Stringoptional{}
exposeExpose ports without publishing them to the host machine - they’ll only be accessible to linked services. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
extendsExtend another service, in the current file or another file. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
external_linksLink to services started outside this Compose application. Specify services as <service_name>:.List of stringsoptional[]
extra_hostsAdd hostname mappings to the container network interface configuration.List of stringsoptional[]
gpusDefine GPU devices to use. Can be set to ‘all’ to use all GPUs, or a list of specific GPU devices. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
group_addAdd additional groups which user inside the container should be member of. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
healthcheckConfigure a health check for the container to monitor its health status. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
hostnameDefine a custom hostname for the service container.Stringoptional""
imageSpecify the image to start the container from. Can be a repository/tag, a digest, or a local image ID.Stringoptional""
initRun as an init process inside the container that forwards signals and reaps processes.BooleanoptionalFalse
ipcIPC sharing mode for the service container. Use ‘host’ to share the host’s IPC namespace, ‘service:[service_name]’ to share with another service, or ‘shareable’ to allow other services to share this service’s IPC namespace.Stringoptional""
isolationContainer isolation technology to use. Supported values are platform-specific.Stringoptional""
label_fileAdd metadata to containers using files containing Docker labels.List of stringsoptional[]
labelsAdd metadata to containers using Docker labels. You can use either an array or a list.Dictionary: String -> Stringoptional{}
linksLink to containers in another service. Either specify both the service name and a link alias (SERVICE:ALIAS), or just the service name.List of stringsoptional[]
loggingLogging configuration for the service. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
mac_addressContainer MAC address to set.Stringoptional""
mem_limitMemory limit for the container. A string value can use suffix like ‘2g’ for 2 gigabytes.Stringoptional""
mem_reservationMemory reservation for the container.Stringoptional""
mem_swappinessContainer memory swappiness as percentage (0 to 100).Stringoptional""
memswap_limitAmount of memory the container is allowed to swap to disk. Set to -1 to enable unlimited swap.Stringoptional""
modelsAI Models to use, referencing entries under the top-level models key.List of stringsoptional[]
network_modeNetwork mode. Values can be ‘bridge’, ‘host’, ‘none’, ‘service:[service name]’, or ‘container:[container name]’.Stringoptional""
networksNetworks to join, referencing entries under the top-level networks key. Can be a list of network names or a mapping of network name to network configuration.List of stringsoptional[]
oom_kill_disableDisable OOM Killer for the container.BooleanoptionalFalse
oom_score_adjTune host’s OOM preferences for the container (accepts -1000 to 1000). (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pidPID mode for container.Stringoptional""
pids_limitTune a container’s PIDs limit. Set to -1 for unlimited PIDs.Stringoptional""
platformTarget platform to run on, e.g., ‘linux/amd64’, ‘linux/arm64’, or ‘windows/amd64’.Stringoptional""
portsExpose container ports. Short format ([HOST:]CONTAINER[/PROTOCOL]).List of stringsoptional[]
post_startCommands to run after the container starts. If any command fails, the container stops. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pre_stopCommands to run before the container stops. If any command fails, the container stop is aborted. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
privilegedGive extended privileges to the service container.BooleanoptionalFalse
profilesList of profiles for this service. When profiles are specified, services are only started when the profile is activated.List of stringsoptional[]
providerSpecify a service which will not be manage by Compose directly, and delegate its management to an external provider. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pull_policyPolicy for pulling images. Options include: ‘always’, ‘never’, ‘if_not_present’, ‘missing’, ‘build’, or time-based refresh policies.Stringoptional""
pull_refresh_afterTime after which to refresh the image. Used with pull_policy=refresh.Stringoptional""
read_onlyMount the container’s filesystem as read only.BooleanoptionalFalse
restartRestart policy for the service container. Options include: ‘no’, ‘always’, ‘on-failure’, and ‘unless-stopped’.Stringoptional""
runtimeRuntime to use for this container, e.g., ‘runc’.Stringoptional""
scaleNumber of containers to deploy for this service.Stringoptional""
secretsGrant access to Secrets on a per-service basis.List of stringsoptional[]
security_optOverride the default labeling scheme for each container.List of stringsoptional[]
service_nameTop-level key for this service in the rendered project. Defaults to the rule name.Stringoptional""
shm_sizeSize of /dev/shm. A string value can use suffix like ‘2g’ for 2 gigabytes.Stringoptional""
stdin_openKeep STDIN open even if not attached.BooleanoptionalFalse
stop_grace_periodTime to wait for the container to stop gracefully before sending SIGKILL (e.g., ‘1s’, ‘1m30s’).Stringoptional""
stop_signalSignal to stop the container (e.g., ‘SIGTERM’, ‘SIGINT’).Stringoptional""
storage_optStorage driver options for the container. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
sysctlsKernel parameters to set in the container. You can use either an array or a list.Dictionary: String -> Stringoptional{}
tmpfsMount a temporary filesystem (tmpfs) into the container. Can be a single value or a list.List of stringsoptional[]
ttyAllocate a pseudo-TTY to service container.BooleanoptionalFalse
ulimitsOverride the default ulimits for a container. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
use_api_socketBind mount Docker API socket and required auth.BooleanoptionalFalse
userUsername or UID to run the container process as.Stringoptional""
userns_modeUser namespace to use. ‘host’ shares the host’s user namespace.Stringoptional""
utsUTS namespace to use. ‘host’ shares the host’s UTS namespace.Stringoptional""
volumesMount host paths or named volumes accessible to the container. Short syntax (VOLUME:CONTAINER_PATH[:MODE])List of stringsoptional[]
volumes_fromMount volumes from another service or container. Optionally specify read-only access (ro) or read-write (rw).List of stringsoptional[]
working_dirThe working directory in which the entrypoint or command will be runStringoptional""

docker_compose_volume

load("@rules_docker_compose//compose:compose_rules.bzl", "docker_compose_volume")

docker_compose_volume(name, driver, driver_opts, external, labels, name_override, volume_name)

Volume configuration for the Compose application.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
driverSpecify which volume driver should be used for this volume.Stringoptional""
driver_optsSpecify driver-specific options.Dictionary: String -> Stringoptional{}
externalSpecifies that this volume already exists and was created outside of Compose.BooleanoptionalFalse
labelsAdd metadata to the volume using labels.Dictionary: String -> Stringoptional{}
name_overrideCustom name for this volume.Stringoptional""
volume_nameTop-level key for this volume in the rendered project. Defaults to the rule name.Stringoptional""

ComposeNetworkInfo

load("@rules_docker_compose//compose:compose_rules.bzl", "ComposeNetworkInfo")

ComposeNetworkInfo(network_name, json)

A network contributed by a target. Shard JSON matches the network schema.

FIELDS

NameDescription
network_namestring: top-level key for this network in the rendered project.
jsonFile: the JSON shard.

ComposeServiceInfo

load("@rules_docker_compose//compose:compose_rules.bzl", "ComposeServiceInfo")

ComposeServiceInfo(service_name, json)

A service contributed by a target. Shard JSON matches the service schema.

FIELDS

NameDescription
service_namestring: top-level key for this service in the rendered project.
jsonFile: the JSON shard.

ComposeVolumeInfo

load("@rules_docker_compose//compose:compose_rules.bzl", "ComposeVolumeInfo")

ComposeVolumeInfo(volume_name, json)

A volume contributed by a target. Shard JSON matches the volume schema.

FIELDS

NameDescription
volume_namestring: top-level key for this volume in the rendered project.
jsonFile: the JSON shard.

from docs/defs.md

User-facing Bazel rules for rules_docker_compose.

The typed schema-derived rules live in compose/compose_rules.bzl — they’re regenerated from the canonical compose-spec schema via rules_jsonschema’s jsonschema_starlark_codegen. Every spec property becomes a typed Bazel attr.* automatically. This file owns the pieces that aren’t schema-derivable:

  • docker_compose — collects shards from the graph and invokes the Rust compose-gen binary to emit canonical YAML.
  • docker_compose_oci_image_ref — resolves an @rules_oci image to <repo>@sha256:<digest> at build time, contributes that ref to the aggregator via ComposeServiceImageRefInfo. The aggregator threads it to compose-gen --service-image=... so the rendered image: field carries the build-time digest.
  • docker_compose_up / _downbazel run wrappers.

Re-exports the generated typed rules + providers so callers can load everything from a single file.

docker_compose

load("@rules_docker_compose//compose:defs.bzl", "docker_compose")

docker_compose(name, deps, out, project_name)

Assemble service / volume / network shards into one canonical compose.yaml.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsTargets contributing services, volumes, networks, or service-image overrides.List of labelsoptional[]
outPath for the generated compose YAML (e.g. compose.yaml).Labelrequired
project_nameTop-level name: field. Defaults to empty (compose derives a name from the file’s containing directory).Stringoptional""

docker_compose_network

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_network")

docker_compose_network(name, attachable, driver, driver_opts, enable_ipv4, enable_ipv6, external,
                       internal, ipam, labels, name_override, network_name)

Network configuration for the Compose application.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
attachableIf true, standalone containers can attach to this network.BooleanoptionalFalse
driverSpecify which driver should be used for this network. Default is ‘bridge’.Stringoptional""
driver_optsSpecify driver-specific options defined as key/value pairs.Dictionary: String -> Stringoptional{}
enable_ipv4Enable IPv4 networking.BooleanoptionalFalse
enable_ipv6Enable IPv6 networking.BooleanoptionalFalse
externalSpecifies that this network already exists and was created outside of Compose.BooleanoptionalFalse
internalCreate an externally isolated network.BooleanoptionalFalse
ipamCustom IP Address Management configuration for this network. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
labelsAdd metadata to the network using labels.Dictionary: String -> Stringoptional{}
name_overrideCustom name for this network.Stringoptional""
network_nameTop-level key for this network in the rendered project. Defaults to the rule name.Stringoptional""

docker_compose_oci_image_ref

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_oci_image_ref")

docker_compose_oci_image_ref(name, oci_image, oci_repo, service_name)

Resolve an OCI image layout to <repo>@sha256:<digest> at build time and override the named service’s image: in the rendered compose YAML.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
oci_imageTarget producing an OCI image layout (typically @rules_oci//oci:defs.bzl%oci_image).Labelrequired
oci_repoRegistry/repo prefix joined with the resolved digest (e.g. ghcr.io/myorg/myapp).Stringrequired
service_nameName of the docker_compose_service whose image: to override.Stringrequired

docker_compose_service

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_service")

docker_compose_service(name, annotations, attach, blkio_config, build, cap_add, cap_drop, cgroup,
                       cgroup_parent, command, configs, container_name, cpu_count, cpu_percent,
                       cpu_period, cpu_quota, cpu_rt_period, cpu_rt_runtime, cpu_shares, cpus, cpuset,
                       credential_spec, depends_on, deploy, develop, device_cgroup_rules, devices,
                       dns, dns_opt, dns_search, domainname, entrypoint, env_file, environment,
                       expose, extends, external_links, extra_hosts, gpus, group_add, healthcheck,
                       hostname, image, init, ipc, isolation, label_file, labels, links, logging,
                       mac_address, mem_limit, mem_reservation, mem_swappiness, memswap_limit, models,
                       network_mode, networks, oom_kill_disable, oom_score_adj, pid, pids_limit,
                       platform, ports, post_start, pre_stop, privileged, profiles, provider,
                       pull_policy, pull_refresh_after, read_only, restart, runtime, scale, secrets,
                       security_opt, service_name, shm_size, stdin_open, stop_grace_period,
                       stop_signal, storage_opt, sysctls, tmpfs, tty, ulimits, use_api_socket, user,
                       userns_mode, uts, volumes, volumes_from, working_dir)

Configuration for a service.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
annotations-Dictionary: String -> Stringoptional{}
attach-BooleanoptionalFalse
blkio_configBlock IO configuration for the service. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
buildConfiguration options for building the service’s image. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cap_addAdd Linux capabilities. For example, ‘CAP_SYS_ADMIN’, ‘SYS_ADMIN’, or ‘NET_ADMIN’.List of stringsoptional[]
cap_dropDrop Linux capabilities. For example, ‘CAP_SYS_ADMIN’, ‘SYS_ADMIN’, or ‘NET_ADMIN’.List of stringsoptional[]
cgroupSpecify the cgroup namespace to join. Use ‘host’ to use the host’s cgroup namespace, or ‘private’ to use a private cgroup namespace.Stringoptional""
cgroup_parentSpecify an optional parent cgroup for the container.Stringoptional""
commandOverride the default command declared by the container image, for example ‘CMD’ in Dockerfile.List of stringsoptional[]
configsGrant access to Configs on a per-service basis.List of stringsoptional[]
container_nameSpecify a custom container name, rather than a generated default name.Stringoptional""
cpu_countNumber of usable CPUs. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cpu_percentPercentage of CPU resources to use. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
cpu_periodLimit the CPU CFS (Completely Fair Scheduler) period.Stringoptional""
cpu_quotaLimit the CPU CFS (Completely Fair Scheduler) quota.Stringoptional""
cpu_rt_periodLimit the CPU real-time period in microseconds or a duration.Stringoptional""
cpu_rt_runtimeLimit the CPU real-time runtime in microseconds or a duration.Stringoptional""
cpu_sharesCPU shares (relative weight) for the container.Stringoptional""
cpusNumber of CPUs to use. A floating-point value is supported to request partial CPUs.Stringoptional""
cpusetCPUs in which to allow execution (0-3, 0,1).Stringoptional""
credential_specConfigure the credential spec for managed service account. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
depends_onExpress dependency between services. Service dependencies cause services to be started in dependency order. The dependent service will wait for the dependency to be ready before starting.List of stringsoptional[]
deployJSON-encoded value. The shard reader deserialises the parsed JSON straight into the typed schema model.Stringoptional""
developJSON-encoded value. The shard reader deserialises the parsed JSON straight into the typed schema model.Stringoptional""
device_cgroup_rulesAdd rules to the cgroup allowed devices list.List of stringsoptional[]
devicesList of device mappings for the container.List of stringsoptional[]
dnsCustom DNS servers to set for the service container.List of stringsoptional[]
dns_optCustom DNS options to be passed to the container’s DNS resolver.List of stringsoptional[]
dns_searchCustom DNS search domains to set on the service container.List of stringsoptional[]
domainnameCustom domain name to use for the service container.Stringoptional""
entrypointOverride the default entrypoint declared by the container image, for example ‘ENTRYPOINT’ in Dockerfile.List of stringsoptional[]
env_fileAdd environment variables from a file or multiple files. Can be a single file path or a list of file paths.List of stringsoptional[]
environmentAdd environment variables. You can use either an array or a list of KEY=VAL pairs.Dictionary: String -> Stringoptional{}
exposeExpose ports without publishing them to the host machine - they’ll only be accessible to linked services. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
extendsExtend another service, in the current file or another file. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
external_linksLink to services started outside this Compose application. Specify services as <service_name>:.List of stringsoptional[]
extra_hostsAdd hostname mappings to the container network interface configuration.List of stringsoptional[]
gpusDefine GPU devices to use. Can be set to ‘all’ to use all GPUs, or a list of specific GPU devices. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
group_addAdd additional groups which user inside the container should be member of. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
healthcheckConfigure a health check for the container to monitor its health status. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
hostnameDefine a custom hostname for the service container.Stringoptional""
imageSpecify the image to start the container from. Can be a repository/tag, a digest, or a local image ID.Stringoptional""
initRun as an init process inside the container that forwards signals and reaps processes.BooleanoptionalFalse
ipcIPC sharing mode for the service container. Use ‘host’ to share the host’s IPC namespace, ‘service:[service_name]’ to share with another service, or ‘shareable’ to allow other services to share this service’s IPC namespace.Stringoptional""
isolationContainer isolation technology to use. Supported values are platform-specific.Stringoptional""
label_fileAdd metadata to containers using files containing Docker labels.List of stringsoptional[]
labelsAdd metadata to containers using Docker labels. You can use either an array or a list.Dictionary: String -> Stringoptional{}
linksLink to containers in another service. Either specify both the service name and a link alias (SERVICE:ALIAS), or just the service name.List of stringsoptional[]
loggingLogging configuration for the service. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
mac_addressContainer MAC address to set.Stringoptional""
mem_limitMemory limit for the container. A string value can use suffix like ‘2g’ for 2 gigabytes.Stringoptional""
mem_reservationMemory reservation for the container.Stringoptional""
mem_swappinessContainer memory swappiness as percentage (0 to 100).Stringoptional""
memswap_limitAmount of memory the container is allowed to swap to disk. Set to -1 to enable unlimited swap.Stringoptional""
modelsAI Models to use, referencing entries under the top-level models key.List of stringsoptional[]
network_modeNetwork mode. Values can be ‘bridge’, ‘host’, ‘none’, ‘service:[service name]’, or ‘container:[container name]’.Stringoptional""
networksNetworks to join, referencing entries under the top-level networks key. Can be a list of network names or a mapping of network name to network configuration.List of stringsoptional[]
oom_kill_disableDisable OOM Killer for the container.BooleanoptionalFalse
oom_score_adjTune host’s OOM preferences for the container (accepts -1000 to 1000). (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pidPID mode for container.Stringoptional""
pids_limitTune a container’s PIDs limit. Set to -1 for unlimited PIDs.Stringoptional""
platformTarget platform to run on, e.g., ‘linux/amd64’, ‘linux/arm64’, or ‘windows/amd64’.Stringoptional""
portsExpose container ports. Short format ([HOST:]CONTAINER[/PROTOCOL]).List of stringsoptional[]
post_startCommands to run after the container starts. If any command fails, the container stops. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pre_stopCommands to run before the container stops. If any command fails, the container stop is aborted. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
privilegedGive extended privileges to the service container.BooleanoptionalFalse
profilesList of profiles for this service. When profiles are specified, services are only started when the profile is activated.List of stringsoptional[]
providerSpecify a service which will not be manage by Compose directly, and delegate its management to an external provider. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
pull_policyPolicy for pulling images. Options include: ‘always’, ‘never’, ‘if_not_present’, ‘missing’, ‘build’, or time-based refresh policies.Stringoptional""
pull_refresh_afterTime after which to refresh the image. Used with pull_policy=refresh.Stringoptional""
read_onlyMount the container’s filesystem as read only.BooleanoptionalFalse
restartRestart policy for the service container. Options include: ‘no’, ‘always’, ‘on-failure’, and ‘unless-stopped’.Stringoptional""
runtimeRuntime to use for this container, e.g., ‘runc’.Stringoptional""
scaleNumber of containers to deploy for this service.Stringoptional""
secretsGrant access to Secrets on a per-service basis.List of stringsoptional[]
security_optOverride the default labeling scheme for each container.List of stringsoptional[]
service_nameTop-level key for this service in the rendered project. Defaults to the rule name.Stringoptional""
shm_sizeSize of /dev/shm. A string value can use suffix like ‘2g’ for 2 gigabytes.Stringoptional""
stdin_openKeep STDIN open even if not attached.BooleanoptionalFalse
stop_grace_periodTime to wait for the container to stop gracefully before sending SIGKILL (e.g., ‘1s’, ‘1m30s’).Stringoptional""
stop_signalSignal to stop the container (e.g., ‘SIGTERM’, ‘SIGINT’).Stringoptional""
storage_optStorage driver options for the container. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
sysctlsKernel parameters to set in the container. You can use either an array or a list.Dictionary: String -> Stringoptional{}
tmpfsMount a temporary filesystem (tmpfs) into the container. Can be a single value or a list.List of stringsoptional[]
ttyAllocate a pseudo-TTY to service container.BooleanoptionalFalse
ulimitsOverride the default ulimits for a container. (JSON-encoded; the Rust shard reader parses this verbatim.)Stringoptional""
use_api_socketBind mount Docker API socket and required auth.BooleanoptionalFalse
userUsername or UID to run the container process as.Stringoptional""
userns_modeUser namespace to use. ‘host’ shares the host’s user namespace.Stringoptional""
utsUTS namespace to use. ‘host’ shares the host’s UTS namespace.Stringoptional""
volumesMount host paths or named volumes accessible to the container. Short syntax (VOLUME:CONTAINER_PATH[:MODE])List of stringsoptional[]
volumes_fromMount volumes from another service or container. Optionally specify read-only access (ro) or read-write (rw).List of stringsoptional[]
working_dirThe working directory in which the entrypoint or command will be runStringoptional""

docker_compose_volume

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_volume")

docker_compose_volume(name, driver, driver_opts, external, labels, name_override, volume_name)

Volume configuration for the Compose application.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
driverSpecify which volume driver should be used for this volume.Stringoptional""
driver_optsSpecify driver-specific options.Dictionary: String -> Stringoptional{}
externalSpecifies that this volume already exists and was created outside of Compose.BooleanoptionalFalse
labelsAdd metadata to the volume using labels.Dictionary: String -> Stringoptional{}
name_overrideCustom name for this volume.Stringoptional""
volume_nameTop-level key for this volume in the rendered project. Defaults to the rule name.Stringoptional""

ComposeNetworkInfo

load("@rules_docker_compose//compose:defs.bzl", "ComposeNetworkInfo")

ComposeNetworkInfo(network_name, json)

A network contributed by a target. Shard JSON matches the network schema.

FIELDS

NameDescription
network_namestring: top-level key for this network in the rendered project.
jsonFile: the JSON shard.

ComposeProjectInfo

load("@rules_docker_compose//compose:defs.bzl", "ComposeProjectInfo")

ComposeProjectInfo(yaml)

A rendered compose project.

FIELDS

NameDescription
yamlFile: the rendered compose.yaml.

ComposeServiceImageRefInfo

load("@rules_docker_compose//compose:defs.bzl", "ComposeServiceImageRefInfo")

ComposeServiceImageRefInfo(service_name, file)

A build-time-resolved <repo>@<digest> image reference targeted at a named service.

FIELDS

NameDescription
service_namestring: name of the service whose image: to override.
fileFile: a one-line text file containing the reference.

ComposeServiceInfo

load("@rules_docker_compose//compose:defs.bzl", "ComposeServiceInfo")

ComposeServiceInfo(service_name, json)

A service contributed by a target. Shard JSON matches the service schema.

FIELDS

NameDescription
service_namestring: top-level key for this service in the rendered project.
jsonFile: the JSON shard.

ComposeVolumeInfo

load("@rules_docker_compose//compose:defs.bzl", "ComposeVolumeInfo")

ComposeVolumeInfo(volume_name, json)

A volume contributed by a target. Shard JSON matches the volume schema.

FIELDS

NameDescription
volume_namestring: top-level key for this volume in the rendered project.
jsonFile: the JSON shard.

docker_compose_down

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_down")

docker_compose_down(name, project, **kwargs)

bazel run :<name> -> docker compose -f <generated.yaml> down.

PARAMETERS

NameDescriptionDefault Value
name

-

none
project

-

none
kwargs

-

none

docker_compose_up

load("@rules_docker_compose//compose:defs.bzl", "docker_compose_up")

docker_compose_up(name, project, **kwargs)

bazel run :<name> -> docker compose -f <generated.yaml> up.

Args after -- are passed through to docker compose (e.g. bazel run :stack.up -- -d for detached mode).

PARAMETERS

NameDescriptionDefault Value
name

-

none
project

-

none
kwargs

-

none

Conformance#

2 findings across 2 invariants. 10 contested atoms. See how gating works or the full report.

D2 a non-dev register_toolchains propagates to every transitive consumer why this matters ↗
versiontoolchain
0.2.6@rust_toolchains//:all
D3 a repo name CHOSEN on a SHARED extension must be namespaced why this matters ↗
repoextension
compose_crates@rules_rust//crate_universe:extension.bzl

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
bazel_skylib 1.8.2 1.9.0 ×2
gazelle 0.36.0 0.30.0 ×50.44.0 ×10.51.0 ×3
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
protobuf 33.4 34.0.bcr.1 ×2
rules_go 0.60.0 0.39.1 ×5
rules_jvm_external 6.7 6.8 ×4
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1

Dependencies#

rules_docker_compose in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

platforms1.0.0bazel_skylib1.8.2rules_jsonschema0.1.0rules_rust0.70.0rules_shell0.6.1devstardoc0.7.2dev

Used by (1 in the registry)

Versions#

1 published version, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.2.6 latest WYkcvqj8HxNgsAi2… tag archive ↗

Changelog#

All notable changes to rules_docker_compose. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.

0.2.3 — CI + CHANGELOG infrastructure

  • .github/workflows/ci.yml: bazel test //... on ubuntu + macos, plus a buildifier lint job.
  • CHANGELOG.md (this file) — backfills v0.2.0 / v0.2.1 / v0.2.2 notes that were previously only in the git log.
  • No API changes.

0.2.2 — config_mounts + secret_mounts on the service façade

  • Adds label_keyed_string_dict variants for mounting configs + secrets at specific in-container paths (the existing configs: / secrets: label_list attrs only support the compose-spec short form, which mounts at /<name> / /run/secrets/<name> — fine for most cases but not for loki/prometheus/promtail/otel/tempo).
  • config_mounts = {":loki_config": "/etc/loki/local-config.yaml"} emits the extended configs: [{source, target}] form.
  • Transitive aspect walks the new attrs so root-level deps still picks up the underlying docker_compose_config / docker_compose_secret targets.

0.2.1 — smart-merge for compose_extra

  • compose_extra on docker_compose_service now merges into the payload semantically instead of dict.update()-overwriting:
    • list-valued keys (volumes, ports, command, networks, …) → append extra to payload.
    • dict-valued keys (environment, labels, sysctls, …) → merge dicts (extra wins on key collision).
    • scalar keys → extra wins.
  • Existing diff_tests unchanged (no smart-merge cases hit them).

0.2.0 — auto-discovery aspect + idiomatic service façade

  • docker_compose’s deps attr now uses _compose_transitive_aspect to walk every docker_compose_service’s label-typed attrs (deps, deps_healthy, deps_completed, networks, configs, secrets, named_volume_mounts) and collect the transitive Compose*Info shards. Consumers only list the root services they actually want exposed; intermediate deps are picked up automatically.
  • docker_compose_service façade replaces the verbose schema-derived raw rule for hand-written services: label-typed attrs for image_ref, deps, networks, etc. The schema-derived rules still ship for callers who want one big dict.

0.1.0 — initial release

  • docker_compose rule: aggregates Bazel shards into a single canonical docker-compose.yml via the Rust compose-gen binary.
  • docker_compose_oci_image_ref: resolves an @rules_oci image reference at build time, threading the <repo>@sha256:<digest> through the aggregator so the rendered image: field carries the digest.
  • docker_compose_up / docker_compose_down bazel run wrappers.
  • Schema-derived typed rules (docker_compose_service, docker_compose_network, docker_compose_volume) generated from the canonical compose-spec via rules_jsonschema’s jsonschema_starlark_codegen. Regenerated on every build; the diff_test in docs/ gates committed output.
  • Stardoc-generated reference docs in docs/.
  • End-to-end smoke tests covering aggregation, OCI image digest threading, and bazel run //...:_up/_down round-trips.

← All modules