compose-spec / compose-go

Reference library for parsing and loading Compose YAML files
https://compose-spec.io
Apache License 2.0
355 stars 112 forks source link

Panic crash if services are not indented correctly with extended compose files. #668

Closed DocFX closed 1 month ago

DocFX commented 2 months ago

Hi, I just had a weird crash (took me some time to figure it out ^^).

Stack trace:

PS F:\Important\xxx\git\xxx> docker compose --env-file "./environment-files/.env" --env-file "./environment-files/.env.prod-zone-1-server-2" --env-file "./environment-files/.env.prod-zone-1-server-2.local" -f "./.devcontainer/docker-compose-files/xxx-containers-compose-prod-zone-1-server-2.yml" config
panic: interface conversion: interface {} is nil, not map[string]interface {}

goroutine 1 [running]:
github.com/compose-spec/compose-go/v2/loader.getExtendsBaseFromFile({0x2ba8da8, 0xc000538870}, {0xc0002f6080, 0x1c}, {0xc0006877e8, 0x14}, {0xc0003b8b00, 0x7f}, {0xc0005347b0, 0x28}, ...)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/extends.go:166 +0x9bc
github.com/compose-spec/compose-go/v2/loader.applyServiceExtends({0x2ba8da8?, 0xc000538870?}, {0xc0002f6080, 0x1c}, 0xc000539aa0, 0xc000536240, 0x4?, {0xc0004968a8, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/extends.go:86 +0x44f
github.com/compose-spec/compose-go/v2/loader.ApplyExtends({0x2ba8da8, 0xc000538870}, 0xc0003f1260?, 0x2957158?, 0xc000496768?, {0xc0004968a8, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/extends.go:40 +0x178
github.com/compose-spec/compose-go/v2/loader.loadYamlFile.func1({0x243dce0?, 0xc000538a50?}, {0xc0004968a8, 0x1, 0x1})
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:428 +0x16d
github.com/compose-spec/compose-go/v2/loader.loadYamlFile({0x2ba8de0, 0xc000444780}, {{0xc0003b8b00, 0x7f}, {0xc00050c700, 0x6f5, 0x6f6}, 0x0}, 0xc000536240, {0xc000057360, ...}, ...)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:493 +0x584
github.com/compose-spec/compose-go/v2/loader.loadYamlModel({0x2ba8de0, 0xc000444780}, {{0x0, 0x0}, {0xc000057360, 0x48}, {0xc0005380c0, 0x1, 0x1}, 0xc0003a3710}, ...)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:364 +0x1b6
github.com/compose-spec/compose-go/v2/loader.load({0x2ba8de0, 0xc000444780}, {{0x0, 0x0}, {0xc000057360, 0x48}, {0xc0005380c0, 0x1, 0x1}, 0xc0003a3710}, ...)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:515 +0x38b
github.com/compose-spec/compose-go/v2/loader.loadModelWithContext({0x2ba8de0, 0xc000444780}, 0xc000120700, 0xc0003a3710?)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:336 +0xfb
github.com/compose-spec/compose-go/v2/loader.LoadWithContext({0x2ba8de0, 0xc000444780}, {{0x0, 0x0}, {0xc000057360, 0x48}, {0xc0005380c0, 0x1, 0x1}, 0xc0003a3710}, ...)
        github.com/compose-spec/compose-go/v2@v2.1.5/loader/loader.go:312 +0xd8
github.com/compose-spec/compose-go/v2/cli.(*ProjectOptions).LoadProject(0xc0003aaf30, {0x2ba8de0, 0xc000444780})
        github.com/compose-spec/compose-go/v2@v2.1.5/cli/options.go:445 +0x12a
github.com/docker/compose/v2/cmd/compose.(*ProjectOptions).ToProject(0xc0002283c0, {0x2ba8de0, 0xc000444780}, {0x2bbe9f8, 0xc00038d180}, {0x3e85f60, 0x0, 0x0}, {0xc0003a3680, 0x6, ...})
        github.com/docker/compose/v2/cmd/compose/compose.go:318 +0x54e
github.com/docker/compose/v2/cmd/compose.(*configOptions).ToProject(0xc000497688, {0x2ba8de0, 0xc000444780}, {0x2bbe9f8, 0xc00038d180}, {0x3e85f60, 0x0, 0x0}, {0x0, 0x0, ...})
        github.com/docker/compose/v2/cmd/compose/config.go:62 +0x16a
github.com/docker/compose/v2/cmd/compose.runConfigInterpolate({0x2ba8de0?, 0xc000444780}, {0x2bbe9f8, 0xc00038d180}, {0xc0002283c0, {0x28045cc, 0x4}, {0x0, 0x0}, 0x0, ...}, ...)
        github.com/docker/compose/v2/cmd/compose/config.go:181 +0x77
github.com/docker/compose/v2/cmd/compose.runConfig({0x2ba8de0?, 0xc000444780?}, {0x2bbe9f8?, 0xc00038d180?}, {0xc0002283c0, {0x28045cc, 0x4}, {0x0, 0x0}, 0x0, ...}, ...)
        github.com/docker/compose/v2/cmd/compose/config.go:159 +0xe5
github.com/docker/compose/v2/cmd/compose.configCommand.func2({0x2ba8de0?, 0xc000444780?}, {0x3e85f60?, 0xc000080000?, 0x21bb499?})
        github.com/docker/compose/v2/cmd/compose/config.go:126 +0x105
github.com/docker/compose/v2/cmd/compose.configCommand.Adapt.func4({0x2ba8de0?, 0xc000444780?}, 0x2?, {0x3e85f60?, 0x2fc07cd?, 0xc1a25d6fe575cbe4?})
        github.com/docker/compose/v2/cmd/compose/compose.go:125 +0x30
github.com/docker/compose/v2/cmd/compose.configCommand.Adapt.AdaptCmd.func7(0x0?, {0x3e85f60, 0x0, 0x0})
        github.com/docker/compose/v2/cmd/compose/compose.go:101 +0x14e
github.com/docker/cli/cli-plugins/plugin.RunPlugin.func1.1.2(0x0?, {0x3e85f60, 0x0, 0x0})
        github.com/docker/cli@v27.1.0+incompatible/cli-plugins/plugin/plugin.go:64 +0x6c
github.com/docker/compose/v2/cmd/cmdtrace.Setup.wrapRunE.func2(0xc00028e400?, {0x3e85f60?, 0x0?, 0x0?})
        github.com/docker/compose/v2/cmd/cmdtrace/cmd_span.go:85 +0x65
github.com/spf13/cobra.(*Command).execute(0xc000281500, {0xc000303f50, 0x0, 0x0})
        github.com/spf13/cobra@v1.8.1/command.go:985 +0xabc
github.com/spf13/cobra.(*Command).ExecuteC(0xc000304600)
        github.com/spf13/cobra@v1.8.1/command.go:1117 +0x3ff
github.com/spf13/cobra.(*Command).Execute(...)
        github.com/spf13/cobra@v1.8.1/command.go:1041
github.com/docker/cli/cli-plugins/plugin.RunPlugin(0xc00038d180, 0xc00013f800, {{0x28050b8, 0x5}, {0x280ee91, 0xb}, {0x2b82970, 0x11}, {0x0, 0x0}, ...})
        github.com/docker/cli@v27.1.0+incompatible/cli-plugins/plugin/plugin.go:79 +0x145
github.com/docker/cli/cli-plugins/plugin.Run(0x2955df8, {{0x28050b8, 0x5}, {0x280ee91, 0xb}, {0x2b82970, 0x11}, {0x0, 0x0}, {0x0, ...}})
        github.com/docker/cli@v27.1.0+incompatible/cli-plugins/plugin/plugin.go:94 +0x165
main.pluginMain()
        github.com/docker/compose/v2/cmd/main.go:38 +0xa5
main.main()
        github.com/docker/compose/v2/cmd/main.go:98 +0x19c

Can't include all the files I'm using (way too many) but in short, I'm extending a docker compose file from another one, and within the base compose file (the one being extended) I misindented the code, putting accidentally the service name on the same level as the service base element. Also using volumes, multiple env files on command call, multiple env files in compose, interpolation, image name forced, container name forced, build args, context and custom dockerfile name (using interpolation in most keys).

Once indenting normally as Compose intends to find it (services > service-name), everything was fine again.

Expected to find the same regular error that Compose throws, like "root element service-name not allowed" or any other relevant one. Hope it helps...

Env: Windows PS from PHPStorm 2023 Docker Desktop on Win 11 / x64 v4.33 Docker Compose version v2.29.1-desktop.1