متغیرهای محیطی
آدرس دیتابیس، کلیدهای API و هر تنظیمی که بین محیطها فرق میکند را در متغیرها بگذارید، نه در کد. برنامه آنها را مثل متغیر محیطی معمولی میخواند (process.env.X، os.environ["X"]، os.Getenv("X"))؛ فایل .env روی سرور لازم نیست.
افزودن متغیر به سرویس
زبانهٔ «متغیرها»ی سرویس را باز کنید
نام و مقدار را بنویسید
دو انتخاب دارید:
- رانتایم یا بیلد تایم: توضیحش پایینتر آمده. بیشتر متغیرها رانتایماند.
- محرمانه یا نمایان: مقدار محرمانه بعد از ذخیره دیگر در پنل نشان داده نمیشود. رمزها و کلیدها را محرمانه کنید.
ذخیره کنید
با ذخیره، سرویس با مقادیر تازه دوباره مستقر میشود. اگر همین الان استقراری در جریان است، تغییر بعد از پایان آن اعمال میشود.
مقدار متغیر محرمانه را هیچجای پنل نمیبینید؛ فقط میتوانید مقدار تازه بگذارید. اگر لازمش دارید، در زبانهٔ «لاگها»ی سرویس، کادر «اجرای دستور» printenv نام_متغیر را اجرا کنید.
سه جا برای تعریف متغیر
| کجا | در پنل | به چه سرویسهایی میرسد |
|---|---|---|
| متغیرهای محرمانهٔ مشترک اپلیکیشن | پنل «محیطها و متغیرها» | همهٔ سرویسهای اپلیکیشن، در همهٔ محیطها |
| متغیرهای محیط | پنل «محیطها و متغیرها»، زیر هر محیط | همهٔ سرویسهای همان محیط (مثلاً فقط production) |
| متغیرهای سرویس | زبانهٔ «متغیرها»ی سرویس | فقط همان سرویس |
اتصال یک افزونهٔ دیتابیس هم متغیرهای اتصال (مثل DATABASE_URL) را به سرویس اضافه میکند.
ترتیب اولویت
اگر یک نام در چند جا تعریف شده باشد، مقدارِ نزدیکتر به سرویس برنده است:
مشترک اپلیکیشن < متغیر محیط < اتصال افزونه < متغیر خود سرویس
(کمترین) (بیشترین)پس اگر LOG_LEVEL=info را برای کل اپلیکیشن گذاشتهاید، میتوانید برای یک سرویس LOG_LEVEL=debug بگذارید و فقط همان سرویس عوض شود.
با تغییر متغیر مشترک یا متغیر محیط، همهٔ سرویسهایی که به آن میرسند دوباره مستقر میشوند.
زمان ساخت یا زمان اجرا
| رانتایم (پیشفرض) | بیلد تایم | |
|---|---|---|
| کِی در دسترس است | وقتی برنامه اجرا میشود | وقتی برنامه ساخته میشود |
| مثال | DATABASE_URL، کلید پرداخت | NEXT_PUBLIC_API_URL، VITE_API_URL، NODE_VERSION |
| با تغییرش | سرویس با همان ایمیج دوباره اجرا میشود | سرویس دوباره ساخته میشود |
فریمورکهای فرانتاند (Next.js، Vite، Nuxt) متغیرهای عمومی را موقع ساخت داخل فایلهای JavaScript مینویسند. اگر NEXT_PUBLIC_API_URL را رانتایم تعریف کنید، در مرورگر undefined میبینید. اینها را بیلد تایم کنید.
هر چیزی که بیلد تایم است ممکن است در خروجی ساخت بماند و در مرورگر دیده شود. رمزها و کلیدهای خصوصی را هرگز بیلد تایم نکنید.
ارجاع به متغیرهای دیگر
به جای کپی کردن یک مقدار در چند جا، به آن ارجاع بدهید. ارجاعها هنگام استقرار با مقدار واقعی جایگزین میشوند:
# یک متغیر مشترک اپلیکیشن
APP_KEY=${{ shared.APP_KEY }}
# متغیری از سرویس دیگر همین اپلیکیشن (با نام آن سرویس)
API_TOKEN=${{ backend.API_TOKEN }}
# آدرس عمومی سرویس دیگر
API_URL=https://${{ backend.GERDOO_PUBLIC_DOMAIN }}
# آدرس خصوصی سرویس دیگر، برای ارتباط داخلی
INTERNAL_API=${{ backend.GERDOO_PRIVATE_URL }}
# متغیر دیگری از همین سرویس
FULL_URL=${{ BASE_URL }}/v1- ارجاعی که پیدا نشود (نام اشتباه، سرویس حذفشده) به رشتهٔ خالی تبدیل میشود، نه خطا. اگر برنامه مقداری خالی میبیند، اول املای نام سرویس و متغیر را بررسی کنید.
GERDOO_PUBLIC_DOMAINهمیشه آدرس پیشفرضgerdoo.appاست، نه دامنهٔ اختصاصی. اگر آدرس دامنهٔ خودتان را لازم دارید، آن را مستقیم بنویسید.RAILWAY_PUBLIC_DOMAINهم کار میکند تا پروژههایی که از Railway آمدهاند بدون تغییر اجرا شوند.
متغیرهایی که گردو خودش میگذارد
| متغیر | مقدار |
|---|---|
PORT | پورت داخلی سرویس. برنامه باید روی همین گوش بدهد. توضیح |
GERDOO_PRIVATE_HOST | نام این سرویس در شبکهٔ خصوصی اپلیکیشن |
GERDOO_PRIVATE_URL | http://<GERDOO_PRIVATE_HOST>:<PORT>؛ آدرسی که سرویسهای دیگر با آن به این سرویس وصل میشوند |
از خط فرمان
# متغیرهای خود سرویس
gerdoo service vars api # فهرست
gerdoo service vars api set STRIPE_KEY=sk_live_xxx --secret
gerdoo service vars api set NEXT_PUBLIC_API_URL=https://api.example.com --build-time
gerdoo service vars api rm OLD_KEY
# متغیرهای یک محیط
gerdoo project env shop vars production set LOG_LEVEL=warnاگر به خطا خوردید
متغیر را عوض کردم ولی برنامه مقدار قبلی را میبیند
- اگر بیلد تایم است، باید ساخت تازه تمام شود. وضعیت را در زبانهٔ «استقرارها» ببینید.
- شاید همین نام با اولویت بالاتری جای دیگر تعریف شده است (ترتیب اولویت). مثلاً متغیر محیط را عوض کردهاید، ولی خود سرویس هم همان نام را دارد.
هشدار دربارهٔ PORT در گزارش استقرار
متغیر PORT را خودتان تعریف کردهاید و با پورت سرویس فرق دارد. گردو مقدار شما را نادیده میگیرد. متغیر را پاک کنید و اگر برنامه باید روی پورت دیگری گوش بدهد، «پورت داخلی» را در تنظیمات عوض کنید.