Skip to content

feat: Hot reload of confd.toml main configuration file #343

@abtreece

Description

@abtreece

Summary

Enable reloading confd's own configuration file without restarting the process, allowing dynamic reconfiguration.

Motivation

Currently, changing confd configuration requires:

  1. Edit confd.toml
  2. Restart confd process
  3. Brief gap in configuration management

For long-running confd instances, this creates unnecessary downtime and operational complexity.

Proposed Implementation

Reload Trigger

# Via signal
kill -SIGHUP $(pidof confd)

# Via admin endpoint (if metrics server enabled)
curl -X POST http://localhost:9100/reload

# Via file watch (optional)
confd --watch-config

Reloadable Settings

Setting Reloadable Notes
interval ✅ Yes Takes effect next cycle
log_level ✅ Yes Immediate
template resources (conf.d/) ✅ Yes Add/remove/modify templates
prefix ✅ Yes Re-fetch keys
backend type ❌ No Requires restart
backend address ⚠️ Partial Reconnects if changed
watch mode ❌ No Requires restart

Reload Sequence

SIGHUP received
    │
    ▼
┌─────────────────────────┐
│ 1. Parse new config     │
│    (validate first)     │
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│ 2. Diff with current    │
│    configuration        │
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│ 3. Apply reloadable     │
│    changes              │
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│ 4. Reload template      │
│    resources            │
└─────────────────────────┘
    │
    ▼
┌─────────────────────────┐
│ 5. Log applied changes  │
└─────────────────────────┘

Template Resource Hot Reload

# Add new template resource
cp new-service.toml /etc/confd/conf.d/
kill -SIGHUP $(pidof confd)
# New template is picked up

# Modify existing template resource
vim /etc/confd/conf.d/nginx.toml
kill -SIGHUP $(pidof confd)
# Changes take effect

# Remove template resource
rm /etc/confd/conf.d/old-service.toml
kill -SIGHUP $(pidof confd)
# Template is unloaded, watches stopped

Configuration Validation

Before applying reload:

func (c *Config) ValidateReload(new *Config) error {
    // Check for incompatible changes
    if c.Backend != new.Backend {
        return errors.New("backend type cannot be changed via reload")
    }
    
    // Validate new template resources
    for _, r := range new.TemplateResources {
        if err := r.Validate(); err != nil {
            return fmt.Errorf("template %s: %w", r.Src, err)
        }
    }
    
    return nil
}

Automatic Config Watching

[confd]
# Watch confd.toml for changes and auto-reload
watch_config = true

# Debounce config file changes
config_reload_debounce = "2s"

Status Reporting

INFO: Received SIGHUP, reloading configuration
INFO: Configuration validated successfully
INFO: Applied changes:
INFO:   - log_level: info -> debug
INFO:   - interval: 600 -> 300
INFO:   - Added template resource: new-service.toml
INFO:   - Modified template resource: nginx.toml
INFO:   - Removed template resource: old-service.toml
INFO: Configuration reload complete

Failed Reload Handling

If reload fails:

  1. Log detailed error message
  2. Keep running with existing configuration
  3. Set error metric/status for monitoring
  4. Return non-zero from admin endpoint
ERROR: Configuration reload failed: template new-service.toml: src file not found
ERROR: Keeping existing configuration

Benefits

  • Zero-downtime configuration changes
  • Dynamic template resource management
  • Log level changes for debugging
  • Interval tuning without restart
  • Reduced operational overhead

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions