Skip to content

Migrate from Trillium [part 8A]: Move assets to Axum (tower-http ServeDir)#2250

Closed
jcjones wants to merge 2 commits intomainfrom
jcj/axum-migration-part8A
Closed

Migrate from Trillium [part 8A]: Move assets to Axum (tower-http ServeDir)#2250
jcjones wants to merge 2 commits intomainfrom
jcj/axum-migration-part8A

Conversation

@jcjones
Copy link
Copy Markdown
Contributor

@jcjones jcjones commented May 8, 2026

Replace the Trillium-based static asset handler (trillium-static-compiled + OriginRouter) with an Axum middleware using tower-http's ServeDir and ServeFile.

The middleware intercepts requests whose Host (or X-Forwarded-Host) matches the configured app_url and serves the React SPA with appropriate cache-control headers (max-age=1year for /assets/*, no-cache for everything else). Unmatched hosts pass through to the API routes.

The proxy now forwards the original Host as X-Forwarded-Host so Axum can perform host-based routing.

Note

assets are no longer embedded at compile time — they are served from the filesystem at runtime. This is fine, we included them in the Docker build anyway. The ASSET_DIR env var still controls whether asset support is compiled in.

jcjones added 2 commits May 8, 2026 09:51
…rectly

Axum is now the primary HTTP listener. The Trillium server, which was a
pure pass-through proxy since Part 7C, is removed from the request path.

Production changes:
- `build_app(Config) -> BuiltApp` replaces `DivviupApi` for production use
- `bin.rs` rewritten: Axum serves directly, monitoring server is a separate
  Axum router, graceful shutdown via tokio signals + CancellationToken
- `Queue` uses `CancellationToken` instead of Trillium's `Stopper`/`CloneCounterObserver`
- `telemetry.rs` and `trace.rs` handlers converted from Trillium to Axum
- `Config` gains `listen_address` field (from HOST/PORT env vars, default [::]:8080)

Dead code removal:
- Deleted: `handler/logger.rs`, `handler/opentelemetry.rs`, `axum_proxy` test
- Removed `FromConn` impls from: `Db`, `User`, `PermissionsActor`,
  `AccountBearerToken`
- Removed Trillium `Handler` impls from: `Db`, `ErrorHandler`, `CorsHeaders`,
  `ReplaceMimeTypes`, `SessionStore`
- Unified `PermissionsActor::is_allowed`/`if_allowed` to use `http::Method`
- Removed deps: `trillium-compression`, `trillium-conn-id`, `trillium-forwarding`,
  `trillium-opentelemetry`, `trillium-prometheus`, `trillium-redirect`,
  `trillium-sessions`, `trillium-cookies`, `async-session`
- Added deps: `cookie` (key-expansion feature, for session key derivation)

`DivviupApi` is kept as a thin test-only shim that spawns Axum on [::1]:0
and proxies via the existing `AxumProxy`, preserving test-support compatibility.
Full test-support rewrite is deferred to Part 9.
…eDir)

Replace the Trillium-based static asset handler (`trillium-static-compiled`
+ `OriginRouter`) with an Axum middleware using `tower-http`'s `ServeDir`
and `ServeFile`.

The middleware intercepts requests whose `Host` (or `X-Forwarded-Host`) matches
the configured `app_url` and serves the React SPA with appropriate
`cache-control` headers (`max-age=1year` for `/assets/*`, `no-cache` for
everything else). Unmatched hosts pass through to the API routes.

The proxy now forwards the original `Host` as `X-Forwarded-Host` so Axum
can perform host-based routing.

Note!!: assets are no longer embedded at compile time — they are served
from the filesystem at runtime. This is fine, we included them in the Docker
build anyway. The `ASSET_DIR` env var still controls whether asset support
is compiled in.
@jcjones jcjones changed the base branch from jcj/axum-migration-part8 to main May 8, 2026 17:28
@jcjones
Copy link
Copy Markdown
Contributor Author

jcjones commented May 8, 2026

Splitting this out is proving to be more headache than it's worth.

@jcjones jcjones closed this May 8, 2026
@jcjones jcjones deleted the jcj/axum-migration-part8A branch May 8, 2026 22:01
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.

1 participant