Skip to content

fix: show logs for compose services with replicas - #1663

Open
jimirocks wants to merge 3 commits into
moghtech:mainfrom
Smarteon:fix/1660-compose-replica-logs
Open

jimirocks wants to merge 3 commits into
moghtech:mainfrom
Smarteon:fix/1660-compose-replica-logs

Conversation

@jimirocks

Copy link
Copy Markdown

Summary

For compose services with deploy.replicas > 1, the service Log tab is empty. Komodo lists each replica as its own service (web-1, web-2, ...) and passes those names straight to docker compose logs, which exits 0 with no output for names that aren't compose services. This PR maps replica entries back to the real compose service or container, and fixes two related bugs found along the way.

Closes #1660.

Motivation

Periphery's parse_compose_services expands a replicated service into one StackServiceNames entry per replica:

service_name: format!("{service_name}-{i}"),            // "web-1"
container_name: format!("{project_name}-{service_name}-{i}"),

These entries are stored in deployed_services / latest_services and returned by ListStackServices, so the UI requests logs for services: ["web-1"], and Core runs:

$ docker compose -p proj logs --tail 100 -- web-1
$ echo $?
0          # no output, no error

Solution

  1. fix: show logs for compose services with replicas
    • Add an optional compose_service field to StackServiceNames. Periphery sets it on per-replica entries to the actual compose service name (web). Other entries leave it as None, and it isn't serialized for them.
    • GetStackLog / SearchStackLog (Server mode):
      • When a single replica is requested (the stack service page), call GetContainerLog / GetContainerLogSearch on that replica's exact container, so you see that replica's log.
      • Otherwise, map replica names back to the compose service (deduplicated) before calling docker compose logs, so the stack-level Log tab shows all replicas combined.
  2. fix: match compose replica containers exactly: replica entries already include the replica number in container_name, so ^proj-web-1-?[0-9]*$ also matched proj-web-10..proj-web-19. For services with 10+ replicas, that attached the wrong container to web-1. Entries with compose_service set are now matched exactly.
  3. fix: add project prefix when searching Swarm stack logs: SearchStackLog in Swarm mode passed the bare service name to docker service logs, without the {project}_ prefix that GetStackLog adds, so searching Swarm stack logs always returned nothing.

The TS types (client/core/ts/src/types.ts, ui/public/client/types.d.ts) were updated by hand to match typeshare output.

Notes

  • Stacks deployed before this change don't have compose_service stored and need a redeploy to pick up the fix. A suffix-stripping fallback would be ambiguous with real services named like web-1, so I didn't add one.
  • Out of scope: per-service executions (restart / stop / ...) still pass replica names to compose (restart web-1 → no such service: web-1). That's a behaviour change and should be its own issue/PR.

Testing

  • cargo test -p komodo_core -p komodo_periphery: 4 new tests, all passing:
    • replicas_record_compose_service: replica expansion sets compose_service, plain services don't.
    • single_replica_resolves_container / replicas_map_to_compose_service: Core name resolution.
    • container_match_regex: exact matching for replica entries (web-1 no longer matches web-10).
  • cargo check and cargo fmt --check are clean.
  • Manually checked the docker compose logs / docker service logs behaviour behind each fix with a 3-replica service (compose, and Swarm in docker-in-docker). Not yet tested end-to-end on a running Komodo instance.

🤖 Generated with Claude Code

jimirocks and others added 3 commits October 1, 2026 09:40
For compose services with `deploy.replicas > 1`, Komodo lists each replica
as its own service (`web-1`, `web-2`, ...). Stack log requests passed these
names straight to `docker compose logs`, which silently returns nothing for
unknown services, so the service Log tab was empty.

- Add `compose_service` to `StackServiceNames`, set by Periphery on replica
  entries to the actual compose service name.
- GetStackLog / SearchStackLog: a single replica request reads that replica's
  container log directly; otherwise replica names are mapped back to the
  compose service before calling `docker compose logs`.

Stacks deployed before this change need a redeploy to record the mapping.

Closes moghtech#1660

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Per-replica service entries already carry the replica number in their
`container_name` (eg `proj-web-1`), so the `^{name}-?[0-9]*$` pattern also
matched `proj-web-10`..`proj-web-19`, attaching the wrong container to `web-1`
for services with 10+ replicas. Match these entries exactly instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SearchStackLog passed the bare compose service name to `docker service logs`,
while Swarm names stack services `{project}_{service}` (as GetStackLog already
handles), so searching Swarm stack logs always came back empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logs not displaying/streaming for services with replicas > 1

1 participant