Hosting
Fly.io
الهدف: تشغيل OpenClaw Gateway على جهاز Fly.io مع تخزين دائم، وHTTPS تلقائي، وإمكانية وصول Discord/القنوات.
ما تحتاجه
- تثبيت flyctl CLI
- حساب Fly.io (تعمل الخطة المجانية)
- مصادقة النموذج: مفتاح API لمزوّد النموذج الذي اخترته
- بيانات اعتماد القناة: رمز بوت Discord، رمز Telegram، وما إلى ذلك.
المسار السريع للمبتدئين
- استنسخ المستودع → خصّص
fly.toml - أنشئ التطبيق + وحدة التخزين → عيّن الأسرار
- انشر باستخدام
fly deploy - ادخل عبر SSH لإنشاء الإعدادات أو استخدم Control UI
Create the Fly app
# Clone the repo
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Create a new Fly app (pick your own name)
fly apps create my-openclaw
# Create a persistent volume (1GB is usually enough)
fly volumes create openclaw_data --size 1 --region iad
نصيحة: اختر منطقة قريبة منك. خيارات شائعة: lhr (لندن)، iad (فيرجينيا)، sjc (سان خوسيه).
Configure fly.toml
عدّل fly.toml ليتطابق مع اسم تطبيقك ومتطلباتك.
ملاحظة أمنية: تكشف الإعدادات الافتراضية عنوان URL عامًا. للحصول على نشر معزّز بلا عنوان IP عام، راجع النشر الخاص أو استخدم deploy/fly.private.toml.
app = "my-openclaw" # Your app name
primary_region = "iad"
[build]
dockerfile = "Dockerfile"
[env]
NODE_ENV = "production"
OPENCLAW_PREFER_PNPM = "1"
OPENCLAW_STATE_DIR = "/data"
NODE_OPTIONS = "--max-old-space-size=1536"
[processes]
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = false
auto_start_machines = true
min_machines_running = 1
processes = ["app"]
[[vm]]
size = "shared-cpu-2x"
memory = "2048mb"
[mounts]
source = "openclaw_data"
destination = "/data"
الإعدادات الأساسية:
| الإعداد | السبب |
|---|---|
--bind lan |
يرتبط بـ 0.0.0.0 حتى يتمكّن وكيل Fly من الوصول إلى Gateway |
--allow-unconfigured |
يبدأ من دون ملف إعدادات (ستنُشئ واحدًا لاحقًا) |
internal_port = 3000 |
يجب أن يطابق --port 3000 (أو OPENCLAW_GATEWAY_PORT) لفحوصات صحة Fly |
memory = "2048mb" |
512MB صغيرة جدًا؛ يوصى بـ 2GB |
OPENCLAW_STATE_DIR = "/data" |
يحفظ الحالة على وحدة التخزين |
Set secrets
# Required: Gateway token (for non-loopback binding)
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
# Model provider API keys
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
# Optional: Other providers
fly secrets set OPENAI_API_KEY=sk-...
fly secrets set GOOGLE_API_KEY=...
# Channel tokens
fly secrets set DISCORD_BOT_TOKEN=MTQ...
ملاحظات:
- تتطلب عمليات الربط غير الخاصة بالاسترجاع (
--bind lan) مسار مصادقة Gateway صالحًا. يستخدم مثال Fly.io هذاOPENCLAW_GATEWAY_TOKEN، لكنgateway.auth.passwordأو نشرtrusted-proxyغير خاص بالاسترجاع ومُعد بشكل صحيح يفيان أيضًا بالمتطلب. - تعامل مع هذه الرموز كما تتعامل مع كلمات المرور.
- فضّل متغيرات البيئة على ملف الإعدادات لجميع مفاتيح API والرموز. هذا يُبقي الأسرار خارج
openclaw.jsonحيث قد تُكشف أو تُسجّل عن طريق الخطأ.
Deploy
fly deploy
يبني النشر الأول صورة Docker (نحو 2-3 دقائق). عمليات النشر اللاحقة أسرع.
بعد النشر، تحقق:
fly status
fly logs
يجب أن ترى:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
Create config file
ادخل إلى الجهاز عبر SSH لإنشاء إعدادات مناسبة:
fly ssh console
أنشئ دليل الإعدادات والملف:
mkdir -p /data
cat > /data/openclaw.json << 'EOF'
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-opus-4-6",
"fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"]
},
"maxConcurrent": 4
},
"list": [
{
"id": "main",
"default": true
}
]
},
"auth": {
"profiles": {
"anthropic:default": { "mode": "token", "provider": "anthropic" },
"openai:default": { "mode": "token", "provider": "openai" }
}
},
"bindings": [
{
"agentId": "main",
"match": { "channel": "discord" }
}
],
"channels": {
"discord": {
"enabled": true,
"groupPolicy": "allowlist",
"guilds": {
"YOUR_GUILD_ID": {
"channels": { "general": { "allow": true } },
"requireMention": false
}
}
}
},
"gateway": {
"mode": "local",
"bind": "auto",
"controlUi": {
"allowedOrigins": [
"https://my-openclaw.fly.dev",
"http://localhost:3000",
"http://127.0.0.1:3000"
]
}
},
"meta": {}
}
EOF
ملاحظة: مع OPENCLAW_STATE_DIR=/data، يكون مسار الإعدادات هو /data/openclaw.json.
ملاحظة: استبدل https://my-openclaw.fly.dev بمنشأ تطبيق Fly الحقيقي لديك. يزرع بدء تشغيل Gateway مناشئ Control UI المحلية من قيمتي وقت التشغيل --bind و--port حتى يمكن للتمهيد الأول أن يتابع قبل وجود الإعدادات، لكن الوصول عبر المتصفح من خلال Fly لا يزال يحتاج إلى منشأ HTTPS الدقيق المدرج في gateway.controlUi.allowedOrigins.
ملاحظة: يمكن أن يأتي رمز Discord من أيٍّ من:
- متغير البيئة:
DISCORD_BOT_TOKEN(موصى به للأسرار) - ملف الإعدادات:
channels.discord.token
إذا كنت تستخدم متغير البيئة، فلا حاجة إلى إضافة الرمز إلى الإعدادات. يقرأ Gateway DISCORD_BOT_TOKEN تلقائيًا.
أعد التشغيل للتطبيق:
exit
fly machine restart <machine-id>
Access the Gateway
Control UI
افتح في المتصفح:
fly open
أو زُر https://my-openclaw.fly.dev/
صادِق باستخدام السر المشترك المُعد. يستخدم هذا الدليل رمز Gateway من OPENCLAW_GATEWAY_TOKEN؛ إذا انتقلت إلى مصادقة كلمة المرور، فاستخدم تلك كلمة المرور بدلًا من ذلك.
السجلات
fly logs # Live logs
fly logs --no-tail # Recent logs
وحدة تحكم SSH
fly ssh console
استكشاف الأخطاء وإصلاحها
"App is not listening on expected address"
يرتبط Gateway بـ 127.0.0.1 بدلًا من 0.0.0.0.
الإصلاح: أضف --bind lan إلى أمر العملية في fly.toml.
فشل فحوصات الصحة / رفض الاتصال
لا يستطيع Fly الوصول إلى Gateway على المنفذ المُعد.
الإصلاح: تأكد من أن internal_port يطابق منفذ Gateway (عيّن --port 3000 أو OPENCLAW_GATEWAY_PORT=3000).
نفاد الذاكرة / مشكلات الذاكرة
تستمر الحاوية في إعادة التشغيل أو يجري إيقافها قسريًا. العلامات: SIGABRT، أو v8::internal::Runtime_AllocateInYoungGeneration، أو عمليات إعادة تشغيل صامتة.
الإصلاح: زِد الذاكرة في fly.toml:
[[vm]]
memory = "2048mb"
أو حدّث جهازًا موجودًا:
fly machine update <machine-id> --vm-memory 2048 -y
ملاحظة: 512MB صغيرة جدًا. قد يعمل 1GB لكنه قد ينفد من الذاكرة تحت الحمل أو مع التسجيل المفصّل. يوصى بـ 2GB.
مشكلات قفل Gateway
يرفض Gateway البدء مع أخطاء "already running".
يحدث هذا عندما تعيد الحاوية التشغيل لكن ملف قفل PID يبقى على وحدة التخزين.
الإصلاح: احذف ملف القفل:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
يوجد ملف القفل في /data/gateway.*.lock (وليس في دليل فرعي).
عدم قراءة الإعدادات
يتجاوز --allow-unconfigured حارس بدء التشغيل فقط. لا ينشئ أو يصلح /data/openclaw.json، لذا تأكد من وجود إعداداتك الحقيقية وأنها تتضمن gateway.mode="local" عندما تريد بدء Gateway محلي عادي.
تحقق من وجود الإعدادات:
fly ssh console --command "cat /data/openclaw.json"
كتابة الإعدادات عبر SSH
لا يدعم الأمر fly ssh console -C إعادة توجيه الصدفة. لكتابة ملف إعدادات:
# Use echo + tee (pipe from local to remote)
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Or use sftp
fly sftp shell
> put /local/path/config.json /data/openclaw.json
ملاحظة: قد يفشل fly sftp إذا كان الملف موجودًا بالفعل. احذفه أولًا:
fly ssh console --command "rm /data/openclaw.json"
عدم استمرار الحالة
إذا فقدت ملفات تعريف المصادقة، أو حالة القناة/المزوّد، أو الجلسات بعد إعادة التشغيل، فإن دليل الحالة يكتب إلى نظام ملفات الحاوية.
الإصلاح: تأكد من تعيين OPENCLAW_STATE_DIR=/data في fly.toml وأعد النشر.
التحديثات
# Pull latest changes
git pull
# Redeploy
fly deploy
# Check health
fly status
fly logs
تحديث أمر الجهاز
إذا كنت بحاجة إلى تغيير أمر بدء التشغيل من دون إعادة نشر كاملة:
# Get machine ID
fly machines list
# Update command
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
# Or with memory increase
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
ملاحظة: بعد fly deploy، قد يُعاد ضبط أمر الجهاز إلى ما هو موجود في fly.toml. إذا أجريت تغييرات يدوية، فأعد تطبيقها بعد النشر.
النشر الخاص (معزّز)
افتراضيًا، يخصص Fly عناوين IP عامة، مما يجعل Gateway لديك متاحًا على https://your-app.fly.dev. هذا ملائم، لكنه يعني أن نشرك قابل للاكتشاف بواسطة ماسحات الإنترنت (Shodan وCensys وما إلى ذلك).
للحصول على نشر معزّز مع عدم وجود تعرّض عام، استخدم القالب الخاص.
متى تستخدم النشر الخاص
- تجري فقط مكالمات/رسائل صادرة (بلا Webhooks واردة)
- تستخدم أنفاق ngrok أو Tailscale لأي استدعاءات Webhook راجعة
- تصل إلى Gateway عبر SSH، أو وكيل، أو WireGuard بدلًا من المتصفح
- تريد أن يكون النشر مخفيًا عن ماسحات الإنترنت
الإعداد
استخدم deploy/fly.private.toml بدلًا من الإعدادات القياسية:
# Deploy with private config
fly deploy -c deploy/fly.private.toml
أو حوّل نشرًا موجودًا:
# List current IPs
fly ips list -a my-openclaw
# Release public IPs
fly ips release <public-ipv4> -a my-openclaw
fly ips release <public-ipv6> -a my-openclaw
# Switch to private config so future deploys don't re-allocate public IPs
# (remove [http_service] or deploy with the private template)
fly deploy -c deploy/fly.private.toml
# Allocate private-only IPv6
fly ips allocate-v6 --private -a my-openclaw
بعد ذلك، يجب أن يُظهر fly ips list عنوان IP بنوع private فقط:
VERSION IP TYPE REGION
v6 fdaa:x:x:x:x::x private global
الوصول إلى نشر خاص
نظرًا لعدم وجود عنوان URL عام، استخدم إحدى هذه الطرق:
الخيار 1: وكيل محلي (الأبسط)
# Forward local port 3000 to the app
fly proxy 3000:3000 -a my-openclaw
# Then open http://localhost:3000 in browser
الخيار 2: WireGuard VPN
# Create WireGuard config (one-time)
fly wireguard create
# Import to WireGuard client, then access via internal IPv6
# Example: http://[fdaa:x:x:x:x::x]:3000
الخيار 3: SSH فقط
fly ssh console -a my-openclaw
عمليات Webhook مع النشر الخاص
إذا كنت بحاجة إلى استدعاءات Webhook رجعية (Twilio، Telnyx، وما إلى ذلك) من دون تعريضها للعامة:
- نفق ngrok - شغّل ngrok داخل الحاوية أو كحاوية جانبية
- Tailscale Funnel - اكشف مسارات محددة عبر Tailscale
- صادر فقط - تعمل بعض المزوّدات (Twilio) بشكل جيد للمكالمات الصادرة من دون Webhook
مثال على إعداد voice-call باستخدام ngrok:
{
plugins: {
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio",
tunnel: { provider: "ngrok" },
webhookSecurity: {
allowedHosts: ["example.ngrok.app"],
},
},
},
},
},
}
يعمل نفق ngrok داخل الحاوية ويوفر عنوان URL عامًا لـ Webhook من دون كشف تطبيق Fly نفسه. اضبط webhookSecurity.allowedHosts على اسم مضيف النفق العام لكي يتم قبول ترويسات المضيف المعاد توجيهها.
مزايا الأمان
| الجانب | عام | خاص |
|---|---|---|
| ماسحات الإنترنت | قابل للاكتشاف | مخفي |
| الهجمات المباشرة | ممكنة | محظورة |
| وصول واجهة التحكم | متصفح | وكيل/VPN |
| تسليم Webhook | مباشر | عبر نفق |
ملاحظات
- يستخدم Fly.io معمارية x86 (وليس ARM)
- ملف Dockerfile متوافق مع كلتا المعماريتين
- لإعداد WhatsApp/Telegram الأولي، استخدم
fly ssh console - توجد البيانات الدائمة على وحدة التخزين في
/data - يتطلب Signal Java + signal-cli؛ استخدم صورة مخصصة وأبقِ الذاكرة عند 2GB+.
التكلفة
باستخدام الإعداد الموصى به (shared-cpu-2x، وذاكرة RAM بسعة 2GB):
- حوالي 10-15 دولارًا شهريًا حسب الاستخدام
- تتضمن الطبقة المجانية قدرًا من الحصة
راجع تسعير Fly.io للحصول على التفاصيل.
الخطوات التالية
- إعداد قنوات المراسلة: القنوات
- تكوين Gateway: تكوين Gateway
- إبقاء OpenClaw محدّثًا: التحديث