From 2acfb1cdf580b220ea02baad4e30cfbf2adce7e1 Mon Sep 17 00:00:00 2001 From: pguerrerox Date: Thu, 30 Apr 2026 23:39:54 +0000 Subject: [PATCH] feat: add docker deployment stack Add container definitions for the web app, API, worker, and PostGIS database so the local stack can be built and run consistently. --- CHANGELOG.md | 3 +++ Dockerfile | 37 ++++++++++++++++++++++++++++++ docker-compose.yml | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 9823ead..50f0d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Added +- Added a multi-stage `Dockerfile` and `docker-compose.yml` for running the web app, API, worker, and PostGIS database as a local container stack. + ## [2026-04-19] ### Added diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..016d018 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM node:22-alpine AS build +WORKDIR /app + +ARG VITE_API_BASE_URL +ARG VITE_GOOGLE_MAPS_PLATFORM_KEY + +ENV VITE_API_BASE_URL=$VITE_API_BASE_URL +ENV VITE_GOOGLE_MAPS_PLATFORM_KEY=$VITE_GOOGLE_MAPS_PLATFORM_KEY + +COPY package*.json ./ +RUN npm ci + +COPY . . +RUN npm run build && npm run build:api + +FROM nginx:alpine AS web +COPY --from=build /app/dist /usr/share/nginx/html + +FROM node:22-alpine AS api +WORKDIR /app + +COPY package*.json ./ +RUN npm ci --omit=dev + +COPY --from=build /app/dist-server ./dist-server + +CMD ["node", "dist-server/server/src/index.js"] + +FROM node:22-alpine AS worker +WORKDIR /app + +COPY package*.json ./ +RUN npm ci --omit=dev + +COPY --from=build /app/dist-server ./dist-server + +CMD ["node", "dist-server/server/src/worker.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..76f5b7d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +services: + db: + image: postgis/postgis:16-3.4 + environment: + POSTGRES_DB: leads4less + POSTGRES_USER: postgres + POSTGRES_PASSWORD: change-me + volumes: + - leads4less-db:/var/lib/postgresql/data + + api: + build: + context: . + target: api + depends_on: + - db + environment: + NODE_ENV: production + APP_HOST: 0.0.0.0 + APP_PORT: 4000 + APP_ORIGIN: https://app.example.com + DATABASE_URL: postgres://postgres:change-me@db:5432/leads4less + COOKIE_SECRET: replace-with-long-random-secret + GOOGLE_MAPS_SERVER_KEY: your-server-key + PG_BOSS_SCHEMA: pgboss + SESSION_TTL_DAYS: 30 + expose: + - "4000" + + worker: + build: + context: . + target: worker + depends_on: + - db + environment: + NODE_ENV: production + DATABASE_URL: postgres://postgres:change-me@db:5432/leads4less + COOKIE_SECRET: replace-with-long-random-secret + GOOGLE_MAPS_SERVER_KEY: your-server-key + PG_BOSS_SCHEMA: pgboss + SESSION_TTL_DAYS: 30 + + web: + build: + context: . + target: web + args: + VITE_API_BASE_URL: https://api.example.com/api + VITE_GOOGLE_MAPS_PLATFORM_KEY: your-browser-key + depends_on: + - api + expose: + - "80" + +volumes: + leads4less-db: