Repository navigation
Installation
There are two ways to install Obelo: the Docker image (recommended, and the only one that needs nothing on the host but Docker) and a build from source.
Whichever you pick, read First Run next — the very first admin account is bootstrapped from a one-time token printed to the server's log, and it is easy to miss.
To run the Docker image: Docker, a folder of media, and a browser. That is
the whole list — ffmpeg is inside the image.
To run a binary you built yourself: ffmpeg (with ffprobe) on the
server's PATH. It is the only runtime dependency. It is used both for probing
files during a scan and for transcoding during playback; without it, scans
cannot determine what your files contain.
To build from source: additionally Go 1.25+ and Node.js 22+.
Build the image. The build context is the repository root, not the docker/
directory — the Dockerfile compiles the web app and the Go binary from source:
git clone https://github.com/goozakdev/obelo-server.git
cd obelo-server
docker build -f docker/Dockerfile -t obelo .Run it, mounting a writable data directory and your media read-only:
docker run -d --name obelo -p 8080:8080 \
-v "$PWD/data:/data" \
-v /path/to/your/media:/media:ro \
obeloThen open http://localhost:8080 and go to First Run.
-
:8080— the web app and API, on the same origin. -
/data— the one writable directory: SQLite database, artwork and subtitle caches, transcode scratch, TLS material. Mount a volume, or you lose your library, your users, and your certificates on every restart. - Your media — mount anywhere, read-only. You will point libraries at these container paths from the web UI, so remember what you mounted them as.
The Docker page covers compose files, GPU passthrough, host networking, and updates.
Building on an arm64 host still produces a linux/amd64 image — the Go
binary is pure Go and cross-compiles, and the runtime stage is pinned to amd64.
If your Docker cannot run amd64 images locally, use buildx:
docker buildx build --platform linux/amd64 -f docker/Dockerfile -t obelo . --loadgit clone https://github.com/goozakdev/obelo-server.git
cd obelo-server
make build # web bundle first, then the Go binary that embeds it
./bin/obelomake build enforces the required order: the React/Vite SPA is bundled into
internal/webui/dist before go build, because the binary embeds it with
go:embed. Running go build on a fresh clone by hand skips that step and
gives you a server that serves a blank page.
By default the server listens on :8080 and stores state in ./data.
| Target | What it does |
|---|---|
make build |
Development build (web bundle → Go binary). |
make build-release |
The artifact that ships — same, but with the tailscale build tag. |
make run |
Build, then run the server. |
make test |
Go tests, then the web suite, then the Playwright E2E suite. |
make check |
Formatting, vet, the Go suite twice (with and without the tailscale tag), and the web checks. |
make fmt |
gofmt the tree. |
make clean |
Remove build outputs. |
This is the one build-from-source gotcha worth knowing about.
The embedded Tailscale node (Remote Access with Tailscale)
is compiled in only under -tags tailscale. A plain make build does not
include it — deliberately, because the tag pulls in roughly 550 dependencies
that a development build has no use for.
-
make build-release(orTAGS=tailscale make build) produces the shipped artifact, and matches whatdocker/Dockerfileproduces. - The two differ in exactly one advertised capability —
features.tailscaleinGET /api/v1/server— and in nothing else. - A build without the tag answers the remote-access endpoints with an error
naming the build, rather than a confusing
404.
Check what you are running:
curl -s http://localhost:8080/api/v1/server | grep -o '"tailscale":[a-z]*'If you want remote access over a tailnet, use the Docker image or
make build-release.
| Path | What lives there |
|---|---|
OBELO_DATA_DIR (default ./data, /data in Docker) |
Everything writable. |
…/obelo.db |
SQLite: libraries, items, users, watch state, settings. |
…/artwork/, …/subtitles/
|
Caches. Safe to delete; they refill. |
…/acme/ |
ACME account key and issued certificates (mode 0700). Not safe to delete — see HTTPS. |
…/transcode/ |
Transcode scratch. Cleaned up as sessions end. |
Back up obelo.db. The caches will rebuild themselves; your library
organization, hand-edits, users and watch history will not.
→ First Run — claim the admin account and create your first library.
Getting started
Reference
Going further
Plugins
Sharing with another household
Reaching it from away
When it breaks