Temă
Producție pe cPanel (fără Docker)
Totul rulează pe o găzduire cPanel obișnuită, fără Node.js pe server: cele trei aplicații web sunt fișiere statice servite de Apache, iar API-ul e o aplicație PHP (Laravel), servită tot de Apache. Fiecare stă pe subdomeniul lui; aplicațiile cer datele direct de la subdomeniul API-ului.
| Ce | Unde | Ce se încarcă |
|---|---|---|
| Site | https://taraba.temporary.ro | deploy/out/site/ |
| Backoffice | https://backoffice.temporary.ro | deploy/out/backoffice/ |
| CRM | https://crm.temporary.ro | deploy/out/crm/ |
| API | https://grahql.temporary.ro | deploy/out/api/ |
| Documentație | https://doc.temporary.ro | deploy/out/docs/ |
| Căsuța de captură (e-mail, SMS, push) | https://mailpit.temporary.ro | nimic: aceeași rădăcină ca API-ul (api/public) |
1. Adresele
În deploy/production.json sunt cele patru adrese. Dacă se schimbă un subdomeniu, se modifică aici și se face din nou build-ul.
2. Build-ul
Pe calculatorul de dezvoltare, în folderul proiectului:
bash
pnpm install
pnpm build:prodPentru API, build-ul are nevoie de Composer pe calculator sau, dacă lipsește, de Docker (folosește imaginea oficială composer). Rezultatul e în deploy/out/:
site/,backoffice/,crm/: aplicația compilată, plusenv.js(adresele; aplicațiile îl citesc la pornire) și.htaccess(orice adresă din aplicație deschideindex.html; HTTPS obligatoriu; cache de un an pentruassets/, fără cache pentruindex.htmlșienv.js; antetele de securitate, cu API-ul permis pentru date și imagini).api/: API-ul, cu dependențele de producție incluse învendor/(pe server nu se rulează Composer), plus.env.example(setările, cu adresele deja completate și o cheieAPP_KEYgenerată).database/:schema.sql(structura, cu toate tabelele),reference-data.sql(datele care sunt mereu aceleași: echipa, categoriile, setările, textele juridice, șabloanele, segmentele, cuvintele interzise) șiupgrades/(câte un fișier pentru fiecare migrare).- Arhivele
site.zip,backoffice.zip,crm.zip,api.zipșidatabase.zip, una pentru fiecare folder, cu fișierele direct la rădăcină: în File Manager încarci arhiva în folderul subdomeniului și alegi „Extract”. Includ și fișierele ascunse (.htaccess,.env.example).
Pe lângă foldere, build-ul creează și câte o arhivă pentru fiecare: site.zip, backoffice.zip, crm.zip, api.zip, cu fișierele direct în rădăcina arhivei (inclusiv cele ascunse, ca .htaccess). În File Manager încarci arhiva în folderul subdomeniului și alegi „Extract”: fișierele ajung direct acolo, fără un subfolder în plus. Apoi ștergi arhiva de pe server.
3. Ce trebuie să ofere găzduirea
| Necesar | Detalii |
|---|---|
| PHP 8.3 sau mai nou | din „MultiPHP Manager” sau „Select PHP Version”; extensiile pdo_mysql, mbstring, intl, gd (cu WebP), bcmath, zip, fileinfo (de obicei active implicit) |
| MySQL 8 sau MariaDB 10.6+ | „MySQL Databases”: o bază și un utilizator cu toate drepturile pe ea |
| Cron | „Cron Jobs”: o linie, la fiecare minut, pentru sarcinile periodice |
| SMTP | o adresă de e-mail din cPanel (de exemplu noreply@…) |
Nu e nevoie de Redis și nici de stocare externă: sesiunile, limitările de încercări și blocările sarcinilor periodice stau în baza de date, iar fotografiile și documentele pe discul serverului (api/storage/app).
4. API-ul
Subdomeniul. La „Domains”, subdomeniul
grahql.temporary.roprimește ca rădăcină (Document Root) folderulapi/public, de exemplu/home/<utilizator>/grahql.temporary.ro/public. Dacă găzduirea nu permite alegerea rădăcinii, folderulapi/poate fi chiar rădăcina: fișierulapi/.htaccesstrimite atunci toate cererile sprepublic/, iar celelalte foldere rămân inaccesibile din web.Fișierele. Încarci conținutul lui
deploy/out/api/în acel folder, inclusiv fișierele ascunse (.htaccess,.env.example; în File Manager: „Show Hidden Files”). Folderelestorage/șibootstrap/cache/trebuie să poată fi scrise de PHP (de obicei sunt, implicit).Setările. Copiezi
.env.exampleîn.env(în același folder) și completezi parola bazei de date, utilizatorul și parola SMTP. Restul e deja completat de build.Baza de date, una din două variante:
- din terminal (cPanel → „Terminal”, sau SSH):
cd ~/grahql.temporary.ro && php artisan taraba:setup. Aplică migrările și, pe o bază goală, încarcă datele de pornire (conturile echipei, categoriile, setările, textele juridice), cuSEED_DEMO_DATA=trueșiSEED_PROFILE=reference(deja puse în.env.example). Apoi puiSEED_DEMO_DATA=false; - din browser: deschizi
https://grahql.temporary.ro/dev/migrate. Aplică migrările și, pe o bază goală, încarcă datele de referință; răspunsul arată ce s-a aplicat; - fără terminal, din phpMyAdmin: imporți
database/schema.sql, apoidatabase/reference-data.sql(vezidatabase/README.md) și puiSEED_DEMO_DATA=false.
Pentru prezentări,
https://grahql.temporary.ro/dev/seedgolește toate tabelele și generează date demo pe ultimele 12 luni (vezidocs/DATABASE.md). Ambele adrese nu au protecție: șterge-le dinapi/routes/api.phpînainte ca platforma să aibă date reale.- din terminal (cPanel → „Terminal”, sau SSH):
Sarcinile periodice. La „Cron Jobs”, o linie care rulează la fiecare minut (calea PHP poate fi alta; cPanel o arată la „Cron Jobs”):
* * * * * cd /home/<utilizator>/grahql.temporary.ro && php artisan schedule:run >> /dev/null 2>&1Planificatorul pornește fiecare sarcină la intervalul ei: plățile către vânzători și alertele pentru căutările salvate la o oră, confirmarea automată a comenzilor la 10 minute, campaniile programate la un minut, automatizările CRM la 5 minute, amintirile juridice zilnic. O sarcină nu rulează niciodată de două ori în același timp, nici când e pornită și manual din Backoffice.
Verificare.
https://grahql.temporary.ro/healthtrebuie să arate"status":"up"pentru bază, cache, stocare și e-mail. În Backoffice, pagina „Stare sistem” arată și ultima rulare a fiecărei sarcini periodice.
La fiecare versiune nouă: încarci din nou fișierele din deploy/out/api/, fără .env și fără storage/ (acolo sunt fotografiile, documentele și jurnalele), apoi rulezi php artisan migrate --force, deschizi /dev/migrate sau imporți în phpMyAdmin fișierele noi din database/upgrades/. Datele existente rămân neatinse.
Important pentru securitate: conturile echipei create la instalare au parola și cheia de verificare în doi pași din documentația demo. După prima conectare, schimbă parola fiecărui cont și reconfigurează verificarea în doi pași (sau creează conturile reale prin invitații și dezactivează-le pe cele demo). Cheia APP_KEY din .env nu se schimbă după pornire: de ea depind sesiunile, linkurile de dezabonare și codurile de telefon.
5. Documentația și căsuța de captură
Documentația (doc.temporary.ro) e un site static, ca aplicațiile: conținutul lui deploy/out/docs/ (sau docs.zip), inclusiv .htaccess, în rădăcina subdomeniului. .htaccess servește adresele fără .html și pagina 404.
Căsuța de captură (mailpit.temporary.ro) ține locul Mailpit, care nu poate rula pe cPanel (e un server care stă pornit permanent). E servită chiar de API: în cPanel → Domains, subdomeniul mailpit.temporary.ro primește aceeași rădăcină ca API-ul (…/grahql.temporary.ro/public). În .env-ul API-ului:
MAIL_MAILER=inbox
SMS_DRIVER=capture
PUSH_DRIVER=capture
CAPTURE_TRANSPORT=inbox
INBOX_HOST=mailpit.temporary.ro
INBOX_PASSWORD=Cu MAIL_MAILER=inbox, niciun e-mail nu pleacă: toate (confirmări, resetări de parolă, comenzi, campanii), plus SMS-urile și notificările push, se păstrează în baza de date și se citesc la mailpit.temporary.ro, cu filtre pe tip și căutare. Mesajele mai vechi de 30 de zile se șterg automat. INBOX_PASSWORD pune o parolă (utilizatorul taraba); gol înseamnă acces liber pentru oricine știe adresa. Pentru e-mail real, MAIL_MAILER=smtp. Căsuța e disponibilă și la https://grahql.temporary.ro/inbox.
6. Cele trei aplicații
Conținutul fiecărui folder (inclusiv fișierul ascuns .htaccess) se încarcă în rădăcina subdomeniului (Document Root). În File Manager, activează „Show Hidden Files”, ca să vezi .htaccess.
7. Cum comunică între ele
- Aplicații → API: fiecare aplicație citește adresa API-ului din
env.jsși îi trimite cererile cu cookie-urile. - API → aplicații:
API_CORS_ORIGINSpermite exact cele trei adrese;COOKIE_SECURE=true(doar HTTPS);COOKIE_DOMAINrămâne gol (cookie-ul aparține subdomeniului API-ului). Subdomeniile aceluiași domeniu sunt același „site” pentru browser, deci cookie-urile circulă fără setări suplimentare. - Adresele din răspunsuri:
PUBLIC_API_URLface ca fotografiile și documentele să aibă adresa completă a API-ului;PUBLIC_SITE_URLșiPUBLIC_BACKOFFICE_URLapar în e-mailuri și în hărțile site-ului. - Motoarele de căutare:
robots.txtșisitemap.xmlde pe site trimit (redirect) la API, care le generează din anunțurile active.
8. Recomandări
- E-mail:
MAIL_ALLOWED_RECIPIENTS=*trimite tuturor. Pentru un mediu de test,@temporary.ro(doar domeniul tău) sau o listă de adrese. - SMS și notificări push: sunt oprite (
SMS_DRIVER=disabled,PUSH_DRIVER=disabled) până se conectează un furnizor. Până atunci, verificarea telefonului prin cod nu trimite SMS-ul. - SSL: AutoSSL / Let's Encrypt din cPanel pentru toate cele patru subdomenii, înainte de prima pornire.
- Copii de siguranță: pe lângă baza de date, folderul
api/storage/app(fotografiile anunțurilor și documentele de identitate în așteptare). - Jurnale:
api/storage/logs/(câte un fișier pe zi, cu avertismentele și erorile).