codai docs
Proiecte și medii

Medii administrate

VM-uri pe care codai le provizionează pentru tine pe OpenStack sau Hetzner — dimensiuni, regiuni, pornire și oprire, oprire automată și snapshot-uri.

Un mediu administrat este un VM pe care codai îl creează, îl înrolează și îl întreține. Alegi un furnizor și o dimensiune; un worker care rulează în fiecare minut provizionează mașina, instalează codaid prin cloud-init, o oprește când e inactivă și o facturează pe secundă de rulare.

Furnizorii administrați sunt în curs de lansare și se activează per cont. Până când contul tău e activat, POST /v1/environments cu un furnizor administrat răspunde 403 — Provider 'hetzner' is not available yet; use 'byo' (bring your own machine) — iar hub-ul afișează opțiunile administrate ca în curând. Propriul server funcționează pentru toată lumea.

Furnizori și regiuni

providerUnderegion implicită
openstackcodai cloud pe Cloudify (UE, România), Ubuntu 24.04eu-east-1
hetznerHetzner Cloudnbg1 (tipurile de mai jos există în fsn1, hel1 și nbg1)

Valoarea de furnizor local există în schemă, dar este rezervată; nu se provizionează.

Dimensiuni

Fiecare furnizor facturează memoria RAM pe care o oferă efectiv.

sizevCPUOpenStack (Cloudify)TarifHetznerTarif
small (implicit)2b2i.2c-2g, 2 GB0,03 € / hcx23, 4 GB0,04 € / h
medium4b2i.4c-4g, 4 GB0,06 € / hcx33, 8 GB0,08 € / h
large8b2i.8c-8g, 8 GB0,12 € / hcx43, 16 GB0,16 € / h

Tarif = vCPU × 0,01 €/h + GB RAM × 0,005 €/h, salvat pe mediu la creare (hourlyRateMicroEur). Tipul de server este o preferință: dacă furnizorul îl retrage, codai alege cel mai ieftin tip disponibil cu cel puțin aceleași vCPU și RAM și facturează în continuare tariful dimensiunii. Discul este cel inclus în flavor sau în tipul de server (OpenStack 20 / 40 / 80 GB, Hetzner 40 / 80 / 160 GB); cât timp mașina este oprită sau arhivată, discul păstrat costă 0,05 € pe GB-lună — vezi stocarea. Mediile cu GPU vin în curând.

Crearea sau pornirea unui mediu administrat cere un sold în portofel de cel puțin o oră la tariful lui, altfel răspunsul este 402 insufficient_balance (detalii).

Rezervă de calcul și perioadă de grație

Setează o rezervă de calcul în Hub → Facturare: utilizarea LLM nu coboară niciodată portofelul sub această sumă, așa că o sesiune de chat intensă nu îți poate opri mașina virtuală. Dacă un interval de 10 minute tot nu poate fi plătit, mediul intră într-o perioadă de grație de 30 de minute (afișată în Hub și în aplicația desktop, cu ora opririi); o alimentare în acest timp plătește intervalul restant și anulează grația. După 30 de minute mediul este oprit cu snapshot — nu se pierde nimic.

Creează unul

În hub.codai.ro/projects deschide un proiect → Mediu nou, alege codai cloud (OpenStack) sau Hetzner, o dimensiune, timpul de inactivitate (5–1440 de minute) și, opțional, un plafon lunar de buget în euro.

Mediul pornește în starea creating. Worker-ul creează serverul (creating → enrolling când acesta are un IP public), cloud-init instalează codaid ca serviciu de sistem și îl înrolează cu un token generat de worker, iar mediul devine running. Pe ambii furnizori, în producție, asta a durat cam două-trei minute. La înrolare, daemonul unei mașini administrate primește propria cheie API, emisă pe proprietarul mediului; distrugerea mediului o revocă.

Această cheie de daemon este limitată la propriul mediu: poate apela inferența, poate conduce sesiunea partajată a unei sarcini pe care o rulează, își poate citi mediul (și proiectul lui) și poate lista numele secretelor propriului mediu — nimic altceva. Orice altă rută răspunde cu 403 key_scope_forbidden, deci o mașină compromisă nu poate ajunge la celelalte medii, chei sau la portofelul tău.

