Phase 3: Go hygiene pass, runtime PUID/PGID, fork README
continuous-integration/drone/push Build encountered an error
continuous-integration/drone/push Build encountered an error
Go: - staticcheck 399 -> 0 with staticcheck.conf (style checks ST1000/1003/ 1005/1016/1020/1021/1022 excluded; error strings are shown in the UI). - io/ioutil and rand.Seed removed; CloseNotifier kept with a lint-ignore until the Phase 2 context rewrite. - Dead code deleted: Auto handler, getStreamByChannelID, updateXEPG, indexOfInt, jsonToMapInt64, removeOldSystemData, randomTime, and the commented-out blocks in struct-buffer.go and internal/authentication. - Duplicates folded: cacheImagesInBackground(), one addErrorToStream(). - Bugs found by SA4006/SA5001: os.Create handle leaked per ffmpeg segment (buffer.go), http.NewRequest error unchecked (buffer.go), xepg.json migration wrote null on read error (migrate.go), WriteUserData errors silently dropped (authentication.go), defer Close before error check (buffer.go, toolchain.go). checkFilePermission results were discarded; an unwritable config or temp dir is now fatal at start-up. - gofmt applied repo-wide; Drone runs gofmt check and staticcheck. Docker: - Entrypoint starts as root, applies PUID/PGID (falls back to XTEVE_UID/ XTEVE_GID, then image defaults), fixes config ownership only when it differs, then drops to xteve via su-exec. --user starts skip all of it. - /xteve removed from LEGACY_CONFIG_DIRS (it is the parent of the default). - mwader/static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config. - Compose files pull registry.coadcorp.com/nathan/xteve:latest, use PUID/PGID/TZ, and explain that SSDP needs host networking. - .dockerignore excludes the npm toolchain (bundle stays in html/js). Docs: README rewritten for the fork (about, registry, compose, env vars, security notes); README-DEV gains a container section.
This commit is contained in:
@@ -4,13 +4,27 @@
|
||||
<br>
|
||||
|
||||
# xTeVe
|
||||
## M3U Proxy for Plex DVR and Emby Live TV.
|
||||
## M3U Proxy for Plex DVR and Emby Live TV.
|
||||
|
||||
Documentation for setup and configuration is [here](https://github.com/xteve-project/xTeVe-Documentation/blob/master/en/configuration.md).
|
||||
|
||||
#### Donation
|
||||
* **Bitcoin:** 1c1iCe4CJPfNUXtqxKBbW2Qd2EtqRPWme
|
||||

|
||||
## About this fork
|
||||
|
||||
The upstream xTeVe project has been inactive since 2021. This fork is maintained privately for a single trusted LAN. It is Docker-only and built for amd64 only. There are no release archives and no self-update.
|
||||
|
||||
What it adds over upstream:
|
||||
|
||||
* Web UI redesign with a mobile and accessibility pass (responsive navigation, keyboard flow, focus visibility, ARIA announcements, contrast).
|
||||
* Plex API guide refresh: after a lineup or XEPG update xTeVe can ask Plex to reload the DVR guide. New settings: `use_plexAPI`, `plex.url`, `plex.token`.
|
||||
* Strict or relaxed handling of channels whose EPG source went missing in XEPG, with automatic re-mapping.
|
||||
* A wizard-completed flag so the setup wizard is not shown again on restart.
|
||||
* First-party Docker image with a static ffmpeg, runtime `PUID`/`PGID`, and a healthcheck.
|
||||
* Drone CI: vet, tests, web bundle check, Dockerfile lint, compose validation, image publishing.
|
||||
* Web UI embedded in the binary with `go:embed`.
|
||||
* Unauthenticated `GET /healthz` endpoint for container health checks.
|
||||
* The self-updater and the GitHub branch switching are removed.
|
||||
|
||||
The plan for further work is in `tasks/improvement-plan.md`.
|
||||
|
||||
## Requirements
|
||||
### Plex
|
||||
@@ -23,7 +37,7 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
|
||||
* Emby Client with Live-TV support
|
||||
* Emby Premiere
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
@@ -48,164 +62,82 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
|
||||
|
||||
---
|
||||
|
||||
## Project Analysis (UI + Operations)
|
||||
## Running the container
|
||||
|
||||
The core architecture is strong: a Go backend with websocket-driven UI updates, filesystem-based state, and very low runtime overhead.
|
||||
The weakest points are mostly operational and UX-focused:
|
||||
### Image
|
||||
|
||||
* UI was historically utility-first and desktop-biased, with limited responsive behavior and visual hierarchy.
|
||||
* Container usage was documented externally but there was no first-party Dockerfile/compose setup in this repository.
|
||||
* Static web assets are generated into `src/webUI.go`, which works, but creates large diffs and a heavier edit/build cycle.
|
||||
The image is built by Drone and pushed to a private registry:
|
||||
|
||||
### Recommended next technical improvements
|
||||
|
||||
1. Replace generated `src/webUI.go` with Go `embed` for simpler static asset management and cleaner PR diffs.
|
||||
2. Add CI checks (`go test ./...`, build on Linux/arm64/amd64, docker build smoke test).
|
||||
3. Add a dedicated health endpoint (for example `/healthz`) to decouple health checks from HDHomeRun endpoints.
|
||||
4. Add integration tests around websocket commands that mutate settings/files to reduce regression risk.
|
||||
|
||||
---
|
||||
|
||||
## Container-First Run (Included In This Repo)
|
||||
|
||||
### Build image
|
||||
```bash
|
||||
docker build -t xteve:local .
|
||||
```
|
||||
registry.coadcorp.com/nathan/xteve
|
||||
```
|
||||
|
||||
### Run with Docker Compose (bridge mode)
|
||||
Tags:
|
||||
|
||||
* `latest` and `<commit sha>` from the `master` branch.
|
||||
* `<branch name>` and `<commit sha>` from every other branch.
|
||||
|
||||
```bash
|
||||
docker pull registry.coadcorp.com/nathan/xteve:latest
|
||||
```
|
||||
|
||||
The image is linux/amd64 only.
|
||||
|
||||
### Start with Docker Compose
|
||||
|
||||
Bridge mode (default). The web UI is on port 34400.
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Compose file: `docker-compose.yml`
|
||||
Persistent config volume: `./docker-data/config:/xteve/config`
|
||||
Host networking. Use this if you want Plex or Emby to discover the tuner by SSDP/DLNA. Multicast does not cross the Docker bridge, so publishing UDP 1900 in bridge mode is not enough on its own. Linux only.
|
||||
|
||||
### Run with Docker Compose (host networking, Linux recommended for discovery)
|
||||
```bash
|
||||
docker compose -f docker-compose.host.yml up -d
|
||||
```
|
||||
|
||||
Host networking improves LAN discovery behavior (SSDP/DLNA) for Plex/Emby in many setups.
|
||||
In bridge mode you can still add the tuner manually in Plex or Emby with `http://<host-ip>:34400`.
|
||||
|
||||
### Container environment variables
|
||||
Both compose files pull `registry.coadcorp.com/nathan/xteve:latest`. To build locally instead, uncomment the `build:` block in the compose file, or run `docker build -t xteve:local .`.
|
||||
|
||||
* `XTEVE_CONFIG` (default: `/xteve/config`)
|
||||
* `XTEVE_PORT` (default: `34400`)
|
||||
### Environment variables
|
||||
|
||||
### Image details
|
||||
| Variable | Default | Meaning |
|
||||
|---|---|---|
|
||||
| `XTEVE_CONFIG` | `/xteve/config` | Config directory inside the container. |
|
||||
| `XTEVE_PORT` | `34400` | HTTP port xTeVe listens on. |
|
||||
| `PUID` | `1000` | User id xTeVe runs as. Set it to the owner of the host config directory. |
|
||||
| `PGID` | `1000` | Group id xTeVe runs as. |
|
||||
| `TZ` | unset (UTC) | Time zone, for example `Australia/Sydney`. |
|
||||
|
||||
* Multi-stage build (Go builder + minimal Alpine runtime)
|
||||
* Runs as non-root user (`xteve`)
|
||||
* Built-in healthcheck against `http://127.0.0.1:${XTEVE_PORT}/healthz`
|
||||
The container starts as root, sets the `xteve` user to `PUID`/`PGID`, fixes the ownership of the config directory if needed, and then drops to that user before starting xTeVe. If the container is started with `--user`, the ids are left alone and xTeVe runs as the given user. The old `XTEVE_UID`/`XTEVE_GID` variables are still accepted as aliases.
|
||||
|
||||
### Volume
|
||||
|
||||
The config lives in `/xteve/config` (declared as a volume in the image). The compose files bind it to `./docker-data/config`. It holds `settings.json`, the mapping and EPG data, backups and the cache, so it is small enough to back up as a whole.
|
||||
|
||||
If an older container kept its config in `/config` or `/home/xteve/.xteve`, the entrypoint copies it to the new location on first start.
|
||||
|
||||
### Healthcheck
|
||||
|
||||
The image has a `HEALTHCHECK` that requests `http://127.0.0.1:${XTEVE_PORT}/healthz` every 30 seconds. The endpoint needs no authentication and returns the version and whether a scan is in progress. `docker ps` shows the state as `healthy` or `unhealthy`.
|
||||
|
||||
### ffmpeg
|
||||
|
||||
A static ffmpeg and ffprobe are in the image at `/usr/local/bin/ffmpeg` and `/usr/local/bin/ffprobe`, taken from the pinned `mwader/static-ffmpeg` image. In a container xTeVe defaults `ffmpeg.path` to that location. VLC is not included.
|
||||
|
||||
---
|
||||
|
||||
## Downloads v2 | 64 Bit only
|
||||
#### 64 Bit Intel / AMD
|
||||
## Security notes
|
||||
|
||||
* [Windows](https://github.com/xteve-project/xTeVe-Downloads/blob/master/xteve_windows_amd64.zip?raw=true)
|
||||
* [OS X](https://github.com/xteve-project/xTeVe-Downloads/blob/master/xteve_darwin_amd64.zip?raw=true)
|
||||
* [Linux](https://github.com/xteve-project/xTeVe-Downloads/blob/master/xteve_linux_amd64.zip?raw=true)
|
||||
* [FreeBSD](https://github.com/xteve-project/xTeVe-Downloads/blob/master/xteve_freebsd_amd64.zip?raw=true)
|
||||
|
||||
#### 64 Bit ARM
|
||||
* [Linux](https://github.com/xteve-project/xTeVe-Downloads/blob/master/xteve_linux_arm64.zip?raw=true)
|
||||
|
||||
#### Recommended Docker Image (Linux 64 Bit)
|
||||
Thanks to @alturismo and @LeeD for creating the Docker Images.
|
||||
|
||||
**Created by alturismo:**
|
||||
[xTeVe](https://hub.docker.com/r/alturismo/xteve)
|
||||
[xTeVe / Guide2go](https://hub.docker.com/r/alturismo/xteve_guide2go)
|
||||
[xTeVe / Guide2go / owi2plex](https://hub.docker.com/r/alturismo/xteve_g2g_owi)
|
||||
|
||||
Including:
|
||||
- Guide2go: XMLTV grabber for Schedules Direct
|
||||
- owi2plex: XMLTV file grabber for Enigma receivers
|
||||
|
||||
**Created by LeeD:**
|
||||
[xTeVe / Guide2go / Zap2XML](https://hub.docker.com/r/dnsforge/xteve)
|
||||
|
||||
Including:
|
||||
- Guide2go: XMLTV grabber for Schedules Direct
|
||||
- Zap2XML: Perl based zap2it XMLTV grabber
|
||||
- Bash: A Unix / Linux shell
|
||||
- Crond: Daemon to execute scheduled commands
|
||||
- Perl: Programming language
|
||||
* This fork is meant for a trusted LAN. Do not put it on the internet.
|
||||
* Web authentication is off by default. Turn it on under Settings > Authentication before you expose it any further than the LAN, for example through a reverse proxy.
|
||||
* `/healthz` is always unauthenticated. It reveals the version and scan state only.
|
||||
* The container starts as root to apply `PUID`/`PGID` and then drops privileges. Start it with `--user` if you prefer it never to run as root.
|
||||
|
||||
---
|
||||
|
||||
### xTeVe Beta branch
|
||||
New features and bug fixes are only available in beta branch. Only after successful testing are they are merged into the master branch.
|
||||
|
||||
**It is not recommended to use the beta version in a production system.**
|
||||
|
||||
With the command line argument `branch` the Git Branch can be changed. xTeVe must be started via the terminal.
|
||||
|
||||
#### Switch from master to beta branch:
|
||||
```
|
||||
xteve -branch beta
|
||||
|
||||
...
|
||||
[xTeVe] GitHub: https://github.com/xteve-project
|
||||
[xTeVe] Git Branch: beta [xteve-project]
|
||||
...
|
||||
```
|
||||
|
||||
#### Switch from beta to master branch:
|
||||
```
|
||||
xteve -branch master
|
||||
|
||||
...
|
||||
[xTeVe] GitHub: https://github.com/xteve-project
|
||||
[xTeVe] Git Branch: master [xteve-project]
|
||||
...
|
||||
```
|
||||
|
||||
When the branch is changed, an update is only performed if there is a new version and the update function is activated in the settings.
|
||||
|
||||
---
|
||||
|
||||
## Build from source code [Go / Golang]
|
||||
|
||||
#### Requirements
|
||||
* [Go](https://golang.org) (go1.16.2 or newer)
|
||||
|
||||
#### Dependencies
|
||||
* [go-ssdp](https://github.com/koron/go-ssdp)
|
||||
* [websocket](https://github.com/gorilla/websocket)
|
||||
* [osext](https://github.com/kardianos/osext)
|
||||
|
||||
#### Build
|
||||
1. Download source code
|
||||
2. Install dependencies
|
||||
```
|
||||
go get github.com/koron/go-ssdp
|
||||
go get github.com/gorilla/websocket
|
||||
go get github.com/kardianos/osext
|
||||
```
|
||||
3. Build xTeVe
|
||||
```
|
||||
go build xteve.go
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fork without pull request :mega:
|
||||
When creating a fork, the xTeVe GitHub account must be changed from the source code or the update function disabled.
|
||||
Future updates of the xteve-project would update your fork. :wink:
|
||||
|
||||
xteve.go - Line: 29
|
||||
```Go
|
||||
var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-Downloads", Update: true}
|
||||
|
||||
/*
|
||||
Branch: GitHub Branch
|
||||
User: GitHub Username
|
||||
Repo: GitHub Repository
|
||||
Update: Automatic updates from the GitHub repository [true|false]
|
||||
*/
|
||||
|
||||
```
|
||||
## Development
|
||||
|
||||
See [README-DEV.md](README-DEV.md) for the layout, how to build the binary and the web UI, and how CI publishes the image.
|
||||
|
||||
Reference in New Issue
Block a user