Headless bir sunucu çalıştırma
Sürekli açık kalan bir makinede cc_server çalıştırın, ardından masaüstünüzden,
bir tarayıcıdan ya da telefonunuzdan ona bağlanın. Sunucu, saf Dart ile yazılmış
yerel bir ikilidir — Flutter motoru yoktur — bu yüzden macOS, Linux ya da Windows
üzerinde headless çalışır. Veritabanına sahiptir, ajanları çalıştırır ve tüm dış
API çağrılarını yapar; istemciler yalnızca çizer.
Docker’da çalıştırma (hazır imajlar)
Bölüm başlığı “Docker’da çalıştırma (hazır imajlar)”Her sürüm, dört GHCR imajından oluşan ve kendi sunucunuzda barındırabileceğiniz
bir yığın yayımlar — arka uç, iki statik ince istemci ve isteğe bağlı eşleştirme
aktarıcısı — ayrıca genel demo ana makinesi için ayrı bir cc-server-demo imajı.
Kendi sunucunuzda barındırılan bir kurulum, kaynak kodu kopyası gerektirmez. Bir
sürüm etiketi sabitleyin (ghcr.io/samuelalev/<image>:v0.0.1-rc.1) ya da
latest ile ilerleyin.
| İmaj | Ne olduğu | Yayımladığı portlar |
|---|---|---|
ghcr.io/samuelalev/cc-server |
Arka uç: veritabanı, ajanlar, MCP, webhook’lar | -p 9030:9030 |
ghcr.io/samuelalev/cc-webapp |
Web istemcisi (statik nginx) | -p 8080:8080 |
ghcr.io/samuelalev/cc-remote |
Telefon yardımcı PWA’sı (statik nginx) | -p 8081:8080 |
ghcr.io/samuelalev/cc-signaling-server |
WebRTC eşleştirme aktarıcısı (isteğe bağlı) | -p 8788:8788 |
Tüm yığın, tek bir compose dosyası olarak:
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:Bunlardan herhangi birini loopback dışına açmadan önce bilmeye değer şeyler:
-
cc-serverimajıCC_SERVER_INSECURE=1ile gelir (yayımlanan port trafiğini alabilmesi için0.0.0.0adresine bağlanmak zorundadır); bu yalnızca güvenilir bir ağda, TLS sonlandıran bir ters proxy’nin — Caddy, Traefik, nginx ya da bir Cloudflare Tunnel — arkasında güvenlidir. TLS’i bunun yerine süreç içinde sonlandırmak için bir sertifika bağlayın veCC_SERVER_TLS_CERT/CC_SERVER_TLS_KEYdeğişkenlerini ayarlayın (ardındanCC_SERVER_INSECUREdeğişkenini kaldırın). Her şeydocker run -e …ya da compose dosyasındakienvironment:bloğu ile geçersiz kılınabilir. -
Tek durum
/datadizinidir. SQLite veritabanları, eşleştirilmiş cihaz sırları, indirilen modeller ve toplantı sesleri hep bu birimde tutulur — onu yedekleyin, kapsayıcı gözden çıkarılabilir hale gelir. -
İlk bağlantıdan önce imajın içinden bir istemci eşleştirin; bu, 3. adımın kapsayıcıdaki karşılığıdır:
Terminal penceresi docker run --rm -it -v cc_data:/data \--entrypoint /app/bin/cc_server ghcr.io/samuelalev/cc-server:latest pair -
İki istemci imajı da statik nginx barındırıcısıdır — çalışma zamanında yapılandırılacak hiçbir şey yoktur; her istemcinin bağlantı formu sunucu URL’nizi, cihaz kimliğini ve eşleştirme anahtarını alır. Sinyal aktarıcısı da aynı şekilde yalnızca portuna ihtiyaç duyar (
SIGNALING_HOST/SIGNALING_PORTgeçersiz kılınabilir); durumsuzdur, hiçbir sır tutmaz ve bir yedek yoldur — bir telefon, erişilebilir bir yol olduğunda loopback’i, LAN’ı, tailnet’i ya da doğrudan birwss://yolunu kullanır ve yalnızca hiçbiri yoksa aktarıcıya düşer. İstemcileriniz sunucuya her zaman doğrudan erişiyorsa bunu atlayın.
Bu kılavuzun geri kalanı sunucuyu kaynaktan derler; ele aldığı bayraklar ve davranış, imajın ortam değişkenlerinin beslediği şeylerin aynısıdır.
Önkoşullar
Bölüm başlığı “Önkoşullar”- Dart SDK. Bu depo SDK’sını fvm ile sabitler, bu yüzden her komutun başına
fvmekleyin. - Bu deponun kopyası alınmış olmalı.
- Hazırlama betiğinin ihtiyaç duyduğu yerel araç zinciri — Rust/
cargoile birliktemeson,ninja,pkg-config,gitve bir C++ derleyicisi. Her derleme betiği, bulamadığı şeyi ve nasıl kurulacağını belirtir. - Erişilebilir bir ana makine: yerel kullanım için loopback ya da uzak istemciler için TLS’li bir LAN/genel adres.
1. Adım: Yerel kitaplıkları hazırlama
Bölüm başlığı “1. Adım: Yerel kitaplıkları hazırlama”Yerel kitaplıklar zorunludur — düşürülmüş bir mod yoktur. Her şeyden önce bunları depo kökünden derleyin:
scripts/natives/build_natives.shBu, rift, fff, tree-sitter ve dil bilgilerini, aec, lame, ccpty,
cc_watcher, cc_inference ile SAML yerel kitaplığını build/natives/
dizinine derler. cc_server derleme kancası, orada hazırlanan her şeyi pakete
yeniden yazar; bu yüzden bu adımı atlamak ya derlemeyi doğrudan başarısız kılar
ya da — aşağıdaki kaçış kapısıyla — açılış ön denetimi başlamayı reddeden ve
eksik kitaplığın adını veren bir ikili üretir.
2. Adım: İkiliyi derleme
Bölüm başlığı “2. Adım: İkiliyi derleme”cd apps/cc_serverfvm dart build cliPaket, ikilinin yanında libsqlite3 ile hazırlanan yerel kitaplıkları da taşır —
sistem SQLite’ı ve Flutter motoru gerekmez. Çalıştırılabilir dosya
./build/cli/<os_arch>/bundle/bin/cc_server yoluna yerleşir.
3. Adım: İlk başlatmadan önce bir istemci eşleştirme
Bölüm başlığı “3. Adım: İlk başlatmadan önce bir istemci eşleştirme”Yeni bir veri dizininde eşleştirilmiş cihaz ve önceden paylaşılan anahtar yoktur,
bu yüzden bir istemcinin eşleştirme anahtarı istemi henüz karşılanamaz. pair
alt komutuyla bir tane üretin. global.db ile secrets.json dosyalarını
doğrudan yazar; o veri dizinini zaten sunan bir sunucu, yeni cihazı yeniden
başlatma olmadan alır:
./build/cli/<os_arch>/bundle/bin/cc_server pair --data-dir ./data --port 9030İstemcinin bağlantı formuna yapıştıracağınız üç değer yazdırır:
Connect a thin client (paste into its connect form): Server ws://localhost:9030/rpc Device id web-client Pairing key <a freshly generated key>İşe yarar bayraklar: --device (varsayılanı web-client; kimlik aynı zamanda
cihaz katmanını da seçer — desktop, ios, android, başka her şey bir web
istemcisidir), --label (varsayılanı platform adı artı bu makinenin ana makine
adıdır), --host (URL’de yazdırılacak ana makine; çünkü loopback’e başka bir
makineden erişilemez) ve --client-url. pair komutunu yeniden çalıştırmak o
cihazın anahtarını döndürür ve açık oturumlarını düşürür. Eşleştirme hiçbir
zaman çalışma alanı oluşturmaz: bağlanan istemcinin ilk kurulum akışı ilkini
adlandırır ve oluşturur.
--client-url ile ayrıca, web istemcisini önceden doldurulmuş halde açan,
terminalden taranabilir bir QR kodu yazdırır:
./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.devcc_server pair ile üretilen bir kimlik bilgisinin son kullanma tarihi
yoktur; uygulamada üretilen bir tanesinin ise süresi her zaman 30 gün sonra
dolar. İşiniz bittiğinde CLI ile üretilmiş bir cihazı Ayarlar → Siz →
Cihazlarınız yolundan iptal edin.
4. Adım: Sunucuyu başlatma
Bölüm başlığı “4. Adım: Sunucuyu başlatma”Loopback üzerinde — varsayılan budur ve aynı makinedeki bir istemci için ihtiyacınız olan tek şeydir:
./build/cli/<os_arch>/bundle/bin/cc_server --data-dir ./data --port 9030Ona başka bir makineden erişmek için tüm arayüzlere bağlanın. TLS olmadan
loopback dışı bir bağlanma başlangıçta reddedilir (Refusing to bind non-loopback address … without TLS), bu yüzden bir sertifika sağlayın:
./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/rpcYa da güvenilir bir özel ağda TLS’i bir ters proxy’de sonlandırın ve onun arkasında düz metin bir bağlanmayı seçin:
./build/cli/<os_arch>/bundle/bin/cc_server --data-dir ./data --port 9030 \ --bind any --insecure --public-url wss://server.example/rpc--tls-cert ve --tls-key birlikte ayarlandığında --insecure yok sayılır —
TLS her zaman kazanır. Sunucu, düz metin durumunu GET /healthz içinde
insecure: true olarak duyurur ve istemciler böyle bir bağlantıyı güvensiz
olarak işaretler.
Sunucu SIGINT/SIGTERM alana kadar çalışır, ardından temiz biçimde kapanır.
5. Adım: Bir istemci bağlama
Bölüm başlığı “5. Adım: Bir istemci bağlama”Bir istemciyi 3. adımdaki sunucu URL’sine ve eşleştirme anahtarına yönlendirin:
- Masaüstü uygulaması: ilk çalıştırma ekranında (Control Center nasıl çalışsın?) Bu uygulamada çalıştır yerine bağlantı alanlarını doldurun ya da sunucuyu daha sonra Ayarlar → Sunucu → Bağlantı ve durum yolundan ekleyin. Bkz. Uzak bir sunucuya bağlanma.
- Web istemcisi: app.usectrl.dev adresini (ya da web paketinin kendi kopyanızı) açın ve sunucu URL’sini, cihaz kimliğini ve eşleştirme anahtarını girin.
- Telefon: Remote uygulamasını çalışan bir istemciden eşleştirin — bkz. Bir cihaz eşleştirme.
6. Adım: Bir Google Calendar bağlama (isteğe bağlı)
Bölüm başlığı “6. Adım: Bir Google Calendar bağlama (isteğe bağlı)”Bir çalışma alanının takvimini arayüz olmadan eşitlemek için cihaz kodu akışını kullanın:
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>Başka bir cihazda onaylamak için bir kod ve bir URL yazdırır, yenileme
belirtecini sunucu tarafında saklar ve çıkar. Kaynak derlemesi bir Google
istemcisi içermez, bu yüzden kimlik ve gizli anahtar ortam değişkenleri
zorunludur — --google-client-id diye bir bayrak yoktur. Bkz. Bir Google
Calendar bağlama.
Yapılandırma
Bölüm başlığı “Yapılandırma”Yukarıda kullanılan bayraklar, ilk kurulumun ihtiyaç duyduğu bayraklardır. Tam
yüzey — 23 bayrak ve ortam değişkeni çifti, dört alt komut ve veri dizini düzeni
— cc_server CLI referansında yer
alır.
En çok ihtiyaç duyacağınız dört tanesi:
| Bayrak | Varsayılan | Anlamı |
|---|---|---|
--data-dir |
işletim sisteminin kullanıcı başına uygulama verisi dizini | Veritabanları, sırlar, modeller ve önbelleğe alınmış medya |
--port |
9030 |
TCP portu (0 = geçici) |
--bind |
loopback |
loopback ya da tüm arayüzler için any (TLS ya da --insecure gerektirir) |
--public-url |
bağlanmadan türetilir | Eşleştirilmiş istemcilere duyurulan RPC URL’si. Bir proxy, NAT ya da tünel arkasında bunu açıkça ayarlayın |
Varsayılan veri dizini macOS’ta ~/Library/Application Support/control-center,
Windows’ta %APPDATA%\control-center, diğer yerlerde
$XDG_DATA_HOME/control-center (yoksa ~/.local/share/control-center) olur.
Çalışma dizinine göreli bir .cc_server yalnızca hiçbir ev ya da uygulama
verisi dizini çözümlenemediğinde kullanılır.
Sunucunun sundukları
Bölüm başlığı “Sunucunun sundukları”cc_server ürünün bir alt kümesi değil, tüm yüzeyidir: repo-RPC veri yolu ve
abonelikleri, aynı portta POST /mcp ve GET /sse üzerindeki MCP araç uç
noktası, gelen webhook’lar, medya ve yazı tipi proxy’leri, tek oturum açma geri
çağrıları, filo kiralama protokolü, 30 dakikalık bir zamanlamayla sunucu tarafı
RSS çekme ve vektör arama (sqlite_vector uzantısı süreç genelinde bir otomatik
uzantı olarak kaydedilir; yalnızca uzantının bulunmadığı yerde tam metin
aramasına düşer).
Dağıtıcı durumsuzdur: oturum başına bir çalışma alanı bağlaması yoktur.
Çalışma alanına özgü her çağrı kendi workspace_id değerini taşır ve erişime,
çağıranın çalışma alanı üyeliği ve rolü karar verir — bir eşleştirme anahtarı
taşımak değil.
Portu loopback dışına açmadan önce bilmeniz gereken iki şey:
- MCP, ana makine dışında kapalıya düşer. Belirteçsiz bir MCP yüzeyi yalnızca loopback’e yanıt verir.
anyadresine bağlanmak bunu genişletmez — ana makine dışından gelen bir istek, siz bir belirteç yapılandırana kadar “MCP requires a bearer token to answer non-loopback clients” ile reddedilir (mcp.setTokenya da Ayarlar → Sunucu → MCP sunucuları). GET /healthztasarımı gereği kimlik doğrulamasızdır, joker CORS ile çalışır ve sunucunun kimliğini, adını, kimlik parmak izini ve derleme sürümünü yayımlar. İstemcilerin sunucuyu sabitlemek için parmak izine ihtiyacı vardır, bu yüzden bu kasıtlıdır — ancak bu, erişilebilir herhangi bircc_server’ın soran herkese bu kadarını açıkladığı anlamına gelir.
İlgili kılavuzlar
Bölüm başlığı “İlgili kılavuzlar”- Uzak bir sunucuya bağlanma
- Bir cihaz eşleştirme
- Bir filo worker’ı çalıştırma
- Bir Google Calendar bağlama