{"id":48848430,"url":"https://github.com/trick77/docker-observium","last_synced_at":"2026-04-15T06:12:50.588Z","repository":{"id":214393692,"uuid":"736406448","full_name":"trick77/docker-observium","owner":"trick77","description":"A containerized Observium network monitoring platform","archived":false,"fork":false,"pushed_at":"2026-01-11T14:39:47.000Z","size":296,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-09T05:21:00.819Z","etag":null,"topics":["compose","docker","docker-compose","network-monitoring","observium","snmp"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trick77.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-27T20:21:28.000Z","updated_at":"2026-01-11T14:39:50.000Z","dependencies_parsed_at":"2024-12-15T16:37:21.910Z","dependency_job_id":null,"html_url":"https://github.com/trick77/docker-observium","commit_stats":null,"previous_names":["trick77/docker-observium"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/trick77/docker-observium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trick77%2Fdocker-observium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trick77%2Fdocker-observium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trick77%2Fdocker-observium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trick77%2Fdocker-observium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trick77","download_url":"https://codeload.github.com/trick77/docker-observium/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trick77%2Fdocker-observium/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31828584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"online","status_checked_at":"2026-04-15T02:00:06.175Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compose","docker","docker-compose","network-monitoring","observium","snmp"],"created_at":"2026-04-15T06:12:48.672Z","updated_at":"2026-04-15T06:12:50.572Z","avatar_url":"https://github.com/trick77.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docker-observium\n\n[![Docker build](https://github.com/trick77/docker-observium/actions/workflows/build-images.yaml/badge.svg)](https://github.com/trick77/docker-observium/actions/workflows/build-images.yaml)\n\nProduction-ready Docker deployment of [Observium](https://www.observium.org/) Community Edition with MariaDB, Smokeping latency monitoring, and automated scheduling.\n\n![Observium screenshot](/screenshot.png?raw=true)\n\n## Overview\n\nThis project provides a containerized Observium Community Edition 24.12 network monitoring platform with:\n\n- **Auto-provisioned infrastructure**: MariaDB database, Apache web server, Smokeping integration\n- **Environment-driven configuration**: Configure Observium via `.env` file - automatically translated to PHP config\n- **Container-native operations**: Logging to stdout/stderr, graceful shutdown handling, health checks\n- **Automated scheduling**: Container-based job scheduler (Ofelia) replaces traditional cron\n- **Data protection**: Automated daily backups of database and RRD files\n- **Production-ready**: Race condition prevention, configurable timeouts, retry logic\n\n## Features\n\n- **Dynamic PHP Configuration**: Generate Observium config.php from environment variables with automatic type conversion (boolean, integer, string)\n- **Container-Based Scheduling**: Ofelia job scheduler handles discovery, polling, housekeeping, and backups\n- **Centralized Logging**: All services log to stdout/stderr for easy monitoring with `docker compose logs`\n- **Automated Backups**: Daily backups of database and RRD files, automatically retains last 10\n- **Smokeping Integration**: Built-in latency monitoring with automatic config generation\n- **Graceful Shutdown**: Proper SIGTERM handling for clean container stops\n- **Database Safety**: Initialization locking prevents race conditions when scaling\n- **Configurable Timeouts**: Database connection timeout and config generation retry logic\n- **Enhanced Observability**: Startup messages show config processing, warnings, and errors\n\n## Architecture\n\n### Services\n\n- **httpd**: Observium web interface and backend (Apache + PHP 8.2)\n- **mariadb**: MySQL-compatible database (MariaDB 11)\n- **smokeping**: Network latency monitoring\n- **ofelia**: Container-based job scheduler\n\n### Volumes\n\n- `observium-rrd`: RRD graph databases (persistent)\n- `observium-logs`: Application logs\n- `observium-db`: MariaDB data files\n- `smokeping-data`: Smokeping RRD files\n- `smokeping-config`: Smokeping configuration\n\n### Initialization Sequence\n\n1. **Database check**: Wait for MariaDB to be ready (configurable timeout)\n2. **Config generation**: Create PHP config from environment variables\n3. **Schema initialization**: If database is empty, create tables and admin user (with distributed locking)\n4. **Device import**: Import SNMP devices from `snmp-devices.txt` if present\n5. **Smokeping config**: Generate Targets configuration\n6. **Start services**: Launch Apache and Smokeping\n\n## Prerequisites\n\n- Docker Engine 20.10+\n- Docker Compose 2.0+\n- SNMP-enabled devices to monitor\n- (Optional) Observium Unix agent deployed on monitored systems\n\n## Quick Start\n\n```bash\n# 1. Clone repository\ngit clone https://github.com/trick77/docker-observium.git\ncd docker-observium\n\n# 2. Configure environment\ncp .env.example .env\n# Edit .env and set:\n#   - MARIADB_ROOT_PASSWORD\n#   - DB_PASSWORD\n#   - OBSERVIUM_ADMIN_PASSWORD\n#   - OBSERVIUM_FQDN\n\n# 3. (Optional) Add SNMP devices to import on first startup\ncp observium/conf/snmp-devices.txt.example observium/conf/snmp-devices.txt\n# Edit snmp-devices.txt with your devices\n\n# 4. Start services\ndocker compose up -d\n\n# 5. Monitor startup (wait for \"Successfully connected to database!\")\ndocker compose logs -f httpd\n\n# 6. Access web interface\n# Navigate to: https://\u003cOBSERVIUM_FQDN\u003e\n# Login: admin / \u003cOBSERVIUM_ADMIN_PASSWORD\u003e\n```\n\nFirst startup takes 2-3 minutes for database initialization. Subsequent startups are faster.\n\n## Configuration\n\n### Core Environment Variables\n\nEdit `.env` to configure the deployment:\n\n| Variable | Description | Default |\n| -------- | ----------- | ------- |\n| `MARIADB_ROOT_PASSWORD` | MariaDB root password | `changeme` |\n| `DB_NAME` | Database name | `observium` |\n| `DB_USER` | Database user | `observium` |\n| `DB_PASSWORD` | Database password | `changeme` |\n| `OBSERVIUM_ADMIN_USER` | Web UI admin username | `admin` |\n| `OBSERVIUM_ADMIN_PASSWORD` | Web UI admin password | `changeme` |\n| `OBSERVIUM_FQDN` | Fully qualified domain name | `changeme.foobar.com` |\n| `DB_CONNECTION_TIMEOUT` | Database connection timeout (seconds) | `60` |\n| `DEBUG_MODE` | Enable debug logging | `false` |\n| `SHOW_GENERATED_CONFIG_DURING_STARTUP` | Show config in logs (⚠️ exposes secrets) | `yes` |\n| `TZ` | Container timezone | `Europe/Berlin` |\n\n### Observium Configuration Mapping\n\nConfigure Observium settings by adding environment variables with the `OBSERVIUM__` prefix to `.env`. These are automatically translated to PHP configuration at container startup.\n\n#### Mapping Rules\n\n| Pattern | Description | Example |\n| ------- | ----------- | ------- |\n| `OBSERVIUM__key` | Simple value | `OBSERVIUM__base_url=https://obs.example.com` → `$config['base_url']` |\n| `OBSERVIUM__key1__key2` | Nested array | `OBSERVIUM__ping__retries=5` → `$config['ping']['retries']` |\n| `OBSERVIUM__key___name` | Dash in key name | `OBSERVIUM__unix___agent__port=6556` → `$config['unix-agent']['port']` |\n| `OBSERVIUM__key__0` | Indexed array | `OBSERVIUM__bad_if__0=docker0` → `$config['bad_if'][0]` |\n\n#### Type Conversion\n\nValues are automatically converted to appropriate PHP types:\n\n- `true` / `false` → PHP boolean (`TRUE` / `FALSE`)\n- Numeric strings → PHP integers\n- Strings with leading zeros → Kept as strings (e.g., `007`)\n- All other values → PHP strings\n\n#### Example Configuration\n\n```env\n# Web interface\nOBSERVIUM__base_url=https://${OBSERVIUM_FQDN}\nOBSERVIUM__web_mouseover=false\nOBSERVIUM__web_show_locations=1\n\n# Polling\nOBSERVIUM__ping__retries=5\nOBSERVIUM__poller___wrapper__threads=2\n\n# Interface filtering (ignore these)\nOBSERVIUM__bad_if__0=docker0\nOBSERVIUM__bad_if__1=lo\nOBSERVIUM__bad_if_regexp__0='/^veth.*/'\nOBSERVIUM__bad_if_regexp__1='/^br-.*/'\n\n# Email notifications\nOBSERVIUM__email__enable=true\nOBSERVIUM__email__backend=smtp\nOBSERVIUM__email__smtp_host=smtp.example.com\nOBSERVIUM__email__smtp_port=587\n```\n\nTranslates to:\n\n```php\n$config['base_url'] = 'https://observium.example.com';\n$config['web_mouseover'] = FALSE;\n$config['web_show_locations'] = 1;\n$config['ping']['retries'] = 5;\n$config['poller-wrapper']['threads'] = 2;\n$config['bad_if'][0] = 'docker0';\n$config['bad_if'][1] = 'lo';\n$config['bad_if_regexp'][0] = '/^veth.*/';\n$config['bad_if_regexp'][1] = '/^br-.*/';\n$config['email']['enable'] = TRUE;\n$config['email']['backend'] = 'smtp';\n$config['email']['smtp_host'] = 'smtp.example.com';\n$config['email']['smtp_port'] = 587;\n```\n\n#### Validation\n\nDuring startup, the config generator reports:\n\n```text\nINFO: Processing 45 OBSERVIUM__ environment variables\nConfiguration generated successfully!\n```\n\nTo debug configuration mapping, set `SHOW_GENERATED_CONFIG_DURING_STARTUP=yes` in `.env` and check container logs. **Warning**: This exposes database credentials in logs.\n\nYou can also view the final configuration in Observium's web UI under **Global Settings** \u003e **Full dump** or **Changed dump**.\n\n### SNMP Device Import\n\nAdd devices to monitor by creating `observium/conf/snmp-devices.txt`:\n\n```text\n# Format: hostname|community|v2c|port|transport|description\n192.168.1.1|public|v2c|161|udp|Router\n192.168.1.10|secret|v2c|161|udp|Switch\n```\n\nDevices are automatically imported on container startup. Check logs:\n\n```bash\ndocker compose logs httpd | grep \"Importing SNMP devices\"\n```\n\nTo add devices after initial startup:\n\n```bash\n# Restart container to trigger import\ndocker compose restart httpd\n\n# Or add manually via web UI: Devices \u003e Add Device\n```\n\n## Scheduled Jobs\n\nOfelia scheduler manages background tasks:\n\n| Job | Schedule | Description |\n| --- | -------- | ----------- |\n| **discover-all** | Every 6 hours | Full discovery of all devices |\n| **discover-new** | Every 5 minutes | Discover new devices |\n| **poll** | Every 5 minutes | Poll all devices for metrics |\n| **cleanup-logs** | Daily at 05:13 | Clean up old log entries |\n| **cleanup-rrds** | Daily at 04:47 | Clean up old RRD files |\n| **smokeping-config** | Every 5 minutes | Regenerate Smokeping targets |\n| **backup-rrd** | Daily | Backup RRD and Smokeping data |\n| **backup-db** | Daily | Backup MariaDB database |\n\nBackups are stored in `/backup/destination/` inside the container. The most recent 10 backups are retained.\n\nTo persist backups, map a host directory:\n\n```yaml\n# compose.override.yaml\nservices:\n  httpd:\n    volumes:\n      - ./backups:/backup/destination\n```\n\n## Monitoring \u0026 Logs\n\n### View Logs\n\n```bash\n# All services\ndocker compose logs -f\n\n# Specific service\ndocker compose logs -f httpd\ndocker compose logs -f mariadb\ndocker compose logs -f smokeping\n\n# Filter by message type\ndocker compose logs httpd | grep \"INFO:\"\ndocker compose logs httpd | grep \"WARNING:\"\ndocker compose logs httpd | grep \"ERROR:\"\n\n# Follow startup sequence\ndocker compose logs -f httpd | grep -E \"(Attempt|Successfully|generated|initialized)\"\n```\n\n### Health Checks\n\nCheck service status:\n\n```bash\n# Service overview\ndocker compose ps\n\n# Detailed health status\ndocker compose ps httpd\n\n# MariaDB ready check\ndocker compose exec mariadb mariadb -uroot -p${MARIADB_ROOT_PASSWORD} -e \"SELECT 1\"\n```\n\n### Container Resource Usage\n\n```bash\n# CPU and memory usage\ndocker stats\n\n# Disk usage\ndocker compose exec httpd du -sh /opt/observium/rrd\ndocker compose exec mariadb du -sh /var/lib/mysql\n```\n\n## Troubleshooting\n\n### Container Won't Start\n\n**Symptoms**: Container exits immediately after startup\n\n**Diagnosis**:\n\n```bash\ndocker compose logs httpd | grep ERROR\n```\n\n**Common Causes**:\n\n- **Missing environment variables**: Check for `ERROR: Required environment variable ... is not set`\n  - Solution: Ensure `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `OBSERVIUM_ADMIN_USER`, and `OBSERVIUM_ADMIN_PASSWORD` are set in `.env`\n\n- **Database connection failure**: Check for `ERROR: Failed to connect to database after 60 attempts`\n  - Solution: Verify MariaDB is running: `docker compose ps mariadb`\n  - Solution: Increase timeout: `DB_CONNECTION_TIMEOUT=120` in `.env`\n\n- **Configuration generation failure**: Check for `ERROR: Failed to generate configuration after 3 attempts`\n  - Solution: Check Python script syntax: `docker compose run --rm httpd python3 /usr/local/bin/generate_config.py`\n\n### Database Initialization Fails\n\n**Symptoms**: `ERROR: Database still not initialized and lock acquisition failed`\n\n**Cause**: Multiple containers trying to initialize simultaneously (race condition)\n\n**Solution**:\n\n1. Stop all containers: `docker compose down`\n2. Remove database volume: `docker volume rm docker-observium_observium-db`\n3. Start single httpd instance: `docker compose up httpd`\n4. Wait for \"Database initialization complete\"\n5. Start remaining services: `docker compose up -d`\n\n### Smokeping Not Working\n\n**Diagnosis**:\n\n```bash\n# Check if Targets file exists\ndocker compose exec smokeping cat /etc/smokeping/config.d/Targets\n\n# Check smokeping logs\ndocker compose logs smokeping\n\n# Verify smokeping process\ndocker compose exec smokeping ps aux | grep smokeping\n```\n\n**Common Issues**:\n\n- **Empty Targets file**: No devices configured for Smokeping\n  - Solution: Add devices in Observium UI, wait 5 minutes for config regeneration\n\n- **Smokeping not running**: Check for startup errors\n  - Solution: Restart: `docker compose restart smokeping`\n\n### Configuration Changes Not Applied\n\n**Symptoms**: Changed `.env` but Observium still uses old config\n\n**Solution**:\n\n```bash\n# Restart container to regenerate config\ndocker compose restart httpd\n\n# Verify config regeneration in logs\ndocker compose logs httpd | grep \"Configuration generated\"\n\n# View generated config (⚠️ contains secrets)\nSHOW_GENERATED_CONFIG_DURING_STARTUP=yes docker compose up httpd\n```\n\n### Web Interface Shows Blank Page\n\n**Diagnosis**:\n\n```bash\n# Check Apache logs\ndocker compose logs httpd | grep -E \"(error|Error|ERROR)\"\n\n# Check PHP errors\ndocker compose exec httpd cat /var/log/apache2/error.log\n\n# Verify database connection\ndocker compose exec httpd mariadb -u${DB_USER} -p${DB_PASSWORD} -h mariadb ${DB_NAME} -e \"SHOW TABLES\"\n```\n\n**Common Causes**:\n\n- **Database not initialized**: No tables in database\n  - Solution: Check initialization logs: `docker compose logs httpd | grep initialization`\n\n- **Wrong base_url**: Config doesn't match accessed URL\n  - Solution: Set correct `OBSERVIUM__base_url` in `.env`\n\n## Upgrading\n\nTo upgrade to a newer version of Observium:\n\n### 1. Backup Current Data\n\n```bash\n# Create backup directory\nmkdir -p backups/$(date +%Y%m%d)\n\n# Backup database\ndocker compose exec mariadb mariadb-dump -uroot -p${MARIADB_ROOT_PASSWORD} ${DB_NAME} | gzip \u003e backups/$(date +%Y%m%d)/db_backup.sql.gz\n\n# Backup RRD files\ndocker compose exec httpd tar czf /tmp/rrd_backup.tar.gz /opt/observium/rrd\ndocker compose cp httpd:/tmp/rrd_backup.tar.gz backups/$(date +%Y%m%d)/rrd_backup.tar.gz\n```\n\n### 2. Update Repository\n\n```bash\ngit pull origin master\n```\n\n### 3. Rebuild Images\n\n```bash\ndocker compose build --no-cache\n```\n\n### 4. Restart Services\n\n```bash\ndocker compose down\ndocker compose up -d\n```\n\n### 5. Verify Upgrade\n\n```bash\n# Check version\ndocker compose logs httpd | grep \"VERSION:\"\n\n# Watch for migration messages\ndocker compose logs -f httpd\n\n# Verify web interface loads\ncurl -I https://${OBSERVIUM_FQDN}\n```\n\n## Development\n\n### Project Scope\n\nThis project is optimized for specific monitoring needs and intentionally excludes:\n\n- RANCID integration\n- CollectD support\n- rrdcached\n- ARM64 support\n\n**Pull Requests**: Bugfix PRs are welcome. Feature requests will be considered on a case-by-case basis.\n\n### Recent Improvements\n\n**Version 24.12** (Current)\n\n- Updated to Observium Community Edition 24.12\n- **Security**: Replaced `eval` with safe indirect expansion\n- **Reliability**: Database initialization locking prevents race conditions\n- **Observability**: Enhanced logging with INFO/WARNING/ERROR messages\n- **Containers**: Graceful shutdown handling (SIGTERM)\n- **Configuration**: Improved type conversion and validation\n- **Error Handling**: Retry logic for config generation\n\n### Building Locally\n\n```bash\n# Build all images\ndocker compose build\n\n# Build specific service\ndocker compose build httpd\n\n# Build without cache\ndocker compose build --no-cache\n\n# Test build\ndocker compose up -d\ndocker compose logs -f\n```\n\n## Contributing\n\nFound a bug? Please [open an issue](https://github.com/trick77/docker-observium/issues).\n\n## License\n\n[MIT License](LICENSE) - See LICENSE file for details\n\n## Acknowledgments\n\n- [Observium](https://www.observium.org/) - Network monitoring platform\n- [Ofelia](https://github.com/mcuadros/ofelia) - Docker job scheduler\n- [Smokeping](https://oss.oetiker.ch/smokeping/) - Latency monitoring\n- All contributors to this project\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrick77%2Fdocker-observium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrick77%2Fdocker-observium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrick77%2Fdocker-observium/lists"}