Skip to content

AWF: inherit the router healthcheck from the router image instead of running Python #10346

Closed as not planned

Description

@rabeckett

Part of github/gh-aw-firewall#10261
(step 4 of 7). No prerequisite changes are needed. Merge this before shipping any
router image that removes Python.

Summary

AWF's compose service for the router spells out a Python healthcheck command. That ties AWF
to the router image's runtime. Once the Go image ships without Python, the
check would fail. The api-proxy waits for service_healthy, so every AWF run with model
routing turned on would then fail to start.

Remove the command, and let the container inherit the HEALTHCHECK that the image already
defines. Keep AWF's timing settings.

Background

  • buildRouterService in src/services/router-service.ts sets
    healthcheck.test: ROUTER_HEALTHCHECK_TEST. That's a CMD that runs python -c with
    urllib.request against http://localhost:8737/healthz.

  • The same healthcheck sets interval: 2s, timeout: 3s, retries: 15 and
    start_period: 10s.

  • tests/integration/model-routing.test.ts imports ROUTER_HEALTHCHECK_TEST for its own
    compose file, and src/compose-generator.test.ts asserts the healthcheck.

  • The supported built-in and legacy router images define a HEALTHCHECK:

    • the AWF-built image from containers/router/Dockerfile, since
      PR #10037;
    • the legacy ghcr.io/githubnext/gh-aw-router image, which the integration test uses
      by default.

    Both run the same Python urllib check with interval 5s, timeout 2s, start period 2s
    and 12 retries. After the Go image cut-over, the image's HEALTHCHECK runs
    gh-aw-router healthcheck.

  • Docker fills in a missing command from the image.

    • If the compose file sets only the timing fields, Compose sends a healthcheck with an
      empty command (ToMobyHealthCheck in docker/compose).
    • The daemon then merges in the image's config: an empty command takes the image's
      HEALTHCHECK command, and unset durations take the image's values (merge() in
      moby daemon/commit.go).

    AWF's timings still apply.

Scope

  • In src/services/router-service.ts:
    • remove test from the router healthcheck, and keep the four timing fields as they
      are;
    • remove the ROUTER_HEALTHCHECK_TEST export.
  • In src/types/docker.ts, make the compose service type's healthcheck.test optional,
    and say that leaving it out uses the image's HEALTHCHECK command.
  • Update src/compose-generator.test.ts. It should assert that the router healthcheck has
    no test field and that the timings are unchanged.
  • Update tests/integration/model-routing.test.ts so that its compose file leaves out
    test too.
  • Documentation:
    • State that custom router images must define a HEALTHCHECK. Without one, Compose
      reports that the router has no healthcheck and the api-proxy never starts.
    • Put this in the router README section about running the image, and in whichever AWF
      doc describes image overrides.

Out of scope

  • Router image or implementation changes. Only the custom-image note in
    containers/router/README.md is in scope here; the image cut-over is separate.
  • Changing the healthcheck timings or the api-proxy's depends_on condition.

Acceptance criteria

  • The generated compose file has a router healthcheck with only interval, timeout,
    retries and start_period.
  • ROUTER_HEALTHCHECK_TEST no longer exists, and nothing in the repository references
    it.
  • Unit tests and the model-routing integration test pass against the current Python
    image. docker inspect on the running router shows the image's command with AWF's
    timings.
  • The documentation says that custom router images must define a HEALTHCHECK.

Validation

  • npm test -- compose-generator
  • npm run test:integration -- --runInBand model-routing.test.ts, run locally with Docker,
    because the test-model-routing workflow runs only on main.
  • On the router started by that test, run
    docker inspect --format '{{json .Config.Healthcheck}}' <router container>. It should
    show the image's command together with interval 2s, timeout 3s, retries 15 and start
    period 10s.

Files likely touched

  • src/services/router-service.ts
  • src/types/docker.ts
  • src/compose-generator.test.ts
  • tests/integration/model-routing.test.ts
  • containers/router/README.md, and the AWF doc on image overrides if there is one

Activity

  1. rabeckett commented on Oct 20, 2026

    @rabeckett
    CollaboratorAuthor

    Not planned: AWF keeps owning the router healthcheck command, like its other services. The cut-over to the Go image (step 5 of #10261) will change the command to the Go router's healthcheck subcommand alongside the image swap. See #10348.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    dockerPull requests that update docker coderefactoring

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions