{"id":47819259,"url":"https://github.com/haydenk/overseer","last_synced_at":"2026-04-03T19:02:20.777Z","repository":{"id":345168356,"uuid":"1183824121","full_name":"haydenk/overseer","owner":"haydenk","description":"A zero-dependency, Procfile-based process manager in Go — a lightweight Foreman clone.","archived":false,"fork":false,"pushed_at":"2026-03-24T18:42:05.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-03-25T23:52:47.817Z","etag":null,"topics":["cli","colorized-output","devtools","dotenv","foreman","formation","go","golang","graceful-shutdown","process-manager","process-orchestration","procfile","static-binary","zero-dependencies"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haydenk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.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-03-17T01:36:29.000Z","updated_at":"2026-03-24T18:42:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/haydenk/overseer","commit_stats":null,"previous_names":["haydenk/overseer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/haydenk/overseer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenk%2Foverseer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenk%2Foverseer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenk%2Foverseer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenk%2Foverseer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haydenk","download_url":"https://codeload.github.com/haydenk/overseer/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haydenk%2Foverseer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31371648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["cli","colorized-output","devtools","dotenv","foreman","formation","go","golang","graceful-shutdown","process-manager","process-orchestration","procfile","static-binary","zero-dependencies"],"created_at":"2026-04-03T19:02:16.565Z","updated_at":"2026-04-03T19:02:20.767Z","avatar_url":"https://github.com/haydenk.png","language":"Go","readme":"# overseer\n\n[![CI](https://github.com/haydenk/overseer/actions/workflows/ci.yml/badge.svg)](https://github.com/haydenk/overseer/actions/workflows/ci.yml)\n[![Release](https://github.com/haydenk/overseer/actions/workflows/release.yml/badge.svg)](https://github.com/haydenk/overseer/actions/workflows/release.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/haydenk/overseer.svg)](https://pkg.go.dev/github.com/haydenk/overseer)\n[![Go Report Card](https://goreportcard.com/badge/github.com/haydenk/overseer)](https://goreportcard.com/report/github.com/haydenk/overseer)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n![Go Version](https://img.shields.io/badge/go-1.26+-00ADD8?logo=go)\n\nA zero-dependency Go clone of [foreman](https://github.com/ddollar/foreman) — a `Procfile`-based process manager. Overseer reads a `Procfile`, spawns each process, streams prefixed and colored output, and handles graceful shutdown on signals.\n\n## Features\n\n- **Zero external dependencies** — pure Go standard library\n- **Colored, timestamped output** — one color per process type, padded labels\n- **Formation support** — run multiple instances of any process type\n- **Port assignment** — auto-assigns `PORT` per instance (`base + processIndex*100 + instanceIndex`)\n- **Dual-stack networking** — reports IPv4 and IPv6 bind addresses at startup\n- **`.env` file loading** — single-quoted, double-quoted, and unquoted values\n- **Graceful shutdown** — `SIGTERM` to all children, `SIGKILL` after configurable timeout\n- **Signal forwarding** — `SIGUSR1`/`SIGUSR2` forwarded to all children\n\n## Installation\n\n**Requires Go 1.26+** (managed automatically via [mise](https://mise.jdx.dev) if you use it).\n\n```sh\ngo install github.com/haydenk/overseer@latest\n```\n\nOr build from source:\n\n```sh\ngit clone https://github.com/haydenk/overseer.git\ncd overseer\nmise run build        # → bin/overseer\n# or\ngo build -o bin/overseer .\n```\n\n## Usage\n\n### `overseer check`\n\nValidate a Procfile and list detected process types.\n\n```sh\noverseer check [-f Procfile]\n```\n\n```\nvalid procfile detected (web, worker)\n```\n\n### `overseer start`\n\nStart all processes (or a single named process) defined in the Procfile.\n\n```sh\noverseer start [PROCESS] [flags]\n\n  -f string         Procfile path (default \"Procfile\")\n  -e string         .env file path (default \".env\")\n  -m string         formation, e.g. all=1,web=2,worker=3\n  -p string         base port — overrides $PORT (default 5000)\n  -t int            graceful shutdown timeout in seconds (default 5)\n  -c                enable colored output (default true)\n  -no-timestamp     disable timestamps\n```\n\n**Examples:**\n\n```sh\n# Start all processes\noverseer start\n\n# Start only the web process\noverseer start web\n\n# Run two web instances and one worker\noverseer start -m web=2,worker=1\n\n# Use a custom Procfile and env file\noverseer start -f Procfile.staging -e .env.staging\n\n# Disable color and timestamps (useful for log aggregators)\noverseer start -c=false -no-timestamp\n```\n\n### `overseer run`\n\nRun a single command (or a named Procfile entry) with the environment loaded from the `.env` file.\n\n```sh\noverseer run [flags] COMMAND\n\n  -f string   Procfile path (default \"Procfile\")\n  -e string   .env file path (default \".env\")\n```\n\n**Examples:**\n\n```sh\n# Inspect the environment overseer would inject\noverseer run env\n\n# Run a Procfile entry by name\noverseer run -e .env.test worker\n\n# Run an arbitrary command with the loaded env\noverseer run -e .env \"bundle exec rake db:migrate\"\n```\n\n## Procfile format\n\n```\nweb:    python3 -m http.server $PORT\nworker: sleep 100\nclock:  python3 clock.py\n```\n\n- One process per line: `name: command`\n- `$PORT` is injected automatically per instance\n- Lines starting with `#` are ignored\n\n## .env format\n\n```sh\nDATABASE_URL=postgres://localhost/myapp\nSECRET_KEY='no escape processing here'\nGREETING=\"Hello\\nWorld\"\n```\n\n- **Unquoted** — value used as-is\n- **Single-quoted** — no escape processing\n- **Double-quoted** — `\\n` → newline, `\\\\` → `\\`\n\n## Formation \u0026 port assignment\n\nThe `-m` flag controls how many instances of each process type are spawned:\n\n| Flag | Effect |\n|---|---|\n| *(none)* | one instance of every process (`all=1`) |\n| `-m all=2` | two instances of every process |\n| `-m web=2,worker=0` | two web instances, no workers |\n| `overseer start web` | shorthand for `-m web=1` |\n\nPorts are assigned as:\n\n```\nPORT = basePort + (processTypeIndex × 100) + instanceIndex\n```\n\nFor example, with base port `5000` and `web=2,worker=2`:\n\n| Instance | PORT |\n|---|---|\n| web.1 | 5000 |\n| web.2 | 5001 |\n| worker.1 | 5100 |\n| worker.2 | 5101 |\n\nOverride the base with `-p PORT` or the `$PORT` environment variable.\n\n## Signal handling\n\n| Signal | Behavior |\n|---|---|\n| `SIGINT`, `SIGTERM`, `SIGHUP` | Graceful shutdown: `SIGTERM` all children, then `SIGKILL` after timeout |\n| `SIGUSR1`, `SIGUSR2` | Forwarded directly to all child processes |\n\n## Development\n\nThis project uses [mise](https://mise.jdx.dev) to manage the Go toolchain and common tasks.\n\n```sh\n# First-time setup\nmise run setup\n\n# Build\nmise run build\n\n# Run the dev server (uses Procfile.dev if present, falls back to Procfile)\nmise run dev\n\n# Test\nmise run test\n\n# Format\nmise run fmt\n\n# Lint (go vet + staticcheck)\nmise run lint\n\n# Full quality gate (fmt → lint → test)\nmise run check\n\n# Install binary to $GOBIN\nmise run install\n\n# Remove build artifacts\nmise run clean\n```\n\nA [devcontainer](.devcontainer/devcontainer.json) is included for VS Code / GitHub Codespaces — it installs mise and runs `mise run setup` automatically on attach.\n\n## Contributing\n\nContributions are welcome. Please read the [Code of Conduct](CODE_OF_CONDUCT.md) before participating.\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feat/my-feature`)\n3. Run `mise run check` before pushing\n4. Open a pull request\n\n## Security\n\nPlease do not open public issues for security vulnerabilities. See [SECURITY.md](SECURITY.md) for the disclosure process.\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaydenk%2Foverseer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaydenk%2Foverseer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaydenk%2Foverseer/lists"}