PixelView High Availability (HA) Installation on Docker
This document describes a production-grade High Availability (HA) deployment of PixelView using Docker, where:
- MongoDB runs as a 3-node replica set on three separate machines
- PixelView services run with multiple replicas
- MongoDB provides durable state
- PixelView services remain stateless and horizontally scalable
HA Architecture Overview
Node Layout
| Node | Role |
|---|---|
| Node-1 | MongoDB (Primary / Secondary) |
| Node-2 | MongoDB (Primary / Secondary) |
| Node-3 | MongoDB (Primary / Secondary) |
| Node-1 | PixelView services (API, UI, workers) |
Important: MongoDB nodes must run on separate hosts (VMs or physical machines). Running multiple MongoDB containers on the same host does not provide real HA.
Host Requirements
Before proceeding with the installation, ensure that you have Docker and Docker Compose installed on your system. To do so you can follow the instructions provided on the docker's website.
System Recommendation
8 vCPU, 16GB RAM, 1GB network : 3 x nodes
To achieve HA we need to have
- 3 node replica mongo db cluster
- Each service in the cluster running on all the nodes
- DNS (round robin) to the frontend on all 3 nodes to achieve DNS loadbalancer
First, on all 3 nodes edit your servers hosts file and put entries for nodes:
$ cat /etc/hosts
127.0.0.1 localhost
192.168.5.1 mongo-node-1
192.168.5.2 mongo-node-2
192.168.5.3 mongo-node-3
NOTE: Make sure to match the name and IP of the server to your actual server.
Next, on all 3 nodes pull all the relevant docker images
docker pull ghcr.io/pixelvirt/inithive-rabbitmq:latest
docker pull ghcr.io/pixelvirt/findescalation:latest
docker pull ghcr.io/pixelvirt/escalation:latest
docker pull mongo:5
docker pull rabbitmq:4.2.2-management
docker pull ghcr.io/pixelvirt/ansible-server:latest
docker pull ghcr.io/pixelvirt/ospc-openstack-go:latest
docker pull ghcr.io/pixelvirt/openstack-go:latest
docker pull ghcr.io/pixelvirt/alertagility:v2.0
docker pull ghcr.io/pixelvirt/alertagility-frontend:latest
MongoDB Replica Set (3 Separate Nodes)
Each MongoDB node runs one MongoDB container, all configured with the same replica set name.
Assumptions
- All MongoDB nodes can reach each other over the network
- Hostnames or IPs:
mongo-node-1mongo-node-2mongo-node-3- Port
27017is open between MongoDB nodes
MongoDB Docker Compose (Run on each MongoDB node)
Create the following docker-compose.yml on each node.
The file is identical on all three nodes.
services:
escalation:
image: ghcr.io/pixelvirt/escalation:latest
restart: always
depends_on:
- rabbitmqservice
- mongoservice
environment:
MONGOURL: "mongodb://mongo-node-1:27017,mongo-node-2:27017,mongo-node-3:27017/alertagility?replicaSet=rs0"
RABBITURL: "amqp://alertagility:dcW41MPUlM54uw2@localhost:5672/alertagility"
network_mode: host
alertagility:
image: ghcr.io/pixelvirt/alertagility:v2.0
restart: always
ports:
- "9090:9090"
depends_on:
- mongoservice
- rabbitmqservice
environment:
DEX_ISSUER_URL: "https://dex.pixelvirt.com/dex"
DEX_REDIRECT_URI: "https://cloud.pixelvirt.com/api/auth/callback"
OPENSTACK_MIDDLEWARE_URL: "http://localhost:8005"
MONGOURL: "mongodb://mongo-node-1:27017,mongo-node-2:27017,mongo-node-3:27017/alertagility?replicaSet=rs0"
DOMAIN: "pixelvirt.com"
SUBDOMAIN: "alertagility"
RABBITURL: "amqp://alertagility:dcW41MPUlM54uw2@localhost:5672/alertagility"
ENVIRONMENT: "dev"
KAMAJI_KUBECONFIG: "/root/kubeconfig.yaml"
network_mode: host
volumes:
- ./kubeconfig.yaml:/root/kubeconfig.yaml
rabbitmqservice:
image: ghcr.io/pixelvirt/inithive-rabbitmq:latest
restart: always
ports:
- "5673:5672"
environment:
- RABBITMQ_PASSWORD=dcW41MPUlM54uw2
- RABBITMQ_USER=alertagility
network_mode: host
mongoservice:
image: mongo:5
command: ["--replSet", "rs0", "--bind_ip_all"]
restart: always
container_name: ${HOSTNAME}
hostname: ${HOSTNAME}
volumes:
- ./pixelview-data:/data/db
network_mode: host
alert-frontend:
image: ghcr.io/pixelvirt/alertagility-frontend:latest
restart: always
network_mode: host
depends_on:
- alertagility
- ansible-server
- openstack
ports:
- "80:80"
environment:
- BACKEND_URL=localhost:9090
- ANSIBLE_BACKEND_URL=localhost:8000
- OPENSTACK_BACKEND_URL=localhost:8005
- KUBERNETES_BACKEND_URL=localhost:4000
- CHAT_BACKEND_URL=localhost:8765
- PIXELVIEW_URL=localhost:9090
- BACKUP_BACKEND_URL=localhost:9191
backup:
image: ghcr.io/pixelvirt/backup:latest
environment:
PORT: "9191"
DB_TYPE: mongodb
MONGO_URI: mongodb://localhost:27017
PIXELVIEW_URL: http://localhost:9090
AUTH_KEY: 6c673f51-6045-47b0-8745-eef9d165a310
ALLOWED_ORIGINS: "*"
depends_on:
- mongoservice
restart: unless-stopped
container_name: pixelvirt_backup
network_mode: host
openstack:
image: ghcr.io/pixelvirt/openstack-go:latest
restart: always
ports:
- "8005:8005"
environment:
- MONGO_URI="mongodb://mongo-node-1:27017,mongo-node-2:27017,mongo-node-3:27017/alertagility?replicaSet=rs0"
- MONGO_DBNAME=dashboard_db
- GOPHER_CLOUD_DEBUG=true
- PIXELVIEW_URL=http://localhost:9090
container_name: openstack-go
network_mode: host
extra_hosts:
- "newcloud.pixelvirt.com:138.199.223.176"
# Include common cloud config. This will be visible to all users.
# volumes:
# - ./clouds.yaml:/etc/openstack/clouds.yaml
kubernetes:
restart: always
image: ghcr.io/pixelvirt/kubernetes-go:latest
ports:
- "4000:4000"
container_name: k8s-dashboard
network_mode: host
environment:
- KUBECONFIG_FILE=/usr/src/app/kubeconfig
- GET_CONFIG_FROM=bla
- PIXELVIEW_URL=http://localhost:9090
# Include common kube config. This will be visible to all users.
# volumes:
# - ./k8s-config/:/usr/src/app/
ansible-server:
image: ghcr.io/pixelvirt/ansible-server:latest
build: .
container_name: ansible-server
ports:
- "8000:8000"
depends_on:
- rabbitmqservice
restart: unless-stopped
network_mode: host
environment:
- SERVER_PORT=8000
- AUTH_KEY=6c673f51-6045-47b0-8745-eef9d165a310
- RABBITMQ_HOST=localhost
- RABBITMQ_PORT=5672
- RABBITMQ_USERNAME=alertagility
- RABBITMQ_PASSWORD=dcW41MPUlM54uw2
- RABBITMQ_VHOST=/
- JOB_INPUT_QUEUE=admin-admin
- JOB_OUTPUT_QUEUE=ansible_output
- MONGODB_URI=mongodb://mongo-node-1:27017,mongo-node-2:27017,mongo-node-3:27017/alertagility?replicaSet=rs0
- MONGODB_DBNAME=ansible_server_db
- PIXELVIEW_URL=http://localhost:9090
volumes:
data:
config:
ansible-rabbitmq-data:
Start MongoDB:
Initialize the MongoDB Replica Set (One-Time)
This step initializes the MongoDB replica set and must be executed only once after all three MongoDB nodes are running.
Run this from mongo-node-1 (or whichever node you want to become the initial primary).
Connect to MongoDB
docker exec -it mongo mongosh
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo-node-1:27017" },
{ _id: 1, host: "mongo-node-2:27017" },
{ _id: 2, host: "mongo-node-3:27017" }
]
})
Verify Replica Set Status
Note
mongo-node-1, mongo-node-2 and mongo-node-3 node hostname and adjust according to the node hostname for your setup.
If everything has gone correctly, you have 3 nodes with PixelView services running on each node.
DNS / LB
At this point you will need to setup a round robin DNS entry or external load balancer that points to your nodes.
Assuming DNS: testing.pixelvirt.com when you dig on the fqdn you see:
dig testing.pixelvirt.com git:master*
testing.pixelvirt.com. 300 IN A 50.56.158.227
testing.pixelvirt.com. 300 IN A 50.56.157.101
testing.pixelvirt.com. 300 IN A 174.143.59.131
Now, on your browser open https://your-domain-name.com and login with the default login: