{"id":50171809,"url":"https://github.com/zinthose/proxmox-technitium-sync","last_synced_at":"2026-05-24T23:38:12.469Z","repository":{"id":339802695,"uuid":"1163388291","full_name":"zinthose/proxmox-technitium-sync","owner":"zinthose","description":"Automated DNS sync from Proxmox to Technitium - Docker service with CI/CD automation","archived":false,"fork":false,"pushed_at":"2026-03-08T03:06:20.000Z","size":55,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T23:38:11.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zinthose.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY_AUDIT_REPORT.md","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":"2026-02-21T15:00:11.000Z","updated_at":"2026-05-06T16:10:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zinthose/proxmox-technitium-sync","commit_stats":null,"previous_names":["zinthose/proxmox-technitium-sync"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zinthose/proxmox-technitium-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zinthose%2Fproxmox-technitium-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zinthose%2Fproxmox-technitium-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zinthose%2Fproxmox-technitium-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zinthose%2Fproxmox-technitium-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zinthose","download_url":"https://codeload.github.com/zinthose/proxmox-technitium-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zinthose%2Fproxmox-technitium-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33455025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-24T19:21:36.376Z","status":"ssl_error","status_checked_at":"2026-05-24T19:21:10.562Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-05-24T23:38:11.829Z","updated_at":"2026-05-24T23:38:12.451Z","avatar_url":"https://github.com/zinthose.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proxmox to Technitium DNS Sync\n\n## Automatically sync Proxmox VM and LXC container IP addresses to Technitium DNS\n\nA lightweight, production-ready Docker service that polls your Proxmox cluster every ~60 seconds and automatically registers active LXC and VM guest IP addresses as A records in your Technitium DNS zone. Perfect for dynamic infrastructure where VMs/containers are frequently created/destroyed.\n\n## Features\n\n- ✅ **Automated polling**: Syncs every 60 seconds (configurable)\n- ✅ **Token-based authentication**: Works with Proxmox API tokens (recommended) or password auth\n- ✅ **Idempotent syncing**: Safe to run 24/7; uses `overwrite=true` for automatic deduplication\n- ✅ **Retry logic**: Exponential backoff for transient API failures\n- ✅ **Lightweight**: Alpine-based, ~50MB footprint, runs as non-root user\n- ✅ **Health checks**: Built-in container health status\n- ✅ **Structured logging**: DEBUG and INFO levels for troubleshooting\n- ✅ **Security hardened**: SSL verification, input validation, rate limiting\n\n## Quick Start\n\n### Docker\n\n```bash\ndocker run -d \\\n  --name proxmox-technitium-sync \\\n  -e PROXMOX_HOST=pve-01.proxmox.local \\\n  -e PROXMOX_USER=root \\\n  -e PROXMOX_TOKEN_NAME=dns-sync \\\n  -e PROXMOX_TOKEN_VALUE=your-token-value \\\n  -e TECHNITIUM_URL=http://10.0.99.14:5380 \\\n  -e TECHNITIUM_TOKEN=your-technitium-token \\\n  -e ZONE=zinthose.pve \\\n  -e POLL_INTERVAL=60 \\\n  --restart unless-stopped \\\n  mcr-gitlab/proxmox-technitium-sync:latest\n```\n\n### Docker Compose\n\n```yaml\nversion: '3.8'\nservices:\n  proxmox-sync:\n    image: mcr-gitlab/proxmox-technitium-sync:latest\n    restart: unless-stopped\n    environment:\n      PROXMOX_HOST: pve-01.proxmox.local\n      PROXMOX_USER: root\n      PROXMOX_TOKEN_NAME: dns-sync\n      PROXMOX_TOKEN_VALUE: ${PROXMOX_TOKEN}\n      TECHNITIUM_URL: http://10.0.99.14:5380\n      TECHNITIUM_TOKEN: ${TECHNITIUM_TOKEN}\n      ZONE: zinthose.pve\n      POLL_INTERVAL: 60\n```\n\n## Configuration\n\n### Required Environment Variables\n\n| Variable | Description | Example |\n| -------- | ----------- | ------- |\n| `PROXMOX_HOST` | Proxmox server hostname or IP | `pve-01.proxmox.local` |\n| `PROXMOX_USER` | Proxmox username | `root` |\n| `PROXMOX_TOKEN_NAME` | API token name | `dns-sync` |\n| `PROXMOX_TOKEN_VALUE` | API token secret | (see creating tokens below) |\n| `TECHNITIUM_URL` | Technitium DNS server URL | `http://10.0.99.14:5380` |\n| `TECHNITIUM_TOKEN` | Technitium API token | (see creating tokens below) |\n| `ZONE` | DNS zone to manage | `zinthose.pve` |\n\n### Optional Environment Variables\n\n| Variable | Description | Default |\n| -------- | ----------- | ------- |\n| `PROXMOX_REALM` | Proxmox auth realm | `pam` |\n| `POLL_INTERVAL` | Sync interval in seconds | `60` |\n| `DEBUG` | Enable debug logging | `false` |\n\n### Creating a Proxmox API Token\n\n1. Log in to Proxmox Web UI\n2. Go to **Datacenter → Permissions → API Tokens**\n3. Click **Add**\n4. Fill in:\n   - **User**: `root@pam`\n   - **Token ID**: Give it a memorable name (e.g., `dns-sync`)\n   - **Expire**: Set an expiration date or leave empty for no expiration\n5. Click **Add** and **immediately copy the token value** (you won't see it again!)\n6. Grant the token the necessary permissions:\n   - **Datacenter → Permissions → Add** (or edit existing role)\n   - Assign role with at least: **Vm.Audit**, **Nodes.Audit**\n\n### Creating a Technitium API Token\n\n1. Log in to Technitium Web Console\n2. Go to **Settings → API**\n3. Create a new API token with appropriate permissions\n4. Copy the token and add it to your environment\n\n### Environment File Setup\n\nCreate a `.env` file:\n\n```bash\ncp .env.example .env  # Copy the template\n# Edit .env with your credentials\ndocker run --env-file .env proxmox-technitium-sync:latest\n```\n\n⚠️ **Security**: Never commit your `.env` file to version control!\n\n## Monitoring \u0026 Logs\n\nCheck container status:\n\n```bash\ndocker ps --filter name=proxmox-technitium-sync\ndocker logs proxmox-technitium-sync\n```\n\nExpected logs show:\n\n```log\nSuccessfully authenticated with Proxmox\nPoll cycle 1: Synced 11 records\nPoll cycle 2: Synced 11 records\n```\n\nIf records aren't syncing:\n\n1. Verify API tokens are correct\n2. Check Proxmox token has **Vm.Audit** and **Nodes.Audit** permissions\n3. Enable `DEBUG=true` environment variable for detailed logging\n4. Run `docker logs proxmox-technitium-sync` and look for error messages\n\n## Automated Deployments (Optional)\n\nThis project includes GitHub Actions CI/CD workflows that automatically build and push Docker images to Docker Hub when you push to main or create tagged releases.\n\nSee [DOCKER_HUB_SETUP.md](DOCKER_HUB_SETUP.md) for automated deployment configuration.\n\n---\n\n## Development\n\n### Directory Structure\n\n```text\nproxmox-technitium-sync/\n├── README.md               # This file\n├── Dockerfile              # Alpine-based container definition\n├── requirements.txt        # Python dependencies\n├── .env.example            # Sample environment configuration\n├── src/\n│   ├── __init__.py\n│   ├── core.py             # Functional Core: Pure data models and mapping logic\n│   └── main.py             # Imperative Shell: Proxmox/Technitium API interactions\n├── tests/\n│   ├── __init__.py\n│   └── test_core.py        # Pytest suite for Functional Core\n├── .github/\n│   └── workflows/\n│       └── docker-build-push.yml  # GitHub Actions CI/CD\n└── docs/\n    ├── DOCKER_HUB_SETUP.md        # Automated deployment guide\n    └── SECURITY.md                 # Security audit trail\n```\n\n### Architecture\n\nBuilt using **Functional Core / Imperative Shell** architecture:\n\n- **Functional Core** (`src/core.py`): Pure, side-effect-free data validation and mapping\n  - No external dependencies or API calls\n  - 100% deterministic and testable\n  - Immutable dataclasses for data models\n  \n- **Imperative Shell** (`src/main.py`): Orchestrates API interactions\n  - Calls the Functional Core for validation\n  - Handles Proxmox and Technitium API communication\n  - Manages polling loop and error handling\n\n### Local Development\n\nInstall dependencies and run locally:\n\n```bash\npip install -r requirements.txt\nsource .env  # Load environment variables\npython src/main.py\n```\n\n### Testing\n\nRun the test suite:\n\n```bash\npip install -r requirements.txt\npytest tests/ -v\n```\n\nAll 9 tests should pass. Tests focus on the Functional Core to ensure data mapping logic is correct and predictable.\n\n### Building the Docker Image Locally\n\n```bash\ndocker build -t proxmox-dns-sync:dev .\ndocker run -d --name test-sync --env-file .env proxmox-dns-sync:dev\ndocker logs test-sync\n```\n\n## Security\n\nThis project prioritizes security with multiple layers of protection:\n\n- ✅ **Input Validation**: Strict hostname and IP address validation\n- ✅ **SSL/TLS**: SSL verification enabled by default\n- ✅ **Rate Limiting**: Minimum 10-second poll interval prevents API flooding\n- ✅ **Secure Authentication**: Token-based API authentication (no hardcoded credentials)\n- ✅ **Audit Logging**: Structured logs track all DNS modifications\n- ✅ **Container Hardening**: Non-root user, Alpine base, health checks\n\n**Latest Security Audit:** See [SECURITY_AUDIT_REPORT.md](SECURITY_AUDIT_REPORT.md)\n\nStatus: ✅ No known vulnerabilities (0 CVEs in direct dependencies)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n### What This Means\n\nYou're free to:\n\n- ✅ Use commercially\n- ✅ Modify and distribute\n- ✅ Use privately\n- ✅ Create derivative works\n\nNo warranty is provided. See [LICENSE](LICENSE) for the full legal text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzinthose%2Fproxmox-technitium-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzinthose%2Fproxmox-technitium-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzinthose%2Fproxmox-technitium-sync/lists"}