Skip to main content

Upgrading Nekzus

This guide covers upgrading Nekzus between versions, including backup procedures, migration steps, and rollback strategies.


Upgrade Overview​

Nekzus follows semantic versioning (SemVer) for releases:

Version TypeFormatDescription
MajorX.0.0Breaking changes, requires migration
Minor0.X.0New features, backward compatible
Patch0.0.XBug fixes, backward compatible

Version Compatibility Matrix​

From VersionTo VersionMigration RequiredNotes
0.x.x1.0.0YesBreaking changes
1.x.x1.y.yNoAutomatic schema updates
AnySame majorNoSafe upgrade path
Current Version

Check your current version with:

./nekzus --version

Or via the API:

curl -s https://localhost:8443/api/v1/status | jq .version

Pre-Upgrade Checklist​

Before upgrading, complete the following checklist to ensure a smooth upgrade process.

1. Backup Your Data​

Critical Step

Always create a full backup before upgrading. This is your safety net for rollback.

# Stop the container gracefully
docker compose stop nekzus

# Create timestamped backup directory
BACKUP_DIR="./backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

# Backup database
cp ./data/nexus.db "$BACKUP_DIR/"

# Backup configuration
cp ./configs/config.yaml "$BACKUP_DIR/"

# Backup TLS certificates (if using custom certs)
cp -r ./certs "$BACKUP_DIR/" 2>/dev/null || true

# Backup toolbox data
cp -r ./data/toolbox "$BACKUP_DIR/" 2>/dev/null || true

echo "Backup created at: $BACKUP_DIR"

2. Check Compatibility​

Before upgrading, verify:

  • Read the release notes for breaking changes
  • Check configuration file compatibility
  • Verify Go version requirements (Go 1.25+ required)
  • Review deprecated features that may be removed
  • Test upgrade in a staging environment first

3. Verify System Requirements​

RequirementMinimumRecommended
CPU1 core2+ cores
RAM256 MB512 MB+
Disk100 MB + data1 GB+
Go (source build)1.25Latest
Docker20.10+Latest

4. Document Current State​

# Save current configuration state
./nekzus -config configs/config.yaml -validate 2>&1 > upgrade-precheck.log

# Record current routes and apps
curl -s https://localhost:8443/api/v1/routes > routes-backup.json
curl -s https://localhost:8443/api/v1/apps > apps-backup.json
curl -s https://localhost:8443/api/v1/devices > devices-backup.json

Docker Upgrades​

Standard Upgrade (Minor/Patch)​

# Pull the latest image
docker compose pull

# Recreate container with new image
docker compose up -d

# Verify upgrade
docker compose logs -f nekzus

Major Version Upgrade​

For major version upgrades (e.g., v1.x to v2.x), follow these additional steps:

# 1. Stop the current container
docker compose stop nekzus

# 2. Create a full backup (see Pre-Upgrade Checklist)
BACKUP_DIR="./backups/major-upgrade-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
cp -r ./data "$BACKUP_DIR/"
cp -r ./configs "$BACKUP_DIR/"

# 3. Review breaking changes in CHANGELOG
# Read: https://github.com/nstalgic/nekzus/releases

# 4. Update configuration file (if required)
# See Configuration Changes section below

# 5. Pull new major version
docker compose pull

# 6. Run database migrations (automatic on startup)
docker compose up -d

# 7. Monitor logs for migration status
docker compose logs -f nekzus | head -100

# 8. Verify all routes and apps are accessible
curl -s https://localhost:8443/api/v1/healthz

Pinning to Specific Versions​

For production environments, pin to specific versions instead of latest:

docker-compose.yml
services:
nekzus:
image: ghcr.io/nstalgic/nekzus:v1.2.3 # Pin to specific version
# ... rest of configuration

Handling Breaking Changes​

When Docker image changes include breaking configuration:

# Compare configuration schemas
docker run --rm ghcr.io/nstalgic/nekzus:v1.0.0 -config-schema > old-schema.json
docker run --rm ghcr.io/nstalgic/nekzus:v2.0.0 -config-schema > new-schema.json

