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.
65 lines
2.4 KiB
Docker
65 lines
2.4 KiB
Docker
# The API 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/api/Dockerfile -t nestri-api .
|
|
#
|
|
# 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/api apps/api
|
|
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
|
|
# AUTH_ISSUER_URL the issuer's public URL required
|
|
# STEAM_API_KEY for linking an account
|
|
# ADMIN_SHARED_SECRET operator access
|
|
ENV NODE_ENV=production
|
|
ENV PORT=3000
|
|
EXPOSE 3000
|
|
|
|
# `bun` is a non-root user the base image already provides.
|
|
USER bun
|
|
|
|
# `/` answers without touching the database, which is the right shape for a
|
|
# liveness probe: it says this process is serving, and leaves "can it reach
|
|
# Postgres" to a readiness check that is allowed to fail loudly.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD wget -q -O /dev/null http://127.0.0.1:${PORT}/ || exit 1
|
|
|
|
CMD ["bun", "run", "apps/api/app/server.ts"]
|