Merge pull request #263 from outis1one/claude/traccar-installation-issues-3scwv7
Claude/traccar installation issues 3scwv7
This commit is contained in:
@@ -304,6 +304,18 @@ Writes `$DIR/README.md` (creates the directory if needed). No-ops in DRY_RUN.
|
||||
Every Docker service should call this so `~/docker/<name>/README.md` is
|
||||
self-documenting on the deployed box.
|
||||
|
||||
**Companion doc files.** If `services/<name>.md` exists next to
|
||||
`services/<name>.sh`, `write_readme` appends its contents automatically —
|
||||
no per-service code needed to opt in, just add the file. It's outside
|
||||
`setup.sh`'s `services/*.sh` glob so it never registers or runs on its own;
|
||||
it's purely markdown that gets tacked onto the generated README. Use it for
|
||||
walkthroughs that don't depend on anything chosen at install time (linking
|
||||
steps in a third-party UI, multi-account setup, troubleshooting notes) —
|
||||
content like that bloats the heredoc without adding anything install-specific.
|
||||
Keep the heredoc for content that *does* depend on install-time values (the
|
||||
actual port chosen, generated credentials, etc.); use `services/<name>.md`
|
||||
for everything else. See `services/traccar.md` for the reference example.
|
||||
|
||||
## Categories
|
||||
|
||||
| Group | Purpose |
|
||||
|
||||
@@ -259,115 +259,14 @@ The wizard shows the detected OS in the header and warns on unknown versions.
|
||||
|
||||
## Gaming scripts
|
||||
|
||||
Standalone scripts in `scripts/` for gaming setup — not part of the main
|
||||
wizard, run separately.
|
||||
Gaming setup walkthroughs live next to their service files, not here — see
|
||||
`services/<name>.md` (e.g. [`services/kyber-launcher.md`](services/kyber-launcher.md)
|
||||
for SWBF2 (2017) + Kyber: playing, hosting, and troubleshooting). It's
|
||||
appended automatically to `~/.local/share/kyber/README.md` when you run
|
||||
`sudo ./setup.sh kyber-launcher`.
|
||||
|
||||
### Star Wars Battlefront II (2017) + Kyber
|
||||
|
||||
**`scripts/setup-swbf2-linux.sh`** — Configure SWBF2 on native Linux Steam
|
||||
(Proton, controller, performance tweaks).
|
||||
|
||||
**`scripts/setup-kyber-linux.sh`** — Install the native Linux Kyber launcher.
|
||||
|
||||
Kyber is the community multiplayer replacement for SWBF2 after EA shut down
|
||||
official servers in 2022. It went open-source (GPL) in January 2026.
|
||||
|
||||
**The correct approach is a native Linux AppImage** — not Wine or Proton for
|
||||
the launcher itself. The AppImage is maintained at:
|
||||
https://github.com/simonlinuxcraft/kyber-linuxport-unofficial
|
||||
|
||||
```bash
|
||||
chmod +x scripts/setup-kyber-linux.sh
|
||||
./scripts/setup-kyber-linux.sh
|
||||
```
|
||||
|
||||
The script downloads the latest AppImage, installs a desktop entry, and
|
||||
creates a `kyber` command in `~/.local/bin`.
|
||||
|
||||
**Every time you want to play:**
|
||||
1. Open **Steam** (must be running for library validation) — do NOT click Play on SWBF2
|
||||
2. Launch **Kyber** (`kyber` or from the app menu)
|
||||
3. In Kyber: join a server (HOME) or create one (HOST)
|
||||
4. Kyber/Maxima launches SWBF2 via its own bundled GE-Proton — wait 1-3 minutes
|
||||
5. If the SWBF2 window appears but won't focus: press **Alt+Tab** or click its
|
||||
taskbar entry — this is normal when the game is launched by a wrapper process
|
||||
|
||||
Do NOT launch SWBF2 from Steam directly. If Steam's SWBF2 is already running
|
||||
when Kyber starts, kill it first — Kyber cannot inject into a Steam-launched instance.
|
||||
|
||||
**If Kyber says "Game Not Found":**
|
||||
Click **SET GAME FOLDER** and point it to the SWBF2 install directory.
|
||||
Find it with:
|
||||
```bash
|
||||
find ~/.steam/steam/steamapps -name "starwarsbattlefrontii.exe" 2>/dev/null | head -1 | xargs dirname
|
||||
```
|
||||
Paste that path into the SET GAME FOLDER dialog.
|
||||
|
||||
**If Origin Error: "title installed in language not entitled to play":**
|
||||
Maxima's Wine prefix is missing locale registry keys — its setup commands fail silently on some systems. Fix:
|
||||
```bash
|
||||
cat > /tmp/swbf2_fix.reg << 'EOF'
|
||||
Windows Registry Editor Version 5.00
|
||||
[HKEY_LOCAL_MACHINE\Software\Origin Games\1035052]
|
||||
"locale"="en_US"
|
||||
"displayname"="STAR WARS Battlefront II"
|
||||
[HKEY_LOCAL_MACHINE\Software\Wow6432Node\Origin Games\1035052]
|
||||
"locale"="en_US"
|
||||
"displayname"="STAR WARS Battlefront II"
|
||||
[HKEY_LOCAL_MACHINE\Software\Electronic Arts\EA Desktop]
|
||||
"InstallSuccessful"="true"
|
||||
[HKEY_LOCAL_MACHINE\Software\Origin]
|
||||
"InstallSuccessful"="true"
|
||||
"ClientPath"="C:\\Windows\\System32\\conhost.exe"
|
||||
[HKEY_CURRENT_USER\Control Panel\International]
|
||||
"Locale"="00000409"
|
||||
"LocaleName"="en-US"
|
||||
"sLanguage"="ENU"
|
||||
EOF
|
||||
WINEPREFIX=~/.local/share/maxima/wine/prefix wine64 regedit /tmp/swbf2_fix.reg
|
||||
```
|
||||
Then restart Kyber and try again.
|
||||
|
||||
**First run (one-time setup):**
|
||||
1. Click **EA Account** → log in with your EA credentials in the browser
|
||||
2. Click **Skip** on Nexus Mods (optional, only needed for mods)
|
||||
3. EA login is cached — you stay logged in across sessions
|
||||
|
||||
**Hosting a private server with bots:**
|
||||
- HOST → pick maps/modes → set a **name** and **PASSWORD** → Start Server
|
||||
- Share the server name + password with friends; they search by name in HOME
|
||||
- Bot count: in the HOST panel right side → **AUTOPLAYERS** section →
|
||||
set **BOTS TEAM 1** and **BOTS TEAM 2** (e.g. 4 each) → click **UPDATE SERVER**
|
||||
- Bot difficulty: the **BOT DIFFICULTY** slider (RECRUIT → OFFICER → KNIGHT → MASTER)
|
||||
- After the game loads you can also update settings live and hit UPDATE SERVER again
|
||||
|
||||
**Requirements:**
|
||||
- SWBF2 (Steam AppID 1237950) installed via Steam
|
||||
(Kyber manages its own GE-Proton for launching the game)
|
||||
- glibc 2.38+ — Ubuntu 24.04+, Fedora 38+, SteamOS 3.7+
|
||||
- EA account (free) at ea.com
|
||||
- Unprivileged user namespaces enabled (Ubuntu 24.04 restricts these by default):
|
||||
```bash
|
||||
sudo sysctl -w kernel.unprivileged_userns_clone=1
|
||||
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
||||
```
|
||||
The setup script applies this automatically when run with sudo and saves it
|
||||
to `/etc/sysctl.d/99-userns.conf` to persist across reboots.
|
||||
Without this fix Kyber fails with: `bwrap: setting up uid map: Permission denied`
|
||||
|
||||
**If SWBF2 crashes immediately when a level starts loading:**
|
||||
Likely a DXVK rendering issue, especially on integrated GPUs (Intel Iris Xe, etc.).
|
||||
Disable fullscreen and HDR in the game settings file — the game writes this on first run:
|
||||
```bash
|
||||
PROFILE=$(find ~/.local/share/maxima -name "ProfileOptions_profile" 2>/dev/null | head -1)
|
||||
sed -i 's/GstRender.FullscreenEnabled 1/GstRender.FullscreenEnabled 0/' "$PROFILE"
|
||||
sed -i 's/GstRender.EnableHDR 1/GstRender.EnableHDR 0/' "$PROFILE"
|
||||
```
|
||||
Then restart Kyber and try hosting/joining again.
|
||||
|
||||
**What does NOT work:**
|
||||
- Running the Windows `kyber_launcher.exe` under Wine/Proton: EA's auth
|
||||
callback uses the `eadesktop://` URI scheme which has no Linux handler,
|
||||
and Wine's cmd.exe crashes on long OAuth URLs anyway
|
||||
- Running Kyber inside Wolf/Games-on-Whales: the Docker double-sandbox
|
||||
blocks the user namespace clone that Proton requires
|
||||
Also in `scripts/` (standalone, not part of the main wizard):
|
||||
`setup-swbf2-linux.sh` (native Steam/Proton fixes for the base game),
|
||||
`setup-kyber-linux.sh` (standalone equivalent of the `kyber-launcher`
|
||||
service), and Wolf/Games-on-Whales container variants
|
||||
(`setup-swbf2-wolf.sh`, `setup-kyber-wolf.sh`).
|
||||
|
||||
@@ -472,6 +472,13 @@ prompt_reinstall_mode() {
|
||||
# # Title
|
||||
# ...
|
||||
# MD
|
||||
#
|
||||
# If services/<name>.md exists next to the calling services/<name>.sh, its
|
||||
# contents are appended automatically. That file is optional and untouched by
|
||||
# setup.sh's services/*.sh glob (doesn't register, doesn't run) — it's just a
|
||||
# place for install-time-invariant walkthroughs (multi-step UI instructions,
|
||||
# third-party linking, etc.) that would otherwise bloat the heredoc above with
|
||||
# content that doesn't depend on any variable chosen during install.
|
||||
write_readme() {
|
||||
local dir="$1"
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
@@ -481,6 +488,16 @@ write_readme() {
|
||||
fi
|
||||
mkdir -p "$dir"
|
||||
cat > "$dir/README.md"
|
||||
|
||||
local caller_script="${BASH_SOURCE[1]:-}"
|
||||
if [ -n "$caller_script" ]; then
|
||||
local companion_doc="${caller_script%.sh}.md"
|
||||
if [ -f "$companion_doc" ]; then
|
||||
printf '\n' >> "$dir/README.md"
|
||||
cat "$companion_doc" >> "$dir/README.md"
|
||||
fi
|
||||
fi
|
||||
|
||||
chown "$ACTUAL_USER:$ACTUAL_USER" "$dir/README.md" 2>/dev/null || true
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
## Roles
|
||||
- **Open WebUI** (chat, research, light coding) — local Ollama + any cloud providers
|
||||
in one model dropdown; wired to your code via the RAG + MCP servers and Gitea.
|
||||
- **PaintPlus** (separate `paintplus` service) — the front end for all image work
|
||||
(inpaint / upscale / generate). Point its `AI_PROVIDER` at a cloud API, or at this
|
||||
stack's local `comfyui` / `invokeai` for local image-gen.
|
||||
- **Gitea + GitHub sync** — `bash gitea-github-sync.sh` mirrors repos both ways
|
||||
(pull GitHub → local git, or push local → GitHub).
|
||||
- **RAG / MCP / Kiwix** — retrieve just the relevant context so you feed the model
|
||||
less text (saves tokens), for both local and cloud models.
|
||||
- Web search uses **DuckDuckGo** (no SearXNG in this build).
|
||||
|
||||
## GPU switcher (small local GPU only)
|
||||
One small GPU can't run local chat and local image-gen at once. Swap it:
|
||||
```bash
|
||||
~/docker/ai-stack/gpu-mode.sh images # before generating locally in PaintPlus
|
||||
~/docker/ai-stack/gpu-mode.sh llm # back to local chat in Open WebUI
|
||||
~/docker/ai-stack/gpu-mode.sh status # see which is active
|
||||
```
|
||||
Cloud models work anytime and need no swap.
|
||||
|
||||
## Service URLs
|
||||
| Service | URL | Auth |
|
||||
|------------|---------------------------|---------------------|
|
||||
| Open WebUI | http://localhost:3000 | built-in (first visit = admin) |
|
||||
| InvokeAI | http://localhost:9090 | none |
|
||||
| ComfyUI | http://localhost:8188 | none |
|
||||
| Kiwix | http://localhost:8181 | none |
|
||||
| Gitea | http://localhost:3001 | built-in |
|
||||
| Portainer | https://localhost:9443 | built-in |
|
||||
|
||||
## Manage the stack
|
||||
```bash
|
||||
cd ~/docker/ai-stack
|
||||
bash start.sh # pull latest images + docker compose up -d
|
||||
bash stop.sh # docker compose down
|
||||
bash status.sh # GPU / container / RAG health
|
||||
bash pull-models.sh # pull Ollama models (run once after first install)
|
||||
```
|
||||
Also a systemd unit: `sudo systemctl {start,stop,status} local-ai`
|
||||
|
||||
## Cloud LLM providers (Open WebUI)
|
||||
Open WebUI uses an OpenAI-compatible connection list. The local RAG server is the
|
||||
first entry; any cloud providers added at install follow it. Two semicolon-separated
|
||||
lists in `.env`, matched by position (RAG must stay first):
|
||||
```bash
|
||||
# ~/docker/ai-stack/.env
|
||||
OPENAI_API_BASE_URLS=http://rag-server:8001/v1;https://api.groq.com/openai/v1
|
||||
OPENAI_API_KEYS=local-rag;gsk_xxx
|
||||
cd ~/docker/ai-stack && docker compose up -d open-webui # apply
|
||||
```
|
||||
| Provider | Base URL | Key |
|
||||
|----------|----------|-----|
|
||||
| Groq | `https://api.groq.com/openai/v1` | https://console.groq.com/keys |
|
||||
| DeepInfra | `https://api.deepinfra.com/v1/openai` | https://deepinfra.com/dash/api_keys |
|
||||
| OpenAI | `https://api.openai.com/v1` | https://platform.openai.com/api-keys |
|
||||
| OpenRouter | `https://openrouter.ai/api/v1` | https://openrouter.ai/keys |
|
||||
|
||||
Alternatively, add them at runtime in Open WebUI → Settings → Admin → Connections
|
||||
(no file edits, survives image upgrades).
|
||||
|
||||
## Update
|
||||
Re-run the `ai-stack` installer (refreshes vendored source, keeps your `.env`),
|
||||
then `bash ~/docker/ai-stack/start.sh`. Or in place:
|
||||
`cd ~/docker/ai-stack && bash local-ai-setup.sh --force`.
|
||||
|
||||
## Caddy
|
||||
Open WebUI is reverse-proxied as `open-webui:8080` on `caddy_net` (or your
|
||||
configured Caddy network name; attached with `docker network connect` after
|
||||
start). Other services are LAN-only by default — add Caddy site blocks for
|
||||
them if you want remote access.
|
||||
+9
-70
@@ -232,82 +232,21 @@ GPUEOF
|
||||
configure_caddy_for_service "Open WebUI" "open-webui:8080" "ai"
|
||||
|
||||
# ── Deploy notes (the app's own docs stay at $AS_DIR/README.md) ───────────
|
||||
# Filename is deliberately not README.md — that name is already taken by
|
||||
# the vendored app's own docs, copied into this same directory above.
|
||||
# Static content (roles, GPU switcher, service URLs, etc.) lives in the
|
||||
# companion services/ai-stack.md and gets appended below, same idea as
|
||||
# write_readme's own companion-doc convention (lib/common.sh) but manual
|
||||
# here since write_readme always targets README.md.
|
||||
cat > "$AS_DIR/POST-INSTALL-NOTES.md" << MD
|
||||
# Local AI Stack — deployment notes (ubuntu-post-install)
|
||||
|
||||
Vendored app source copied here from the \`ai-stack\` service. Full app docs:
|
||||
\`README.md\` in this directory. Source: github.com/outis1one/local-ai
|
||||
|
||||
## Roles
|
||||
- **Open WebUI** (chat, research, light coding) — local Ollama + any cloud providers
|
||||
in one model dropdown; wired to your code via the RAG + MCP servers and Gitea.
|
||||
- **PaintPlus** (separate \`paintplus\` service) — the front end for all image work
|
||||
(inpaint / upscale / generate). Point its \`AI_PROVIDER\` at a cloud API, or at this
|
||||
stack's local \`comfyui\` / \`invokeai\` for local image-gen.
|
||||
- **Gitea + GitHub sync** — \`bash gitea-github-sync.sh\` mirrors repos both ways
|
||||
(pull GitHub → local git, or push local → GitHub).
|
||||
- **RAG / MCP / Kiwix** — retrieve just the relevant context so you feed the model
|
||||
less text (saves tokens), for both local and cloud models.
|
||||
- Web search uses **DuckDuckGo** (no SearXNG in this build).
|
||||
|
||||
## GPU switcher (small local GPU only)
|
||||
One small GPU can't run local chat and local image-gen at once. Swap it:
|
||||
\`\`\`bash
|
||||
$AS_DIR/gpu-mode.sh images # before generating locally in PaintPlus
|
||||
$AS_DIR/gpu-mode.sh llm # back to local chat in Open WebUI
|
||||
$AS_DIR/gpu-mode.sh status # see which is active
|
||||
\`\`\`
|
||||
Cloud models work anytime and need no swap.
|
||||
|
||||
## Service URLs
|
||||
| Service | URL | Auth |
|
||||
|------------|---------------------------|---------------------|
|
||||
| Open WebUI | http://localhost:3000 | built-in (first visit = admin) |
|
||||
| InvokeAI | http://localhost:9090 | none |
|
||||
| ComfyUI | http://localhost:8188 | none |
|
||||
| Kiwix | http://localhost:8181 | none |
|
||||
| Gitea | http://localhost:3001 | built-in |
|
||||
| Portainer | https://localhost:9443 | built-in |
|
||||
|
||||
## Manage the stack
|
||||
\`\`\`bash
|
||||
cd $AS_DIR
|
||||
bash start.sh # pull latest images + docker compose up -d
|
||||
bash stop.sh # docker compose down
|
||||
bash status.sh # GPU / container / RAG health
|
||||
bash pull-models.sh # pull Ollama models (run once after first install)
|
||||
\`\`\`
|
||||
Also a systemd unit: \`sudo systemctl {start,stop,status} local-ai\`
|
||||
|
||||
## Cloud LLM providers (Open WebUI)
|
||||
Open WebUI uses an OpenAI-compatible connection list. The local RAG server is the
|
||||
first entry; any cloud providers added at install follow it. Two semicolon-separated
|
||||
lists in \`.env\`, matched by position (RAG must stay first):
|
||||
\`\`\`bash
|
||||
# $AS_DIR/.env
|
||||
OPENAI_API_BASE_URLS=http://rag-server:8001/v1;https://api.groq.com/openai/v1
|
||||
OPENAI_API_KEYS=local-rag;gsk_xxx
|
||||
cd $AS_DIR && docker compose up -d open-webui # apply
|
||||
\`\`\`
|
||||
| Provider | Base URL | Key |
|
||||
|----------|----------|-----|
|
||||
| Groq | \`https://api.groq.com/openai/v1\` | https://console.groq.com/keys |
|
||||
| DeepInfra | \`https://api.deepinfra.com/v1/openai\` | https://deepinfra.com/dash/api_keys |
|
||||
| OpenAI | \`https://api.openai.com/v1\` | https://platform.openai.com/api-keys |
|
||||
| OpenRouter | \`https://openrouter.ai/api/v1\` | https://openrouter.ai/keys |
|
||||
|
||||
Alternatively, add them at runtime in Open WebUI → Settings → Admin → Connections
|
||||
(no file edits, survives image upgrades).
|
||||
|
||||
## Update
|
||||
Re-run the \`ai-stack\` installer (refreshes vendored source, keeps your \`.env\`),
|
||||
then \`bash $AS_DIR/start.sh\`. Or in place: \`cd $AS_DIR && bash local-ai-setup.sh --force\`.
|
||||
|
||||
## Caddy
|
||||
Open WebUI is reverse-proxied as \`open-webui:8080\` on \`${SITE_CADDY_NET:-caddy_net}\`
|
||||
(attached with \`docker network connect\` after start). Other services are LAN-only by
|
||||
default — add Caddy site blocks for them if you want remote access.
|
||||
MD
|
||||
if [ -f "$SELF_DIR/ai-stack.md" ]; then
|
||||
cat "$SELF_DIR/ai-stack.md" >> "$AS_DIR/POST-INSTALL-NOTES.md"
|
||||
fi
|
||||
ensure_docker_dir_ownership "$AS_DIR"
|
||||
|
||||
echo ""
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
## Star Wars Battlefront II (2017) + Kyber
|
||||
|
||||
Kyber is the community multiplayer replacement for SWBF2 after EA shut down
|
||||
official servers in 2022. It went open-source (GPL) in January 2026.
|
||||
|
||||
**The correct approach is a native Linux AppImage** — not Wine or Proton for
|
||||
the launcher itself. The AppImage is maintained at:
|
||||
https://github.com/simonlinuxcraft/kyber-linuxport-unofficial
|
||||
|
||||
This service (`sudo ./setup.sh kyber-launcher`) downloads the latest
|
||||
AppImage, installs a desktop entry, and creates a `kyber` command in
|
||||
`~/.local/bin`. A standalone equivalent also exists at
|
||||
`scripts/setup-kyber-linux.sh` for machines not running the full wizard.
|
||||
|
||||
**Every time you want to play:**
|
||||
1. Open **Steam** (must be running for library validation) — do NOT click Play on SWBF2
|
||||
2. Launch **Kyber** (`kyber` or from the app menu)
|
||||
3. In Kyber: join a server (HOME) or create one (HOST)
|
||||
4. Kyber/Maxima launches SWBF2 via its own bundled GE-Proton — wait 1-3 minutes
|
||||
5. If the SWBF2 window appears but won't focus: press **Alt+Tab** or click its
|
||||
taskbar entry — this is normal when the game is launched by a wrapper process
|
||||
|
||||
Do NOT launch SWBF2 from Steam directly. If Steam's SWBF2 is already running
|
||||
when Kyber starts, kill it first — Kyber cannot inject into a Steam-launched instance.
|
||||
|
||||
**If Kyber says "Game Not Found":**
|
||||
Click **SET GAME FOLDER** and point it to the SWBF2 install directory.
|
||||
Find it with:
|
||||
```bash
|
||||
find ~/.steam/steam/steamapps -name "starwarsbattlefrontii.exe" 2>/dev/null | head -1 | xargs dirname
|
||||
```
|
||||
Paste that path into the SET GAME FOLDER dialog.
|
||||
|
||||
**If Origin Error: "title installed in language not entitled to play":**
|
||||
Maxima's Wine prefix is missing locale registry keys — its setup commands fail silently on some systems. Fix:
|
||||
```bash
|
||||
cat > /tmp/swbf2_fix.reg << 'EOF'
|
||||
Windows Registry Editor Version 5.00
|
||||
[HKEY_LOCAL_MACHINE\Software\Origin Games\1035052]
|
||||
"locale"="en_US"
|
||||
"displayname"="STAR WARS Battlefront II"
|
||||
[HKEY_LOCAL_MACHINE\Software\Wow6432Node\Origin Games\1035052]
|
||||
"locale"="en_US"
|
||||
"displayname"="STAR WARS Battlefront II"
|
||||
[HKEY_LOCAL_MACHINE\Software\Electronic Arts\EA Desktop]
|
||||
"InstallSuccessful"="true"
|
||||
[HKEY_LOCAL_MACHINE\Software\Origin]
|
||||
"InstallSuccessful"="true"
|
||||
"ClientPath"="C:\\Windows\\System32\\conhost.exe"
|
||||
[HKEY_CURRENT_USER\Control Panel\International]
|
||||
"Locale"="00000409"
|
||||
"LocaleName"="en-US"
|
||||
"sLanguage"="ENU"
|
||||
EOF
|
||||
WINEPREFIX=~/.local/share/maxima/wine/prefix wine64 regedit /tmp/swbf2_fix.reg
|
||||
```
|
||||
Then restart Kyber and try again.
|
||||
|
||||
**First run (one-time setup):**
|
||||
1. Click **EA Account** → log in with your EA credentials in the browser
|
||||
2. Click **Skip** on Nexus Mods (optional, only needed for mods)
|
||||
3. EA login is cached — you stay logged in across sessions
|
||||
|
||||
**Hosting a private server with bots:**
|
||||
- HOST → pick maps/modes → set a **name** and **PASSWORD** → Start Server
|
||||
- Share the server name + password with friends; they search by name in HOME
|
||||
- Bot count: in the HOST panel right side → **AUTOPLAYERS** section →
|
||||
set **BOTS TEAM 1** and **BOTS TEAM 2** (e.g. 4 each) → click **UPDATE SERVER**
|
||||
- Bot difficulty: the **BOT DIFFICULTY** slider (RECRUIT → OFFICER → KNIGHT → MASTER)
|
||||
- After the game loads you can also update settings live and hit UPDATE SERVER again
|
||||
- For a headless, always-on dedicated server instead (no local Kyber client
|
||||
needed to host), see the separate `kyber-server` service.
|
||||
|
||||
**Requirements:**
|
||||
- SWBF2 (Steam AppID 1237950) installed via Steam
|
||||
(Kyber manages its own GE-Proton for launching the game)
|
||||
- glibc 2.38+ — Ubuntu 24.04+, Fedora 38+, SteamOS 3.7+
|
||||
- EA account (free) at ea.com
|
||||
- Unprivileged user namespaces enabled (Ubuntu 24.04 restricts these by default):
|
||||
```bash
|
||||
sudo sysctl -w kernel.unprivileged_userns_clone=1
|
||||
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
||||
```
|
||||
The setup script applies this automatically when run with sudo and saves it
|
||||
to `/etc/sysctl.d/99-userns.conf` to persist across reboots.
|
||||
Without this fix Kyber fails with: `bwrap: setting up uid map: Permission denied`
|
||||
|
||||
**If SWBF2 crashes immediately when a level starts loading:**
|
||||
Likely a DXVK rendering issue, especially on integrated GPUs (Intel Iris Xe, etc.).
|
||||
Disable fullscreen and HDR in the game settings file — the game writes this on first run:
|
||||
```bash
|
||||
PROFILE=$(find ~/.local/share/maxima -name "ProfileOptions_profile" 2>/dev/null | head -1)
|
||||
sed -i 's/GstRender.FullscreenEnabled 1/GstRender.FullscreenEnabled 0/' "$PROFILE"
|
||||
sed -i 's/GstRender.EnableHDR 1/GstRender.EnableHDR 0/' "$PROFILE"
|
||||
```
|
||||
Then restart Kyber and try hosting/joining again.
|
||||
|
||||
**What does NOT work:**
|
||||
- Running the Windows `kyber_launcher.exe` under Wine/Proton: EA's auth
|
||||
callback uses the `eadesktop://` URI scheme which has no Linux handler,
|
||||
and Wine's cmd.exe crashes on long OAuth URLs anyway
|
||||
- Running Kyber inside Wolf/Games-on-Whales: the Docker double-sandbox
|
||||
blocks the user namespace clone that Proton requires
|
||||
|
||||
**Fixing the base game on native Linux Steam** (EA Desktop/Origin
|
||||
registration, unrelated to Kyber itself) is a separate script:
|
||||
`scripts/setup-swbf2-linux.sh` — see that file's header for what it does
|
||||
and its prerequisites.
|
||||
@@ -223,7 +223,17 @@ EOF
|
||||
echo " Paste that path into Kyber's SET GAME FOLDER dialog."
|
||||
echo ""
|
||||
echo " Troubleshooting — 'Origin Error: language not entitled':"
|
||||
echo " See README.md Gaming section for the registry fix."
|
||||
echo " See $INSTALL_DIR/README.md for the registry fix."
|
||||
|
||||
write_readme "$INSTALL_DIR" << MD
|
||||
# Kyber Launcher
|
||||
|
||||
Native Linux AppImage client for SWBF2 (2017) community multiplayer.
|
||||
|
||||
- Launch: \`kyber\` (terminal) or search "Kyber Launcher" in the app menu
|
||||
- AppImage: $APPIMAGE_PATH
|
||||
- Update: re-run \`sudo ./setup.sh kyber-launcher\`
|
||||
MD
|
||||
}
|
||||
|
||||
# ── Standalone bootstrap ──────────────────────────────────────────────────────
|
||||
@@ -248,6 +258,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
eval "$_var='${_r:-$_def}'"
|
||||
}
|
||||
|
||||
write_readme() {
|
||||
local _dir="$1"; shift
|
||||
mkdir -p "$_dir"
|
||||
cat > "$_dir/README.md"
|
||||
}
|
||||
|
||||
ACTUAL_USER="${SUDO_USER:-$USER}"
|
||||
ACTUAL_HOME=$(eval echo "~$ACTUAL_USER")
|
||||
DRY_RUN="${DRY_RUN:-false}"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
## Configure providers / keys
|
||||
Edit `src/.env` then restart (the compose file interpolates these — no env_file):
|
||||
```bash
|
||||
cd ~/docker/paintplus/src
|
||||
nano .env # AI_PROVIDER, OPENAI_API_KEY / REPLICATE_API_KEY, HF_TOKEN
|
||||
docker compose up -d --build
|
||||
```
|
||||
Keys: OpenAI https://platform.openai.com/api-keys · Replicate https://replicate.com/account/api-tokens
|
||||
|
||||
## Cloud mode (no GPU)
|
||||
```bash
|
||||
cd ~/docker/paintplus/src
|
||||
docker compose up -d --build # starts on http://localhost:3080
|
||||
docker compose logs -f
|
||||
docker compose down
|
||||
```
|
||||
|
||||
## Local GPU mode (NVIDIA, ~13 GB of models)
|
||||
```bash
|
||||
cd ~/docker/paintplus/src
|
||||
./install-local-gpu.sh # toolkit + DNS fix + model prefetch
|
||||
./bring-up-local-gpu.sh # docker compose -f docker-compose.gpu.yml up -d --build
|
||||
```
|
||||
GPU auto-selects models by VRAM (FLUX >=24 GB, SDXL 12-24 GB, SD 1.5 <2 GB).
|
||||
|
||||
## ai-stack backend (no extra GPU download)
|
||||
If the `ai-stack` service is installed on this box, PaintPlus can use its
|
||||
InvokeAI/ComfyUI containers instead of the cloud or its own GPU installer —
|
||||
select it during install, or switch later:
|
||||
```bash
|
||||
cd ~/docker/paintplus/src
|
||||
nano .env # AI_PROVIDER=invokeai (or comfyui), INVOKEAI_URL=http://invokeai:9090
|
||||
docker network connect ai-stack_default paintplus # one-time, if not already joined
|
||||
docker compose up -d --build
|
||||
```
|
||||
PaintPlus reaches those containers by Docker network name, not localhost —
|
||||
both must be on the same network (`ai-stack_default`, ai-stack's default).
|
||||
If a small GPU is shared with ai-stack's local chat, swap to images first:
|
||||
`~/docker/ai-stack/gpu-mode.sh images`.
|
||||
|
||||
## Update the app
|
||||
Re-run the PaintPlus installer (copies the latest vendored source over `src/`,
|
||||
keeping your `src/.env`), then rebuild:
|
||||
```bash
|
||||
cd ~/docker/paintplus/src && docker compose up -d --build
|
||||
```
|
||||
|
||||
## Caddy
|
||||
Reverse-proxied as `paintplus:8000` on `caddy_net` (or your configured Caddy
|
||||
network name). Cloud mode joins that network via
|
||||
`src/docker-compose.override.yml`; GPU mode is attached with `docker network
|
||||
connect` after start. Same for the ai-stack backend — attached to
|
||||
`ai-stack_default` with `docker network connect` after start.
|
||||
+9
-58
@@ -209,71 +209,22 @@ OVR
|
||||
configure_caddy_for_service "PaintPlus" "paintplus:8000" "paintplus" "$EXTRA_BLOCK"
|
||||
|
||||
# ── README (deploy notes; the app's own docs are at src/README.md) ────────
|
||||
write_readme "$PP_DIR" << MD
|
||||
# Static usage sections (config, cloud/GPU/ai-stack modes, update, Caddy)
|
||||
# live in the companion services/paintplus.md and get appended
|
||||
# automatically by write_readme (lib/common.sh) — kept out of this
|
||||
# heredoc since none of it depends on anything chosen during install.
|
||||
write_readme "$PP_DIR" << 'MD'
|
||||
# PaintPlus (deployment)
|
||||
|
||||
Self-hosted AI photo editor: paint a mask over any object, describe what you
|
||||
want, and the AI replaces just that region. The application source is vendored
|
||||
in ubuntu-post-install and copied here to \`src/\` (no network clone).
|
||||
App docs: \`src/README.md\`. Based on EditmaskwithAI.
|
||||
in ubuntu-post-install and copied here to `src/` (no network clone).
|
||||
App docs: `src/README.md`. Based on EditmaskwithAI.
|
||||
|
||||
- URL: http://localhost:3080
|
||||
- No built-in login — protect via Authelia SSO if exposed.
|
||||
- Provider: set \`AI_PROVIDER\` in \`src/.env\` (openai, replicate, local_gpu, stability, comfyui, invokeai).
|
||||
- \`comfyui\`/\`invokeai\` can point at this box's own \`ai-stack\` service — see below.
|
||||
|
||||
## Configure providers / keys
|
||||
Edit \`src/.env\` then restart (the compose file interpolates these — no env_file):
|
||||
\`\`\`bash
|
||||
cd $APP_DIR
|
||||
nano .env # AI_PROVIDER, OPENAI_API_KEY / REPLICATE_API_KEY, HF_TOKEN
|
||||
docker compose up -d --build
|
||||
\`\`\`
|
||||
Keys: OpenAI https://platform.openai.com/api-keys · Replicate https://replicate.com/account/api-tokens
|
||||
|
||||
## Cloud mode (no GPU)
|
||||
\`\`\`bash
|
||||
cd $APP_DIR
|
||||
docker compose up -d --build # starts on http://localhost:3080
|
||||
docker compose logs -f
|
||||
docker compose down
|
||||
\`\`\`
|
||||
|
||||
## Local GPU mode (NVIDIA, ~13 GB of models)
|
||||
\`\`\`bash
|
||||
cd $APP_DIR
|
||||
./install-local-gpu.sh # toolkit + DNS fix + model prefetch
|
||||
./bring-up-local-gpu.sh # docker compose -f docker-compose.gpu.yml up -d --build
|
||||
\`\`\`
|
||||
GPU auto-selects models by VRAM (FLUX >=24 GB, SDXL 12-24 GB, SD 1.5 <2 GB).
|
||||
|
||||
## ai-stack backend (no extra GPU download)
|
||||
If the \`ai-stack\` service is installed on this box, PaintPlus can use its
|
||||
InvokeAI/ComfyUI containers instead of the cloud or its own GPU installer —
|
||||
select it during install, or switch later:
|
||||
\`\`\`bash
|
||||
cd $APP_DIR
|
||||
nano .env # AI_PROVIDER=invokeai (or comfyui), INVOKEAI_URL=http://invokeai:9090
|
||||
docker network connect ai-stack_default paintplus # one-time, if not already joined
|
||||
docker compose up -d --build
|
||||
\`\`\`
|
||||
PaintPlus reaches those containers by Docker network name, not localhost —
|
||||
both must be on the same network (\`ai-stack_default\`, ai-stack's default).
|
||||
If a small GPU is shared with ai-stack's local chat, swap to images first:
|
||||
\`~/docker/ai-stack/gpu-mode.sh images\`.
|
||||
|
||||
## Update the app
|
||||
Re-run the PaintPlus installer (copies the latest vendored source over \`src/\`,
|
||||
keeping your \`src/.env\`), then rebuild:
|
||||
\`\`\`bash
|
||||
cd $APP_DIR && docker compose up -d --build
|
||||
\`\`\`
|
||||
|
||||
## Caddy
|
||||
Reverse-proxied as \`paintplus:8000\` on \`${SITE_CADDY_NET:-caddy_net}\`. Cloud mode
|
||||
joins that network via \`src/docker-compose.override.yml\`; GPU mode is attached
|
||||
with \`docker network connect\` after start. Same for the ai-stack backend —
|
||||
attached to \`ai-stack_default\` with \`docker network connect\` after start.
|
||||
- Provider: set `AI_PROVIDER` in `src/.env` (openai, replicate, local_gpu, stability, comfyui, invokeai).
|
||||
- `comfyui`/`invokeai` can point at this box's own `ai-stack` service — see below.
|
||||
MD
|
||||
|
||||
echo ""
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
## Getting ntfy notifications to actually fire (multi-user setup)
|
||||
|
||||
If `.env` has `SMS_HTTP_URL` set (the ntfy setup above), a Traccar user still
|
||||
needs two separate things configured on their own account before they'll
|
||||
receive anything — this trips people up because both are per-user, not
|
||||
global, and neither is optional:
|
||||
|
||||
1. **Their own Phone field set to their ntfy topic.**
|
||||
Settings → Users → click the user → Phone field → their topic name.
|
||||
Different users can share one topic or each get their own, depending on
|
||||
whether you want them to see the same alerts or separate ones.
|
||||
|
||||
2. **The notification rule linked to that user.**
|
||||
Creating a notification (e.g. "Geofence exited" with the SMS channel
|
||||
checked) does not automatically apply to every user — it has to be
|
||||
attached. Go to **Settings → Users → click the user → Connections tab**,
|
||||
and select which Devices, Geofences, Notifications, and Users are linked
|
||||
to that account. A user only gets alerts for notifications, devices, and
|
||||
geofences actually selected there.
|
||||
|
||||
Both steps are required per account. There's no way to configure this once
|
||||
for everyone — a non-admin user who can't see a device/geofence/notification
|
||||
in their own Connections list won't get notified about it, even if the admin
|
||||
configured everything else correctly.
|
||||
|
||||
### Why "TEST CHANNELS" can return success with nothing arriving
|
||||
|
||||
The `TEST CHANNELS` button only ever tests the **currently logged-in
|
||||
session's user** — there's no way for an admin to test "as" another account.
|
||||
Worse, it can report success (HTTP 204) even when nothing was sent: Traccar's
|
||||
SMS notificator silently no-ops (no error, no log line) if that user's Phone
|
||||
field is empty, since `HttpSmsClient` — which is what actually calls out to
|
||||
ntfy and would throw on failure — never gets invoked in that case. A 204
|
||||
from this button only proves the request loop completed, not that ntfy was
|
||||
reached.
|
||||
|
||||
To verify a specific account actually works, log in **as that account** and
|
||||
click the button there, or just trigger a real matching event (e.g. cross a
|
||||
linked geofence) and watch for the notification.
|
||||
Reference in New Issue
Block a user