This document provides procedures for upgrading Oxidized to a new version and rolling back if issues occur.
- Upgrade Strategy
- Pre-Upgrade Checklist
- Upgrade Procedure
- Rollback Procedure
- Testing New Versions
- Version History
This deployment uses pinned container image versions to ensure:
- ✅ Predictable behavior - no surprise changes
- ✅ Controlled upgrades - manual, deliberate updates
- ✅ Easy rollback - revert to previous working version
- ✅ Testing before production - validate in non-prod first
The Quadlet file pins the Oxidized version:
Image=docker.io/oxidized/oxidized:0.35.0Recommended Schedule:
- Security patches: Within 7 days of release
- Minor versions: Every 3-6 months
- Major versions: Annually, after thorough testing
Before upgrading, complete the following steps:
# List available tags on Docker Hub
curl -s https://registry.hub.docker.com/v2/repositories/oxidized/oxidized/tags \
| jq -r '.results[].name' | sort -V | tail -20
# Or visit: https://hub.docker.com/r/oxidized/oxidized/tagsCheck the Oxidized changelog for breaking changes:
- GitHub: https://github.com/yggdrasil-network/oxidized/releases
- Look for:
- Configuration changes
- Model updates
- Deprecated features
- New dependencies
Critical: Always backup before upgrading!
# Create backup directory
sudo mkdir -p /var/backups/oxidized/$(date +%Y%m%d)
# Backup Git repository (adjust path if you customized OXIDIZED_ROOT in .env)
sudo tar -czf /var/backups/oxidized/$(date +%Y%m%d)/oxidized-git.tar.gz \
-C /var/lib/oxidized repo/
# Backup configuration files
sudo tar -czf /var/backups/oxidized/$(date +%Y%m%d)/oxidized-config.tar.gz \
-C /var/lib/oxidized config/
# Backup Quadlet file
sudo cp /etc/containers/systemd/oxidized.container \
/var/backups/oxidized/$(date +%Y%m%d)/oxidized.container.backup
# Verify backups
ls -lh /var/backups/oxidized/$(date +%Y%m%d)/# Record current version
podman inspect oxidized | jq -r '.[0].ImageName' > /tmp/oxidized-version-before.txt
# Record current service status
sudo systemctl status oxidized.service > /tmp/oxidized-status-before.txt
# Take note of last backup times
curl -s http://localhost:8888/nodes.json | jq '.' > /tmp/oxidized-nodes-before.json- ⏰ Estimated downtime: 5-10 minutes
- 📅 Schedule: Off-peak hours
- 👥 Notify: Inform team of maintenance window
- 📊 Monitor: Have monitoring tools ready
# Determine target version (example: 0.36.0)
NEW_VERSION="0.36.0"
# Pull new image
sudo podman pull docker.io/oxidized/oxidized:${NEW_VERSION}
# Verify image
podman images | grep oxidized# Edit Quadlet file
sudo vim /etc/containers/systemd/oxidized.container
# Update the Image line:
# FROM: Image=docker.io/oxidized/oxidized:0.35.0
# TO: Image=docker.io/oxidized/oxidized:0.36.0Or use sed for automation:
OLD_VERSION="0.35.0"
NEW_VERSION="0.36.0"
sudo sed -i "s|oxidized:${OLD_VERSION}|oxidized:${NEW_VERSION}|g" \
/etc/containers/systemd/oxidized.container
# Verify change
grep "Image=" /etc/containers/systemd/oxidized.container# Reload systemd to pick up Quadlet changes
sudo systemctl daemon-reload
# Verify service file was regenerated
sudo systemctl cat oxidized.service | grep ExecStart# Stop current service
sudo systemctl stop oxidized.service
# Verify it's stopped
sudo systemctl status oxidized.service
# Start with new version
sudo systemctl start oxidized.service
# Check status
sudo systemctl status oxidized.service# Check running container version
podman inspect oxidized | jq -r '.[0].ImageName'
# Check container logs for errors
podman logs oxidized | tail -50
# Test API
curl -s http://localhost:8888/ && echo "API OK"
# Test node list
curl -s http://localhost:8888/nodes.json | jq '.[] | .name'
# Access Web UI
# Open browser: http://<server-ip>:8888# Watch logs in real-time
podman logs -f oxidized
# Wait for first backup cycle (up to 1 hour)
# Monitor for errors in logs
# Check Git commits (adjust path if you customized OXIDIZED_ROOT in .env)
cd /var/lib/oxidized/repo
sudo git log --oneline -10
# Verify node status
curl -s http://localhost:8888/nodes.json | jq '.[] | {name, status: .last.status}'# Record new version
podman inspect oxidized | jq -r '.[0].ImageName' > /tmp/oxidized-version-after.txt
# Compare versions
diff /tmp/oxidized-version-before.txt /tmp/oxidized-version-after.txt
# Update version tracking (adjust path if you customized OXIDIZED_ROOT in .env)
echo "$(date): Upgraded from 0.30.1 to 0.31.0" | \
sudo tee -a /var/lib/oxidized/UPGRADE_HISTORY.logIf the upgrade fails or causes issues, rollback to the previous version:
# Set previous version
OLD_VERSION="0.35.0"
# Update Quadlet back to old version
sudo sed -i "s|oxidized:.*|oxidized:${OLD_VERSION}|g" \
/etc/containers/systemd/oxidized.container
# Reload and restart
sudo systemctl daemon-reload
sudo systemctl restart oxidized.service
# Verify rollback
podman inspect oxidized | jq -r '.[0].ImageName'
sudo systemctl status oxidized.serviceIf configuration was also changed:
# Stop service
sudo systemctl stop oxidized.service
# Restore Quadlet file
sudo cp /var/backups/oxidized/$(date +%Y%m%d)/oxidized.container.backup \
/etc/containers/systemd/oxidized.container
# Restore configuration (if needed - adjust path if you customized OXIDIZED_ROOT)
sudo tar -xzf /var/backups/oxidized/$(date +%Y%m%d)/oxidized-config.tar.gz \
-C /var/lib/oxidized
# Reload and restart
sudo systemctl daemon-reload
sudo systemctl start oxidized.service
# Verify
sudo systemctl status oxidized.service
podman logs oxidizedIf Git repository is corrupted:
# Stop service
sudo systemctl stop oxidized.service
# Restore Git repository (adjust paths if you customized OXIDIZED_ROOT in .env)
sudo rm -rf /var/lib/oxidized/repo
sudo tar -xzf /var/backups/oxidized/$(date +%Y%m%d)/oxidized-git.tar.gz \
-C /var/lib/oxidized
# Restart service
sudo systemctl start oxidized.serviceBefore upgrading production, test in a separate environment:
# Create test directory (adjust path based on your OXIDIZED_ROOT from .env)
sudo mkdir -p /var/lib/oxidized-test
# Copy configuration
sudo cp -r /var/lib/oxidized/config /var/lib/oxidized-test/
sudo cp -r /var/lib/oxidized/ssh /var/lib/oxidized-test/
# Create test Quadlet
sudo cp /etc/containers/systemd/oxidized.container \
/etc/containers/systemd/oxidized-test.container
# Modify test Quadlet:
# - Change container name to "oxidized-test"
# - Change port to 8889
# - Change volumes to /var/lib/oxidized-test/*
# - Use new version
# Start test instance
sudo systemctl daemon-reload
sudo systemctl start oxidized-test.service
# Test new version
curl http://localhost:8889/
# Clean up when done
sudo systemctl stop oxidized-test.service
sudo rm /etc/containers/systemd/oxidized-test.container- Service starts successfully
- API responds correctly
- Web UI loads
- Device backups work
- Git commits are created
- Logs are written
- No SELinux denials
- Resource usage is acceptable
- Release Date: 2025-12-04
- Status: Stable
- Known Issues: None
- Deployed: 2026-01-22
- Release Date: 2024-xx-xx
- Status: Superseded
- Replaced by: 0.35.0
- Release Date: TBD
- Status: Not deployed
- Breaking Changes: TBD
- Migration Notes: TBD
Keep a log of upgrades (adjust path if you customized OXIDIZED_ROOT in .env):
# Create upgrade log
sudo tee -a /var/lib/oxidized/UPGRADE_HISTORY.log <<EOF
$(date): Initial deployment - version 0.35.0
EOF
# After each upgrade, append:
# $(date): Upgraded from X.Y.Z to A.B.C - Reason: ...# Get image digest
podman images --digests | grep oxidized
# Compare with Docker Hub
# Visit: https://hub.docker.com/r/oxidized/oxidized/tags# View image metadata
podman inspect docker.io/oxidized/oxidized:0.35.0 | jq '.[0]'
# Check image layers
podman history docker.io/oxidized/oxidized:0.35.0
# Verify image architecture
podman inspect docker.io/oxidized/oxidized:0.35.0 | \
jq -r '.[0].Architecture'Symptoms: Service fails to start with new version
Diagnosis:
sudo journalctl -u oxidized.service -n 100
podman logs oxidizedSolution: Check for configuration incompatibilities, rollback if needed
Symptoms: Errors about invalid configuration
Solution: Review release notes for configuration changes, update config file
Symptoms: Devices that worked before now fail
Solution: Check Oxidized model updates, may need to specify different model in CSV
Symptoms: Image pull fails or container crashes immediately
Solution:
# Remove corrupted image
podman rmi docker.io/oxidized/oxidized:0.36.0
# Re-pull image
podman pull docker.io/oxidized/oxidized:0.36.0
# Restart service
sudo systemctl restart oxidized.serviceNote: Use with caution! Always test thoroughly first.
#!/usr/bin/env bash
set -euo pipefail
# Variables
OLD_VERSION="${1:-0.35.0}"
NEW_VERSION="${2:-0.36.0}"
BACKUP_DIR="/var/backups/oxidized/$(date +%Y%m%d_%H%M%S)"
echo "🔄 Upgrading Oxidized from ${OLD_VERSION} to ${NEW_VERSION}"
# Backup (adjust paths if you customized OXIDIZED_ROOT in .env)
echo "📦 Creating backup..."
mkdir -p "${BACKUP_DIR}"
tar -czf "${BACKUP_DIR}/oxidized-git.tar.gz" -C /var/lib/oxidized repo/
tar -czf "${BACKUP_DIR}/oxidized-config.tar.gz" -C /var/lib/oxidized config/
cp /etc/containers/systemd/oxidized.container "${BACKUP_DIR}/oxidized.container.backup"
# Pull new image
echo "⬇️ Pulling new image..."
podman pull docker.io/oxidized/oxidized:${NEW_VERSION}
# Update Quadlet
echo "📝 Updating Quadlet..."
sed -i "s|oxidized:${OLD_VERSION}|oxidized:${NEW_VERSION}|g" \
/etc/containers/systemd/oxidized.container
# Restart service
echo "🔄 Restarting service..."
systemctl daemon-reload
systemctl restart oxidized.service
# Verify
echo "✅ Verifying upgrade..."
sleep 5
systemctl status oxidized.service
podman logs oxidized | tail -20
echo "🎉 Upgrade complete!"
echo "📚 Backup location: ${BACKUP_DIR}"- ✅ Upgrade complete!
- 📖 Monitor service for 24-48 hours
- 🔍 Review monitoring/ZABBIX.md for alerting
- 📋 Update documentation if configuration changed
- Oxidized Documentation: https://github.com/yggdrasil-network/oxidized
- Docker Hub: https://hub.docker.com/r/oxidized/oxidized
- GitHub Issues: https://github.com/yggdrasil-network/oxidized/issues
Remember: Always backup before upgrading! 💾