174 lines
8.7 KiB
Markdown
174 lines
8.7 KiB
Markdown
# راهنمای دیپلوی ClinicPro روی لیارا (Docker)
|
||
|
||
این راهنما قدمبهقدم نشان میدهد چطور بکاند Symfony را روی **لیارا** با پلتفرم **Docker** بالا بیاوری.
|
||
|
||
> چرا متفاوت با Coolify؟ لیارا **از docker-compose پشتیبانی نمیکند**. استک ۳-سرویسی compose (وب + ۲ worker) به یک **برنامهٔ داکر تکی** تبدیل شده که هر سه پروسه را با Supervisor اجرا میکند. MariaDB و Redis سرویسهای مدیریتشدهٔ جدا روی شبکهٔ خصوصیاند.
|
||
|
||
---
|
||
|
||
## نمای کلی معماری
|
||
|
||
```
|
||
┌─────────────────────────── Liara private network ───────────────────────────┐
|
||
│ │
|
||
│ ┌────────────────────────────┐ ┌───────────────┐ ┌──────────────┐ │
|
||
│ │ clinicpro-api (Docker) │ │ MariaDB 11.8 │ │ Redis │ │
|
||
│ │ Supervisor: │◄────►│ (managed) │ │ (managed) │ │
|
||
│ │ • php-fpm + nginx :8080 │ └───────────────┘ └──────────────┘ │
|
||
│ │ • worker-async │ │
|
||
│ │ • worker-scheduler │ disks: jwt / uploads / var-uploads │
|
||
│ └─────────────┬──────────────┘ │
|
||
└─────────────────┼────────────────────────────────────────────────────────────┘
|
||
│ :8080 (تنها پورت HTTP بیرونی)
|
||
▼
|
||
https://<your-domain>
|
||
```
|
||
|
||
فایلهای کلیدی در ریپو:
|
||
- [`liara.json`](../liara.json) — پیکربندی دیپلوی (platform، port، دیسکها، healthcheck)
|
||
- [`Dockerfile`](../Dockerfile) — image چندمرحلهای (بدون تغییر برای لیارا)
|
||
- [`docker/supervisord.conf`](../docker/supervisord.conf) — اجرای php-fpm + nginx + دو worker
|
||
- [`docker/entrypoint.sh`](../docker/entrypoint.sh) — wait-for-DB، تولید JWT، migration
|
||
- [`.env.liara.example`](../.env.liara.example) — مرجع متغیرهای محیطی
|
||
|
||
---
|
||
|
||
## پیشنیازها
|
||
|
||
```bash
|
||
npm i -g @liara/cli
|
||
liara login
|
||
```
|
||
|
||
مقادیری که از قبل آماده کن:
|
||
|
||
```bash
|
||
# APP_SECRET
|
||
php -r "echo bin2hex(random_bytes(32)).\"\n\";"
|
||
|
||
# JWT_PASSPHRASE
|
||
openssl rand -hex 32
|
||
|
||
# دامنههای فرانت (ALLOWED_FRONTEND_HOSTS + CORS_ALLOW_ORIGIN)
|
||
ddev exec php docker/gen-cors-env.php
|
||
```
|
||
|
||
---
|
||
|
||
## گام ۱ — ساخت دیتابیس و Redis
|
||
|
||
در [کنسول لیارا](https://console.liara.ir):
|
||
|
||
1. **MariaDB 11.8** بساز. (نسخه باید با `serverVersion=mariadb-11.8.0` در `DATABASE_URL` یکی باشد.)
|
||
2. **Redis** بساز.
|
||
3. روی هر دو **شبکهٔ خصوصی** را فعال کن.
|
||
4. **هاست خصوصی** و کاربر/رمز هرکدام را از صفحهٔ سرویس یادداشت کن (مثلاً `clinicpro-db`، `clinicpro-redis`).
|
||
|
||
---
|
||
|
||
## گام ۲ — ساخت برنامهٔ داکر
|
||
|
||
1. در کنسول یک **App** از نوع **Docker** بساز با شناسهٔ `clinicpro-api` (همان `app` در `liara.json`).
|
||
2. آن را به **همان شبکهٔ خصوصیِ** DB و Redis متصل کن.
|
||
|
||
---
|
||
|
||
## گام ۳ — ساخت دیسکهای ماندگار
|
||
|
||
در صفحهٔ برنامه، بخش **Disks**، این سه دیسک را با **همین نامها** بساز (مسیر mount از `liara.json` خوانده میشود):
|
||
|
||
| نام دیسک | mountTo | محتوا |
|
||
|---|---|---|
|
||
| `jwt` | `/app/config/jwt` | کلید JWT (نباید هر دیپلوی نو شود) |
|
||
| `uploads` | `/app/public/uploads` | فایلهای عمومی آپلودی |
|
||
| `var-uploads` | `/app/var/uploads` | فایلهای خصوصی آپلودی |
|
||
|
||
> ⚠️ بدون دیسک `jwt`، هر دیپلوی کلید جدید میسازد و **همهٔ توکنهای صادرشده باطل** میشوند.
|
||
|
||
---
|
||
|
||
## گام ۴ — ستکردن متغیرهای محیطی
|
||
|
||
از روی [`.env.liara.example`](../.env.liara.example) مقادیر را در تب **Environment** یا با CLI ست کن:
|
||
|
||
```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://<redis-private-host>:6379" --app clinicpro-api
|
||
liara env set MESSENGER_TRANSPORT_DSN="redis://<redis-private-host>:6379/messages" --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
|
||
```
|
||
|
||
نکتهها:
|
||
- `RUN_INIT` را ست **نکن** — `entrypoint.sh` پیشفرض `1` میگیرد و چون تکبرنامه است، تولید JWT + migration یکبار اجرا میشود.
|
||
- کلیدهای SMS و درگاه پرداخت از **دیتابیس** خوانده میشوند، نه env.
|
||
|
||
---
|
||
|
||
## گام ۵ — دیپلوی
|
||
|
||
از ریشهٔ `clinicpro/`:
|
||
|
||
```bash
|
||
liara deploy
|
||
```
|
||
|
||
`liara.json` تنظیمات platform/port/disks/healthcheck را میدهد، پس فلگ اضافه لازم نیست. در اولین بالا آمدن:
|
||
|
||
1. `entrypoint.sh` تا ~۶۰ ثانیه صبر میکند تا DB جواب دهد.
|
||
2. کلید JWT میسازد (روی دیسک `jwt`).
|
||
3. کش prod را warmup میکند.
|
||
4. `doctrine:migrations:migrate` را اجرا میکند.
|
||
5. Supervisor، nginx/php-fpm و هر دو worker را بالا میآورد.
|
||
|
||
---
|
||
|
||
## گام ۶ — اتصال دامنه و تأیید
|
||
|
||
1. در بخش **Domains** برنامه، دامنهٔ API را وصل کن و TLS بگیر.
|
||
2. تست سلامت:
|
||
```bash
|
||
curl -i https://<domain>/health # باید 200 بدهد
|
||
```
|
||
3. لاگها:
|
||
```bash
|
||
liara logs --app clinicpro-api --follow
|
||
```
|
||
باید php-fpm، nginx، `worker-async` و `worker-scheduler` هر چهار بالا باشند.
|
||
4. ورود به پنل ادمین `/admin` و تست یک endpoint برای تأیید اتصال DB/Redis.
|
||
|
||
---
|
||
|
||
## دیپلویهای بعدی
|
||
|
||
```bash
|
||
git pull # یا تغییرات محلی
|
||
liara deploy
|
||
```
|
||
|
||
migrationهای جدید خودکار در `entrypoint.sh` اجرا میشوند. دیسکها و env بین دیپلویها حفظ میشوند.
|
||
|
||
---
|
||
|
||
## رفع اشکال
|
||
|
||
| نشانه | علت محتمل | راهحل |
|
||
|---|---|---|
|
||
| `Database not reachable after 60s` در لاگ | شبکهٔ خصوصی وصل نیست یا `DATABASE_URL` غلط | DB و app روی یک شبکهٔ خصوصی باشند؛ هاست خصوصی و رمز را چک کن |
|
||
| توکنها بعد از هر دیپلوی باطل | دیسک `jwt` mount نشده | دیسک `jwt` روی `/app/config/jwt` بساز |
|
||
| `/health` غیر-۲۰۰ | DB/Redis در دسترس نیست یا migration نخورده | لاگ entrypoint را ببین |
|
||
| خطای CORS از فرانت | `CORS_ALLOW_ORIGIN`/`ALLOWED_FRONTEND_HOSTS` قدیمی | `docker/gen-cors-env.php` را دوباره بزن و env را بهروزرسانی کن |
|
||
| آپلودها بعد از دیپلوی گم میشوند | دیسک uploads mount نشده | دیسکهای `uploads` و `var-uploads` را بساز |
|
||
|
||
---
|
||
|
||
## گزینهٔ جایگزین — worker مجزا
|
||
|
||
اگر خواستی workerها ایزوله باشند (بهجای Supervisor تککانتینر)، همین ریپو را بهعنوان برنامهٔ داکر دومی با `liara.json` متفاوت دیپلوی کن که `command` را به `php bin/console messenger:consume ...` override کند، `RUN_INIT=0` بدهد و **بدون** پورت/دامنه باشد. گرانتر (دو برنامهٔ داکر) ولی ایزولهتر. برای اکثر موارد گزینهٔ پیشفرض (Supervisor) کافی است.
|