PasLimită de timpLa depășire
Crearea serverului10 minse reîncearcă; după 3 eșecuri consecutive ale furnizorului, mediul este parcat în error
Înrolarea daemonului15 minerror, motiv enroll_timeout — o înrolare întârziată îl readuce totuși la running
Pornirea din stopped10 minerror

Worker-ul nu distruge niciodată o mașină pe o cale de eroare; decizia îți aparține.

Un mediu în error al cărui server încă există se taxează ca unul care rulează; după 30 de minute în error, worker-ul îl oprește cu snapshot, ca o mașină defectă să nu te taxeze în continuare.

Ciclul de viață

AcțiunePermisă dinTrece înRol
stoprunningstopping → stoppedmaintainer
startstoppedstarting → runningmaintainer
archivestoppedarchiving → archivedmaintainer
destroyorice stare în afară de destroying/destroyeddestroying → destroyedowner

Orice altceva răspunde 409 invalid_transition. Butoanele din hub, codaid env start|stop|destroy și POST /v1/environments/{id}/{action} trec toate prin același tabel de tranziții.

Ce fac oprirea și pornirea la fiecare furnizor:

OprirePornire
OpenStackShelve, apoi shelve-offload: id-ul serverului și IP-ul public se păstrează, resursele de calcul se eliberează.Unshelve pe același server.
HetznerSe face un snapshot, apoi serverul este șters.Se creează un server nou din snapshot. Snapshot-ul anterior se șterge după următoarea oprire.

archive parcurge aceeași cale de oprire și parchează mașina în archived; singura ieșire din archived este destroy. destroy șterge serverul (iar pe Hetzner și snapshot-ul lui) și revocă cheia daemonului.

Oprire automată la inactivitate

Fiecare mediu are idle_timeout_minutes (implicit 30, 5–1440; îl schimbi cu PATCH /v1/environments/{id} sau din hub). Worker-ul oprește un mediu administrat care rulează atunci când

now − max(last_activity_at, started_at) > idle_timeout_minutes

cu motivul idle. Se consideră activitate:

  • orice exec, terminal sau octet de flux de port de la un client atașat, prin relay;
  • heartbeat-urile daemonului care raportează activitate human sau agent — un heartbeat idle nu contează niciodată;
  • cererile pe care daemonul însuși le face către gateway cu cheia lui (de exemplu o buclă de agent care rulează în mașină);
  • propriile tale cereri de start/stop/archive/destroy.

Traficul de preview venit de la terți contează doar ca octeți de flux de port, deci un preview public cu vizitatori ține mașina trează. Activitatea se înregistrează cel mult o dată pe minut.

Mașina poate fi oprită și din motive de facturare — insufficient_funds, billing_error sau budget_exceeded; vezi facturarea. Motivul apare pe pagina mediului și este returnat ca stateReason.

Prebuild-uri

Un proiect poate păstra un pool de până la 5 mașini pregătite, astfel încât un mediu nou pornește dintr-un snapshot deja încălzit, nu dintr-o instalare de la zero:

curl -X PATCH https://ai.codai.ro/v1/projects/$PROJECT_ID \
  -H "Authorization: Bearer $CODAI_API_KEY" -H 'content-type: application/json' \
  -d '{"prebuild_pool_size": 2, "prebuild_provider": "openstack", "prebuild_size": "small"}'
  • Doar owner-ul proiectului sau un owner/admin al organizației îl poate seta. Worker-ul completează pool-ul în fiecare minut, rulează doar onCreateCommand și updateContentCommand din devcontainer, apoi oprește fiecare mașină.
  • Owner-ul proiectului plătește compute-ul de încălzire și stocarea mașinilor oprite din pool (tariful normal de stocare). Pool-ul nu se completează cât timp portofelul owner-ului are mai puțin decât o oră dintr-o mașină de pool.
  • POST /v1/environments cu același furnizor și aceeași dimensiune (și fără slug) revendică o mașină gata: proprietatea trece la tine, pornește imediat, iar răspunsul conține prebuild_claimed: true. De atunci plătești tu. Verificarea soldului pentru o oră se aplică în continuare.
  • Mașinile nerevendicate din pool sunt vizibile doar owner-ului proiectului. Scăderea prebuild_pool_size sau schimbarea furnizorului/dimensiunii distruge mașinile nerevendicate în plus.

În curând

Mediile cu GPU și alegerea regiunii din hub nu sunt încă disponibile.

Ultima actualizare:

Pe această pagină