docker/compose · error
your Compose stack cannot be published as it only contains a
Error message
your Compose stack cannot be published as it only contains a build section for service(s): - %q
What it means
`docker compose publish` builds and pushes images to a registry; a service that has only `build:` and no `image:` produces an image with no registry tag to push, so the pre-flight check rejects the whole stack with a list of offending services. Every service must reference a publishable image name.
Source
Thrown at pkg/compose/publish.go:666
layers = append(layers, layerDescriptor)
}
return layers
}
func (s *composeService) checkOnlyBuildSection(project *types.Project) (bool, error) {
errorList := []string{}
for _, service := range project.Services {
if service.Image == "" && service.Build != nil {
errorList = append(errorList, service.Name)
}
}
if len(errorList) > 0 {
var errMsg strings.Builder
errMsg.WriteString("your Compose stack cannot be published as it only contains a build section for service(s):\n")
for _, serviceInError := range errorList {
fmt.Fprintf(&errMsg, "- %q\n", serviceInError)
}
return false, errors.New(errMsg.String())
}
return true, nil
}
func (s *composeService) checkForBindMount(project *types.Project) map[string][]types.ServiceVolumeConfig {
allFindings := map[string][]types.ServiceVolumeConfig{}
for serviceName, config := range project.Services {
bindMounts := []types.ServiceVolumeConfig{}
for _, volume := range config.Volumes {
if volume.Type == types.VolumeTypeBind {
bindMounts = append(bindMounts, volume)
}
}
if len(bindMounts) > 0 {
allFindings[serviceName] = bindMounts
}
}
return allFindingsView on GitHub (pinned to ddc4b044b6)
Solutions
- Add an `image: <registry>/<namespace>/<name>:<tag>` to every service that has `build:`
- Use an override file (docker-compose.publish.yml) that adds image: entries, and publish with -f overrides
- Remove non-publishable helper services from the published stack via profiles
Example fix
# before
services:
api:
build: .
# after
services:
api:
build: .
image: ghcr.io/acme/api:latest Defensive patterns
Strategy: validation
Validate before calling
python3 - <<'EOF'
import yaml,sys
cfg=yaml.safe_load(open('compose.yaml'))
bad=[n for n,s in (cfg.get('services') or {}).items() if not s.get('image') and s.get('build')]
if bad: sys.exit(f"services missing image: {bad}")
print('publishable')
EOF Prevention
- Adopt the habit of always pairing build: with image: so every built service is tagged
- Run the publishability check in CI before the actual publish job
When it happens
Trigger: Running `docker compose publish` when at least one service sets build: without an image: — canBePublished collects services where service.Image == "" && service.Build != nil and fails.
Common situations: Typical dev compose files build locally without tagging (`build: .` only); attempting to publish a dev-oriented stack; adding a new service and forgetting the image: tag.
Related errors
- cannot publish compose file with local includes
- healthcheck.start_interval requires healthcheck.start_period
- 'compose' is not a valid provider type
- watch rules MUST define a path
- service %q build configuration does not support platform: %s
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/6dc766ab4fe89f98.
Report an issue: GitHub.