codai docs
Proiecte și medii

Porturi și preview-uri

Ajungi la un server de dezvoltare din mediu printr-un URL de preview sau o redirecționare locală de port și decizi cine îl poate deschide.

Orice port care ascultă în mediu este raportat de daemon la fiecare 15 secunde. Nimic nu e accesibil din exterior până nu îl publici cu o vizibilitate; abia atunci primește un URL de preview pe preview.codai.ro și poate fi redirecționat pe mașina ta. Tot traficul circulă prin WebSocket-ul de ieșire al daemonului — mediul nu deschide niciodată un port de intrare.

URL-uri de preview

https://{port}-{slug}.preview.codai.ro/
        3000-brivio-k3xq.preview.codai.ro

slug este slug-ul mediului, unic la nivel global (3–40 de litere mici, cifre sau cratime). Relay-ul face proxy HTTP/1.1 către 127.0.0.1:{port} din mașină, păstrează Host, adaugă X-Forwarded-For/Proto/Host și transmite răspunsul nemodificat (cookie-uri, CSP, cache), plus un header X-Codai-Environment.

WebSocket-urile funcționează, deci și hot reload-ul: Vite are nevoie de server.allowedHosts: ['.preview.codai.ro']; Next.js acceptă host-ul redirecționat așa cum este. Un upstream care vorbește el însuși HTTPS ({port}s-{slug}) nu este încă suportat și răspunde 501 https_upstream_not_supported.

Vizibilitate

VizibilitateCine poate deschide portul
ownerDoar proprietarul mediului. Aceasta este valoarea implicită pentru orice port pe care nu l-ai publicat.
orgProprietarul și membrii organizației mediului.
authenticatedProprietarul și fiecare membru al acestui mediu (orice rol) — nu orice utilizator codai.
publicOricine, fără autentificare.

Dezvoltatorii pot publica până la authenticated; public cere maintainer sau mai mult. Fiecare schimbare se înregistrează ca eveniment port_visibility_changed.

Vizualizarea Medii → meniul ⋯ al mediului → Porturi. Fiecare port care ascultă își afișează procesul și un selector de vizibilitate (Doar eu, Organizație, Utilizatori autentificați, Public), plus Copiază URL-ul de previzualizare și Deschide previzualizarea.

Hub-ul nu are încă un panou de porturi; folosește desktop-ul, CLI-ul sau API-ul.

Deschiderea unui preview care nu e public

Un browser care vizitează un preview nepublic trebuie să dovedească cine este. Relay-ul acceptă, în ordine:

  1. Un token de preview în ?token= sau în header-ul X-Preview-Token — legat de un singur mediu și un singur port, valabil implicit 60 s (până la 24 h). Acordă ce putea vedea persoana care l-a generat.
  2. Cookie-ul codai_preview pe .preview.codai.ro (12 h) — conține doar identitatea ta; vizibilitatea se verifică din nou la fiecare cerere.
  3. Authorization: Bearer codai_… — pentru scripturi și clienți nativi.

Cea mai simplă cale este un link cu token:

codaid env preview brivio-k3xq 3000 --ttl 600
# https://3000-brivio-k3xq.preview.codai.ro/?token=codai_pv1.…

sau direct la relay:

curl -X POST https://relay.codai.ro/v1/environments/$ENV_ID/preview-token \
  -H "Authorization: Bearer $CODAI_API_KEY" -H "Content-Type: application/json" \
  -d '{ "port": 3000, "ttl_s": 600 }'
{ "token": "codai_pv1.…", "expires_at": "2026-09-25T10:10:00.000Z", "ttl_s": 600, "port": 3000,
  "host": "3000-brivio-k3xq.preview.codai.ro", "url": "https://3000-brivio-k3xq.preview.codai.ro/?token=codai_pv1.…" }

Pentru a seta cookie-ul, un client apelează GET https://preview.codai.ro/v1/environments/{id}/preview-cookie cu o cheie bearer (opțional cu ?redirect= către un URL de preview din același domeniu, pentru un 302). Doar proprietarul și membrii pot genera cookie-uri sau tokenuri; ceilalți primesc 404.

Un vizitator fără credențiale primește JSON, nu o redirecționare la login:

StatuscodeSemnificație
401preview_auth_requiredPort nepublic și niciun token, cookie sau cheie valide.
403preview_forbiddenEști autentificat, dar vizibilitatea te exclude.
404environment_not_foundNiciun mediu cu acel slug (un slug nou poate avea nevoie de până la 30 s ca să fie recunoscut).
404bad_preview_hostHostname-ul nu se potrivește cu {port}-{slug}.preview.codai.ro.
503environment_offlineDaemonul nu e conectat (Retry-After: 5).
503env_on_other_instanceDaemonul e pe altă instanță de relay (Retry-After: 2); reîncearcă.
429max_streamsPeste 256 de fluxuri deschise pe acest mediu.
502upstream_errorNimic nu a răspuns pe port — de obicei serverul încă nu ascultă.

Redirecționează un port pe mașina ta

codaid env forward brivio-k3xq 5432 --local 15432
# 127.0.0.1:15432 → 5432 în mediu
psql "postgres://[email protected]:15432/app"

Fiecare conexiune TCP locală devine un flux prin relay, supus aceleiași verificări de vizibilitate (un port refuzat se închide cu port_forbidden). Merge orice TCP simplu — baze de date, Redis, orice. Aplicația desktop nu are încă o interfață de redirecționare.

Limite

LimităValoare
Fluxuri deschise per mediu256
Date netrimise per flux256 KB, apoi fluxul se închide cu backpressure
Flux TCP/HTTP inactiv10 min (terminalele nu expiră niciodată)
Cea mai lungă conexiune1 oră — timeout-ul de cerere al relay-ului; clienții se reconectează
Căderea daemonuluifluxurile deschise se închid la 30 s după deconectarea daemonului; nu sunt reluate

Tailscale ca rută directă opțională este planificat; azi tot traficul trece prin relay.

Pe această pagină