122 lines
4.7 KiB
Markdown
122 lines
4.7 KiB
Markdown
# Developing Silo
|
|
|
|
This document covers building, running, and contributing to the Silo server. If you just want to run Silo, see the [README](README.md).
|
|
|
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution expectations, merge request guidance, and the policy for AI-assisted submissions.
|
|
|
|
## Prerequisites
|
|
|
|
- **Go** 1.26.4+
|
|
- **Node.js** 22+ with **pnpm** 10.32.1
|
|
- **PostgreSQL** 18 with pgvector
|
|
- **Redis**
|
|
- **FFmpeg** (for transcoding support)
|
|
|
|
## Local Development
|
|
|
|
Local development remains intentionally separate from the deploy-oriented compose setup. Use [docker-compose.yml](docker-compose.yml) for local services and the source-build workflow below.
|
|
|
|
```sh
|
|
# Create the local bootstrap configuration
|
|
cp .env.example .env
|
|
printf '\nSECRET_KEY=%s\nDATABASE_URL=%s\nREDIS_URL=%s\n' \
|
|
"$(openssl rand -base64 48)" \
|
|
'postgres://silo:silo@localhost:5432/silo?sslmode=disable' \
|
|
'redis://localhost:6379' >> .env
|
|
|
|
# Start local PostgreSQL and Redis
|
|
docker compose up -d postgres redis
|
|
|
|
# Run the frontend dev server (hot reload, proxies API to :8090)
|
|
make dev-frontend
|
|
|
|
# Run the Go backend
|
|
make dev-backend
|
|
```
|
|
|
|
The template supplies a non-empty `MEDIA_ROOT` because Compose validates the whole file even when
|
|
you start only PostgreSQL and Redis. Change it before testing libraries against real media.
|
|
|
|
If you are developing `Silo` and `silo-plugin-sdk` together, keep using the local [`go.work`](go.work) workspace. That workspace is a developer convenience only. CI and release builds run with `GOWORK=off`, so any new SDK helper used here must be pushed and tagged in `silo-plugin-sdk` before this repo can merge or release the change.
|
|
|
|
Plugin authors should start with [docs/architecture/plugin-development.md](docs/architecture/plugin-development.md), which covers the RPC plugin package format, generated proto workflow, SDK import paths, route and asset exposure, and auth or user-config integration points.
|
|
|
|
## Make Targets
|
|
|
|
| Target | Description |
|
|
|---|---|
|
|
| `make build` | Build frontend + Go binary |
|
|
| `make frontend` | Build frontend only |
|
|
| `make dev-frontend` | Vite dev server with HMR |
|
|
| `make dev-backend` | Run Go backend (integrated mode) |
|
|
| `make dev-proxy` | Run a standalone proxy node |
|
|
| `make dev-transcode` | Run a standalone transcode node |
|
|
| `make migrate-create NAME=add_thing` | Create a timestamped Goose SQL migration |
|
|
| `make migrate-validate` | Validate Goose migration files without touching a database |
|
|
| `make migrate-status` | Show Goose migration status using Silo's bootstrapping runner |
|
|
| `make migrate-up` | Apply pending Goose migrations using Silo's bootstrapping runner |
|
|
| `make clean` | Remove build artifacts |
|
|
|
|
## Database Migrations
|
|
|
|
PostgreSQL schema migrations are managed by Goose. Migration SQL files live in
|
|
`migrations/sql/` and use Goose annotations. Converted legacy migrations keep
|
|
their original numeric versions so existing `schema_versions` rows can bootstrap
|
|
cleanly into Goose without replaying old SQL. New migrations should be created
|
|
with timestamped filenames:
|
|
|
|
```sh
|
|
make migrate-create NAME=add_thing
|
|
make migrate-validate
|
|
```
|
|
|
|
Do not run `goose fix`; timestamped migrations are the repository policy because
|
|
they avoid version collisions across parallel PRs. The existing `001`-style
|
|
files are historical compatibility records, not the naming pattern for new work.
|
|
Runtime migrations are applied by the integrated/API server only. Proxy and
|
|
transcode modes never mutate schema.
|
|
For existing installs, use `make migrate-status` and `make migrate-up` rather
|
|
than invoking the Goose CLI directly; those targets copy legacy
|
|
`schema_versions` rows into `public.goose_db_version` under the migration lock
|
|
before reading or applying migrations. Set `ENV_FILE=path/to/.env` when the
|
|
database URL should be read from a non-default env file.
|
|
|
|
## Running Tests
|
|
|
|
```sh
|
|
# Go tests (uses testcontainers — Docker must be running)
|
|
go test ./...
|
|
|
|
# Frontend tests
|
|
cd web && pnpm test
|
|
```
|
|
|
|
## Linting
|
|
|
|
```sh
|
|
# Go
|
|
golangci-lint run
|
|
|
|
# Frontend
|
|
cd web && pnpm run lint
|
|
cd web && pnpm run format:check
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
cmd/silo/ Entry point
|
|
internal/
|
|
api/ HTTP router, handlers, middleware
|
|
auth/ JWT authentication and sessions
|
|
catalog/ Media item, episode, season repositories
|
|
config/ YAML + env var configuration
|
|
jellycompat/ Jellyfin/Emby protocol compatibility
|
|
metadata/ Plugin-driven metadata matching and enrichment
|
|
playback/ Direct play, remux, transcode session management
|
|
scanner/ Media file discovery and FFProbe
|
|
worker/ Background jobs (scan, match, reconcile)
|
|
web/ React + TypeScript frontend (Vite, Tailwind, shadcn/ui)
|
|
migrations/sql/ Goose-managed PostgreSQL schema migrations
|
|
```
|