feat(deploy): configure deployment for ClinicPro on Liara PHP platform
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# راهنمای دیپلوی ClinicPro روی لیارا (پلتفرم PHP)
|
||||
|
||||
دیپلوی بکاند Symfony روی **پلتفرم PHP لیارا** (نوع برنامه `php` هنگام «ساخت برنامهی جدید»). اینجا داکری در کار نیست؛ لیارا کد را میگیرد، خودش `composer install` میزند و روی Apache + PHP-FPM سرو میکند.
|
||||
|
||||
> مسیر جایگزین (داکر) در [docs/deploy-liara.md](deploy-liara.md) است. **همزمان فقط یک مسیر** را نگه دار — هر دو از یک `liara.json` استفاده میکنند.
|
||||
|
||||
---
|
||||
|
||||
## نمای کلی
|
||||
|
||||
```
|
||||
┌──────────────── Liara private network ─────────────────┐
|
||||
│ │
|
||||
│ ┌──────────────────────────────┐ ┌──────────────┐ │
|
||||
│ │ clinicpro-api (PHP app) │ │ MariaDB 11.8 │ │
|
||||
│ │ • Apache + PHP-FPM (docroot │◄─►│ (managed) │ │
|
||||
│ │ = public/) :80 │ └──────────────┘ │
|
||||
│ │ • supervisor.conf: │ ┌──────────────┐ │
|
||||
│ │ worker-async │◄─►│ Redis │ │
|
||||
│ │ worker-scheduler │ │ (managed) │ │
|
||||
│ └──────────────────────────────┘ └──────────────┘ │
|
||||
│ disks: jwt / uploads / var-uploads │
|
||||
└────────────────────────────────────────────────────────┘
|
||||
│ :80
|
||||
▼ https://<domain>
|
||||
```
|
||||
|
||||
همهٔ پروسهها (وب + هر دو worker) در **یک** کانتینر اجرا میشوند؛ workerها کانتینر جدا ندارند (برخلاف نسخهٔ docker-compose).
|
||||
|
||||
---
|
||||
|
||||
## فایلهای دخیل (همه ساخته شدهاند)
|
||||
|
||||
| فایل | نقش |
|
||||
|---|---|
|
||||
| [`liara.json`](../liara.json) | `platform: php`، `php.version: 8.2`، `documentRoot: public`، دیسکها |
|
||||
| [`public/.htaccess`](../public/.htaccess) | rewrite front-controller سیمفونی روی Apache |
|
||||
| [`liara_pre_build.sh`](../liara_pre_build.sh) | قبل `composer install`: ساخت `.env` مینیمال prod |
|
||||
| [`liara_pre_start.sh`](../liara_pre_start.sh) | قبل start: انتظار DB، تولید JWT، cache، migration |
|
||||
| [`supervisor.conf`](../supervisor.conf) | دو worker مسنجر (`async` + `scheduler_default`) |
|
||||
| [`liara_php.ini`](../liara_php.ini) | memory_limit، حجم آپلود، زمان اجرا |
|
||||
| [`.liaraignore`](../.liaraignore) | کنترل آپلود (تا `public/build` آپلود شود، سکرتها مستثنی) |
|
||||
| [`.env.liara.example`](../.env.liara.example) | مرجع متغیرهای محیطی |
|
||||
|
||||
---
|
||||
|
||||
## پیشنیاز
|
||||
|
||||
```bash
|
||||
npm i -g @liara/cli
|
||||
liara login
|
||||
```
|
||||
|
||||
مقادیر آماده:
|
||||
```bash
|
||||
php -r "echo bin2hex(random_bytes(32)).\"\n\";" # APP_SECRET
|
||||
openssl rand -hex 32 # JWT_PASSPHRASE
|
||||
ddev exec php docker/gen-cors-env.php # ALLOWED_FRONTEND_HOSTS + CORS_ALLOW_ORIGIN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## گام ۱ — build محلی assetها (حیاتی)
|
||||
|
||||
پلتفرم PHP لیارا **`yarn` اجرا نمیکند** و assetهای React را نمیسازد. قبل هر دیپلوی محلی build کن (خروجی در `public/build`؛ `.liaraignore` آن را آپلود میکند):
|
||||
|
||||
```bash
|
||||
ddev exec yarn install --frozen-lockfile
|
||||
ddev exec yarn build
|
||||
```
|
||||
|
||||
> اگر این مرحله را رد کنی، پنل ادمین `/admin` لود نمیشود.
|
||||
|
||||
---
|
||||
|
||||
## گام ۲ — ساخت دیتابیس و Redis
|
||||
|
||||
کنسول لیارا:
|
||||
1. **MariaDB 11.8** بساز (هماهنگ با `serverVersion=mariadb-11.8.0`).
|
||||
2. **Redis** بساز.
|
||||
3. روی هر دو **شبکهٔ خصوصی** فعال؛ هاست خصوصی/کاربر/رمز را یادداشت کن.
|
||||
|
||||
---
|
||||
|
||||
## گام ۳ — ساخت برنامهٔ PHP
|
||||
|
||||
1. New App → نوع **PHP** → نسخهٔ **8.2** (پروژه `php: >=8.2` میخواهد) → شناسه `clinicpro-api`.
|
||||
2. آن را به **همان شبکهٔ خصوصیِ** DB و Redis وصل کن.
|
||||
|
||||
---
|
||||
|
||||
## گام ۴ — ساخت دیسکهای ماندگار
|
||||
|
||||
در صفحهٔ برنامه، بخش Disks، این سه دیسک را با همین نامها بساز (mount از `liara.json`):
|
||||
|
||||
| نام | mountTo | محتوا |
|
||||
|---|---|---|
|
||||
| `jwt` | `/var/www/config/jwt` | کلید JWT (نباید هر دیپلوی نو شود) |
|
||||
| `uploads` | `/var/www/public/uploads` | فایلهای عمومی |
|
||||
| `var-uploads` | `/var/www/var/uploads` | فایلهای خصوصی |
|
||||
|
||||
> ⚠️ ریشهٔ اپ فرض شده `/var/www`. اگر در لاگ مسیر دیگری دیدی، `mountTo` در `liara.json` را اصلاح کن.
|
||||
|
||||
---
|
||||
|
||||
## گام ۵ — متغیرهای محیطی
|
||||
|
||||
از روی [`.env.liara.example`](../.env.liara.example) ست کن (تب Environment یا CLI). یکبار روی app؛ workerها همان را میگیرند.
|
||||
|
||||
```bash
|
||||
liara env set APP_ENV=prod APP_DEBUG=0 --app clinicpro-api
|
||||
liara env set APP_SECRET=<...> JWT_PASSPHRASE=<...> --app clinicpro-api
|
||||
liara env set DATABASE_URL="mysql://<user>:<pass>@<db-private-host>:3306/<db>?serverVersion=mariadb-11.8.0&charset=utf8mb4" --app clinicpro-api
|
||||
liara env set REDIS_URL="redis://:<pass>@<redis-private-host>:6379" --app clinicpro-api
|
||||
liara env set MESSENGER_TRANSPORT_DSN="redis://:<pass>@<redis-private-host>:6379/messages" --app clinicpro-api
|
||||
liara env set JWT_SECRET_KEY='%kernel.project_dir%/config/jwt/private.pem' JWT_PUBLIC_KEY='%kernel.project_dir%/config/jwt/public.pem' --app clinicpro-api
|
||||
liara env set APP_BASE_URL=https://<domain> DEFAULT_URI=https://<domain> --app clinicpro-api
|
||||
liara env set TRUSTED_PROXIES="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1" --app clinicpro-api
|
||||
liara env set ALLOWED_FRONTEND_HOSTS="<output>" CORS_ALLOW_ORIGIN="<output>" --app clinicpro-api
|
||||
liara env set API_IR_BASE_URL=https://s.api.ir API_IR_TOKEN=<token> --app clinicpro-api
|
||||
liara env set REFRESH_TOKEN_TTL=2592000 OTP_TTL=1200 MAX_FILE_SIZE_BYTES=5242880 UPLOAD_DIR=var/uploads --app clinicpro-api
|
||||
```
|
||||
|
||||
نکتهها:
|
||||
- `RUN_INIT` را ست **نکن** — init یکبار در `liara_pre_start.sh` اجرا میشود.
|
||||
- `APP_ENV=prod` موقع build هم لازم است (composer اسکریپت `cache:clear` را اجرا میکند).
|
||||
- کلیدهای SMS و درگاه پرداخت از **دیتابیس** خوانده میشوند، نه env.
|
||||
|
||||
---
|
||||
|
||||
## گام ۶ — دیپلوی
|
||||
|
||||
از ریشهٔ `clinicpro/`:
|
||||
```bash
|
||||
liara deploy
|
||||
```
|
||||
|
||||
روند خودکار:
|
||||
1. `liara_pre_build.sh` → `.env` مینیمال prod (اگر نبود).
|
||||
2. `composer install` (لیارا).
|
||||
3. `liara_pre_start.sh` → انتظار DB → تولید JWT (روی دیسک) → warmup → migration.
|
||||
4. Apache (docroot=`public`) + `supervisor.conf` (هر دو worker) بالا میآیند.
|
||||
|
||||
---
|
||||
|
||||
## گام ۷ — اتصال دامنه و تأیید
|
||||
|
||||
1. بخش Domains: دامنهٔ API را وصل کن، TLS بگیر.
|
||||
2. سلامت:
|
||||
```bash
|
||||
curl -i https://<domain>/health # باید 200
|
||||
```
|
||||
3. workerها:
|
||||
```bash
|
||||
# در کنسول/CLI برنامه:
|
||||
supervisorctl status # worker-async و worker-scheduler = RUNNING
|
||||
```
|
||||
4. ورود `/admin` و تست یک endpoint (تأیید DB/Redis).
|
||||
|
||||
---
|
||||
|
||||
## دیپلویهای بعدی
|
||||
|
||||
```bash
|
||||
ddev exec yarn build # اگر assets عوض شد
|
||||
liara deploy
|
||||
```
|
||||
|
||||
migrationها خودکار در `liara_pre_start.sh` اجرا میشوند. دیسکها و env حفظ میشوند.
|
||||
|
||||
---
|
||||
|
||||
## نگاشت compose → لیارا (PHP platform)
|
||||
|
||||
در `docker-compose.yml` هر worker یک کانتینر جدا بود؛ اینجا هر دو در همان کانتینر با `supervisor.conf`:
|
||||
|
||||
| compose | لیارا |
|
||||
|---|---|
|
||||
| سرویس `app` (php-fpm+nginx) | خود پلتفرم PHP (Apache+PHP-FPM)، docroot=`public` |
|
||||
| `worker-async` (کانتینر جدا) | `[program:worker-async]` در `supervisor.conf` |
|
||||
| `worker-scheduler` (کانتینر جدا) | `[program:worker-scheduler]` در `supervisor.conf` |
|
||||
| `environment: *app-env` + `RUN_INIT` | env روی app؛ init در `liara_pre_start.sh` |
|
||||
| `volumes` | دیسکهای `liara.json` |
|
||||
| `networks: [coolify]` | شبکهٔ خصوصی لیارا |
|
||||
| `restart`/`healthcheck` | `autorestart=true` |
|
||||
| `stop_grace_period: 30s` | `stopsignal=TERM` + `stopwaitsecs=30` |
|
||||
|
||||
---
|
||||
|
||||
## رفع اشکال
|
||||
|
||||
| نشانه | علت | راهحل |
|
||||
|---|---|---|
|
||||
| پنل `/admin` سفید/۴۰۴ asset | `public/build` آپلود نشده | `ddev exec yarn build` قبل deploy؛ `.liaraignore` build را مستثنی نکند |
|
||||
| کل سایت ۴۰۳/۴۰۴ | documentRoot روی `public` نیست یا `.htaccess` نیست | `documentRoot: public` در liara.json + `public/.htaccess` |
|
||||
| `Database not reachable after 60s` | شبکهٔ خصوصی/`DATABASE_URL` غلط | DB و app یک شبکه؛ هاست خصوصی را چک کن |
|
||||
| توکنها بعد هر دیپلوی باطل | دیسک `jwt` mount نشده | دیسک `jwt` → `/var/www/config/jwt` |
|
||||
| worker بالا نمیآید / messenger خطای redis | افزونهٔ `redis` روی پلتفرم نیست | `php -m \| grep redis`؛ نبود → `MESSENGER_TRANSPORT_DSN=doctrine://default` + کش فایلسیستم |
|
||||
| build بهخاطر composer scripts شکست | `cache:clear` موقع نصب | مطمئن شو `APP_ENV=prod` ست است؛ در صورت لزوم نصب را `--no-scripts` کن و همهچیز را به `liara_pre_start.sh` بسپار |
|
||||
| خطای CORS از فرانت | `CORS_ALLOW_ORIGIN` قدیمی | `docker/gen-cors-env.php` دوباره؛ env بهروز |
|
||||
|
||||
---
|
||||
|
||||
## ریسکهای شناختهشده
|
||||
|
||||
- **ext-redis:** اگر پلتفرم PHP لیارا phpredis نداشته باشد، Redis (cache + messenger) کار نمیکند → fallback به Doctrine transport و کش فایلسیستم. قبل اتکا verify کن.
|
||||
- **مسیر دیسک:** ریشهٔ `/var/www` فرض است؛ با لاگ واقعی تطبیق بده.
|
||||
- **انتخاب مسیر:** یا Docker یا PHP platform — هر دو `liara.json` را همزمان نگه ندار.
|
||||
Reference in New Issue
Block a user