Install

Every supported way to run Goalfeed, in the order most people should try them, with the caveats stated up front rather than discovered later.

bash — fastest working path
gh release download --repo goalfeed/goalfeed --pattern "*linux_amd64.tar.gz"
tar xzf goalfeed_*_linux_amd64.tar.gz
./goalfeed --nhl WPG --web

That's the "binary from Releases" method below, the one that needs the least explanation. The sections after it cover the Home Assistant add-on (best if you already run HA), building from source, and Docker (currently broken as shipped — read that section before trying it).

Home Assistant add-on

Best choice if Goalfeed's only job is talking to your existing Home Assistant instance — the Supervisor handles authentication for you, so there's no URL or token to configure.

  1. In Home Assistant: Settings → Add-ons → Add-on Store, open the ⋮ menu, choose Repositories, and add:
    repository url
    https://github.com/goalfeed/hassio-goalfeed-repository
  2. Install the Goalfeed add-on from the store.
  3. Open its Configuration tab and enter team codes:
    yaml
    nhl_teams: "TOR,WPG"
    mlb_teams: "TOR,NYY"
    test_goals: false
  4. Start the add-on ("Start on boot" and "Watchdog" are worth enabling). It runs ./goalfeed --web --web-port 8080 internally with SUPERVISOR_API auto-exported, so it reaches Home Assistant through the Supervisor proxy without any URL/token configuration.
  5. Open the web UI from the Home Assistant sidebar (ingress), or http://homeassistant.local:8080.
Caveat

The add-on's config.json manifest only exposes nhl_teams and mlb_teams (plus test_goals) as options — there is no CFL or NFL option in the Configuration tab, even though the underlying binary supports those leagues. To watch CFL or NFL teams from the add-on, you need to mount your own config.yaml into the container or set GOALFEED_WATCH_CFL / GOALFEED_WATCH_NFL environment variables on it directly — there's no in-UI path for this today. See the configuration reference for every key.

Supported architectures for the add-on's Docker image: aarch64 and amd64 only — narrower than the binary release matrix below (no armhf/armv7/386 add-on image).

Binary from GitHub Releases

Every push to main publishes a GitHub Release built by GoReleaser. Each archive bundles the Go binary and the built React web UI (GoReleaser's build hook runs npm ci && npm run build before packaging), so this is the one channel where the frontend build question never comes up.

Exact platforms shipped, verified against a release's actual asset list rather than just the build config (checked against v1.0.39; the matrix itself hasn't changed across recent releases, but check the current release if in doubt):

OSArchitectures
Linuxamd64, arm64, 386, armv6, armv7
Windowsamd64, arm64, 386, armv6, armv7
macOS (Darwin)amd64, arm64 only — Go dropped 32-bit and ARMv6/v7 Darwin support years ago, so those combinations from the build matrix simply don't produce a macOS asset
bash — requires the GitHub CLI
# swap linux_amd64 for darwin_arm64, windows_386, linux_armv7, etc.
gh release download --repo goalfeed/goalfeed --pattern "*linux_amd64.tar.gz"
tar xzf goalfeed_*_linux_amd64.tar.gz
./goalfeed --nhl WPG --web

No gh? Download the matching archive by hand from the Releases page. Each one contains the goalfeed (or goalfeed.exe) binary, README.md, and the prebuilt web/frontend/build/ directory — keep that directory alongside the binary so the web UI serves.

macOS: "cannot be opened because the developer cannot be verified"

The released binaries are unsigned and not notarized — spctl --assess --type execute ./goalfeed reports rejected (TeamIdentifier=not set), checked against a downloaded archive, not assumed. A curl/gh download in a terminal isn't quarantined, so running the binary right after extracting it works fine. A browser download is quarantined, though — and clicking the archive in a browser is the more common way people actually get this file — so that copy shows "goalfeed cannot be opened because the developer cannot be verified" the first time you try to run it. Nothing is wrong with the binary; nobody has paid Apple to notarize it. Clear the quarantine flag and it runs normally:

bash
xattr -d com.apple.quarantine ./goalfeed