# Use diff to identify changes
diff old-schema.json new-schema.json

Binary Upgrades​

From Pre-built Binaries​

# Download new version
VERSION="v1.2.3"
curl -LO "https://github.com/nstalgic/nekzus/releases/download/${VERSION}/nekzus_linux_amd64.tar.gz"

# Stop current service
sudo systemctl stop nekzus

# Backup current binary
sudo cp /usr/local/bin/nekzus /usr/local/bin/nekzus.bak

# Extract and install new binary
tar -xzf nekzus_linux_amd64.tar.gz
sudo mv nekzus /usr/local/bin/

# Verify installation
nekzus --version

# Start service
sudo systemctl start nekzus
sudo systemctl status nekzus

Building from Source​

# Clone or update repository
git clone https://github.com/nstalgic/nekzus.git
cd nekzus

# Checkout specific version
git fetch --all --tags
git checkout v1.2.3

# Build with version information
go build -ldflags="-s -w -X main.version=v1.2.3" -o nekzus ./cmd/nekzus

# Verify build
./nekzus --version
Build Requirements

Building from source requires:

  • Go 1.25 or later
  • GCC (for CGO/SQLite support)
  • Node.js 20+ (for web UI)

Install dependencies on Debian/Ubuntu:

sudo apt-get install gcc libc6-dev libsqlite3-dev

Database Migrations​

Nekzus uses SQLite with automatic schema migrations. Migrations run automatically on startup.

How Migrations Work​

The database schema is managed through idempotent migrations in internal/storage/storage.go:

  1. Table Creation: CREATE TABLE IF NOT EXISTS ensures tables are created only if missing
  2. Index Creation: CREATE INDEX IF NOT EXISTS for performance optimization

Migration Process​

Startup
|
v
Open Database
|
v
Run Migrations (in order)
|
+-- Create core tables (apps, routes, devices, proposals)
+-- Create health tables (service_health)
+-- Create activity tables (activity_events)
+-- Create certificate tables (certificates, certificate_history)
+-- Create API key tables (api_keys)
+-- Create notification tables (notifications)
+-- Create toolbox tables (toolbox_deployments)
+-- Create federation tables (federation_peers, federation_services)
+-- Create script tables (scripts, script_executions, workflows)
+-- Add new columns to existing tables (if needed)
+-- Create indexes
|
v
Application Ready

Current Schema Tables​

TablePurposeAdded In
appsApplication catalogv0.1.0
routesProxy route definitionsv0.1.0
devicesPaired mobile devicesv0.1.0
proposalsDiscovery proposalsv0.1.0
service_healthService health statusv0.2.0
activity_eventsActivity feedv0.3.0
certificatesTLS certificate storagev0.4.0
certificate_historyCertificate audit logv0.4.0
api_keysAPI key managementv0.5.0
notificationsPush notificationsv0.6.0
request_logsRequest analyticsv0.6.0
audit_logsSecurity audit trailv0.6.0
toolbox_deploymentsDeployed servicesv0.7.0
federation_peersFederation cluster peersv0.8.0
federation_servicesFederated servicesv0.8.0
system_secretsAuto-generated secretsv0.9.0
proxy_session_cookiesWebView cookie persistencev0.10.0
scriptsScript definitionsv0.11.0
script_executionsScript execution historyv0.11.0
workflowsWorkflow definitionsv0.11.0
workflow_executionsWorkflow execution historyv0.11.0
script_schedulesScheduled script runsv0.11.0

Checking Migration Status​

# View current schema
sqlite3 ./data/nexus.db ".schema"

# List all tables
sqlite3 ./data/nexus.db ".tables"

# Check specific table schema
sqlite3 ./data/nexus.db ".schema devices"

# View row counts
sqlite3 ./data/nexus.db "SELECT 'apps', COUNT(*) FROM apps UNION ALL SELECT 'routes', COUNT(*) FROM routes UNION ALL SELECT 'devices', COUNT(*) FROM devices;"

Manual Recovery (Emergency)​

If automatic migration fails, you can inspect and fix the database manually:

# Backup first
cp ./data/nexus.db ./data/nexus.db.backup

