mirror of
https://github.com/nestriness/nestri.git
synced 2026-09-19 17:25:19 +03:00
Moving the issuer's state into Postgres removed the last thing that tied either app to one hosting provider. What was left was a deployment tool describing resources that no longer existed — so this replaces it with `wrangler`, which is what actually deploys a Worker, and adds a second way to run each app that involves no provider at all. Each app now has a `wrangler.jsonc` with an environment per stage, and a `Dockerfile` beside it. The handler is the same one in both cases; what differs is only where its settings come from. Two of them gained a second spelling so that nothing has to branch on the runtime: Postgres arrives as a pooled binding or as `DATABASE_URL`, and the route to the issuer is a service binding or `AUTH_INTERNAL_URL`. That last one is new, and it is a split the binding was already making without saying so. `AUTH_ISSUER_URL` has to be the issuer's public name, because it is compared literally against every token's `iss` claim — but the public name is often not routable from inside a deployment. So the name and the route are two settings now rather than one that cannot be both. DNS moves out of code and into `docs/dns.md`, which lists every hostname and what it is for. Six records that change roughly never did not need a tool, and the table outlives whatever is answering the names — which is the point, since some of them will stop being Workers. The sandbox hostnames are hyphenated rather than nested for the same reason: a certificate covering `*.nestri.io` covers one label and not two, so `api-sandbox.nestri.io` can become an ordinary origin later without a certificate having to be ordered for it first. Also drops `EMAIL_DEV_LOG` from committed configuration into `.dev.vars`, which `wrangler deploy` cannot upload. Printing a live sign-in code to a log should not be one forgotten override away from production.
69 lines
2.6 KiB
Docker
69 lines
2.6 KiB
Docker
# The issuer as a container.
|
|
#
|
|
# Build from the repository root — the workspace lockfile and two shared
|
|
# packages live there, so a context rooted at this directory could not resolve
|
|
# them:
|
|
#
|
|
# docker build -f apps/auth/Dockerfile -t nestri-auth .
|
|
#
|
|
# The repository-wide `.dockerignore` is what this build excludes. It used to
|
|
# exclude the whole TypeScript half, because the guest rootfs build was the
|
|
# only Dockerfile here — that part now lives in `build/Dockerfile.dockerignore`,
|
|
# beside the build it belongs to.
|
|
FROM oven/bun:1.3.11-alpine AS deps
|
|
|
|
WORKDIR /app
|
|
|
|
# Manifests first, source second. Dependencies change far less often than code
|
|
# does, so this layer survives most rebuilds. Every workspace member's manifest
|
|
# has to be here even if this image does not import it: the lockfile describes
|
|
# the whole workspace, and resolving it against a partial one is not frozen.
|
|
COPY package.json bun.lock ./
|
|
COPY apps/api/package.json apps/api/
|
|
COPY apps/auth/package.json apps/auth/
|
|
COPY packages/core/package.json packages/core/
|
|
COPY packages/auth/package.json packages/auth/
|
|
|
|
# No dev dependencies. Bun runs TypeScript without a build step, so nothing in
|
|
# them is reachable at runtime — they are the type definitions, the linter and
|
|
# the deployment CLI.
|
|
RUN bun install --frozen-lockfile --production
|
|
|
|
|
|
FROM oven/bun:1.3.11-alpine AS runtime
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=deps /app/node_modules node_modules
|
|
COPY tsconfig.json ./
|
|
COPY package.json bun.lock ./
|
|
COPY apps/auth apps/auth
|
|
COPY packages/core packages/core
|
|
COPY packages/auth packages/auth
|
|
|
|
# The image ships no configuration. Every setting arrives from the environment,
|
|
# which is what makes one image good for a self-hoster and for us:
|
|
#
|
|
# DATABASE_URL postgres://… required
|
|
# EMAIL_SEND_URL where a code is posted \
|
|
# EMAIL_API_KEY credential for it > all three together, or none
|
|
# EMAIL_FROM the sender address /
|
|
# EMAIL_DEV_LOG `true` prints codes to the log instead of sending them
|
|
#
|
|
# With none of the three set and no `EMAIL_DEV_LOG`, the issuer refuses to send
|
|
# rather than falling back — a deployment that forgot its mail settings is
|
|
# exactly the one with nothing marking it as a real one.
|
|
ENV NODE_ENV=production
|
|
ENV PORT=1337
|
|
EXPOSE 1337
|
|
|
|
# `bun` is a non-root user the base image already provides.
|
|
USER bun
|
|
|
|
# The discovery document is served from memory and reaches no database, which
|
|
# is the right shape for a liveness probe.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD wget -q -O /dev/null http://127.0.0.1:${PORT}/.well-known/oauth-authorization-server || exit 1
|
|
|
|
CMD ["bun", "run", "apps/auth/src/server.ts"]
|