Determine whether upaas can deploy a second container beside an app with the traefik labels moved onto it #205

Closed
opened 2026-09-22 15:31:41 +02:00 by clawbot · 1 comment
Collaborator

smallwebwaf (https://git.eeqj.de/sneak/smallwebwaf/src/branch/main/SPEC.md) deploys as a protective reverse proxy in a second container next to an app's container, with the app's traefik labels moved onto that second container so it receives the traffic and forwards to the app. Its SPEC notes upaas was never examined for whether it supports this shape.

Investigation only, no code in this unit. Answer on this issue, citing the relevant upaas code/config paths:

  1. Can a repo's deploy produce two containers today, with the traefik labels on the second one instead of the app?
  2. If not, what is the minimal feature that would allow it?

Definition of done: a definitive written answer here with citations; if the answer to (1) is no, a follow-up feature-request issue is filed in this repo describing the minimal feature and referencing this issue.

(model: claude-fable-5)

smallwebwaf (https://git.eeqj.de/sneak/smallwebwaf/src/branch/main/SPEC.md) deploys as a protective reverse proxy in a second container next to an app's container, with the app's traefik labels moved onto that second container so it receives the traffic and forwards to the app. Its SPEC notes upaas was never examined for whether it supports this shape. Investigation only, no code in this unit. Answer on this issue, citing the relevant upaas code/config paths: 1. Can a repo's deploy produce two containers today, with the traefik labels on the second one instead of the app? 2. If not, what is the minimal feature that would allow it? Definition of done: a definitive written answer here with citations; if the answer to (1) is no, a follow-up feature-request issue is filed in this repo describing the minimal feature and referencing this issue. (model: claude-fable-5)
Author
Collaborator

Answer

Q1: No. A deploy cannot today produce two long-lived containers with the
traefik labels on the second one. upaas deploys exactly one container per app
and attaches all labels to it.

(a) How many containers a deploy launches — one.

  • deployContainerWithTimeout (internal/service/deploy/deploy.go:565) removes
    the single existing container (removeOldContainer, deploy.go:1034), then
    calls createAndStartContainer (deploy.go:1061) once.
  • createAndStartContainer calls docker.CreateContainer then
    docker.StartContainer exactly once; the container is named
    "upaas-" + app.Name (deploy.go:1156).
  • CreateContainer is a single ContainerCreate call
    (internal/docker/client.go:242, API call at client.go:254).
  • The lookup/replace path assumes one container: FindContainerByAppID returns
    containers[0] (client.go:431).
  • The only other container ever created is a throwaway alpine/git clone helper
    during the build phase, always force-removed (client.go:706). README lists
    "Multiple container orchestration" as a Non-Goal.

(b) Which container gets the traefik/ingress labels — always the app
container.

  • upaas has no traefik-specific code. Labels are a generic per-app key/value
    list (internal/models/label.go), fetched by app.GetLabels and passed
    through buildLabelMap (deploy.go:1168), which attaches every app label plus
    the upaas.id label to the one app container (buildContainerOptions,
    deploy.go:1108 -> client.go:258).
  • traefik.* values appear only as user-entered examples in tests
    (internal/service/app/app_test.go:492); there is no plumbing to send labels
    anywhere but the app container.

So the smallwebwaf shape (a proxy sidecar carrying the traefik labels, app off
the ingress network) is not supported.

Q2: Minimal feature. Add an optional per-app sidecar container plus label
routing:

  • Data model: a sidecar spec (image, env/ports, internal network) and a marker
    for which labels are "ingress" labels (internal/models/app.go plus a new
    child table alongside the env/label/volume/port tables).
  • Deploy flow: create/start the app + sidecar set and remove the whole set on
    redeploy/rollback (deploy.go:565, :1061, :1034; drop the
    containers[0] single-container assumption at client.go:431).
  • Label routing: send the ingress/traefik labels to the sidecar, keep upaas.id
    on every container (deploy.go:1108 / :1168).
  • Networking: put the app on an internal-only network with the sidecar bridging
    the ingress and internal networks (app already has one docker_network,
    app.go:48).

Filed as a feature request: #206

Disclosure: this investigation ran on opus-4-8 rather than fable because the
fable weekly quota is exhausted.

Model: opus-4-8

## Answer **Q1: No.** A deploy cannot today produce two long-lived containers with the traefik labels on the second one. upaas deploys exactly one container per app and attaches all labels to it. **(a) How many containers a deploy launches — one.** - `deployContainerWithTimeout` (`internal/service/deploy/deploy.go:565`) removes the single existing container (`removeOldContainer`, `deploy.go:1034`), then calls `createAndStartContainer` (`deploy.go:1061`) once. - `createAndStartContainer` calls `docker.CreateContainer` then `docker.StartContainer` exactly once; the container is named `"upaas-" + app.Name` (`deploy.go:1156`). - `CreateContainer` is a single `ContainerCreate` call (`internal/docker/client.go:242`, API call at `client.go:254`). - The lookup/replace path assumes one container: `FindContainerByAppID` returns `containers[0]` (`client.go:431`). - The only other container ever created is a throwaway `alpine/git` clone helper during the build phase, always force-removed (`client.go:706`). README lists "Multiple container orchestration" as a Non-Goal. **(b) Which container gets the traefik/ingress labels — always the app container.** - upaas has no traefik-specific code. Labels are a generic per-app key/value list (`internal/models/label.go`), fetched by `app.GetLabels` and passed through `buildLabelMap` (`deploy.go:1168`), which attaches every app label plus the `upaas.id` label to the one app container (`buildContainerOptions`, `deploy.go:1108` -> `client.go:258`). - `traefik.*` values appear only as user-entered examples in tests (`internal/service/app/app_test.go:492`); there is no plumbing to send labels anywhere but the app container. So the smallwebwaf shape (a proxy sidecar carrying the traefik labels, app off the ingress network) is not supported. **Q2: Minimal feature.** Add an optional per-app sidecar container plus label routing: - Data model: a sidecar spec (image, env/ports, internal network) and a marker for which labels are "ingress" labels (`internal/models/app.go` plus a new child table alongside the env/label/volume/port tables). - Deploy flow: create/start the app + sidecar set and remove the whole set on redeploy/rollback (`deploy.go:565`, `:1061`, `:1034`; drop the `containers[0]` single-container assumption at `client.go:431`). - Label routing: send the ingress/traefik labels to the sidecar, keep `upaas.id` on every container (`deploy.go:1108` / `:1168`). - Networking: put the app on an internal-only network with the sidecar bridging the ingress and internal networks (app already has one `docker_network`, `app.go:48`). Filed as a feature request: https://git.eeqj.de/sneak/upaas/issues/206 Disclosure: this investigation ran on opus-4-8 rather than fable because the fable weekly quota is exhausted. Model: opus-4-8
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/upaas#205