Skip to content

[BUG] Extending compose files in certain ways panics #12990

@paranoidPhantom

Description

@paranoidPhantom

Description

TL;DR extending a compose with another and running compose commands panics

I have a compose.yml:

services:
  traefik:
    container_name: traefik
    image: traefik:v3.4
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.dev.toml:/traefik.toml
  ui:
    build:
      context: ui
      dockerfile: Dockerfile.dev
    container_name: ui
    develop:
      watch:
        - action: sync
          path: ./ui/app
          target: /app/app
          ignore:
            - node_modules/
    labels:
      - traefik.enable=true
      - traefik.http.routers.ui-router.rule=PathPrefix(`/`)
      - traefik.http.routers.ui-router.entrypoints=web
  engine:
    build:
      context: .
      dockerfile: engine/Dockerfile.dev
    container_name: engine
    labels:
      - traefik.enable=true
      # Main web interface router
      - traefik.http.routers.engine-router.rule=PathPrefix(`/engine`)
      - traefik.http.routers.engine-router.entrypoints=web
    develop:
      watch:
        - action: sync
          path: ./engine/src
          target: /app/engine/src/
  postgres:
    container_name: postgres
    image: postgres:17.5
    environment:
      POSTGRES_USER: example_user
      POSTGRES_PASSWORD: example_password
      POSTGRES_DB: example_db
    ports:
      - "5432:5432"
    volumes:
      - .temp/postgres_data:/var/lib/postgresql/data

And a production.compose.yml:

services:
  traefik:
    extends:
      file: compose.yml
      services: traefik
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik.toml:/traefik.toml"
  ui:
    extends:
      file: compose.yml
      services: ui
    build:
      context: ui
      dockerfile: Dockerfile
  engine:
    extends:
      file: compose.yml
      services: engine
    build:
      context: .
      dockerfile: engine/Dockerfile
  postgres:
    extends:
      file: compose.yml
      services: postgres

Here is the trace:

➜  _ git:(master) ✗ docker compose -f production.compose.yml config
panic: interface conversion: interface {} is nil, not string

