2026-07-22 06:28:49 -07:00
|
|
|
|
name: arr-stack
|
|
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
|
# Arr stack
|
|
|
|
|
|
# gluetun WireGuard VPN client + firewall killswitch
|
|
|
|
|
|
# qbittorrent torrent client, lives INSIDE gluetun's network namespace
|
2026-07-22 11:59:51 -07:00
|
|
|
|
# prowlarr indexer manager (torrents + NZB/Usenet indexers)
|
|
|
|
|
|
# sabnzbd Usenet NZB download client (Newshosting, Tweaknews, …)
|
2026-07-22 06:28:49 -07:00
|
|
|
|
# sonarr TV radarr movies bazarr subtitles
|
|
|
|
|
|
# jellyfin media server
|
|
|
|
|
|
#
|
|
|
|
|
|
# AI / coding stack (local, no VPN)
|
|
|
|
|
|
# bonsai Prism Ternary-Bonsai-27B via llama-server (OpenAI-compatible API)
|
|
|
|
|
|
# open-webui Chat UI + RAG + tools + code interpreter
|
|
|
|
|
|
# searxng Private metasearch for web RAG
|
|
|
|
|
|
# forgejo Self-hosted Git (repos for coding + OpenHands)
|
|
|
|
|
|
# openhands Optional autonomous coding agent (profile: coding)
|
|
|
|
|
|
#
|
|
|
|
|
|
# Lockdown model:
|
|
|
|
|
|
# * qbittorrent uses `network_mode: service:gluetun` -> it has NO network
|
|
|
|
|
|
# interface of its own. Every packet it sends/receives goes through
|
|
|
|
|
|
# gluetun, and gluetun's built-in firewall only lets traffic out via the
|
|
|
|
|
|
# WireGuard tunnel. Tunnel down = zero connectivity. No leaks possible.
|
|
|
|
|
|
# * Do NOT publish qBittorrent's BitTorrent listening port on the host -
|
|
|
|
|
|
# inbound peer connections must come through the tunnel (port forwarding),
|
|
|
|
|
|
# never via your real IP.
|
|
|
|
|
|
# * AI services stay on arr-net (LAN only). They do NOT route through gluetun.
|
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
networks:
|
|
|
|
|
|
arr-net:
|
|
|
|
|
|
driver: bridge
|
|
|
|
|
|
|
|
|
|
|
|
services:
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------- VPN gateway #
|
|
|
|
|
|
gluetun:
|
|
|
|
|
|
image: qmcgaw/gluetun:v3
|
|
|
|
|
|
container_name: gluetun
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
cap_add:
|
|
|
|
|
|
- NET_ADMIN
|
|
|
|
|
|
devices:
|
|
|
|
|
|
- /dev/net/tun:/dev/net/tun
|
|
|
|
|
|
networks:
|
|
|
|
|
|
- arr-net
|
|
|
|
|
|
ports:
|
|
|
|
|
|
# Ports for anything running inside gluetun's namespace are published
|
|
|
|
|
|
# HERE, on gluetun - not on the inner container.
|
|
|
|
|
|
- 8080:8080/tcp # qBittorrent WebUI
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
# Your provider's WireGuard config, renamed to wg0.conf
|
|
|
|
|
|
# (see wireguard/wg0.conf.example and the README for required edits)
|
|
|
|
|
|
- ./wireguard/wg0.conf:/gluetun/wireguard/wg0.conf:ro
|
|
|
|
|
|
environment:
|
|
|
|
|
|
VPN_SERVICE_PROVIDER: custom
|
|
|
|
|
|
VPN_TYPE: wireguard
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
# Lets your LAN reach the qBittorrent WebUI through gluetun's firewall
|
|
|
|
|
|
FIREWALL_OUTBOUND_SUBNETS: ${LAN_SUBNET}
|
|
|
|
|
|
# --- optional: provider port forwarding (better swarm connectivity) ---
|
|
|
|
|
|
# FIREWALL_VPN_INPUT_PORTS: "12345" # port your provider assigned you
|
|
|
|
|
|
# VPN_PORT_FORWARDING: "on" # for providers with NAT-PMP API
|
|
|
|
|
|
# VPN_PORT_FORWARDING_PROVIDER: protonvpn
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------- torrent client #
|
|
|
|
|
|
qbittorrent:
|
|
|
|
|
|
image: lscr.io/linuxserver/qbittorrent:latest
|
|
|
|
|
|
container_name: qbittorrent
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
network_mode: service:gluetun # <-- the entire isolation trick
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
gluetun:
|
|
|
|
|
|
condition: service_healthy # start only once the tunnel is up
|
|
|
|
|
|
environment:
|
|
|
|
|
|
PUID: ${PUID}
|
|
|
|
|
|
PGID: ${PGID}
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
WEBUI_PORT: "8080"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/qbittorrent:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data # single shared tree -> hardlinks
|
|
|
|
|
|
|
|
|
|
|
|
# -------------------------------------------------------------- indexers #
|
|
|
|
|
|
prowlarr:
|
|
|
|
|
|
image: lscr.io/linuxserver/prowlarr:latest
|
|
|
|
|
|
container_name: prowlarr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 9696:9696
|
|
|
|
|
|
environment: &arr-env
|
|
|
|
|
|
PUID: ${PUID}
|
|
|
|
|
|
PGID: ${PGID}
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/prowlarr:/config
|
2026-07-22 07:40:41 -07:00
|
|
|
|
depends_on:
|
|
|
|
|
|
- flaresolverr
|
|
|
|
|
|
|
|
|
|
|
|
# Cloudflare / JS challenge proxy for Prowlarr indexers (not a general captcha solver)
|
|
|
|
|
|
# Wire in Prowlarr: Settings → Indexers → FlareSolverr → http://flaresolverr:8191
|
|
|
|
|
|
flaresolverr:
|
|
|
|
|
|
image: ghcr.io/flaresolverr/flaresolverr:latest
|
|
|
|
|
|
container_name: flaresolverr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
environment:
|
|
|
|
|
|
LOG_LEVEL: ${FLARESOLVERR_LOG_LEVEL:-info}
|
|
|
|
|
|
LOG_HTML: "false"
|
|
|
|
|
|
CAPTCHA_SOLVER: ${FLARESOLVERR_CAPTCHA_SOLVER:-none}
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
# Optional LAN debug UI/API — leave commented to keep it internal-only
|
|
|
|
|
|
# ports:
|
|
|
|
|
|
# - "8191:8191"
|
2026-07-22 06:28:49 -07:00
|
|
|
|
|
2026-07-22 12:00:16 -07:00
|
|
|
|
# ---------------------------------------------------------- usenet / NZB #
|
|
|
|
|
|
# SABnzbd talks to Usenet providers over SSL (no VPN required).
|
|
|
|
|
|
# Incomplete + complete under /data/usenet so Sonarr/Radarr can hardlink.
|
|
|
|
|
|
sabnzbd:
|
|
|
|
|
|
image: lscr.io/linuxserver/sabnzbd:latest
|
|
|
|
|
|
container_name: sabnzbd
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${SABNZBD_PORT:-8085}:8080"
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/sabnzbd:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data
|
|
|
|
|
|
|
2026-07-22 06:28:49 -07:00
|
|
|
|
# -------------------------------------------------------------------- TV #
|
|
|
|
|
|
sonarr:
|
|
|
|
|
|
image: lscr.io/linuxserver/sonarr:latest
|
|
|
|
|
|
container_name: sonarr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 8989:8989
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/sonarr:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------- movies #
|
|
|
|
|
|
radarr:
|
|
|
|
|
|
image: lscr.io/linuxserver/radarr:latest
|
|
|
|
|
|
container_name: radarr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 7878:7878
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/radarr:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data
|
|
|
|
|
|
|
|
|
|
|
|
# -------------------------------------------------------------- subtitles #
|
|
|
|
|
|
bazarr:
|
|
|
|
|
|
image: lscr.io/linuxserver/bazarr:latest
|
|
|
|
|
|
container_name: bazarr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 6767:6767
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/bazarr:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------- media server #
|
|
|
|
|
|
jellyfin:
|
|
|
|
|
|
image: lscr.io/linuxserver/jellyfin:latest
|
|
|
|
|
|
container_name: jellyfin
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 8096:8096/tcp # web UI / clients
|
|
|
|
|
|
# - 8920:8920/tcp # optional HTTPS
|
|
|
|
|
|
# - 7359:7359/udp # optional client autodiscovery
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/jellyfin:/config
|
|
|
|
|
|
- ${DATA_DIR}/media:/data/media:ro # read-only: Jellyfin never touches files
|
|
|
|
|
|
# --- optional: Intel QuickSync hardware transcoding --- (Unused on this AMD machine)
|
|
|
|
|
|
# devices:
|
|
|
|
|
|
# - /dev/dri:/dev/dri
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------- music #
|
|
|
|
|
|
lidarr:
|
|
|
|
|
|
image: lscr.io/linuxserver/lidarr:latest
|
|
|
|
|
|
container_name: lidarr
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- 8686:8686
|
|
|
|
|
|
environment: *arr-env
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/lidarr:/config
|
|
|
|
|
|
- ${DATA_DIR}:/data # same /data tree as Sonarr/Radarr
|
|
|
|
|
|
|
|
|
|
|
|
# ==========================================================================
|
|
|
|
|
|
# Optional media extras - uncomment as needed
|
|
|
|
|
|
# ==========================================================================
|
|
|
|
|
|
#
|
|
|
|
|
|
# jellyseerr: # request UI for Jellyfin
|
|
|
|
|
|
# image: fallenbagel/jellyseerr:latest
|
|
|
|
|
|
# container_name: jellyseerr
|
|
|
|
|
|
# restart: unless-stopped
|
|
|
|
|
|
# networks: [arr-net]
|
|
|
|
|
|
# ports: ["5055:5055"]
|
|
|
|
|
|
# environment: *arr-env
|
|
|
|
|
|
# volumes:
|
|
|
|
|
|
# - ${CONFIG_DIR}/jellyseerr:/app/config
|
|
|
|
|
|
|
|
|
|
|
|
# ==========================================================================
|
|
|
|
|
|
# Local AI — Ternary-Bonsai-27B + Open WebUI + RAG + coding helpers
|
|
|
|
|
|
# Target: Beelink SER5 PRO (Ryzen 7 7735HS + Radeon 680M, no NVIDIA)
|
|
|
|
|
|
# ==========================================================================
|
|
|
|
|
|
|
|
|
|
|
|
# OpenAI-compatible API for Ternary-Bonsai-27B (PrismML Q2_0 GGUF)
|
|
|
|
|
|
# First: ./scripts/download-bonsai-model.sh
|
|
|
|
|
|
# Then: docker compose up -d --build bonsai open-webui searxng
|
|
|
|
|
|
bonsai:
|
|
|
|
|
|
build:
|
|
|
|
|
|
context: ./ai
|
|
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
|
args:
|
|
|
|
|
|
# cpu = reliable default on SER5 PRO
|
|
|
|
|
|
# vulkan = try Radeon 680M offload (also set NGL=99 and uncomment devices)
|
|
|
|
|
|
BONSAI_BACKEND: ${BONSAI_BACKEND:-vulkan}
|
|
|
|
|
|
image: arr-stack/bonsai:local
|
|
|
|
|
|
container_name: bonsai
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${BONSAI_PORT:-8081}:8080" # avoid clash with qBittorrent :8080
|
|
|
|
|
|
environment:
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
MODEL_PATH: ${BONSAI_MODEL_PATH:-/models/Ternary-Bonsai-27B-Q2_0.gguf}
|
|
|
|
|
|
# 0 = CPU (recommended start). Vulkan image: try 99 with /dev/dri mounted.
|
|
|
|
|
|
NGL: ${BONSAI_NGL:-99}
|
|
|
|
|
|
# 16k is a good default on 32–64 GB systems with media stack co-resident.
|
|
|
|
|
|
# Long docs / full-repo: try 32768 or 65536; enable KV4=1 if RAM is tight.
|
|
|
|
|
|
CTX_SIZE: ${BONSAI_CTX:-16384}
|
|
|
|
|
|
TEMP: ${BONSAI_TEMP:-0.7}
|
|
|
|
|
|
TOP_P: ${BONSAI_TOP_P:-0.95}
|
|
|
|
|
|
TOP_K: ${BONSAI_TOP_K:-20}
|
|
|
|
|
|
# 0 = auto; or set to physical cores (e.g. 8 on 7735HS) leaving some for Arrs
|
|
|
|
|
|
THREADS: ${BONSAI_THREADS:-0}
|
|
|
|
|
|
KV4: ${BONSAI_KV4:-0}
|
|
|
|
|
|
EXTRA_ARGS: ${BONSAI_EXTRA_ARGS:-}
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${BONSAI_MODELS_DIR:-./models/bonsai}:/models:ro
|
|
|
|
|
|
# Shared memory helps large context / mmap
|
|
|
|
|
|
shm_size: "4gb"
|
|
|
|
|
|
# Vulkan / AMD iGPU: devices + group_add live ONLY in
|
|
|
|
|
|
# docker-compose.override.yml (Compose merges lists and rejects duplicates).
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/health"]
|
|
|
|
|
|
interval: 30s
|
|
|
|
|
|
timeout: 10s
|
|
|
|
|
|
start_period: 180s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
|
|
# ChatGPT-style UI with built-in RAG, tools, and code interpreter
|
|
|
|
|
|
open-webui:
|
|
|
|
|
|
image: ghcr.io/open-webui/open-webui:main
|
|
|
|
|
|
container_name: open-webui
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${OPEN_WEBUI_PORT:-3000}:8080"
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
bonsai:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
searxng:
|
|
|
|
|
|
condition: service_started
|
|
|
|
|
|
environment:
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
# Point at local llama-server (OpenAI-compatible)
|
|
|
|
|
|
OPENAI_API_BASE_URL: http://bonsai:8080/v1
|
|
|
|
|
|
OPENAI_API_KEY: ${OPENAI_API_KEY:-sk-local-bonsai}
|
|
|
|
|
|
# Disable Ollama unless you add it later
|
|
|
|
|
|
ENABLE_OLLAMA_API: "false"
|
|
|
|
|
|
# First account becomes admin; set WEBUI_AUTH=false only on trusted LAN
|
|
|
|
|
|
WEBUI_AUTH: ${WEBUI_AUTH:-true}
|
|
|
|
|
|
# RAG: local embeddings run inside open-webui (downloads on first use)
|
|
|
|
|
|
RAG_EMBEDDING_ENGINE: ${RAG_EMBEDDING_ENGINE:-}
|
|
|
|
|
|
CHUNK_SIZE: ${RAG_CHUNK_SIZE:-1000}
|
|
|
|
|
|
CHUNK_OVERLAP: ${RAG_CHUNK_OVERLAP:-100}
|
|
|
|
|
|
# Web search via local SearXNG
|
|
|
|
|
|
ENABLE_RAG_WEB_SEARCH: "true"
|
|
|
|
|
|
ENABLE_SEARCH_QUERY: "true"
|
|
|
|
|
|
RAG_WEB_SEARCH_ENGINE: searxng
|
|
|
|
|
|
SEARXNG_QUERY_URL: http://searxng:8080/search?q=<query>
|
|
|
|
|
|
# Allow fetching internal / LAN URLs for RAG (homelab docs)
|
|
|
|
|
|
ENABLE_RAG_LOCAL_WEB_FETCH: "true"
|
|
|
|
|
|
# Code interpreter (runs in open-webui sandbox)
|
|
|
|
|
|
ENABLE_CODE_INTERPRETER: "true"
|
|
|
|
|
|
# Reduce background LLM spam on a single local model
|
|
|
|
|
|
ENABLE_TITLE_GENERATION: "false"
|
|
|
|
|
|
ENABLE_FOLLOW_UP_GENERATION: "false"
|
|
|
|
|
|
ENABLE_TAGS_GENERATION: "false"
|
|
|
|
|
|
# Default model id as reported by llama-server /v1/models
|
|
|
|
|
|
DEFAULT_MODELS: ${OPENWEBUI_DEFAULT_MODEL:-}
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/open-webui:/app/backend/data
|
|
|
|
|
|
# Your local files for RAG / "read my project" workflows
|
|
|
|
|
|
- ${AI_WORKSPACE_DIR:-./workspace}:/workspace:ro
|
|
|
|
|
|
# Optional: expose media library read-only for Q&A about your library tree
|
|
|
|
|
|
# - ${DATA_DIR}/media:/media:ro
|
|
|
|
|
|
extra_hosts:
|
|
|
|
|
|
- "host.docker.internal:host-gateway"
|
|
|
|
|
|
|
|
|
|
|
|
# Private metasearch (no API keys) for Open WebUI web RAG
|
|
|
|
|
|
searxng:
|
|
|
|
|
|
image: docker.io/searxng/searxng:latest
|
|
|
|
|
|
container_name: searxng
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
# Bind to localhost only — Open WebUI reaches it on arr-net
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "127.0.0.1:${SEARXNG_PORT:-8888}:8080"
|
|
|
|
|
|
environment:
|
|
|
|
|
|
SEARXNG_BASE_URL: http://localhost:${SEARXNG_PORT:-8888}/
|
|
|
|
|
|
SEARXNG_SECRET: ${SEARXNG_SECRET:-change-me-to-a-long-random-string}
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ./searxng:/etc/searxng:rw
|
|
|
|
|
|
cap_drop:
|
|
|
|
|
|
- ALL
|
|
|
|
|
|
cap_add:
|
|
|
|
|
|
- CHOWN
|
|
|
|
|
|
- SETGID
|
|
|
|
|
|
- SETUID
|
|
|
|
|
|
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# Forgejo — self-hosted Git (Gitea soft-fork). SQLite is fine for a homelab.
|
|
|
|
|
|
# Web: http://host:3002 Git SSH: host:2222 (git@host:user/repo.git with port 2222)
|
|
|
|
|
|
# First visit: create admin account, then create repos / push code.
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
forgejo:
|
|
|
|
|
|
image: codeberg.org/forgejo/forgejo:11
|
|
|
|
|
|
container_name: forgejo
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${FORGEJO_HTTP_PORT:-3002}:3000"
|
|
|
|
|
|
- "${FORGEJO_SSH_PORT:-2222}:22"
|
|
|
|
|
|
environment:
|
|
|
|
|
|
USER_UID: ${PUID:-1000}
|
|
|
|
|
|
USER_GID: ${PGID:-1000}
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
# Image already runs OpenSSH on :22 (mapped to host FORGEJO_SSH_PORT).
|
|
|
|
|
|
# Do NOT enable Forgejo's built-in SSH too — both bind :22 and the
|
|
|
|
|
|
# process fatals with "address already in use" (connection refused on :3002).
|
|
|
|
|
|
FORGEJO__server__START_SSH_SERVER: "false"
|
|
|
|
|
|
FORGEJO__server__DISABLE_SSH: "false"
|
|
|
|
|
|
FORGEJO__server__SSH_PORT: ${FORGEJO_SSH_PORT:-2222}
|
|
|
|
|
|
FORGEJO__server__SSH_DOMAIN: ${FORGEJO_DOMAIN:-192.168.8.123}
|
|
|
|
|
|
FORGEJO__server__DOMAIN: ${FORGEJO_DOMAIN:-192.168.8.123}
|
|
|
|
|
|
FORGEJO__server__ROOT_URL: ${FORGEJO_ROOT_URL:-http://192.168.8.123:3002/}
|
|
|
|
|
|
FORGEJO__server__HTTP_PORT: "3000"
|
|
|
|
|
|
# SQLite by default (no extra DB container)
|
|
|
|
|
|
FORGEJO__database__DB_TYPE: sqlite3
|
|
|
|
|
|
FORGEJO__service__DISABLE_REGISTRATION: ${FORGEJO_DISABLE_REGISTRATION:-false}
|
|
|
|
|
|
FORGEJO__actions__ENABLED: "true"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ${CONFIG_DIR}/forgejo:/data
|
|
|
|
|
|
- /etc/localtime:/etc/localtime:ro
|
|
|
|
|
|
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# OpenHands — autonomous coding agent (opt-in)
|
|
|
|
|
|
# Start with: docker compose --profile coding up -d openhands
|
|
|
|
|
|
# UI: http://host:3001 → Settings → custom model openai/<id>
|
|
|
|
|
|
# Base URL: http://bonsai:8080/v1 API key: sk-local-bonsai
|
|
|
|
|
|
# Needs Docker socket to spawn sandboxed runtimes.
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
openhands:
|
|
|
|
|
|
profiles: ["coding"]
|
|
|
|
|
|
# Prefer GHCR — docker.all-hands.dev often fails DNS / is decommissioned
|
|
|
|
|
|
image: ghcr.io/all-hands-ai/openhands:0.54
|
|
|
|
|
|
container_name: openhands
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
networks: [arr-net]
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "${OPENHANDS_PORT:-3001}:3000"
|
|
|
|
|
|
extra_hosts:
|
|
|
|
|
|
- "host.docker.internal:host-gateway"
|
|
|
|
|
|
environment:
|
|
|
|
|
|
TZ: ${TZ}
|
|
|
|
|
|
SANDBOX_RUNTIME_CONTAINER_IMAGE: ghcr.io/all-hands-ai/runtime:0.54-nikolaik
|
|
|
|
|
|
LOG_ALL_EVENTS: "true"
|
|
|
|
|
|
# Pre-wire local Bonsai (override in UI if model id differs)
|
|
|
|
|
|
LLM_BASE_URL: http://bonsai:8080/v1
|
|
|
|
|
|
LLM_API_KEY: ${OPENAI_API_KEY:-sk-local-bonsai}
|
|
|
|
|
|
LLM_MODEL: ${OPENHANDS_MODEL:-openai/local}
|
|
|
|
|
|
WORKSPACE_MOUNT_PATH: ${AI_WORKSPACE_DIR:-./workspace}
|
|
|
|
|
|
SANDBOX_VOLUMES: ${AI_WORKSPACE_DIR:-./workspace}:/workspace:rw
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
|
|
|
|
- ${CONFIG_DIR}/openhands:/.openhands-state
|
|
|
|
|
|
- ${AI_WORKSPACE_DIR:-./workspace}:/opt/workspace_base
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
bonsai:
|
|
|
|
|
|
condition: service_healthy
|