From source

Requires Go 1.24+ and Node 20+ (for the web UI).

bash
git clone https://github.com/goalfeed/goalfeed.git
cd goalfeed
make build   # npm ci && npm run build (frontend), then go build -o goalfeed .
./goalfeed --nhl WPG --web

Other Makefile targets: make backend (Go binary only, skips the frontend — you get the API-only fallback page), make frontend (React build only), and ./dev.sh dev for an fswatch-based hot-reload loop (documented in DEV.md).

Docker

Currently broken as shipped

The repo's own Dockerfile builds from FROM golang:1.21, but go.mod requires Go 1.24.0. Building the image as committed fails on the Go toolchain version mismatch — this is not a hypothetical edge case, it's the file as it exists in the repository today. It also only compiles the Go binary; it never runs npm ci && npm run build, so even patched to a current Go image, a container built from it would serve the REST/WebSocket API in fallback mode without the React web UI. There is no published, maintained standalone Docker image for Goalfeed. Until this is fixed upstream, building from source or using a release tarball (above) is the reliable path.

If you want to build it anyway, bump the base image first:

bash
git clone https://github.com/goalfeed/goalfeed.git
cd goalfeed
perl -pi -e 's/golang:1\.21/golang:1.24/' Dockerfile   # portable; or edit by hand
docker build -t goalfeed .
docker run -d --name goalfeed -p 8080:8080 \
  -e GOALFEED_WEB=true \
  -e GOALFEED_WATCH_NHL=WPG \
  -e GOALFEED_HOME_ASSISTANT_URL=http://homeassistant.local:8123 \
  -e GOALFEED_HOME_ASSISTANT_ACCESS_TOKEN=your-long-lived-token \
  goalfeed

your-long-lived-token is the Home Assistant long-lived access token from your profile → Security → Long-Lived Access Tokens — see the configuration reference for every other key. perl -pi -e edits the file in place identically on macOS and Linux; sed -i does not — BSD/macOS sed requires an empty extension argument (sed -i '' 's/.../.../ ') that GNU sed (most Linux distros, where Docker actually runs) rejects, so a sed -i command copy-pasted from one platform routinely fails on the other.

Even after that patch, this image serves the API/WebSocket only — the frontend build step still isn't in the Dockerfile. Build the frontend into your own image if you need the web UI in a container.

docker-compose.yml is not "run Goalfeed in Docker"

The docker-compose.yml checked into this repo spins up a local Home Assistant instance for development and testing — it defines no Goalfeed service at all:

docker-compose.yml
services:
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: goalfeed-ha
    ports: ["8123:8123"]
    volumes:
      - ./dev/homeassistant/config:/config
      - /etc/localtime:/etc/localtime:ro

Run Goalfeed itself alongside it (from source, or the binary) and point it at http://localhost:8123. macOS/Windows developers should have that local Home Assistant point back at Goalfeed via http://host.docker.internal:8080, per the file's own comment.

Upgrade and uninstall

Upgrade — tested, not assumed. Going from v1.0.36 to v1.0.39 by downloading the new release and overwriting the old binary in place (same directory, same filename) works cleanly: config.yaml is left untouched, and ./goalfeed --version reports the new version afterward. There's no migration step and no separate uninstall/reinstall dance — download the new archive, extract it over the old one (or into the same directory), and restart the process.

Uninstall. A binary install (release archive, or make build from source) creates exactly four things, all inside the one directory you ran it from, and nothing outside it — no launchd/systemd unit, no shell profile edits, no cache elsewhere on the machine:

  • the goalfeed (or goalfeed.exe) binary itself
  • the bundled web/ directory (the web UI's static files)
  • config.yaml, if you created one
  • app.log.jsonl, written at runtime once Goalfeed logs its first event

To uninstall, delete that directory. Running the Home Assistant add-on instead? Uninstall it from Settings → Add-ons → Goalfeed → Uninstall, the same way you'd remove any other add-on.

Next

Once Goalfeed is running, wire the goal event into an automation — Home Assistant automations — or look up every config key in the configuration reference.