# Connect to database
sqlite3 ./data/nexus.db

# View current schema
.schema

# Check for issues
PRAGMA integrity_check;

# Exit
.quit
Schema Compatibility

Manual schema changes may cause issues with future upgrades. Only use manual migrations as a last resort and document any changes made.


Configuration Changes​

Reviewing Configuration Changes​

When upgrading, compare your configuration against the example:

# Download latest example config
curl -O https://raw.githubusercontent.com/nstalgic/nekzus/main/configs/config.example.yaml

# Compare with your config
diff -u configs/config.yaml configs/config.example.yaml

Deprecated Options​

The following configuration options are deprecated and will be removed in future versions:

Deprecated OptionReplacementRemoved In
toolbox.catalog_pathtoolbox.catalog_dirv2.0.0
Deprecated: toolbox.catalog_path

The YAML-based catalog (catalog_path) is deprecated in favor of Compose-based catalogs (catalog_dir).

Before (deprecated):

toolbox:
enabled: true
catalog_path: "./configs/toolbox-catalog.yaml"

After (recommended):

toolbox:
enabled: true
catalog_dir: "./toolbox"

See the Toolbox documentation for migration details.

New Configuration Options​

When upgrading, review new options that may enhance your deployment:

# Script execution (new in v0.11.0)
scripts:
enabled: false
directory: "./scripts"
default_timeout: 300
max_output_bytes: 10485760

Environment Variable Changes​

VariableStatusNotes
NEKZUS_JWT_SECRETCurrentJWT signing secret
NEKZUS_BOOTSTRAP_TOKENCurrentBootstrap token
NEKZUS_DATABASE_PATHCurrentDatabase path
NEKZUS_TOOLBOX_HOST_DATA_DIRCurrentHost data directory
NEKZUS_HOST_ROOT_PATHCurrentHost root for metrics
ENVIRONMENTCurrentSet to production for strict validation

Rollback Procedures​

If an upgrade fails, follow these rollback procedures.

Docker Rollback​

# Stop current container
docker compose stop nekzus

# Edit docker-compose.yml to use previous version
# Change: image: ghcr.io/nstalgic/nekzus:latest
# To: image: ghcr.io/nstalgic/nekzus:v1.1.0

# Start with previous version
docker compose up -d

# Verify rollback
docker compose logs nekzus | head -20

Binary Rollback​

# Stop service
sudo systemctl stop nekzus

# Restore backup binary
sudo cp /usr/local/bin/nekzus.bak /usr/local/bin/nekzus

# Restore backup database
BACKUP_DIR="/opt/nekzus/backups/20240101_120000"
sudo cp "$BACKUP_DIR/nexus.db" /opt/nekzus/data/

# Restore configuration
sudo cp "$BACKUP_DIR/config.yaml" /opt/nekzus/configs/

# Start service
sudo systemctl start nekzus

Database Rollback​

If only the database needs rollback:

# Stop service
docker compose stop nekzus # or: sudo systemctl stop nekzus

# Restore database from backup
cp ./backups/20240101_120000/nexus.db ./data/nexus.db

# Start service
docker compose up -d # or: sudo systemctl start nekzus
Schema Downgrade Warning

Rolling back to an older version after schema migrations may cause data loss or application errors. Always test rollbacks in a staging environment first.


Breaking Changes by Version​

v1.0.0 (Upcoming)​

Major Release

Version 1.0.0 will include breaking changes. Migration guides will be provided.

Planned Breaking Changes:

  • Removal of deprecated toolbox.catalog_path option
  • API response format changes for consistency
  • Configuration schema updates

Current Development (v0.x)​

No breaking changes in patch releases. Minor releases may add new features but maintain backward compatibility.


Post-Upgrade Verification​

After upgrading, verify the installation is working correctly.

Health Checks​

# Quick health check
curl https://localhost:8443/api/v1/healthz
# Expected: ok

# Detailed health check
curl -s https://localhost:8443/healthz | jq .
# Expected output includes: status, version, uptime, timestamp, components

API Verification​

