Add AWS Lambda deployment target#87
Open
busla wants to merge 7 commits into
Open
Conversation
Add lambda.ts, a serverless entry point for running the admin panel as a single AWS Lambda behind a Function URL or API Gateway HTTP API (payload format 2.0). The handler serves both server routes and the static client assets itself, so no CDN or S3 bucket is required. - `build:lambda` bundles the handler + client into `dist/lambda/` - README documents the serverless deployment path - `GET /health` returns 200 for load-balancer health checks Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Detect the incoming event shape and reply in the matching format: ELB event (statusDescription + multiValueHeaders) for ALB targets, and payload format 2.0 (headers + cookies[]) for Function URLs / HTTP API. Document both deployment paths in the README, including the ALB target group's multi-value-headers requirement and 1 MB response cap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror server.ts: assets live on disk without the base prefix, so strip VITE_BASE_PATH before the static lookup while still handing the app the original request (its router is configured with the base path). Without this, /<base>/assets/* requests skipped the static branch and 404'd. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…duction-ideal Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The pull-model /metrics endpoint is a server.ts feature; in-process counters don't fit Lambda's ephemeral instances. Narrow the env-var list to the ones that actually apply and point to CloudWatch for Lambda metrics. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring the Lambda handler to parity with the long-running server.ts: - apply security headers (CSP report-only/enforced, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, HSTS in prod) to text/html responses - only serve static assets under VITE_BASE_PATH (not at the unprefixed path) when a base path is configured - redirect the bare base path to its trailing-slash form (302) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Adds
lambda.ts, a serverless entry point for running the admin panel as a single AWS Lambda. The handler detects the incoming event shape and supports both:target_type = lambda)The same Lambda serves both the server routes and the static client assets, so no CDN or S3 bucket is required — the deployed zip is self-contained.
Why
The panel currently ships only the long-running
server.ts/ Docker deployment. This adds a zero-infrastructure serverless option for teams that prefer to run it as a Lambda.Usage
bun run build:lambda # outputs dist/lambda/{index.mjs, client/}Zip the contents of
dist/lambda/and deploy with handlerindex.handleron a Node.js runtime. Set the runtime environment variables used by the Docker deployment (SESSION_SECRET,VITE_API_BASE_URL,ADMIN_SSO_*,SESSION_COOKIE_SECURE,VITE_BASE_PATH, etc.). AGET /healthroute returns200 okfor health checks.Changes
lambda.ts— the handler:requestContext.elb) vs. payload-2.0 events and replies in the matching format (statusDescription+multiValueHeadersfor ALB;headers+cookies[]for HTTP API)Requestfrom the event and delegates dynamic routes to the existing fetch handlerdist/clientassets directly (immutable caching, gzip for compressible types, path-traversal guarded)VITE_BASE_PATH: serves assets only under the prefix and redirects the bare base path to its trailing-slash form, matchingserver.tsserver.ts(CSP report-only/enforced,X-Frame-Options,X-Content-Type-Options,Referrer-Policy, HSTS in production) totext/htmlresponsespackage.json—build:lambdascript bundles handler + client intodist/lambda/.tsconfig.json— excludeslambda.ts(consistent withserver.ts; it imports the built server bundle).README.md— documents both deployment paths and their caveats.Notes
dist/clientdirectly. The inline serving keeps the deploy to a single self-contained zip.Set-Cookieheaders survive; ALB caps responses at 1 MB (gzip keeps assets under it)./metricsendpoint is not exposed by the Lambda — pull-model metrics don't fit Lambda's ephemeral instances; use CloudWatch / a push exporter instead.