فانکشنها
کدی که با درخواست اجرا میشود: یک handler استاندارد وب، با متغیرهای محیطی، cron، لاگ، مانیتورینگ و پیشنمایش برای هر شاخه.
ساختار فانکشن#
فانکشن یک ماژول است که خروجی پیشفرضش fetch(request, env) دارد: یک Request استاندارد میگیرد و یک Response برمیگرداند. env متغیرهای محیطی، تنظیمهای [vars] و اتصالها (env.DB، env.CACHE، env.BUCKET) را دارد.
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
return Response.json({ hello: url.searchParams.get("name") ?? "world", path: url.pathname });
},
};- TypeScript و JavaScript هر دو کار میکنند؛ CLI ورودی و importهایش را در یک ماژول میبندد.
- ماژولهای داخلی Node با نام
node:در دسترساند (node:crypto،node:buffer، …). fetch()به اینترنت کار میکند؛ آدرسهای خصوصی و آدرسهای داخلی سرورها رد میشوند.- فانکشنها با JavaScript و TypeScript نوشته میشوند.
استقرار، نسخهها و بازگشت#
cloudhost deploy my-api index.ts --var GREETING=salam
# https://my-api.fn.trustpage.ir
cloudhost functions versions my-api
# * v3 2026-11-04T09:30:00.000Z code 9f86d081884c
# v2 …
cloudhost functions rollback my-api # the version before
cloudhost functions rollback my-api --to 2هر استقرار یک نسخهٔ تغییرناپذیر بیلد میکند (کد و تنظیمات) و آن را زنده میکند. بازگشت چیزی را دوباره بیلد نمیکند؛ فقط نسخهٔ قبلی را دوباره زنده میکند. --date YYYY-MM-DD رفتار محیط اجرا را روی یک تاریخ ثابت نگه میدارد.
در پوشهای که cloudhost.toml دارد، cloudhost deploy بدون آرگومان کافی است: فایل cloudhost.toml.
محدودیتها#
اندازهٔ کد هر فانکشن بسته به پلن محدود است. کد همانطور سنجیده میشود که ذخیره میشود: همهٔ ماژولها با هم، فشرده با gzip؛ پیش از فشردهسازی هم در همهٔ پلنها حداکثر ۶۴ MiB است. فایلهای استاتیک مال برنامهها هستند: محدودیتهای برنامه.
| محدودیت | رایگان | حرفهای | سازمانی |
|---|---|---|---|
| کد فانکشن، فشرده | ۳ MB | ۱۰ MB | طبق قرارداد |
| کد فانکشن پیش از فشردهسازی | ۶۴ MB | ۶۴ MB | طبق قرارداد |
cloudhost deploy پیش از آپلود، استقرار را با محدودیتهای پلن شما میسنجد و بیلد روی سرور هم پیش از آپلود خروجی همین کار را میکند؛ API هم دوباره بررسی میکند. استقرار بیش از محدودیت با کد limit_exceeded (HTTP 413) رد میشود و پیام میگوید کدام محدودیت، اندازهٔ استقرار شما، سقف پلنتان و سقف پلن حرفهای چیست؛ برای نمونه: «فایل استاتیک در هر استقرار: این استقرار ۲۵٬۰۰۰ فایل دارد؛ پلن رایگان ۲۰٬۰۰۰ فایل اجازه میدهد و پلن حرفهای ۱۰۰٬۰۰۰ فایل.» سقفهای پلن سازمانی در قرارداد تعیین میشوند. همین سقفها در قیمتها آمدهاند و GET /v1/limits آنها را برای پلن شما و همهٔ پلنها برمیگرداند.
فانکشنها چطور بزرگ میشوند#
هر فانکشن روی همهٔ سرورها اجرا میشود. وقتی پرکار است، هر سرور رپلیکاهای بیشتری از آن اجرا میکند و درخواستها میان آنها پخش میشوند: رپلیکا جدید وقتی راه میافتد که درخواستها در صف بمانند یا تأخیر بالا برود، و وقتی بیکار شد خاموش میشود. هر رپلیکا اضافه یک استارت سرد دارد. تعداد رپلیکاها روی هر سرور تا سقف پلن شماست:
| محدودیت | رایگان | حرفهای | سازمانی |
|---|---|---|---|
| رپلیکا روی هر سرور | ۲ | ۸ | طبق قرارداد |
وقتی همهٔ رپلیکاها مشغولاند و به سقف رسیدهاید، درخواست کوتاه (حدود ۱ ثانیه) در صف میماند تا یک رپلیکا آزاد شود. اگر آزاد نشود، پاسخ HTTP 429 است (فانکشن به سقف رپلیکاهای پلن رسیده) یا HTTP 503 (سرور پر است)، هر دو با Retry-After: 1. پس از همین زمان دوباره درخواست بفرستید. صفحهٔ مانیتورینگ رپلیکاها در طول زمان، زمان انتظار در صف، رپلیکاهای اضافهٔ راهاندازیشده و درخواستهای ردشده را نشان میدهد.
در مرورگر: نمونهها و ویرایش کد#
در داشبورد، «ایجاد» ← «فانکشن» یک نمونه را در ویرایشگر کد باز میکند: سلام دنیا، API با JSON، دریافت وبهوک، کار زمانبندیشده، با دیتابیس (env.DB) یا با کش (env.CACHE). نامی بدهید، کد را تغییر دهید و «استقرار» را بزنید: فانکشن و اولین نسخهاش ایجاد میشود. برای نمونههایی که دیتابیس یا کش میخوانند، یکی از دیتابیسها یا کشهای تیم را انتخاب میکنید؛ نمونهٔ زمانبندیشده cron خودش را هم میگذارد.
«کد» در صفحهٔ فانکشن فایلهای نسخهٔ فعال را در ویرایشگر باز میکند. «تغییرها» تفاوت با نسخهٔ فعال را نشان میدهد؛ «استقرار نسخهٔ جدید» نسخهای ایجاد میکند و فعالش میکند و «ذخیره بدون استقرار» فقط نسخه را میسازد. اتصالها (env.DB و …) از نسخهٔ فعال میمانند. ویرایش فقط برای نسخههایی است که از کد خام ساخته شدهاند (ویرایشگر، cloudhost functions new، cloudhost functions source deploy یا ابزار MCP)؛ نسخهای که ساخته یا با cloudhost functions deploy بستهبندی شده، کدی را که نوشتهاید ندارد، پس آن را در پوشه یا ریپازیتوری خودتان ویرایش کنید.
cloudhost functions starters
cloudhost functions new my-api --starter json-api
cloudhost functions new visits --starter database --db DB=shop
cloudhost functions source my-api ./my-api # the live version's files
cloudhost functions source deploy my-api ./my-api # deploy them as they areسقف کد هر فانکشن در پلن رایگان ۱۰ فایل و ۲۵۶ کیلوبایت است و در پلن حرفهای ۵۰ فایل و ۴ مگابایت. هر فایل پیش از استقرار بررسی میشود و خطای نگارشی با شمارهٔ خط برمیگردد.
متغیرهای محیطی#
type Env = { GREETING?: string; API_KEY?: string; CLOUDHOST_ENV?: string };
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return Response.json({ greeting: env.GREETING ?? null, has_key: !!env.API_KEY, environment: env.CLOUDHOST_ENV });
},
};هر متغیر یک کلید، یک مقدار و محیطهایی دارد که در آنها اعمال میشود: production (آدرس اصلی)، preview (هر پیشنمایش شاخه) و development (هرگز مستقر نمیشود؛ برای cloudhost env pull و کار روی رایانهٔ خودتان). یک کلید میتواند در هر محیط مقدار جداگانه داشته باشد. برای preview میتوان مقداری فقط برای یک شاخهٔ git گذاشت که در پیشنمایشهای آن شاخه بر مقدار preview برتری دارد. متغیر ساده را مالک، ادمین و توسعهدهنده میتوانند دوباره ببینند؛ متغیر حساس پس از ذخیره هرگز خوانده نمیشود، حتی برای سازندهاش، و فقط جایگزین میشود، و فقط برای production و preview است. تغییر هر متغیر فوراً اعمال میشود: فانکشنهای در حال اجرا با مقدار جدید دوباره راه میافتند و به استقرار جدید نیازی نیست. مقدارها با کلید جداگانهٔ هر تیم رمز میشوند و در لاگ و رویدادنگار نمیآیند.
متغیرهای مشترک تیم یک بار برای تیم تعریف و به پروژههای انتخابی لینک میشوند؛ متغیر خود پروژه با همان کلید بر آن برتری دارد. با سیاست تیمی «حساس بهطور پیشفرض» (فقط مالک) هر متغیر جدید production و preview حساس است. [vars] در cloudhost.toml یا --var تنظیمهای ساده و جزئی از نسخهاند؛ متغیر محیطی همنام بر آن برتری دارد. دستورهای قدیمی secrets همچنان کار میکنند: secrets put متغیر حساس برای production و preview میگذارد.
| تنظیم `[vars]` | متغیر محیطی | |
|---|---|---|
| نام | ^[A-Za-z_][A-Za-z0-9_]{0,63}$ | ^[A-Za-z_][A-Za-z0-9_]{0,63}$ |
| تعداد | تا ۶۴ | تا ۱۲۸ در هر پروژه؛ تا ۲۵۶ مشترک در هر تیم |
| اندازهٔ مقدار | تا ۵ KiB | تا ۵ KiB |
| هر محیط مقدار خودش | نه: همان نسخه | بله، و برای هر شاخهٔ preview |
| تغییر | با استقرار جدید | فوری |
| متغیر سیستمی | مقدار |
|---|---|
CLOUDHOST_ENV | production یا preview |
CLOUDHOST_URL | آدرس همین استقرار، بی https:// |
CLOUDHOST_GIT_BRANCH | شاخهٔ پیشنمایش (فقط preview) |
CLOUDHOST_GIT_COMMIT | commit، وقتی از بیلد با git آمده |
متغیرهای سیستمی خودکار به هر استقرار داده میشوند، مگر نامشان را یک متغیر، تنظیم یا اتصال گرفته باشد.
cron#
export default {
async fetch(): Promise<Response> {
return new Response("I also run on a schedule\n");
},
async scheduled(event: { cron: string; scheduledTime: number }): Promise<void> {
console.log(`tick for ${event.cron} at ${new Date(event.scheduledTime).toISOString()}`);
},
};cronهای استاندارد ۵ بخشی (دقیقه، ساعت، روز ماه، ماه، روز هفته؛ با *، فهرست، بازه، گام و نام ماه و روز) scheduled(event, env) نسخهٔ زنده را صدا میزنند، در هر نوبت حداکثر یک بار. تا ۵ cron در هر پروژه؛ منطقهٔ زمانی پیشفرض Asia/Tehran است. crons set کل فهرست را جایگزین میکند.
لاگ، لاگ زنده و مصرف#
cloudhost functions logs my-api --limit 50
# 09:30:01.204 v3 GET /orders 200 12ms
# 09:30:01.210 v3 [log] handling /orders
cloudhost functions tail my-api # live, Ctrl-C to stop
cloudhost functions usage my-api --from 2026-11-04T00:00:00Z --to 2026-11-04T06:00:00Zهر console.log، هر درخواست و هر اجرای cron یک خط لاگ است. logs جدیدترین خطها را میدهد (۱ تا ۱۰۰۰، پیشفرض ۱۰۰)، tail لاگ را زنده دنبال میکند و usage درخواستها، خطاها، زمان و ترافیک را دقیقهبهدقیقه نشان میدهد (پیشفرض یک ساعت اخیر، حداکثر ۳۱ روز).
مانیتورینگ#
درخواستها، خطاهای 4xx و 5xx و تأخیر p50، p95 و p99 در طول زمان و برای هر مسیر، در بازههای ۱ ساعت، ۲۴ ساعت یا ۷ روز. تأخیر از رسیدن درخواست تا پاسخ اندازه گرفته میشود و استارت سرد را هم در بر دارد. در داشبورد، با ابزار MCP get_observability، یا از API:
curl -H "Authorization: Bearer $KEY" "https://api.ibel.ai/v1/functions/my-api/observability?range=24h"برای اینکه وقتی چیزی خراب شد خبردار شوید، هشدار بگذارید.
پیشنمایش شاخهها#
cloudhost deploy my-api index.ts --branch feature-x
# deployed function my-api v4 as preview "feature-x"
# https://feature-x--my-api.fn.trustpage.ir
cloudhost functions previews my-api
cloudhost functions previews delete my-api feature-xهر شاخهای جز main، master و production آدرس خودش را میگیرد: <branch>--<name>. پروداکشن دست نمیخورد. پیشنمایشی که به دیتابیس متصل است شاخهٔ دیتابیس خودش (preview-<branch>) را میگیرد، پس هرگز در دادهٔ production نمینویسد.
بیلد روی سرورهای ما#
cloudhost build # production
cloudhost build --branch feature-x # a preview
cloudhost functions builds my-apicloudhost build پوشهٔ پروژه را (بدون node_modules، .git و خروجیهای بیلد) میفرستد؛ نصب وابستگیها، بیلد و استقرار روی سرورهای ما انجام میشود و لاگ زنده در ترمینال میآید. تاریخچهٔ بیلدها در داشبورد، با builds و با ابزار MCP get_build_log هست.
استقرار با git push#
git remote add cloudhost https://git.ibel.ai/my-api.git
git push cloudhost main # production
git push cloudhost feature-x # https://feature-x--my-api.fn.trustpage.ir
git push cloudhost --delete feature-x # removes that previewهر push یک بیلد است: main به پروداکشن میرود و هر شاخهٔ دیگر به پیشنمایش خودش. git نام کاربری و رمز میخواهد: نام کاربری هر چیزی میتواند باشد و رمز یک کلید API است (cloudhost keys create git --role developer). این آدرس فقط push میگیرد؛ clone و مرور ندارد.
پروژه باید از قبل وجود داشته باشد (یک deploy یا cloudhost functions create my-api). ریپازیتوری فانکشن به cloudhost.toml با main نیاز دارد.
انتقال به تیم دیگر#
ادمین یا مالکِ هر دو تیم میتواند فانکشن یا برنامه را از داشبورد به تیم دیگری منتقل کند. آدرس و متغیرهای محیطیاش میمانند (لینک به متغیرهای مشترک تیم قبلی برداشته میشود) و هشدارهایش حذف میشوند. تا وقتی نسخهای به دیتابیس، کش یا باکت متصل است انتقال انجام نمیشود؛ اول نسخهای بدون اتصال مستقر کنید.