Spusťte headless server
Spusť cc_server na stroji, který zůstane zapnutý, a připoj se k němu z počítače,
prohlížeče nebo telefonu. Server je nativní binárka v čistém Dartu, bez enginu
Flutteru, takže běží bez rozhraní na macOS, Linuxu i Windows. Vlastní databázi,
spouští agenty a dělá každé volání externího API. Klienti jen vykreslují.
Spuštění v Dockeru (předpřipravené obrazy)
Sekce “Spuštění v Dockeru (předpřipravené obrazy)”Každé vydání publikuje sestavu čtyř obrazů na GHCR pro vlastní hosting: backend, dva
statické tenké klienty a volitelné relé párování, plus samostatný obraz
cc-server-demo pro veřejného hostitele dema. Instalace s vlastním hostingem
nepotřebuje checkout zdrojů. Připni tag verze
(ghcr.io/samuelalev/<image>:v0.0.1-rc.1), nebo jeď na latest.
| Obraz | Co to je | Publikuje |
|---|---|---|
ghcr.io/samuelalev/cc-server |
Backend: databáze, agenti, MCP, webhooky | -p 9030:9030 |
ghcr.io/samuelalev/cc-webapp |
Webový klient (statický nginx) | -p 8080:8080 |
ghcr.io/samuelalev/cc-remote |
PWA telefonního společníka (statický nginx) | -p 8081:8080 |
ghcr.io/samuelalev/cc-signaling-server |
Relé párování WebRTC (volitelné) | -p 8788:8788 |
Celá sestava jako compose soubor:
services: server: image: ghcr.io/samuelalev/cc-server:latest ports: ["9030:9030"] volumes: ["cc_data:/data"] restart: unless-stopped web: image: ghcr.io/samuelalev/cc-webapp:latest ports: ["8080:8080"] restart: unless-stopped remote: image: ghcr.io/samuelalev/cc-remote:latest ports: ["8081:8080"] restart: unless-stopped signaling: image: ghcr.io/samuelalev/cc-signaling-server:latest ports: ["8788:8788"] restart: unless-stopped
volumes: cc_data:Než cokoli z toho vystavíš mimo loopback, vyplatí se vědět:
-
Obraz
cc-servervozíCC_SERVER_INSECURE=1(musí se vázat na0.0.0.0, aby přijímal provoz z publikovaných portů), což je bezpečné jen za reverzní proxy, která ukončuje TLS (Caddy, Traefik, nginx nebo Cloudflare Tunnel), v důvěryhodné síti. Když chceš TLS ukončit přímo v procesu, připoj certifikát a nastavCC_SERVER_TLS_CERT/CC_SERVER_TLS_KEY(a pak zrušCC_SERVER_INSECURE). Všechno přepíšeš přesdocker run -e …nebo blokenvironment:v compose. -
/dataje jediný stav. Databáze SQLite, tajemství spárovaných zařízení, stažené modely i zvuk schůzek žijí ve svazku. Zálohuj ho a kontejner je na odpis. -
Klienta spáruj zevnitř obrazu ještě před prvním připojením, ekvivalent kontejneru ke kroku 3:
Terminál docker run --rm -it -v cc_data:/data \--entrypoint /app/bin/cc_server ghcr.io/samuelalev/cc-server:latest pair -
Oba klientské obrazy jsou statičtí hostitelé nginx. Za běhu není co nastavovat. Formulář připojení každého klienta bere URL serveru, ID zařízení a párovací klíč. Signalizační relé stejně potřebuje jen svůj port (
SIGNALING_HOST/SIGNALING_PORTse dají přepsat). Je bezstavové, nedrží žádná tajemství a je to záloha: telefon použije loopback, LAN, tailnet nebo přímou cestuwss://, když je některá dosažitelná, a na relé spadne, až když žádná není. Přeskoč ho, když klienti na server dosáhnou vždy přímo.
Zbytek návodu sestavuje server ze zdrojů. Příznaky a chování, které popisuje, jsou ty samé, které do obrazu přivádějí proměnné prostředí.
Předpoklady
Sekce “Předpoklady”- Dart SDK. Tohle repo si SDK připíná přes fvm, takže před každý příkaz dej
fvm. - Checkout tohoto repozitáře.
- Nativní toolchain, který potřebuje přípravný skript: Rust/
cargo, plusmeson,ninja,pkg-config,gita překladač C++. Každý skript sestavení pojmenuje, co nenašel, a jak to nainstalovat. - Dosažitelný hostitel: loopback pro místní použití, nebo adresa v LAN či veřejná adresa s TLS pro vzdálené klienty.
Krok 1: Připrav nativní knihovny
Sekce “Krok 1: Připrav nativní knihovny”Nativní knihovny jsou povinné. Zhoršený režim neexistuje. Sestav je z kořene repozitáře dřív než cokoli jiného:
scripts/natives/build_natives.shSestaví se rift, fff, tree-sitter i s gramatikami, aec, lame,
ccpty, cc_watcher, cc_inference a nativní SAML do
build/natives/. Build hook cc_server
znovu vloží do balíku, co je tam připravené, takže přeskočení tohohle kroku
buď sestavení rovnou shodí, nebo s únikovou cestou níže vyrobí binárku, jejíž
preflight při startu odmítne naběhnout a pojmenuje chybějící knihovnu.
Krok 2: Sestav binárku
Sekce “Krok 2: Sestav binárku”cd apps/cc_serverfvm dart build cliBalík veze libsqlite3 a připravené nativní knihovny vedle binárky. Systémové
SQLite ani engine Flutteru nepotřebuje. Spustitelný soubor skončí v
./build/cli/<os_arch>/bundle/bin/cc_server.
Krok 3: Spáruj klienta před prvním startem
Sekce “Krok 3: Spáruj klienta před prvním startem”Čerstvý datový adresář nemá spárované zařízení ani předem sdílený klíč, takže
výzvu na párovací klíč klient ještě neuspokojí. Vystav ho podpříkazem pair.
Zapíše global.db a secrets.json přímo. Server, který ten datový adresář už
obsluhuje, nové zařízení vezme bez restartu:
./build/cli/<os_arch>/bundle/bin/cc_server pair --data-dir ./data --port 9030Vypíše tři hodnoty, které vložíš do formuláře připojení klienta:
Connect a thin client (paste into its connect form): Server ws://localhost:9030/rpc Device id web-client Pairing key <a freshly generated key>Užitečné příznaky: --device (výchozí web-client; id zároveň volí vrstvu
zařízení, tedy desktop, ios, android, a cokoli jiného je webový klient),
--label (výchozí je název platformy plus hostname tohohle stroje), --host
(hostitel, který se vypíše do URL, protože loopback z jiného stroje není
dosažitelný) a --client-url. Opakované pair tomu zařízení otočí klíč a
shodí jeho živé relace. Párování pracovní prostor nikdy nezaloží: onboarding
připojujícího se klienta ten první pojmenuje a vytvoří.
S --client-url navíc vypíše QR, které se dá naskenovat z terminálu a otevře
webového klienta už vyplněného:
./build/cli/<os_arch>/bundle/bin/cc_server pair --data-dir ./data --port 9030 \ --bind any --host 192.168.1.42 --client-url https://app.usectrl.devPověření vystavené přes cc_server pair neexpiruje. Pověření vystavené
v aplikaci vyprší vždy po 30 dnech. Zařízení vystavené z CLI odvolej v
Nastavení → Vy → Vaše zařízení, až ho nebudeš potřebovat.
Krok 4: Spusť server
Sekce “Krok 4: Spusť server”Na loopbacku, což je výchozí hodnota a všechno, co potřebuješ pro klienta na tom samém stroji:
./build/cli/<os_arch>/bundle/bin/cc_server --data-dir ./data --port 9030Aby na něj dosáhl jiný stroj, navaž každé rozhraní. Vazba mimo loopback bez TLS
se při startu odmítne (Refusing to bind non-loopback address … without TLS), takže dej certifikát:
./build/cli/<os_arch>/bundle/bin/cc_server --data-dir ./data --port 9030 \ --bind any --tls-cert /path/fullchain.pem --tls-key /path/privkey.pem \ --public-url wss://server.example:9030/rpcNebo ukonči TLS v reverzní proxy na důvěryhodné privátní síti a za ní se přihlas k nešifrované vazbě:
./build/cli/<os_arch>/bundle/bin/cc_server --data-dir ./data --port 9030 \ --bind any --insecure --public-url wss://server.example/rpc--insecure se ignoruje, když jsou nastavené --tls-cert i --tls-key. TLS
vždy vyhraje. Server nešifrovaný stav inzeruje jako insecure: true v
GET /healthz a klienti takové spojení označí jako nezabezpečené.
Server běží do SIGINT/SIGTERM a pak se čistě vypne.
Krok 5: Připoj klienta
Sekce “Krok 5: Připoj klienta”Namiř klienta na URL serveru a párovací klíč z kroku 3:
- Aplikace pro počítač: na obrazovce prvního spuštění (Jak má Control Center běžet?) vyplň pole připojení místo Spustit v této aplikaci, nebo server přidej později v Nastavení → Server → Připojení a stav. Viz Připojte se ke vzdálenému serveru.
- Webový klient: otevři app.usectrl.dev (nebo vlastní kopii webového sestavení) a zadej URL serveru, ID zařízení a párovací klíč.
- Telefon: aplikaci Remote spáruj z běžícího klienta. Viz Spárujte zařízení.
Krok 6: Připoj Google Calendar (volitelné)
Sekce “Krok 6: Připoj Google Calendar (volitelné)”Kalendář pracovního prostoru bez připojeného rozhraní synchronizuješ tokem kódu zařízení:
GOOGLE_OAUTH_CLIENT_ID=<id> GOOGLE_OAUTH_CLIENT_SECRET=<secret> \ ./build/cli/<os_arch>/bundle/bin/cc_server calendar connect \ --data-dir ./data --workspace <workspace-id>Vypíše kód a URL ke schválení na jiném zařízení, refresh token uloží na serveru
a skončí. Sestavení ze zdrojů žádného klienta Google neveze, takže proměnné
prostředí s id a secretem jsou povinné. Příznak --google-client-id neexistuje.
Viz Připojte Google Calendar.
Konfigurace
Sekce “Konfigurace”Příznaky výše stačí na první nastavení. Celá plocha, 23 dvojic příznaku a
proměnné prostředí, čtyři podpříkazy a rozložení datového adresáře, je v
CLI cc_server.
Čtyři, které budeš potřebovat nejspíš:
| Příznak | Výchozí | Význam |
|---|---|---|
--data-dir |
adresář dat aplikace pro uživatele podle OS | Databáze, tajemství, modely a mezipaměť médií |
--port |
9030 |
TCP port (0 = dočasný) |
--bind |
loopback |
loopback, nebo any pro každé rozhraní (chce TLS nebo --insecure) |
--public-url |
odvozená z vazby | RPC URL inzerovaná spárovaným klientům. Za proxy, NAT nebo tunelem ji nastav výslovně |
Výchozí datový adresář je ~/Library/Application Support/control-center na
macOS, %APPDATA%\control-center na Windows a $XDG_DATA_HOME/control-center
(jinak ~/.local/share/control-center) jinde. .cc_server relativní k cwd se
použije jen tehdy, když se nevyřeší domovský adresář ani adresář dat aplikace.
Co server obsluhuje
Sekce “Co server obsluhuje”cc_server je celá plocha produktu, ne její výsek: datová cesta repo-RPC a
odběry, endpoint nástrojů MCP na POST /mcp a GET /sse na tom samém portu,
příchozí webhooky, proxy médií a písem, callbacky jednotného přihlášení,
protokol zápůjčky flotily, stahování RSS na straně serveru v třicetiminutovém
rytmu a vektorové hledání (rozšíření sqlite_vector se registruje jako
automatické rozšíření pro celý proces a tam, kde není k dispozici, se zhorší
jen na fulltextové hledání).
Dispečer je bezstavový: vazba pracovního prostoru na relaci neexistuje.
Každé volání v rozsahu pracovního prostoru veze vlastní workspace_id a přístup
rozhoduje členství volajícího v pracovním prostoru a jeho role, ne držení
párovacího klíče.
Než port vystavíš mimo loopback, platí dvě věci:
- MCP mimo hostitele selhává do zamítnutí. Plocha MCP bez tokenu odpovídá jen na loopback. Vazba
anyji nerozšíří. Požadavek mimo hostitele se odmítne hláškou „MCP requires a bearer token to answer non-loopback clients“, dokud token nenastavíš (mcp.setToken, nebo Nastavení → Server → Servery MCP). GET /healthzje schválně bez ověření, s CORS na všechny originy, a publikuje id serveru, název, otisk identity a verzi sestavení. Klienti otisk potřebují, aby si server připnuli, takže je to záměr. Znamená to ale, že každý dosažitelnýcc_servertolik prozradí komukoli, kdo se zeptá.