From a5ceb721f3e89d0eba1e8f9f526ec7f2cf42af7a Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sat, 5 Sep 2026 20:37:03 -0400 Subject: [PATCH] chore(docker): portable image and registry run template Dockerfile: stop baking secrets into the image. Only NODE_ENV remains; all runtime config (MONGO_URI, SMTP_*, token secrets) comes from the environment so one image runs anywhere. Install curl for container healthchecks. App variable names untouched (singular JWT_EXPIRE as read by models/User.js). docker-compose.example.yml: rewrite as a prod run template for git.linuxhg.com/games-database/games-api (IMAGE_TAG, default latest) with restart, env_file .env, and a curl /health healthcheck. Copy to docker-compose.yml next to the server .env, then pull and up. Full variable list kept commented out so values can live in the file instead of .env if preferred. --- Dockerfile | 17 ++++---------- docker-compose.example.yml | 48 ++++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0677efc..f94232b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,9 @@ FROM oven/bun:1 AS base WORKDIR /usr/src/app +# curl is needed for container healthchecks (curl -f http://localhost:5000/health) +RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* + # install dependencies into temp directory # this will cache them and speed up future builds FROM base AS install @@ -27,20 +30,10 @@ COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /usr/src/app/ . COPY --from=prerelease /usr/src/app/package.json . -# Set Environment Variables +# Runtime config comes from the environment (compose env_file: .env), +# not baked in at build time, so one image runs anywhere. ARG NODE_ENV=production ENV NODE_ENV=$NODE_ENV -ENV ACCESS_TOKEN_SECRET=$ACCESS_TOKEN_SECRET -ENV REFRESH_TOKEN_SECRET=$REFRESH_TOKEN_SECRET -ENV JWT_EXPIRES=$JWT_EXPIRES -ENV MONGO_URI=$MONGO_URI -ENV SMTP_HOST=$SMTP_HOST -ENV SMTP_PORT=$SMTP_PORT -ENV SMTP_USER=$SMTP_USER -ENV SMTP_PASSWORD=$SMTP_PASSWORD -ENV FROM_EMAIL=$FROM_EMAIL -ENV FROM_NAME=$FROM_NAME -ENV SECURE=$SECURE # run the app USER bun diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 9ed3908..65e9ae1 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -1,21 +1,39 @@ --- +# Prod run template. Copy to docker-compose.yml next to the server .env: +# cp docker-compose.example.yml docker-compose.yml +# Then: docker compose pull && docker compose up -d +# +# Required keys in .env (singular JWT_EXPIRE, as read by models/User.js): +# ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET, JWT_EXPIRE, +# MONGO_URI, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, +# FROM_EMAIL, FROM_NAME, SECURE, NODE_ENV +# Alternatively, comment out env_file above and uncomment the +# environment list below to keep values directly in this file. + # environment: + # - ACCESS_TOKEN_SECRET= + # - REFRESH_TOKEN_SECRET= + # - JWT_EXPIRE= + # - MONGO_URI= + # - SMTP_HOST= + # - SMTP_PORT= + # - SMTP_USER= + # - SMTP_PASSWORD= + # - FROM_EMAIL= + # - FROM_NAME= + # - SECURE=false + # - NODE_ENV= services: games-api: - image: games-api - build: . + image: git.linuxhg.com/games-database/games-api:${IMAGE_TAG:-latest} container_name: games-api - environment: - - ACCESS_TOKEN_SECRET= - - REFRESH_TOKEN_SECRET= - - JWT_EXPIRE= - - MONGO_URI= - - SMTP_HOST= - - SMTP_PORT= - - SMTP_USER= - - SMTP_PASSWORD= - - FROM_EMAIL= - - FROM_NAME= - - SECURE=false - - NODE_ENV= + restart: unless-stopped + env_file: + - .env ports: - 5000:5000 + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:5000/health || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s