Merge pull request #115 from PatchMon/feat/docker_changes

This commit is contained in:
tigattack
2025-10-02 17:25:57 +01:00
committed by GitHub
5 changed files with 141 additions and 51 deletions

View File

@@ -1,4 +1,40 @@
require("dotenv").config(); require("dotenv").config();
// Validate required environment variables on startup
function validateEnvironmentVariables() {
const requiredVars = {
JWT_SECRET: "Required for secure authentication token generation",
DATABASE_URL: "Required for database connection",
};
const missing = [];
// Check required variables
for (const [varName, description] of Object.entries(requiredVars)) {
if (!process.env[varName]) {
missing.push(`${varName}: ${description}`);
}
}
// Fail if required variables are missing
if (missing.length > 0) {
console.error("❌ Missing required environment variables:");
for (const error of missing) {
console.error(` - ${error}`);
}
console.error("");
console.error(
"Please set these environment variables and restart the application.",
);
process.exit(1);
}
console.log("✅ Environment variable validation passed");
}
// Validate environment variables before importing any modules that depend on them
validateEnvironmentVariables();
const express = require("express"); const express = require("express");
const cors = require("cors"); const cors = require("cors");
const helmet = require("helmet"); const helmet = require("helmet");

View File

@@ -10,8 +10,8 @@ PatchMon is a containerised application that monitors system patches and updates
## Images ## Images
- **Backend**: [ghcr.io/9technologygroup/patchmon-backend:latest](https://github.com/9technologygroup/patchmon.net/pkgs/container/patchmon-backend) - **Backend**: [ghcr.io/patchmon/patchmon-backend:latest](https://github.com/patchmon/patchmon.net/pkgs/container/patchmon-backend)
- **Frontend**: [ghcr.io/9technologygroup/patchmon-frontend:latest](https://github.com/9technologygroup/patchmon.net/pkgs/container/patchmon-frontend) - **Frontend**: [ghcr.io/patchmon/patchmon-frontend:latest](https://github.com/patchmon/patchmon.net/pkgs/container/patchmon-frontend)
Version tags are also available (e.g. `1.2.3`) for both of these images. Version tags are also available (e.g. `1.2.3`) for both of these images.
@@ -20,26 +20,37 @@ Version tags are also available (e.g. `1.2.3`) for both of these images.
### Production Deployment ### Production Deployment
1. Download the [Docker Compose file](docker-compose.yml) 1. Download the [Docker Compose file](docker-compose.yml)
2. Change the default database password in the file: 2. Set a database password in the file where it says:
```yaml ```yaml
environment: environment:
POSTGRES_PASSWORD: YOUR_SECURE_PASSWORD_HERE POSTGRES_PASSWORD: # CREATE A STRONG PASSWORD AND PUT IT HERE
``` ```
3. Update the corresponding `DATABASE_URL` in the backend service: 3. Update the corresponding `DATABASE_URL` with your password in the backend service where it says:
```yaml ```yaml
environment: environment:
DATABASE_URL: postgresql://patchmon_user:YOUR_SECURE_PASSWORD_HERE@database:5432/patchmon_db DATABASE_URL: postgresql://patchmon_user:REPLACE_YOUR_POSTGRES_PASSWORD_HERE@database:5432/patchmon_db
``` ```
4. Configure environment variables (see [Configuration](#configuration) section) 4. Generate a strong JWT secret. You can do this like so:
5. Start the application: ```bash
openssl rand -hex 64
```
5. Set a JWT secret in the backend service where it says:
```yaml
environment:
JWT_SECRET: # CREATE A STRONG SECRET AND PUT IT HERE
```
6. Configure environment variables (see [Configuration](#configuration) section)
7. Start the application:
```bash ```bash
docker compose up -d docker compose up -d
``` ```
6. Access the application at `http://localhost:3000` 8. Access the application at `http://localhost:3000`
## Updating ## Updating
To update PatchMon to the latest version: By default, the compose file uses the `latest` tag for both backend and frontend images.
This means you can update PatchMon to the latest version as easily as:
```bash ```bash
docker compose up -d --pull docker compose up -d --pull
@@ -52,16 +63,18 @@ This command will:
### Version-Specific Updates ### Version-Specific Updates
If you're using specific version tags instead of `latest` in your compose file: If you'd like to pin your Docker deployment of PatchMon to a specific version, you can do this in the compose file.
1. Update the image tags in your `docker-compose.yml`. For example: When you do this, updating to a new version requires manually updating the image tags in the compose file yourself:
1. Update the image tags in `docker-compose.yml`. For example:
```yaml ```yaml
services: services:
backend: backend:
image: ghcr.io/9technologygroup/patchmon-backend:1.2.7 # Update version here image: ghcr.io/patchmon/patchmon-backend:1.2.3 # Update version here
... ...
frontend: frontend:
image: ghcr.io/9technologygroup/patchmon-frontend:1.2.7 # Update version here image: ghcr.io/patchmon/patchmon-frontend:1.2.3 # Update version here
... ...
``` ```
@@ -71,7 +84,7 @@ If you're using specific version tags instead of `latest` in your compose file:
``` ```
> [!TIP] > [!TIP]
> Check the [releases page](https://github.com/9technologygroup/patchmon.net/releases) for version-specific changes and migration notes. > Check the [releases page](https://github.com/PatchMon/PatchMon/releases) for version-specific changes and migration notes.
## Configuration ## Configuration
@@ -79,31 +92,68 @@ If you're using specific version tags instead of `latest` in your compose file:
#### Database Service #### Database Service
- `POSTGRES_DB`: Database name (default: `patchmon_db`) | Variable | Description | Default |
- `POSTGRES_USER`: Database user (default: `patchmon_user`) | ------------------- | ----------------- | ---------------- |
- `POSTGRES_PASSWORD`: Database password - **MUST BE CHANGED!** | `POSTGRES_DB` | Database name | `patchmon_db` |
| `POSTGRES_USER` | Database user | `patchmon_user` |
| `POSTGRES_PASSWORD` | Database password | **MUST BE SET!** |
#### Backend Service #### Backend Service
- `LOG_LEVEL`: Logging level (`debug`, `info`, `warn`, `error`) ##### Database Configuration
- `DATABASE_URL`: PostgreSQL connection string
- `PM_DB_CONN_MAX_ATTEMPTS`: Maximum database connection attempts (default: 30) | Variable | Description | Default |
- `PM_DB_CONN_WAIT_INTERVAL`: Wait interval between connection attempts in seconds (default: 2) | -------------------------- | ---------------------------------------------------- | ------------------------------------------------ |
- `SERVER_PROTOCOL`: Frontend server protocol (`http` or `https`) | `DATABASE_URL` | PostgreSQL connection string | **MUST BE UPDATED WITH YOUR POSTGRES_PASSWORD!** |
- `SERVER_HOST`: Frontend server host (default: `localhost`) | `PM_DB_CONN_MAX_ATTEMPTS` | Maximum database connection attempts | `30` |
- `SERVER_PORT`: Frontend server port (default: 3000) | `PM_DB_CONN_WAIT_INTERVAL` | Wait interval between connection attempts in seconds | `2` |
- `PORT`: Backend API port (default: 3001)
- `API_VERSION`: API version (default: `v1`) ##### Authentication & Security
- `CORS_ORIGIN`: CORS origin URL
- `RATE_LIMIT_WINDOW_MS`: Rate limiting window in milliseconds (default: 900000) | Variable | Description | Default |
- `RATE_LIMIT_MAX`: Maximum requests per window (default: 100) | ------------------------------------ | --------------------------------------------------------- | ---------------- |
- `ENABLE_HSTS`: Enable HTTP Strict Transport Security (default: true) | `JWT_SECRET` | JWT signing secret - Generate with `openssl rand -hex 64` | **MUST BE SET!** |
- `TRUST_PROXY`: Trust proxy headers (default: true) - See [Express.js docs](https://expressjs.com/en/guide/behind-proxies.html) for usage. | `JWT_EXPIRES_IN` | JWT token expiration time | `1h` |
| `JWT_REFRESH_EXPIRES_IN` | JWT refresh token expiration time | `7d` |
| `SESSION_INACTIVITY_TIMEOUT_MINUTES` | Session inactivity timeout in minutes | `30` |
| `DEFAULT_USER_ROLE` | Default role for new users | `user` |
##### Server & Network Configuration
| Variable | Description | Default |
| ----------------- | ----------------------------------------------------------------------------------------------- | ----------------------- |
| `PORT` | Backend API port | `3001` |
| `SERVER_PROTOCOL` | Frontend server protocol (`http` or `https`) | `http` |
| `SERVER_HOST` | Frontend server host | `localhost` |
| `SERVER_PORT` | Frontend server port | `3000` |
| `CORS_ORIGIN` | CORS origin URL | `http://localhost:3000` |
| `ENABLE_HSTS` | Enable HTTP Strict Transport Security | `true` |
| `TRUST_PROXY` | Trust proxy headers - See [Express.js docs](https://expressjs.com/en/guide/behind-proxies.html) | `true` |
##### Rate Limiting
| Variable | Description | Default |
| ---------------------------- | --------------------------------------------------- | -------- |
| `RATE_LIMIT_WINDOW_MS` | Rate limiting window in milliseconds | `900000` |
| `RATE_LIMIT_MAX` | Maximum requests per window | `5000` |
| `AUTH_RATE_LIMIT_WINDOW_MS` | Authentication rate limiting window in milliseconds | `600000` |
| `AUTH_RATE_LIMIT_MAX` | Maximum authentication requests per window | `500` |
| `AGENT_RATE_LIMIT_WINDOW_MS` | Agent API rate limiting window in milliseconds | `60000` |
| `AGENT_RATE_LIMIT_MAX` | Maximum agent requests per window | `1000` |
##### Logging
| Variable | Description | Default |
| ---------------- | ------------------------------------------------ | ------- |
| `LOG_LEVEL` | Logging level (`debug`, `info`, `warn`, `error`) | `info` |
| `ENABLE_LOGGING` | Enable application logging | `true` |
#### Frontend Service #### Frontend Service
- `BACKEND_HOST`: Backend service hostname (default: `backend`) | Variable | Description | Default |
- `BACKEND_PORT`: Backend service port (default: 3001) | -------------- | ------------------------ | --------- |
| `BACKEND_HOST` | Backend service hostname | `backend` |
| `BACKEND_PORT` | Backend service port | `3001` |
### Volumes ### Volumes
@@ -129,7 +179,7 @@ For development with live reload and source code mounting:
1. Clone the repository: 1. Clone the repository:
```bash ```bash
git clone https://github.com/9technologygroup/patchmon.net.git git clone https://github.com/PatchMon/PatchMon.git
cd patchmon.net cd patchmon.net
``` ```
@@ -203,7 +253,7 @@ The development setup exposes additional ports for debugging:
1. **Initial Setup**: Clone repository and start development environment 1. **Initial Setup**: Clone repository and start development environment
```bash ```bash
git clone https://github.com/9technologygroup/patchmon.net.git git clone https://github.com/PatchMon/PatchMon.git
cd patchmon.net cd patchmon.net
docker compose -f docker/docker-compose.dev.yml up -d --build docker compose -f docker/docker-compose.dev.yml up -d --build
``` ```

View File

@@ -59,7 +59,10 @@ ENV NODE_ENV=production \
ENABLE_LOGGING=true \ ENABLE_LOGGING=true \
LOG_LEVEL=info \ LOG_LEVEL=info \
PM_LOG_TO_CONSOLE=true \ PM_LOG_TO_CONSOLE=true \
PORT=3001 PORT=3001 \
JWT_EXPIRES_IN=1h \
JWT_REFRESH_EXPIRES_IN=7d \
SESSION_INACTIVITY_TIMEOUT_MINUTES=30
RUN apk add --no-cache openssl tini curl RUN apk add --no-cache openssl tini curl

View File

@@ -1,3 +1,5 @@
name: patchmon-dev
services: services:
database: database:
image: postgres:17-alpine image: postgres:17-alpine
@@ -5,7 +7,7 @@ services:
environment: environment:
POSTGRES_DB: patchmon_db POSTGRES_DB: patchmon_db
POSTGRES_USER: patchmon_user POSTGRES_USER: patchmon_user
POSTGRES_PASSWORD: INSECURE_REPLACE_ME_PLEASE_INSECURE POSTGRES_PASSWORD: 1NS3CU6E_DEV_D8_PASSW0RD
ports: ports:
- "5432:5432" - "5432:5432"
volumes: volumes:
@@ -21,19 +23,17 @@ services:
context: .. context: ..
dockerfile: docker/backend.Dockerfile dockerfile: docker/backend.Dockerfile
target: development target: development
tags: [patchmon-backend:dev]
restart: unless-stopped restart: unless-stopped
environment: environment:
NODE_ENV: development NODE_ENV: development
LOG_LEVEL: info LOG_LEVEL: info
DATABASE_URL: postgresql://patchmon_user:INSECURE_REPLACE_ME_PLEASE_INSECURE@database:5432/patchmon_db DATABASE_URL: postgresql://patchmon_user:1NS3CU6E_DEV_D8_PASSW0RD@database:5432/patchmon_db
PM_DB_CONN_MAX_ATTEMPTS: 30 JWT_SECRET: INS3CURE_DEV_7WT_5ECR3T
PM_DB_CONN_WAIT_INTERVAL: 2
SERVER_PROTOCOL: http SERVER_PROTOCOL: http
SERVER_HOST: localhost SERVER_HOST: localhost
SERVER_PORT: 3000 SERVER_PORT: 3000
CORS_ORIGIN: http://localhost:3000 CORS_ORIGIN: http://localhost:3000
RATE_LIMIT_WINDOW_MS: 900000
RATE_LIMIT_MAX: 100
ports: ports:
- "3001:3001" - "3001:3001"
volumes: volumes:
@@ -59,6 +59,7 @@ services:
context: .. context: ..
dockerfile: docker/frontend.Dockerfile dockerfile: docker/frontend.Dockerfile
target: development target: development
tags: [patchmon-frontend:dev]
restart: unless-stopped restart: unless-stopped
environment: environment:
BACKEND_HOST: backend BACKEND_HOST: backend

View File

@@ -1,3 +1,5 @@
name: patchmon
services: services:
database: database:
image: postgres:17-alpine image: postgres:17-alpine
@@ -5,7 +7,7 @@ services:
environment: environment:
POSTGRES_DB: patchmon_db POSTGRES_DB: patchmon_db
POSTGRES_USER: patchmon_user POSTGRES_USER: patchmon_user
POSTGRES_PASSWORD: INSECURE_REPLACE_ME_PLEASE_INSECURE POSTGRES_PASSWORD: # CREATE A STRONG PASSWORD AND PUT IT HERE
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
healthcheck: healthcheck:
@@ -15,19 +17,17 @@ services:
retries: 7 retries: 7
backend: backend:
image: ghcr.io/9technologygroup/patchmon-backend:latest image: ghcr.io/patchmon/patchmon-backend:latest
restart: unless-stopped restart: unless-stopped
# See PatchMon Docker README for additional environment variables and configuration instructions
environment: environment:
LOG_LEVEL: info LOG_LEVEL: info
DATABASE_URL: postgresql://patchmon_user:INSECURE_REPLACE_ME_PLEASE_INSECURE@database:5432/patchmon_db DATABASE_URL: postgresql://patchmon_user:REPLACE_YOUR_POSTGRES_PASSWORD_HERE@database:5432/patchmon_db
PM_DB_CONN_MAX_ATTEMPTS: 30 JWT_SECRET: # CREATE A STRONG SECRET AND PUT IT HERE - Generate with 'openssl rand -hex 64'
PM_DB_CONN_WAIT_INTERVAL: 2
SERVER_PROTOCOL: http SERVER_PROTOCOL: http
SERVER_HOST: localhost SERVER_HOST: localhost
SERVER_PORT: 3000 SERVER_PORT: 3000
CORS_ORIGIN: http://localhost:3000 CORS_ORIGIN: http://localhost:3000
RATE_LIMIT_WINDOW_MS: 900000
RATE_LIMIT_MAX: 100
volumes: volumes:
- agent_files:/app/agents - agent_files:/app/agents
depends_on: depends_on:
@@ -35,7 +35,7 @@ services:
condition: service_healthy condition: service_healthy
frontend: frontend:
image: ghcr.io/9technologygroup/patchmon-frontend:latest image: ghcr.io/patchmon/patchmon-frontend:latest
restart: unless-stopped restart: unless-stopped
ports: ports:
- "3000:3000" - "3000:3000"