Web-based server hardware monitoring via IPMI and Redfish
This guide covers the development workflow, CI/CD pipeline, and release process for IPMI Monitor.
Current Version: v1.1.x
Last Updated: January 2026
git clone git@github.com:cryptolabsza/ipmi-monitor.git
cd ipmi-monitor
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run locally
python app.py
# Build image locally
docker build -t ipmi-monitor:local .
# Run locally
docker run -p 5001:5001 -v ipmi-data:/app/data ipmi-monitor:local
We use a simplified Git Flow with two main branches:
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ main ────●────────●────────●────────●────────●───────► STABLE │
│ │ ↑ │ ↑ │ │
│ │ (release) │ (release) │ │
│ │ │ │ │ │ │
│ dev ─────●────●───●────●───●────●───●────●───●───────► DEVELOPMENT│
│ │ │ │ │ │ │
│ ↓ ↓ ↓ ↓ ↓ │
│ feat feat feat feat feat │
│ │
└─────────────────────────────────────────────────────────────────────┘
| Branch | Purpose | Protected | Auto-Deploy |
|---|---|---|---|
main |
Production-ready stable code | ✅ Yes | :latest tag |
dev |
Integration branch for features | ✅ Yes | :dev tag |
feature/* |
Individual feature work | ❌ No | PR builds only |
hotfix/* |
Emergency production fixes | ❌ No | - |
For main:
For dev:
# Always start from latest develop
git checkout dev
git pull origin dev
# Create feature branch
git checkout -b feature/my-awesome-feature
Naming conventions:
feature/add-gpu-monitoring - New featuresfix/resolve-memory-leak - Bug fixesrefactor/cleanup-alerts - Code improvementsdocs/update-readme - Documentation# Make changes to code
# ...
# Stage and commit (use meaningful messages)
git add .
git commit -m "feat: Add GPU temperature monitoring
- Added GPU sensor collection via nvidia-smi
- Display GPU temps on dashboard
- Alert when GPU exceeds threshold
Closes #123"
Commit Message Format:
type: Short description (max 50 chars)
Longer description if needed. Explain what and why,
not how (the code shows how).
Closes #issue_number
Types: feat, fix, docs, refactor, test, chore
# Push to remote
git push origin feature/my-awesome-feature
Then on GitHub:
devdevAfter merge:
git checkout dev
git pull origin dev
git branch -d feature/my-awesome-feature
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Push to │────►│ GitHub │────►│ Docker │
│ Branch │ │ Actions │ │ Build │
└──────────────┘ └──────────────┘ └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Tests │ │ Push to │
│ (future) │ │ GHCR │
└──────────────┘ └──────────────┘
| Event | What Happens |
|---|---|
Push to dev |
Build :dev, :develop tags |
Push to main |
Build :main tag |
Push tag v* |
Build :v1.x.x, :latest, :stable |
| Pull Request | Build only (no push) |
| Manual dispatch | Build with optional custom tag |
Located at: .github/workflows/docker-build.yml
# Key sections:
on:
push:
branches: [ main, master, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ main, master, develop ]
# Tags generated:
# - develop → :dev, :develop
# - main → :main
# - v1.6.0 → :v1.6.0, :1.6.0, :1.6, :latest, :stable
All builds include:
View in running container:
docker exec ipmi-monitor env | grep -E "GIT_|BUILD_|APP_"
| Tag | Source | Stability | Use Case |
|---|---|---|---|
v1.1.1 |
Git tag | ⭐ Stable | Production (pinned) |
latest |
Latest release tag | ⭐ Stable | Production (auto-update) |
stable |
Latest release tag | ⭐ Stable | Production alias |
main |
main branch | 🔶 Pre-release | Staging |
dev |
dev branch | ⚠️ Unstable | Development testing |
sha-abc123 |
Any commit | 🔍 Debug | Troubleshooting |
# Production (recommended)
docker pull ghcr.io/cryptolabsza/ipmi-monitor:v1.1.1
# Latest stable
docker pull ghcr.io/cryptolabsza/ipmi-monitor:latest
# Development build
docker pull ghcr.io/cryptolabsza/ipmi-monitor:dev
# CryptoLabs Proxy (required for quickstart with HTTPS)
docker pull ghcr.io/cryptolabsza/cryptolabs-proxy:latest
devghcr.io/cryptolabsza/cryptolabs-proxy is also released with matching tag if changes were madeCreate a list of changes since last release:
git log v1.0.0..dev --oneline
# Ensure dev is up to date
git checkout dev
git pull origin dev
# Create PR on GitHub: dev → main
# Title: "Release v1.1.1"
# Description: Include release notes
After PR approval:
git checkout main
git pull origin main
# Create annotated tag
git tag -a v1.1.1 -m "Release v1.1.1
## New Features
- Quickstart wizard with CryptoLabs Proxy integration
- DC Overview detection and import
- SSH log collection option during setup
- Initial data collection on fresh installs
- Certbot auto-renewal for Let's Encrypt
- Enhanced SSH key management (detect, paste, generate)
## Improvements
- Unified cryptolabs-proxy for reverse proxy
- SEL management dropdown (enable/disable/info/time)
- Sensor value change highlighting
- Diagnostics loading states
- Grafana integration instructions
## Bug Fixes
- Export/import alert rules
- Let's Encrypt fallback to self-signed
- Nginx config for single-service installations
"
# Push tag to trigger CI
git push origin v1.1.1
v1.1.1v1.1.1# Check new image is available
docker pull ghcr.io/cryptolabsza/ipmi-monitor:v1.1.1
# Verify tags
docker images | grep ipmi-monitor
# Also verify cryptolabs-proxy is available
docker pull ghcr.io/cryptolabsza/cryptolabs-proxy:latest
# Sync develop with main
git checkout dev
git merge main
git push origin develop
For critical production bugs that can’t wait for normal release:
git checkout main
git pull origin main
git checkout -b hotfix/critical-security-fix
# Make minimal fix
git add .
git commit -m "fix: Patch critical security vulnerability
- Sanitize user input in X endpoint
- Add rate limiting
CVE: CVE-2025-XXXX"
git push origin hotfix/critical-security-fix
# Create PR: hotfix/critical-security-fix → main
After approval:
git checkout main
git pull origin main
# Create patch version
git tag -a v1.6.1 -m "Hotfix: Critical security patch"
git push origin v1.6.1
git checkout dev
git merge main
git push origin develop
# Using docker-compose.prod.yml
cd /path/to/deployment
# Update to new version
export IMAGE_TAG=v1.6.0
# Pull and restart
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d
# Verify
docker-compose -f docker-compose.prod.yml logs -f
# Using docker-compose.dev.yml
docker-compose -f docker-compose.dev.yml pull
docker-compose -f docker-compose.dev.yml up -d
# Access on port 5002 (to avoid prod conflicts)
open http://localhost:5002
If a release has issues:
# 1. Identify last good version
docker images | grep ipmi-monitor
# 2. Update docker-compose to previous version
# image: ghcr.io/cryptolabsza/ipmi-monitor:v1.5.0
# 3. Rollback
docker-compose down
docker-compose up -d
# 4. Verify
docker-compose logs -f
Problem: CI fails with “no space left on device”
# On self-hosted runner
docker system prune -af
docker volume prune -f
Problem: Image push fails with 403
GITHUB_TOKEN permissionsProblem: Container won’t start
# Check logs
docker logs ipmi-monitor
# Common fixes
docker-compose down
docker volume rm ipmi-data # ⚠️ Loses data
docker-compose up -d
Problem: Database migration errors
# Add missing columns manually
docker exec -it ipmi-monitor sqlite3 /app/data/ipmi_events.db
# Run ALTER TABLE statements
# Run dev build alongside production
docker run -d \
--name ipmi-monitor-test \
-p 5002:5001 \
-v ipmi-test-data:/app/data \
ghcr.io/cryptolabsza/ipmi-monitor:dev
# Compare behavior
open http://localhost:5001 # prod
open http://localhost:5002 # dev
# Switch to dev and update
git checkout dev && git pull
# Create feature branch
git checkout -b feature/name
# Push feature and create PR
git push -u origin feature/name
# Create release tag
git tag -a v1.x.x -m "Release v1.x.x" && git push origin v1.x.x
# Pull latest dev image
docker pull ghcr.io/cryptolabsza/ipmi-monitor:dev
# View container version
docker exec ipmi-monitor cat /app/VERSION
If you have questions about the development process:
Happy coding! 🚀