diff --git a/.env.example b/.env.example index a5af73f..16a8862 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,12 @@ -# Server Configuration +# Server Container Configuration (Internal application listener) PORT=3000 NODE_ENV=production -# PostgreSQL Connection String (Coolify / Managed Postgres / Docker) +# Host Port Mappings for Docker / Coolify (Prevents conflict if host ports 3000 or 5432 are occupied) +HOST_PORT=8080 +POSTGRES_HOST_PORT=5433 + +# PostgreSQL Database Configuration DATABASE_URL=postgresql://postgres:postgres_secure_pass_2026@postgres:5432/balance_sheet_db POSTGRES_PASSWORD=postgres_secure_pass_2026 diff --git a/COOLIFY.md b/COOLIFY.md index 0a7e1fe..2721a14 100644 --- a/COOLIFY.md +++ b/COOLIFY.md @@ -2,7 +2,7 @@ This application consists of: 1. **Server Side**: Node.js + Express backend (`server.ts`) serving REST APIs, managing authentication, ledger reconciliation, audit logs, FX rates, and financial reports. -2. **Database**: PostgreSQL (via `pg` connection pool) with automatic JSON fall-back backup. +2. **Database**: PostgreSQL (via `pg` connection pool) with automatic JSON fallback backup. 3. **Frontend**: React SPA served directly via Express in production. --- @@ -19,6 +19,8 @@ This application consists of: ```env NODE_ENV=production PORT=3000 + HOST_PORT=8080 # Customize if host port 3000 is occupied by another app + POSTGRES_HOST_PORT=5433 # Customize if host port 5432 is occupied by another database POSTGRES_PASSWORD=your_custom_secure_password ``` 3. **Deploy**: @@ -45,9 +47,11 @@ If you prefer using Coolify's built-in managed PostgreSQL database resource: --- -## 2. Server-Side Architecture Details +## 2. Server-Side Architecture & Port Configuration +- **Internal Container Port**: Application listens on `3000` inside the container. +- **Conflict Prevention**: Host port mappings in `docker-compose.yml` use `${HOST_PORT:-8080}:3000` and `${POSTGRES_HOST_PORT:-5433}:5432`. If port 3000 or 5432 is already used by another app on your server, simply set `HOST_PORT` or `POSTGRES_HOST_PORT` in your `.env` to any available port (e.g. `8080`, `8081`, `5433`). - **Automatic Table Creation**: On server boot, the backend runs `initPgDatabase()` to verify/create `app_portal_state`. -- **Automatic State Recovery**: If PostgreSQL contains existing data, the portal state is loaded directly from PostgreSQL. If empty, baseline seed data is written to PostgreSQL. +- **Automatic State Recovery**: If PostgreSQL contains existing data, portal state is loaded directly from PostgreSQL. - **Resilient Fallback**: If `DATABASE_URL` is omitted, the app gracefully operates using persistent JSON storage (`/app/data/portal-data.json`). - **Health Check**: Express exposes `GET /api/health` for Docker container monitoring. diff --git a/Dockerfile.txt b/Dockerfile.txt new file mode 100644 index 0000000..4b5c4a3 --- /dev/null +++ b/Dockerfile.txt @@ -0,0 +1,55 @@ +# ============================================================================== +# Multi-stage Dockerfile for Coolify & Containerized Environments +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Stage 1: Build Stage +# ------------------------------------------------------------------------------ +FROM node:20-alpine AS builder + +WORKDIR /app + +# Copy package manifests +COPY package*.json ./ + +# Install dependencies needed for vite & esbuild build +RUN npm install + +# Copy full application source code +COPY . . + +# Run production build (vite client build + esbuild server compilation) +RUN npm run build + +# ------------------------------------------------------------------------------ +# Stage 2: Production Runner Stage +# ------------------------------------------------------------------------------ +FROM node:20-alpine AS runner + +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 +ENV DATA_PATH=/app/data/portal-data.json + +# Copy package manifests +COPY package*.json ./ + +# Install production dependencies only +RUN npm install --omit=dev && npm cache clean --force + +# Copy compiled distribution output from builder stage +COPY --from=builder /app/dist ./dist + +# Create persistent data directory +RUN mkdir -p /app/data + +# Expose server port (default 3000) +EXPOSE 3000 + +# Healthcheck to verify Express server status +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1 + +# Start production application server +CMD ["node", "dist/server.cjs"] diff --git a/README.md b/README.md index 7688e50..f50c5e2 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,62 @@ -
-