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.
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.
- 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 - Install the Goalfeed add-on from the store.
- Open its Configuration tab and enter team codes:
yaml
nhl_teams: "TOR,WPG" mlb_teams: "TOR,NYY" test_goals: false - Start the add-on ("Start on boot" and "Watchdog" are worth enabling). It runs
./goalfeed --web --web-port 8080internally withSUPERVISOR_APIauto-exported, so it reaches Home Assistant through the Supervisor proxy without any URL/token configuration. - Open the web UI from the Home Assistant sidebar (ingress), or
http://homeassistant.local:8080.
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):
| OS | Architectures |
|---|---|
| Linux | amd64, arm64, 386,
armv6, armv7 |
| Windows | amd64, 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 |
# 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:
xattr -d com.apple.quarantine ./goalfeed
From source
Requires Go 1.24+ and Node 20+ (for the web UI).
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
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:
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:
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(orgoalfeed.exe) binary itself - the bundled
web/directory (the web UI's static files) config.yaml, if you created oneapp.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.