diff --git a/.dockerignore b/.dockerignore index 29a5f3a..f019469 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,16 +1,15 @@ -# What does not reach the image. +# Nothing in here reaches the image. # -# `.env.production` IS copied in — see the Dockerfile's runtime stage. The -# container reads its own configuration from that file, so the deployment does -# not depend on every variable having been typed into a hosting platform's -# settings screen. Anything the platform DOES set still wins: godotenv never -# overwrites a variable that is already present in the environment. +# `.env*` most of all: the Dockerfile does `COPY . .`, and the production +# credentials in `.env.production` were being baked into every image built +# from this folder. The running container gets its environment from the +# platform (Dokploy / Kubernetes), never from a file. # -# Every other `.env.*` stays out. `.env.local` and `.env.secrets` are one -# developer's machine, and `.env.secrets` in particular is the file that holds -# a key — it must never be inside an image. +# An exception for `.env.production` was added on 2026-09-25 so the container +# could read its own configuration, and the deploy came back 502 on every +# endpoint. Reverted. The committed file is a stale snapshot; letting it fill +# whatever the platform leaves unset is not a safe default. .env* -!.env.production .git .claude diff --git a/Dockerfile b/Dockerfile index cc49c5f..b1c78dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,22 +28,26 @@ WORKDIR /app COPY --from=builder /app/server /app COPY nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json . -# The container's own configuration. +# Nearle Buddy's credential, as ONE container variable. # -# Copied in so the deployment does not depend on every variable having been -# entered into a hosting platform's settings screen. A variable missed there is -# a variable unset in production, and the failure is silent — the assistant sat -# switched off for two days for exactly that reason, with nothing on any screen -# saying which value was absent. +# Not an env file. `COPY .env.production .` was tried on 2026-09-25 and took the +# backend down with 502 on every endpoint: that file declares twenty-three +# variables, and godotenv fills any the platform leaves unset, so a stale +# committed DB or Redis value replaced a live one and the process died at boot. +# Twenty-three variables shipped to deliver one. # -# Anything the platform DOES set still wins: `godotenv` only fills variables -# that are not already in the environment, so Dokploy can override any line in -# this file without the file having to change. -COPY .env.production . +# A single ENV cannot do that — it sets this name and no other. A value set on +# the platform still wins, because `docker run -e` overrides a Dockerfile ENV, +# so this is a default rather than an override. +# +# Provider, endpoint and model are constants in config.go, so this is the only +# thing the assistant needs to come up. +ENV ASSISTANT_API_KEY=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 -# Decides which rules config.Load applies — production insists on a signing -# secret and never falls back to localhost values — and which file above is -# read: loadEnvFiles reads `.env.` then `.env`. +# No `.env.*` is copied in (see .dockerignore), so this only decides which rules +# config.Load applies: production insists on a signing secret and never falls +# back to localhost values. Every other real value comes from the platform's +# environment settings, exactly as before. ENV APP_ENV=production # Must match APP_PORT in the platform's environment (1009 in production).