goroutine 1 [running]:
github.com/compose-spec/compose-go/v2/loader.applyServiceExtends({0x1055e5b68, 0x1400059b050}, {0x140002c8868, 0x8}, 0x1400059b4d0, 
0x14000216510, 0x1400006ab10, {0x1400006a818, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/extends.go:71 +0x85c
github.com/compose-spec/compose-go/v2/loader.ApplyExtends({0x1055e5b68, 0x1400059b050}, 0x1400059b4a0, 0x14000216510, 0x1400006ab10,
 {0x1400006a818, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/extends.go:40 +0x124
github.com/compose-spec/compose-go/v2/loader.loadYamlFile.func1({0x105156500?, 0x1400059b260?}, {0x1400006a818, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:448 +0x12c
github.com/compose-spec/compose-go/v2/loader.loadYamlFile({0x1055e5ba0, 0x1400016a230}, {{0x140002ec100, 0x3b}, {0x14000696200, 0x1f
a, 0x200}, 0x0}, 0x14000216510, {0x140002ec0c0, ...}, ...)
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:515 +0x440
github.com/compose-spec/compose-go/v2/loader.loadYamlModel({0x1055e5ba0, 0x1400016a230}, {{0x0, 0x0}, {0x140002ec0c0, 0x24}, {0x1400
059a720, 0x1, 0x1}, 0x1400059a540}, ...)
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:376 +0x110
github.com/compose-spec/compose-go/v2/loader.load({0x1055e5ba0, 0x1400016a230}, {{0x0, 0x0}, {0x140002ec0c0, 0x24}, {0x1400059a720, 
0x1, 0x1}, 0x1400059a540}, ...)
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:536 +0x260
github.com/compose-spec/compose-go/v2/loader.loadModelWithContext({0x1055e5ba0, 0x1400016a230}, 0x1400068e340, 0x14000216510)
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:348 +0xc4
github.com/compose-spec/compose-go/v2/loader.LoadWithContext({0x1055e5ba0, 0x1400016a230}, {{0x0, 0x0}, {0x140002ec0c0, 0x24}, {0x14
00059a720, 0x1, 0x1}, 0x1400059a540}, ...)
        github.com/compose-spec/compose-go/v2@v2.6.0/loader/loader.go:324 +0xc8
github.com/compose-spec/compose-go/v2/cli.(*ProjectOptions).LoadProject(0x14000216360, {0x1055e5ba0, 0x1400016a230})
        github.com/compose-spec/compose-go/v2@v2.6.0/cli/options.go:446 +0xa0
github.com/docker/compose/v2/cmd/compose.(*ProjectOptions).ToProject(0x14000327720, {0x1055e5ba0, 0x1400016a230}, {0x105604b08, 0x14
0000fa640}, {0x106b71e80, 0x0, 0x0}, {0x1400059a4b0, 0x6, ...})
        github.com/docker/compose/v2/cmd/compose/compose.go:335 +0x448
github.com/docker/compose/v2/cmd/compose.(*configOptions).ToProject(0x1400006b698, {0x1055e5ba0, 0x1400016a230}, {0x105604b08, 0x140
000fa640}, {0x106b71e80, 0x0, 0x0}, {0x0, 0x0, ...})
        github.com/docker/compose/v2/cmd/compose/config.go:63 +0x120
github.com/docker/compose/v2/cmd/compose.runConfigInterpolate({0x1055e5ba0, 0x1400016a230}, {0x105604b08, 0x140000fa640}, {0x1400032
7720, {0x104ad73dd, 0x4}, {0x0, 0x0}, 0x0, ...}, ...)
        github.com/docker/compose/v2/cmd/compose/config.go:183 +0x64
github.com/docker/compose/v2/cmd/compose.runConfig({0x1055e5ba0?, 0x1400016a230?}, {0x105604b08, 0x140000fa640}, {0x14000327720, {0x
104ad73dd, 0x4}, {0x0, 0x0}, 0x0, ...}, ...)
        github.com/docker/compose/v2/cmd/compose/config.go:161 +0x90
github.com/docker/compose/v2/cmd/compose.configCommand.func2({0x1055e5ba0?, 0x1400016a230?}, {0x106b71e80?, 0x1400059e1c8?, 0x140000
021c0?})
        github.com/docker/compose/v2/cmd/compose/config.go:127 +0xd8
github.com/docker/compose/v2/cmd/compose.configCommand.Adapt.func4({0x1055e5ba0?, 0x1400016a230?}, 0x2?, {0x106b71e80?, 0x1339dd7?, 
0xc2102a40983a6868?})
        github.com/docker/compose/v2/cmd/compose/compose.go:137 +0x3c
github.com/docker/compose/v2/cmd/compose.configCommand.Adapt.AdaptCmd.func7(0x140001c3508, {0x106b71e80, 0x0, 0x0})
        github.com/docker/compose/v2/cmd/compose/compose.go:121 +0x10c
github.com/docker/cli/cli-plugins/plugin.RunPlugin.func1.1.2(0x140001c3508, {0x106b71e80, 0x0, 0x0})
        github.com/docker/cli@v28.1.0+incompatible/cli-plugins/plugin/plugin.go:65 +0x68
github.com/docker/compose/v2/cmd/cmdtrace.Setup.wrapRunE.func2(0x140001c3508?, {0x106b71e80?, 0x0?, 0x0?})
        github.com/docker/compose/v2/cmd/cmdtrace/cmd_span.go:85 +0x58
github.com/spf13/cobra.(*Command).execute(0x140001c3508, {0x140000be890, 0x0, 0x0})
        github.com/spf13/cobra@v1.9.1/command.go:1015 +0x82c
github.com/spf13/cobra.(*Command).ExecuteC(0x1400039d508)
        github.com/spf13/cobra@v1.9.1/command.go:1148 +0x350
github.com/spf13/cobra.(*Command).Execute(...)
        github.com/spf13/cobra@v1.9.1/command.go:1071
github.com/docker/cli/cli-plugins/plugin.RunPlugin(0x140000fa640, 0x14000050c08, {{0x104ad7f49, 0x5}, {0x104ae1e6d, 0xb}, {0x104e883
e0, 0x11}, {0x0, 0x0}, ...})
        github.com/docker/cli@v28.1.0+incompatible/cli-plugins/plugin/plugin.go:80 +0x138
github.com/docker/cli/cli-plugins/plugin.Run(0x1055af978, {{0x104ad7f49, 0x5}, {0x104ae1e6d, 0xb}, {0x104e883e0, 0x11}, {0x0, 0x0}, 
{0x0, ...}})
        github.com/docker/cli@v28.1.0+incompatible/cli-plugins/plugin/plugin.go:95 +0x124
main.pluginMain()
        github.com/docker/compose/v2/cmd/main.go:38 +0x98
main.main()
        github.com/docker/compose/v2/cmd/main.go:98 +0x1a4

Steps To Reproduce

No response

Compose Version

Docker Compose version v2.35.1-desktop.1

Docker Environment

Client:
 Version:    28.1.1
 Context:    desktop-linux
 Debug Mode: false
 Plugins:
  ai: Docker AI Agent - Ask Gordon (Docker Inc.)
    Version:  v1.1.7
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-ai
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.23.0-desktop.1
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-buildx
  cloud: Docker Cloud (Docker Inc.)
    Version:  v0.3.0
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-cloud
  compose: Docker Compose (Docker Inc.)
    Version:  v2.35.1-desktop.1
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-compose
  debug: Get a shell into any image or container (Docker Inc.)
    Version:  0.0.38
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-debug
  desktop: Docker Desktop commands (Docker Inc.)
    Version:  v0.1.8
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-desktop
  dev: Docker Dev Environments (Docker Inc.)
    Version:  v0.1.2
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-dev
  extension: Manages Docker extensions (Docker Inc.)
    Version:  v0.2.27
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-extension
  init: Creates Docker-related starter files for your project (Docker Inc.)
    Version:  v1.4.0
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-init
  mcp: Docker MCP Plugin (Docker Inc.)
    Version:  dev
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-mcp
  model: Docker Model Runner (Docker Inc.)
    Version:  v0.1.11
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-model
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
    Version:  0.6.0
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-sbom
  scout: Docker Scout (Docker Inc.)
    Version:  v1.17.1
    Path:     /Users/andreihudalla/.docker/cli-plugins/docker-scout

Server:
 Containers: 4
  Running: 0
  Paused: 0
  Stopped: 4
 Images: 4
 Server Version: 28.1.1
 Storage Driver: overlayfs
  driver-type: io.containerd.snapshotter.v1
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 CDI spec directories:
  /etc/cdi
  /var/run/cdi
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 05044ec0a9a75232cad458027ca83437aae3f4da
 runc version: v1.2.5-0-g59923ef
 init version: de40ad0
 Security Options:
  seccomp
   Profile: unconfined
  cgroupns
 Kernel Version: 6.10.14-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: aarch64
 CPUs: 10
 Total Memory: 7.654GiB
 Name: docker-desktop
 ID: cec4081a-3803-4e5e-a400-f4c105720861
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Labels:
  com.docker.desktop.address=unix:///Users/andreihudalla/Library/Containers/com.docker.docker/Data/docker-cli.sock
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  ::1/128
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: DOCKER_INSECURE_NO_IPTABLES_RAW is set
WARNING: daemon is not using the default seccomp profile

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions