{"id":43640436,"url":"https://github.com/ruben-sprengel/vigil-cd","last_synced_at":"2026-02-04T18:03:04.954Z","repository":{"id":328071518,"uuid":"1106264864","full_name":"ruben-sprengel/vigil-cd","owner":"ruben-sprengel","description":"VigilCD is a lightweight GitOps deployment agent that automatically monitors Git repositories and performs Docker Compose deployments on changes. Built for self-hosted environments with support for private repositories and Docker registries.","archived":false,"fork":false,"pushed_at":"2025-12-22T07:54:50.000Z","size":443,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-23T18:58:55.464Z","etag":null,"topics":["deployment","docker","docker-compose","fastapi","gitops","selfhosted"],"latest_commit_sha":null,"homepage":"","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/ruben-sprengel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"ko_fi":"rubensprengel"}},"created_at":"2025-11-28T23:04:25.000Z","updated_at":"2025-12-22T07:54:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ruben-sprengel/vigil-cd","commit_stats":null,"previous_names":["ruben-sprengel/vigil-cd"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/ruben-sprengel/vigil-cd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruben-sprengel%2Fvigil-cd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruben-sprengel%2Fvigil-cd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruben-sprengel%2Fvigil-cd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruben-sprengel%2Fvigil-cd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ruben-sprengel","download_url":"https://codeload.github.com/ruben-sprengel/vigil-cd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruben-sprengel%2Fvigil-cd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29092732,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"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":["deployment","docker","docker-compose","fastapi","gitops","selfhosted"],"created_at":"2026-02-04T18:03:02.122Z","updated_at":"2026-02-04T18:03:04.944Z","avatar_url":"https://github.com/ruben-sprengel.png","language":"Python","funding_links":["https://ko-fi.com/rubensprengel"],"categories":[],"sub_categories":[],"readme":"# VigilCD - GitOps Deployment Agent\n\n**VigilCD** is a lightweight GitOps deployment agent that automatically monitors Git repositories and performs Docker Compose deployments on changes. Built for self-hosted environments with support for private repositories and Docker registries.\n\n[![VigilCD CI Checks](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/vigilcd-ci.yml/badge.svg?branch=main)](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/vigilcd-ci.yml)\n[![VigilCD image build](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/vigilcd-image-build.yml/badge.svg?\u0026event=release)](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/vigilcd-image-build.yml)\n[![trivy-scan](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/trivy-scan.yml/badge.svg)](https://github.com/ruben-sprengel/vigil-cd/actions/workflows/trivy-scan.yml)\n\n[![Python 3.14](https://img.shields.io/badge/python-3.14-blue.svg?logo=python\u0026logoColor=white)](https://www.python.org/downloads/)\n[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty)\n[![pytest](https://img.shields.io/badge/pytest-green.svg?logo=pytest\u0026logoColor=white)](https://github.com/pytest-dev/pytest)\n\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/rubensprengel)\n\n## 🎯 Features\n\n- ✅ **Automatic Git Sync** - Periodic polling or webhook-based\n- ✅ **Parallel Processing** - Independent jobs per repo/branch for maximum performance\n- ✅ **Multi-Repository** - Manage multiple repos and branches simultaneously\n- ✅ **SSH \u0026 HTTPS Auth** - Private GitHub/GitLab repositories\n- ✅ **Private Registries** - GHCR, Docker Hub, self-hosted with secure credential cleanup\n- ✅ **Health Checks** - Auto-recovery on failures\n- ✅ **RESTful API** - Status monitoring and manual triggers\n- ✅ **Flexible Timeouts** - Configurable timeouts with float precision or disable entirely\n- ✅ **Secure** - Non-root container (UID 1000) + guaranteed credential cleanup\n- ✅ **Multi-Arch** - AMD64 and ARM64 (Raspberry Pi)\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Docker\n- Docker Compose\n\n### Installation\n\n```bash\n# 1. Clone repository\ngit clone https://github.com/ruben-sprengel/vigil-cd.git\ncd vigil-cd\n\n# 2. Run setup (auto-configures everything)\nchmod +x setup.sh\n./setup.sh\n\n# 3. Edit configuration\nvim config/config.yaml  # Add your repositories\n\n# 4. Add secrets\nvim .env  # Add authentication tokens\n\n# 5. Start VigilCD\ndocker-compose up -d\n\n# 6. Verify\ncurl http://localhost:8000/health\n```\n\n**That's it!** VigilCD is now monitoring your repositories.\n\n## ⚙️ Configuration\n\n### What `setup.sh` Does\n\nThe setup script automatically:\n- ✅ Creates `config.yaml` from template\n- ✅ **Auto-detects Docker socket GID** (required for deployments)\n- ✅ Generates `.env` with correct permissions\n- ✅ Sets up directories (`repos/`, `ssh-keys/`, `logs/`)\n- ✅ (Optional) Generates SSH keys for private repos\n- ✅ Validates configuration\n\n### Repository Configuration\n\nEdit `config/config.yaml`:\n\n```yaml\nrepos:\n  # Public HTTPS repository\n  - name: \"my-app\"\n    url: \"https://github.com/username/my-app\"\n    auth_method: \"https\"\n    branches:\n      - name: \"main\"\n        targets:\n          - name: \"app\"\n            file: \"docker-compose.yml\"\n            deploy: true\n            build_images: false\n\n  # Private SSH repository\n  - name: \"private-app\"\n    url: \"git@github.com:username/private-app.git\"\n    auth_method: \"ssh\"\n    branches:\n      - name: \"production\"\n        targets:\n          - name: \"api\"\n            file: \"docker-compose.yml\"\n            deploy: true\n            build_images: true\n\n  # With private Docker registry\n  - name: \"microservice\"\n    url: \"git@github.com:company/microservice.git\"\n    auth_method: \"ssh\"\n    registries:\n      - url: \"ghcr.io\"\n        username: \"bot\"\n        password_env_var: \"GHCR_TOKEN\"\n    branches:\n      - name: \"main\"\n        targets:\n          - name: \"service\"\n            file: \"docker-compose.yml\"\n            deploy: true\n```\n\n### Environment Variables\n\nEdit `.env` (auto-generated by `setup.sh`):\n\n```bash\n# Docker Configuration (auto-detected)\nDOCKER_GID=999\n\n# Git Authentication\nVIGILCD_GITHUB_TOKEN=ghp_xxxxx\n\n# Docker Registry Authentication\nGHCR_TOKEN=ghp_xxxxx\n\n# Scheduling (optional)\nVIGILCD_CHECK_INTERVAL_MINUTES=5\nVIGILCD_LOG_LEVEL=INFO\n```\n\n## 🔐 SSH Keys for Private Repos\n\n### Automatic Setup\n\nThe `setup.sh` script prompts you to generate SSH keys. Alternatively:\n\n```bash\n# Generate key\nssh-keygen -t ed25519 -C \"vigilcd-test\" -f id_ed25519_vigilcd\n\n# Show public key\ncat ./ssh-keys/id_ed25519_vigilcd.pub\n\n# Add to GitHub:\n# Repository → Settings → Deploy Keys → Add deploy key\n```\n\n### Multiple Keys\n\nFor different repos with different keys:\n\n```yaml\nrepos:\n  - name: \"service-a\"\n    url: \"git@github.com:company/service-a.git\"\n    auth_method: \"ssh\"\n    ssh_key_path: \"/home/vigilcd/.ssh/service_a_key\"\n```\n\n## 🐳 Private Docker Registries\n\n### Configuration\n\n1. **Add token to `.env`:**\n\n```bash\nGHCR_TOKEN=ghp_xxxxx\n```\n\n2. **Configure in `config.yaml`:**\n\n```yaml\nrepos:\n  - name: \"my-app\"\n    registries:\n      - url: \"ghcr.io\"\n        username: \"deployment-bot\"\n        password_env_var: \"GHCR_TOKEN\"\n```\n\n### Supported Registries\n\n- GitHub Container Registry (ghcr.io)\n- Docker Hub (docker.io)\n- Self-hosted registries\n- AWS ECR, GCR, etc.\n\n## 📡 API Endpoints\n\nCheck out the interactive swagger docs here:\n\n```\nhttp://localhost:8000/docs\n```\n\n## 🏗️ Architecture\n\n```\nVigilCD Container (vigilcd user)\n├── FastAPI (Web API)\n├── APScheduler (Periodic checks)\n├── GitPython (Git operations)\n└── DeploymentService\n    ├── Git sync (fetch + reset --hard)\n    ├── Docker Compose deployment\n    └── Health checks\n```\n\n### How It Works\n\n1. **Scheduler** triggers sync check every N minutes\n2. **Git Check** fetches remote commit hash\n3. **Comparison** with local commit\n4. **Update** if different: `git fetch` + `git reset --hard`\n5. **Deploy** via `docker compose up -d`\n6. **Health Check** monitors container status\n7. **Recovery** redeploys failed containers\n\n## 🐛 Troubleshooting\n\n### Permission Issues\n\n```bash\n./fix-permissions.sh\ndocker-compose restart vigilcd\n```\n\n### Docker Socket Access\n\n```bash\n# Verify DOCKER_GID in .env\ncat .env | grep DOCKER_GID\n\n# Re-run setup if changed\n./setup.sh\n```\n\n### SSH Authentication Failed\n\n```bash\n# Check key permissions\nls -la ./ssh-keys/\n\n# Test connection\ndocker exec vigilcd ssh -T git@github.com\n```\n\n### Config Changes Not Applied\n\n```bash\ndocker-compose restart vigilcd\ndocker-compose logs vigilcd\n```\n\n### View Logs\n\n```bash\n# Follow logs\ndocker-compose logs -f vigilcd\n\n# Last 100 lines\ndocker-compose logs --tail=100 vigilcd\n\n# Search for errors\ndocker-compose logs vigilcd | grep -i error\n```\n\n## 🔒 Security\n\n### Files in Git ✅\n\n```\n✅ config/config.template.yaml\n✅ .env.template\n✅ docker-compose.yml\n✅ Dockerfile\n✅ setup.sh\n```\n\n### Never Commit ❌\n\n```\n❌ config/config.yaml (repo-specific)\n❌ .env (secrets!)\n❌ ssh-keys/ (private keys!)\n❌ repos/ (cloned repos)\n```\n\n### Best Practices\n\n- ✅ Use **Deploy Keys** (not personal tokens)\n- ✅ Rotate credentials every 90 days\n- ✅ Limit token scopes (`read:packages` only)\n- ✅ Run container as non-root (UID 1000)\n- ✅ Use HTTPS for webhooks (reverse proxy)\n\n## 🔄 Updating\n\n### Configuration Changes\n\n```bash\nvim config/config.yaml\ndocker-compose restart vigilcd\n```\n\n### Update Image\n\n```bash\ndocker-compose pull\ndocker-compose up -d\n```\n\n### Add New Repository\n\n1. Edit `config/config.yaml`\n2. Restart: `docker-compose restart vigilcd`\n3. Verify: `curl http://localhost:8000/api/status`\n\n## 🎛️ Advanced Configuration\n\n### Environment Variables\n\n| Variable                         | Default       | Description                             |\n|----------------------------------|---------------|-----------------------------------------|\n| `DOCKER_GID`                     | Auto-detected | Docker socket group (required)          |\n| `VIGILCD_CHECK_INTERVAL_MINUTES` | `5`           | Polling interval                        |\n| `VIGILCD_GIT_RETRY_COUNT`        | `3`           | Git operation retries                   |\n| `VIGILCD_DOCKER_TIMEOUT`         | `300`         | Docker Compose timeout (seconds)        |\n| `VIGILCD_LOG_LEVEL`              | `INFO`        | Log level (DEBUG, INFO, WARNING, ERROR) |\n\n### Repository Options\n\n| Field          | Required | Description                               |\n|----------------|----------|-------------------------------------------|\n| `name`         | ✅        | Unique identifier                         |\n| `url`          | ✅        | Git URL (HTTPS or SSH)                    |\n| `auth_method`  | ❌        | `\"https\"` or `\"ssh\"` (default: `\"https\"`) |\n| `ssh_key_path` | ❌        | Custom SSH key path                       |\n| `registries`   | ❌        | Private Docker registries                 |\n\n### Target Options\n\n| Field          | Default | Description                     |\n|----------------|---------|---------------------------------|\n| `deploy`       | `true`  | Auto-deploy on changes          |\n| `build_images` | `false` | Run `docker compose up --build` |\n\n## 📊 Production Deployment\n\n### Resource Limits\n\n```yaml\n# docker-compose.yml\ndeploy:\n  resources:\n    limits:\n      cpus: '1.0'\n      memory: 512M\n```\n\n### Logging\n\n```yaml\nlogging:\n  driver: \"json-file\"\n  options:\n    max-size: \"10m\"\n    max-file: \"3\"\n```\n\n### Monitoring\n\n- Health endpoint: `/health`\n- Status endpoint: `/api/status`\n- Metrics: (Coming soon)\n\n### Backup\n\n```bash\ntar -czf vigilcd-backup.tar.gz config/ .env ssh-keys/\n```\n\n## 🤝 Contributing\n\nContributions welcome! Please:\n\n1. Fork the repository\n2. Create feature branch\n3. Submit pull request\n\n### Development Setup\n\n```bash\npip install uv\nuv sync --extra dev\nuv run uvicorn src.app:app --reload\n```\n\n## 📝 License\n\nMIT License - see [LICENSE](LICENSE) file\n\n## 🙏 Acknowledgments\n\nBuilt with:\n- [FastAPI](https://fastapi.tiangolo.com/)\n- [GitPython](https://gitpython.readthedocs.io/)\n- [APScheduler](https://apscheduler.readthedocs.io/)\n- [uv](https://github.com/astral-sh/uv)\n\n## 📮 Support\n\n- **Issues:** [GitHub Issues](https://github.com/ruben-sprengel/vigil-cd/issues)\n- **Documentation:** This README\n- **Sponsor:** [Ko-fi](https://ko-fi.com/rubensprengel)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruben-sprengel%2Fvigil-cd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fruben-sprengel%2Fvigil-cd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruben-sprengel%2Fvigil-cd/lists"}