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
provider | Unde | region implicită |
|---|---|---|
openstack | codai cloud pe Cloudify (UE, România), Ubuntu 24.04 | eu-east-1 |
hetzner | Hetzner Cloud | nbg1 (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.
size | vCPU | OpenStack (Cloudify) | Tarif | Hetzner | Tarif |
|---|---|---|---|---|---|
small (implicit) | 2 | b2i.2c-2g, 2 GB | 0,03 € / h | cx23, 4 GB | 0,04 € / h |
medium | 4 | b2i.4c-4g, 4 GB | 0,06 € / h | cx33, 8 GB | 0,08 € / h |
large | 8 | b2i.8c-8g, 8 GB | 0,12 € / h | cx43, 16 GB | 0,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.
| Pas | Limită de timp | La depășire |
|---|---|---|
| Crearea serverului | 10 min | se reîncearcă; după 3 eșecuri consecutive ale furnizorului, mediul este parcat în error |
| Înrolarea daemonului | 15 min | error, motiv enroll_timeout — o înrolare întârziată îl readuce totuși la running |
Pornirea din stopped | 10 min | error |
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țiune | Permisă din | Trece în | Rol |
|---|---|---|---|
stop | running | stopping → stopped | maintainer |
start | stopped | starting → running | maintainer |
archive | stopped | archiving → archived | maintainer |
destroy | orice stare în afară de destroying/destroyed | destroying → destroyed | owner |
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:
| Oprire | Pornire | |
|---|---|---|
| OpenStack | Shelve, apoi shelve-offload: id-ul serverului și IP-ul public se păstrează, resursele de calcul se eliberează. | Unshelve pe același server. |
| Hetzner | Se 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_minutescu 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
humansauagent— un heartbeatidlenu 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șiupdateContentCommanddin 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/environmentscu 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țineprebuild_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_sizesau 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:
Instalare pe propriul server
Înrolează orice mașină Linux pe care o controlezi ca mediu gratuit, cu daemonul codaid — instalare, înrolare, rulare ca serviciu.
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.