# Verify routes are accessible
curl -s https://localhost:8443/api/v1/routes | jq 'length'

# Verify apps are accessible
curl -s https://localhost:8443/api/v1/apps | jq 'length'

# Verify devices are preserved
curl -s https://localhost:8443/api/v1/devices | jq 'length'

# Test proxy functionality
curl -I https://localhost:8443/apps/your-app/

Service Discovery​

# Check discovery is running
curl -s https://localhost:8443/api/v1/proposals | jq 'length'

# Verify Docker discovery (if enabled)
docker ps # Compare with discovered services

Metrics Verification​

# Check Prometheus metrics endpoint
curl -s https://localhost:8443/metrics | head -20

# Verify key metrics are present
curl -s https://localhost:8443/metrics | grep "nekzus_http_requests_total"

WebSocket Verification​

// Test WebSocket connection (browser console or wscat)
const ws = new WebSocket('wss://localhost:8443/ws');
ws.onopen = () => console.log('Connected');
ws.onmessage = (e) => console.log('Message:', e.data);
ws.onerror = (e) => console.error('Error:', e);

Log Analysis​

# Check for errors in logs
docker compose logs nekzus 2>&1 | grep -i error

# Check for migration completion
docker compose logs nekzus 2>&1 | grep -i migration

# Check for warnings
docker compose logs nekzus 2>&1 | grep -i warning

Upgrade Automation​

For automated deployments, consider these patterns:

CI/CD Pipeline Example​

.github/workflows/upgrade.yml
name: Upgrade Nekzus

on:
workflow_dispatch:
inputs:
version:
description: 'Version to upgrade to'
required: true
default: 'latest'

jobs:
upgrade:
runs-on: self-hosted
steps:
- name: Backup
run: |
BACKUP_DIR="/opt/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp /opt/nekzus/data/nexus.db "$BACKUP_DIR/"
cp /opt/nekzus/configs/config.yaml "$BACKUP_DIR/"

- name: Pull new image
run: docker pull ghcr.io/nstalgic/nekzus:${{ inputs.version }}

- name: Upgrade
run: |
cd /opt/nekzus
docker compose up -d

- name: Verify
run: |
sleep 10
curl -f https://localhost:8443/api/v1/healthz || exit 1

- name: Rollback on failure
if: failure()
run: |
cd /opt/nekzus
docker compose down
# Restore from backup
cp /opt/backups/$(ls -t /opt/backups | head -1)/nexus.db /opt/nekzus/data/
docker compose up -d

Pre-Upgrade Script​

scripts/pre-upgrade.sh
#!/bin/bash
set -euo pipefail

# Pre-upgrade checks and backup
BACKUP_DIR="./backups/pre-upgrade-$(date +%Y%m%d_%H%M%S)"

echo "Creating backup at $BACKUP_DIR..."
mkdir -p "$BACKUP_DIR"

# Backup data
cp ./data/nexus.db "$BACKUP_DIR/" 2>/dev/null || true
cp ./configs/config.yaml "$BACKUP_DIR/" 2>/dev/null || true
cp -r ./certs "$BACKUP_DIR/" 2>/dev/null || true

# Export current state
curl -sf https://localhost:8443/api/v1/routes > "$BACKUP_DIR/routes.json" || true
curl -sf https://localhost:8443/api/v1/apps > "$BACKUP_DIR/apps.json" || true

# Health check
if curl -sf https://localhost:8443/api/v1/healthz > /dev/null; then
echo "Current instance is healthy"
else
echo "WARNING: Current instance may not be healthy"
fi

echo "Pre-upgrade backup complete: $BACKUP_DIR"

Getting Help​

If you encounter issues during upgrade:

  1. Check Logs: Review application logs for error messages
  2. GitHub Issues: Search or open an issue at github.com/nstalgic/nekzus/issues
  3. Rollback: Use the rollback procedures if the upgrade fails
  4. Community: Join discussions in GitHub Discussions
Include Version Information

When reporting upgrade issues, include:

  • Previous version
  • Target version
  • Error messages from logs
  • Configuration file (sanitized)
  • Platform (Docker, Linux, macOS, etc.)