Installing PatchMon Server on Docker
Overview
PatchMon runs as a containerised application made up of four services:
- Database - PostgreSQL 17
- Redis - Redis 7 (used for BullMQ job queues and caching)
- Backend - Node.js API server
- Frontend - React application served via NGINX
Container Images
- Backend: ghcr.io/patchmon/patchmon-backend
- Frontend: ghcr.io/patchmon/patchmon-frontend
Available Tags
| Tag | Description |
|---|---|
latest |
Latest stable release |
x.y.z |
Exact version pin (e.g. 1.2.3) |
x.y |
Latest patch in a minor series (e.g. 1.2) |
x |
Latest minor and patch in a major series (e.g. 1) |
edge |
Latest development build in main branch - may be unstable, for testing only |
Both backend and frontend images share the same version tags.
Quick Start
1. Download the files
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/PatchMon/PatchMon/refs/heads/main/docker/docker-compose.yml
curl -fsSL -o env.example https://raw.githubusercontent.com/PatchMon/PatchMon/refs/heads/main/docker/env.example
2. Create your .env file
Copy the example file and generate the three required secrets:
cp env.example .env
# Generate and insert strong secrets
sed -i "s/^POSTGRES_PASSWORD=$/POSTGRES_PASSWORD=$(openssl rand -hex 32)/" .env
sed -i "s/^REDIS_PASSWORD=$/REDIS_PASSWORD=$(openssl rand -hex 32)/" .env
sed -i "s/^JWT_SECRET=$/JWT_SECRET=$(openssl rand -hex 64)/" .env
Then open .env and configure your server access settings:
# Set these to the URL you will use to access PatchMon.
# SERVER_PROTOCOL, SERVER_HOST and SERVER_PORT are used by agents to connect back to PatchMon.
# CORS_ORIGIN should match the full URL you access PatchMon from in your browser.
SERVER_PROTOCOL=http
SERVER_HOST=localhost
SERVER_PORT=3000
CORS_ORIGIN=http://localhost:3000
Tip: If you are deploying PatchMon behind a reverse proxy with a domain name, set
SERVER_PROTOCOL=https,SERVER_HOST=patchmon.example.com,SERVER_PORT=443, andCORS_ORIGIN=https://patchmon.example.com.
That's it. The docker-compose.yml uses env_file: .env to pass all your configuration straight into the containers. You do not need to edit the compose file itself.
For a full list of optional environment variables (rate limiting, logging, database pool tuning, session timeouts, etc.), see the Environment Variables page.
3. Start PatchMon
docker compose up -d
Once all containers are healthy, open your browser at http://localhost:3000 (or your configured URL) and complete the first-time setup to create your admin account.
Updating PatchMon
By default the compose file uses the latest tag. To update:
docker compose pull
docker compose up -d
This pulls the latest images, recreates containers, and keeps all your data intact.
Pinning to a specific version
If you prefer to pin versions, update the image tags in docker-compose.yml:
services:
backend:
image: ghcr.io/patchmon/patchmon-backend:1.4.0
frontend:
image: ghcr.io/patchmon/patchmon-frontend:1.4.0
Then run:
docker compose pull
docker compose up -d
Check the releases page for version-specific changes and migration notes.
Volumes
The compose file creates the following Docker volumes:
| Volume | Purpose |
|---|---|
postgres_data |
PostgreSQL data directory |
redis_data |
Redis data directory |
agent_files |
PatchMon agent scripts |
branding_assets |
Custom branding files (logos, favicons) - optional, new in 1.4.0 |
You can bind any of these to a host path instead of a Docker volume by editing the compose file.
Note: The backend container runs as user and group ID 1000. If you rebind the
agent_filesorbranding_assetsvolumes to a host path, make sure that user/group has write permissions.
Docker Swarm Deployment
This section covers deploying PatchMon to a Docker Swarm cluster. For standard single-host deployments, use the production guide above.
Network Configuration
The default compose file uses an internal bridge network (patchmon-internal) for service-to-service communication. All services connect to this network and discover each other by service name.
If you are using an external reverse proxy network (e.g. Traefik):
- Keep all PatchMon services on
patchmon-internalfor internal communication - Optionally add the frontend service to the reverse proxy network
- Make sure service name resolution works within the same network
Example: Traefik integration
services:
frontend:
image: ghcr.io/patchmon/patchmon-frontend:latest
networks:
- patchmon-internal
deploy:
replicas: 1
labels:
- "traefik.enable=true"
- "traefik.http.routers.patchmon.rule=Host(`patchmon.example.com`)"
The frontend reaches the backend via patchmon-internal using the hostname backend, while Traefik routes external traffic to the frontend.
Troubleshooting: host not found in upstream "backend"
This usually means the frontend and backend are on different networks, or services haven't fully started. Check:
- All services are on the same internal network
- Service health status with
docker psordocker service ps - Network connectivity with
docker exec <container> ping backend
Development Setup
This section is for developers who want to contribute to PatchMon or run it locally in development mode.
Getting started
git clone https://github.com/PatchMon/PatchMon.git
cd PatchMon
docker compose -f docker/docker-compose.dev.yml up --watch --build
The development compose file:
- Builds images locally from source
- Enables hot reload via Docker Compose watch
- Exposes all service ports for debugging
- Mounts source code directly into containers
Development ports
| Service | Port | URL |
|---|---|---|
| Frontend | 3000 | http://localhost:3000 |
| Backend API | 3001 | http://localhost:3001 |
| PostgreSQL | 5432 | localhost:5432 |
| Redis | 6379 | localhost:6379 |
Common commands
# Start with hot reload (attached)
docker compose -f docker/docker-compose.dev.yml up --watch
# Start detached
docker compose -f docker/docker-compose.dev.yml up -d
# Rebuild a specific service
docker compose -f docker/docker-compose.dev.yml up -d --build backend
# View logs
docker compose -f docker/docker-compose.dev.yml logs -f
How hot reload works
- Frontend/backend source changes are synced automatically in watch mode
- package.json changes trigger an automatic service rebuild
- Prisma schema changes cause the backend to restart automatically
Building images locally
# Development images
docker build -f docker/backend.Dockerfile --target development -t patchmon-backend:dev .
docker build -f docker/frontend.Dockerfile --target development -t patchmon-frontend:dev .
# Production images
docker build -f docker/backend.Dockerfile -t patchmon-backend:latest .
docker build -f docker/frontend.Dockerfile -t patchmon-frontend:latest .
No comments to display
No comments to display