{"id":50782691,"url":"https://github.com/arumes31/servworx","last_synced_at":"2026-06-12T05:01:25.188Z","repository":{"id":313265806,"uuid":"1050048323","full_name":"arumes31/servworx","owner":"arumes31","description":"Lightweight, Go-based self-healing Docker container monitor \u0026 automatic restarter. Keeps your self-hosted web services alive with real-time dashboards, log tailing, grace periods, and secure container management via the Docker API. 🛠️","archived":false,"fork":false,"pushed_at":"2026-06-08T20:13:36.000Z","size":38824,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T21:07:20.045Z","etag":null,"topics":["auto-restart","container-monitoring","devops","docker","docker-compose","go","golang","homelab","microservices","monitoring","ping-monitor","self-healing","self-hosted","server-monitoring","sysadmin","uptime","web-dashboard"],"latest_commit_sha":null,"homepage":"","language":"Go","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/arumes31.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":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":"2025-09-03T21:47:51.000Z","updated_at":"2026-06-08T20:13:10.000Z","dependencies_parsed_at":"2025-09-04T23:43:58.020Z","dependency_job_id":"5999b673-1d97-42ae-81df-e507d6723177","html_url":"https://github.com/arumes31/servworx","commit_stats":null,"previous_names":["arumes31/servworx"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/arumes31/servworx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arumes31%2Fservworx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arumes31%2Fservworx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arumes31%2Fservworx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arumes31%2Fservworx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arumes31","download_url":"https://codeload.github.com/arumes31/servworx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arumes31%2Fservworx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34229624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"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":["auto-restart","container-monitoring","devops","docker","docker-compose","go","golang","homelab","microservices","monitoring","ping-monitor","self-healing","self-hosted","server-monitoring","sysadmin","uptime","web-dashboard"],"created_at":"2026-06-12T05:01:22.483Z","updated_at":"2026-06-12T05:01:25.159Z","avatar_url":"https://github.com/arumes31.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# servworx\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"static/logo.svg\" width=\"120\" height=\"120\" alt=\"servworx logo\"\u003e\n\u003c/div\u003e\n\n![Build and Publish Docker Image](https://github.com/arumes31/servworx/actions/workflows/docker-publish.yml/badge.svg)\n![Daily Security Scan](https://github.com/arumes31/servworx/actions/workflows/security-scan.yml/badge.svg)\n![Go Version](https://img.shields.io/badge/Go-1.26.1+-00ADD8.svg?style=flat-square\u0026logo=go\u0026logoColor=white)\n![Docker Image Size](https://img.shields.io/docker/image-size/arumes31/servworx/latest?style=flat-square\u0026logo=docker\u0026logoColor=white\u0026color=2496ED)\n![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)\n![Repo Size](https://img.shields.io/github/repo-size/arumes31/servworx?style=flat-square)\n![Last Commit](https://img.shields.io/github/last-commit/arumes31/servworx?style=flat-square\u0026color=orange)\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA lightweight, ultra-reliable self-healing Docker container monitor and automatic restarter written in Go.\u003c/strong\u003e\n\u003c/p\u003e\n\n---\n\n[Key Features](#-key-features) • [How it Works](#%EF%B8%8F-how-it-works) • [Getting Started](#-getting-started) • [Configuration Guide](#-configuration-guide) • [Security Best Practices](#%EF%B8%8F-security-best-practices) • [Deployment](#-deployment) • [License](#-license)\n\n\u003c/div\u003e\n\n**servworx** is a lightweight, web-based service monitoring and self-healing auto-restart tool for Docker containers. Written in Go, it continuously tracks the availability of specified website URLs or API endpoints. If a service becomes unresponsive or returns error codes, `servworx` acts as an automated operator—automatically restarting the associated Docker containers after a configurable number of retries. \n\nDesigned for high reliability in homelabs and small production setups, `servworx` features a premium, responsive dashboard for live log inspection, state control, and detailed monitoring statistics.\n\n---\n\n## 📸 Dashboards\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"881\" alt=\"Dashboard Status Page\" src=\"https://github.com/user-attachments/assets/29a77b6f-32a1-4bbc-a90a-c82e19a24f05\" style=\"border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.15);\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"1243\" alt=\"Config and Management Page\" src=\"https://github.com/user-attachments/assets/7d77d667-75c7-4e3c-81f1-02eae578d011\" style=\"border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.15);\" /\u003e\n\u003c/p\u003e\n\n---\n\n## 🌟 Key Features\n\n*   **🔍 Active Service Monitoring**: Continuously polls service endpoints over HTTP/HTTPS with custom interval loops.\n*   **🩺 Automatic Container Restart**: Triggers graceful restarts of one or more specified Docker containers using the Docker Engine API when services remain down.\n*   **⚙️ In-App Dynamic Configuration**: Add, update, pause, resume, or delete monitored services dynamically through the secure web UI without restarting `servworx`.\n*   **⏳ Configurable Grace Periods**: Prevents infinite restart loops by letting containers warm up and stabilize after restarts.\n*   **🔒 Built-in User Authentication**: A secure admin portal with forced first-login password changes.\n*   **📜 Live Container Log Viewer**: Read the last few lines of Docker container logs directly from the dashboard to debug downtime instantly.\n*   **🔌 Self-Signed TLS Support**: Skip TLS verification per-service to monitor internal homelab services running with self-signed SSL/TLS certificates.\n*   **⚡ Forced Manual Restarts**: Manually trigger container restarts with a single click.\n\n---\n\n## ⚙️ How it Works\n\nThe following flowchart outlines the lifecycle of a `servworx` monitor loop:\n\n```mermaid\nflowchart TD\n    Start([Start Health Check Loop]) --\u003e Load[Load Service Configurations]\n    Load --\u003e CheckPaused{Is Service Paused?}\n    \n    CheckPaused -- Yes --\u003e Wait[Wait for next interval] --\u003e Load\n    CheckPaused -- No --\u003e Poll[HTTP/HTTPS Poll to website_url]\n    \n    Poll --\u003e CodeCheck{HTTP Status in accepted_status_codes?}\n    \n    CodeCheck -- Yes (Healthy) --\u003e Reset[Reset Fail Counter \u0026 Mark UP]\n    Reset --\u003e Wait\n    \n    CodeCheck -- No (Failed) --\u003e Inc[Increment Failure Count]\n    Inc --\u003e Threshold{Failures \u003e= retries?}\n    \n    Threshold -- No --\u003e Wait\n    Threshold -- Yes --\u003e Grace{Grace Period Active?}\n    \n    Grace -- Yes --\u003e LogGrace[Log: Skip restart, inside grace period] --\u003e Wait\n    Grace -- No --\u003e Restart[Docker Engine API: Restart associated containers]\n    Restart --\u003e LogRestart[Log: Container auto-restarted]\n    LogRestart --\u003e SetGrace[Initialize Grace Period Timer]\n    SetGrace --\u003e ResetCounter[Reset Fail Counter]\n    ResetCounter --\u003e Wait\n```\n\n---\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n*   [Docker](https://docs.docker.com/get-docker/) installed and running.\n*   [Docker Compose](https://docs.docker.com/compose/install/) installed.\n\n### Installation \u0026 Setup\n\n1.  **Clone the Repository**\n    ```bash\n    git clone https://github.com/arumes31/servworx.git\n    cd servworx\n    ```\n\n2.  **Build and Start with Docker Compose**\n    ```bash\n    docker compose up --build -d\n    ```\n    This builds the secure Go application binary using a multi-stage Alpine build, embeds templates, and starts the container on port `7676`.\n\n3.  **Access the Web Interface**\n    Open your browser and head to: **`http://localhost:7676`**\n\n    *   **Default Username**: `admin`\n    *   **Default Password**: `changeme` (You will be prompted to change this immediately upon your first login).\n\n---\n\n## 📦 Deployment Options\n\n### Using the Pre-Built GHCR Image\n\nIf you want to avoid compiling the code locally, use our pre-built image hosted directly on the GitHub Container Registry. Create a `docker-compose.yaml` with the following configuration:\n\n```yaml\nservices:\n  monitor:\n    container_name: servworx\n    image: ghcr.io/arumes31/servworx:latest\n    ports:\n      - \"7676:5000\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n      - ./config:/app/config\n    restart: unless-stopped\n```\n\nDeploy instantly using:\n```bash\ndocker compose up -d\n```\n\n---\n\n## 📘 Configuration Guide\n\n`servworx` persists configurations under the host's `./config` directory, which mounts to `/app/config` inside the container:\n\n*   **`config.json`**: Stores encrypted user credentials and active service monitoring parameters.\n*   **`status.json`**: Persists the real-time operational status (uptime/downtime durations, stability counters).\n\n### Example `config.json` Structure\nBelow is an example of an operational configuration file:\n\n```json\n{\n    \"users\": {\n        \"admin\": \"$2a$10$tQO2U0s...\"\n    },\n    \"services\": [\n        {\n            \"name\": \"Nginx Web Server\",\n            \"website_url\": \"https://my-website.local\",\n            \"container_names\": \"nginx-web,nginx-db\",\n            \"retries\": 3,\n            \"interval\": 60,\n            \"grace_period\": 300,\n            \"accepted_status_codes\": [200, 201, 301, 302],\n            \"paused\": false,\n            \"insecure_skip_verify\": true,\n            \"enable_webhook\": false,\n            \"enable_teams\": true,\n            \"enable_telegram\": false,\n            \"enable_email\": true\n        }\n    ]\n}\n```\n\n### Parameter Explanations\n\n| Parameter | Type | Default | Description |\n| :--- | :---: | :---: | :--- |\n| `name` | `string` | *Required* | A unique descriptive label for the monitored service. |\n| `website_url` | `string` | *Required* | The full HTTP/HTTPS URL of the target endpoint to monitor. |\n| `container_names` | `string` | *Required* | Comma-separated list of Docker container names to restart on failure. |\n| `retries` | `int` | `15` | Number of consecutive failed polling attempts allowed before trigger. |\n| `interval` | `int` | `120` | Polling frequency in seconds between health checks. |\n| `grace_period` | `int` | `3600` | Prevention window (in seconds) post-restart to let the service fully boot up before triggering another restart. |\n| `accepted_status_codes` | `array` | `[200]` | List of HTTP status codes considered healthy and operational. |\n| `paused` | `bool` | `false` | Set to `true` to temporarily disable polling and auto-restarting for this service. |\n| `insecure_skip_verify` | `bool` | `false` | Skip SSL certificate validation (useful for internal DNS or self-signed certs). |\n| `enable_webhook` | `bool` | `false` | Set to `true` to enable Generic Webhook notification alerts for this service. |\n| `enable_teams` | `bool` | `false` | Set to `true` to enable Microsoft Teams webhook notification alerts for this service. |\n| `enable_telegram` | `bool` | `false` | Set to `true` to enable Telegram bot notification alerts for this service. |\n| `enable_email` | `bool` | `false` | Set to `true` to enable SMTP Email notification alerts for this service. |\n\n---\n\n### 🔔 Notification Setup\n\n`servworx` supports optional, multi-channel notifications (Generic Webhooks, MS Teams, Telegram, and SMTP Email) to alert you whenever a service's state changes (e.g., from `Up` to `Down`, or `Down` to `Up`) or when a container restart is triggered.\n\nGlobal notification settings (such as API tokens, endpoints, and credentials) are configured securely using **Docker container environment variables**. Once configured, each monitored service can selectively toggle channels on or off directly from the sleek settings panel on the web dashboard.\n\n\u003e [!NOTE]\n\u003e All notification channels are executed asynchronously inside high-performance Go goroutines. Slow endpoints, DNS resolutions, or SMTP handshakes will never block or delay your main health-checking threads.\n\n#### 1. Generic Webhook (`enable_webhook`)\nSends a custom HTTP `POST` request with a JSON payload containing the event details.\n* **Environment Variable**: `NOTIFICATION_WEBHOOK_URL` (e.g., `http://your-webhook-endpoint.local/alert`)\n* **JSON Payload Format**:\n  ```json\n  {\n    \"service\": \"Nginx Web Server\",\n    \"url\": \"https://my-website.local\",\n    \"status\": \"Down\",\n    \"timestamp\": \"2026-05-30 19:15:30\",\n    \"message\": \"Service status changed from Up to Down\"\n  }\n  ```\n\n#### 2. Microsoft Teams (`enable_teams`)\nDispatches rich, colored Office 365 Connector cards to Microsoft Teams or compatible endpoints.\n* **Environment Variable**: `NOTIFICATION_MSTEAMS_URL`\n* **Features**: Displays automatic color-coding (vibrant red for downtime, green for recovery) and custom emojis to display event urgency along with metadata on restarted containers.\n\n#### 3. Telegram Bot (`enable_telegram`)\nSends beautifully formatted Markdown alerts directly to a specified personal chat, group, or channel.\n* **Environment Variables**:\n  * `NOTIFICATION_TELEGRAM_TOKEN`: The API token obtained from [@BotFather](https://t.me/BotFather).\n  * `NOTIFICATION_TELEGRAM_CHAT_ID`: The unique target chat or channel ID.\n\n#### 4. SMTP Email (`enable_email`)\nSends standard plain-text e-mail notifications.\n* **Environment Variables**:\n  * `NOTIFICATION_SMTP_HOST`: The address of the outgoing mail server (e.g., `smtp.gmail.com`).\n  * `NOTIFICATION_SMTP_PORT`: The SMTP server port (usually `587` or `25`).\n  * `NOTIFICATION_SMTP_USER`: The authentication email address. *Leave blank for unauthenticated local homelab mail relays.*\n  * `NOTIFICATION_SMTP_PASS`: The password or app token for the SMTP server.\n  * `NOTIFICATION_SMTP_FROM`: The sender email address.\n  * `NOTIFICATION_SMTP_TO`: The destination email address.\n\n---\n\n## 🛡️ Security Best Practices\n\nSince `servworx` communicates directly with the Docker Engine to perform self-healing container management, it requires access to the host's `/var/run/docker.sock`. Below are crucial configuration measures to ensure a secure setup:\n\n1.  **Change the Default Admin Password Immediately**: Never leave the default password `changeme` active on public-facing servers.\n2.  **Restrict Network Access**: \n    *   Do not expose port `7676` directly to the open web.\n    *   Bind it locally (`127.0.0.1:7676:5000`) and put it behind a secure reverse proxy (like Nginx, Traefik, or Caddy) equipped with TLS/SSL.\n    *   Alternatively, access the dashboard exclusively via a secure VPN or overlay network (like WireGuard, Tailscale, or OpenVPN).\n3.  **Audit Container Name Inputs**: `servworx` incorporates container name validation patterns to avoid command-injection exploits. Always double-check that you only specify exact, valid Docker container names.\n4.  **Least Privilege Docker Sock (Optional)**: If you want to limit `servworx` permissions, consider using a Docker Socket proxy (e.g. `tecnativa/docker-socket-proxy`) to only permit `POST /containers/{name}/restart` operations and block access to other critical Docker actions.\n\n---\n\n## 🏛️ Directory Layout\n\n```\n.\n├── cmd/                          # Command-line entry points\n│   └── servworx/\n│       └── main.go               # Web server and monitor entry point\n├── internal/                     # Private Go packages\n│   ├── auth/                     # Session and security handling\n│   ├── config/                   # Read, write, and load configurations\n│   ├── handlers/                 # HTTP controller logic split by domain\n│   │   ├── api_handlers.go       # JSON/SSE endpoints\n│   │   ├── web_handlers.go       # HTML page handlers\n│   │   ├── helpers.go            # UI formatting and logic helpers\n│   │   ├── middleware.go         # Authentication gate\n│   │   └── routes.go             # Central router registration\n│   └── monitor/                  # Polling engine and Docker restart worker\n├── templates/                    # Go HTML layout templates\n│   ├── change_password.html      # Authentication profile page\n│   ├── config.html               # Main live monitoring dashboard\n│   └── login.html                # Web portal login screen\n├── static/                       # Static assets (logo, icons, etc.)\n│   └── logo.svg\n├── Dockerfile                    # Multi-stage optimized Docker build instructions\n├── docker-compose.yaml           # Local container orchestration file\n├── LICENSE                       # MIT License file\n├── go.mod                        # Go module file\n└── README.md                     # Modern project overview (this file)\n```\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to open Issues or submit Pull Requests to help improve `servworx`.\n\n1. Fork the Project.\n2. Create your Feature Branch (`git checkout -b feature/amazing-feature`).\n3. Commit your Changes (`git commit -m 'Add some amazing-feature'`).\n4. Push to the Branch (`git push origin feature/amazing-feature`).\n5. Open a Pull Request.\n\n---\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farumes31%2Fservworx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farumes31%2Fservworx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farumes31%2Fservworx/lists"}