Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions modules/compose/compose_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -321,17 +320,16 @@ func (d *DockerCompose) Up(ctx context.Context, opts ...StackUpOption) (err erro
}

if len(upOptions.Services) != len(d.project.Services) {
sort.Strings(upOptions.Services)

filteredServices := types.Services{}

for _, srv := range upOptions.Services {
if srvConfig, ok := d.project.Services[srv]; ok {
filteredServices[srv] = srvConfig
}
// Disable (rather than delete) the non-selected services so a selected
// service's `service:` additional build-contexts stay resolvable at build
// time; only the selected services are created and started.
// IgnoreDependencies excludes their runtime depends_on from the selection.
d.project, err = d.project.WithSelectedServices(upOptions.Services, types.IgnoreDependencies)
if err != nil {
return err
}

d.project.Services = filteredServices
// WithSelectedServices returns a new project; point the up options at it too.
upOptions.Project = d.project
}

err = d.composeService.Up(ctx, d.project, api.UpOptions{
Expand Down
31 changes: 31 additions & 0 deletions modules/compose/compose_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,37 @@ func TestDockerComposeAPIWithRunServices(t *testing.T) {
assert.Contains(t, serviceNames, "api-nginx")
}

func TestDockerComposeAPIWithRunServicesAndServiceBuildContext(t *testing.T) {
// "app" builds with a `service:build-dep` additional build context, so the
// build needs build-dep to remain in the project even though RunServices
// selects only "app" and build-dep is never started as a container.
//
// Regression test: Up used to shrink d.project down to the selected
// services, which dropped the build-only build-dep service and made the
// build fail with "service ... declares unknown service ... as additional
// contexts" — even though `docker compose up app` on the same project works.
path := filepath.Join(testdataPackage, "docker-compose-service-build-context.yml")
compose, err := NewDockerCompose(path)
require.NoError(t, err, "NewDockerCompose()")

ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

err = compose.
WaitForService("app", wait.ForHTTP("/env").WithPort("8080/tcp")).
Up(ctx, Wait(true), RunServices("app"))
cleanup(t, compose)
require.NoError(t, err, "compose.Up()")

// Only the selected runtime service is started; the build-only context is not.
serviceNames := compose.Services()
require.Len(t, serviceNames, 1)
assert.Contains(t, serviceNames, "app")

_, err = compose.ServiceContainer(context.Background(), "build-dep")
require.Error(t, err, "build-dep is a build-only context and must not be started")
}

func TestDockerComposeAPIWithProfiles(t *testing.T) {
path := RenderComposeProfiles(t)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
services:
# build-only dependency: never started, only used as a build context by "app".
build-dep:
build:
context: .
dockerfile: service-build-context-dep.Dockerfile
image: testcontainers/compose-service-build-dep:latest
Comment on lines +3 to +7
app:
build:
context: .
dockerfile: service-build-context-app.Dockerfile
additional_contexts:
build-dep: service:build-dep
image: testcontainers/compose-service-build-app:latest
Comment on lines +8 to +14
ports:
- "8080/tcp"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM golang:1.24-alpine@sha256:fc2cff6625f3c1c92e6c85938ac5bd09034ad0d4bc2dfb08278020b68540dbb5
WORKDIR /app
# Consumes the `service:build-dep` additional build context.
COPY --from=build-dep /artifact /artifact
COPY echoserver.go .
CMD go run echoserver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM golang:1.24-alpine@sha256:fc2cff6625f3c1c92e6c85938ac5bd09034ad0d4bc2dfb08278020b68540dbb5
RUN echo "service-build-context-dep" > /artifact
Loading