نصب و راهاندازی
استقرار روی VPS یا سرور اختصاصی
راهاندازی پیشنهادی WZML-X با Docker Compose، پیدا کردن آدرس تونل Cloudflare و آنچه هنگام شروع ربات اتفاق میافتد.
این روش پیشنهادی خود پروژه است: ربات و یک تونل Cloudflare در دو کانتینر با Docker Compose اجرا میشوند و رابط وب بدون باز کردن هیچ پورتی روی سرور، از طریق یک آدرس https://….trycloudflare.com در دسترس قرار میگیرد.
پیش از شروع، موارد صفحهٔ پیشنیازها را آماده کنید.
۱. دریافت کد
git clone https://github.com/SilentDemonSD/WZML-X.git
cd WZML-X
۲. ساختن config.py
از روی نمونه یک کپی بسازید و آن را ویرایش کنید:
cp config_sample.py config.py
nano config.py
دستکم این پنج متغیر را پر کنید:
BOT_TOKEN = "1234567890:AA..."
OWNER_ID = 123456789
TELEGRAM_API = 1234567
TELEGRAM_HASH = "0123456789abcdef0123456789abcdef"
DATABASE_URL = "mongodb+srv://USERNAME:PASSWORD@CLUSTER.mongodb.net/?retryWrites=true&w=majority"
BASE_URL را میتوانید خالی بگذارید؛ در این روش ربات آدرس تونل را خودش پیدا میکند. توضیح بقیهٔ متغیرها در نحوهٔ پیکربندی و مرجع متغیرها آمده است.
۳. اجرا
ایمیجها را بسازید و ربات را اجرا کنید:
docker compose up -d --build
این دستور دو ایمیج میسازد (یکی برای ربات و یکی برای تونل) و هر دو سرویس را در پسزمینه اجرا میکند. اولین اجرا به خاطر ساخت ایمیج و نصب بستهها کمی طول میکشد.
۴. پیدا کردن آدرس تونل
ربات بهطور پیشفرض پشت یک «تونل سریع» (quick tunnel) Cloudflare اجرا میشود. آدرس آن را در لاگ سرویس tunnel ببینید:
docker compose logs tunnel
دنبال یک آدرس به شکل https://….trycloudflare.com بگردید. اسکریپت tunnel.sh هر بار که آدرس جدیدی پیدا کند، یک خط جداگانه با پیشوند tunnel_url: هم چاپ میکند، پس میتوانید فقط همان را جدا کنید:
docker compose logs tunnel | grep tunnel_url
این آدرس، آدرس رابط وب ربات شماست. لازم نیست آن را جایی وارد کنید: ربات آن را از فایل مشترک میخواند و خودکار در BASE_URL میگذارد (در لاگ ربات خطی مثل tunnel_monitor: initial BASE_URL = … میبینید).
۵. بررسی اینکه ربات بالا آمده است
لاگ ربات را دنبال کنید:
docker compose logs -f app
وقتی همه چیز آماده باشد، خط WZ Client(s) & Services Started ! را میبینید. حالا در تلگرام به ربات /start بفرستید. چون شما مالک ربات هستید، پیام خوشآمد و راهنما نمایش داده میشود.
۶. توقف، ریاستارت و لاگها
توقف و حذف کانتینرها:
docker compose down
دیدن لاگ زندهٔ ربات (با Ctrl+C از آن خارج میشوید و ربات متوقف نمیشود):
docker compose logs -f app
ریاستارت کانتینر ربات، مثلاً بعد از ویرایش config.py:
docker compose restart app
دیدن وضعیت سرویسها:
docker compose ps
داخل تلگرام هم دستور /log (برای مالک و سودو) فایل log.txt را میفرستد.
پشت صحنه چه اتفاقی میافتد؟
سرویسها و والیومها در docker-compose.yml
| سرویس | ساختهشده از | توضیح |
|---|---|---|
app | Dockerfile | خود ربات. با bash start.sh اجرا میشود و سیاست ریاستارت آن unless-stopped است. پورت 8080 را فقط expose میکند و هیچ پورتی روی سرور باز نمیکند. |
tunnel | tunnel.Dockerfile | یک ایمیج کوچک Alpine با فایل اجرایی cloudflared. با network_mode: "service:app" در شبکهٔ همان کانتینر app اجرا میشود و http://localhost:8080 را تونل میکند. |
مسیرهایی که به کانتینر app وصل میشوند:
| روی سرور | داخل کانتینر | کاربرد |
|---|---|---|
./config.py | /usr/src/app/config.py (فقطخواندنی، :ro) | پیکربندی |
./accounts | /usr/src/app/accounts | سرویساکانتهای گوگل |
./downloads | /usr/src/app/downloads | فایلهای در حال دانلود و آپلود |
والیوم tunnel_data | /data (فقطخواندنی) | فایل آدرس تونل |
سرویس tunnel همان والیوم tunnel_data را با دسترسی نوشتن دارد. اسکریپت tunnel.sh دستور cloudflared tunnel --no-autoupdate --protocol http2 --url http://localhost:8080 را اجرا میکند، خروجی را دنبال میکند و آدرس trycloudflare.com را در فایل /data/tunnel_url.txt مینویسد (مسیر با متغیر محیطی TUNNEL_URL_FILE قابل تغییر است). ربات این فایل را هنگام شروع و بعد از آن هر ۵ ثانیه یک بار میخواند و اگر آدرس عوض شده باشد، BASE_URL را بهروز میکند.
Dockerfile
ایمیج ربات بر پایهٔ mysterysd/wzmlx:wzadv ساخته میشود؛ بستههای requirements.txt با uv در محیط /wzvenv نصب میشوند، کل کد در /usr/src/app کپی میشود و نقطهٔ ورود bash start.sh است.
ترتیب شروع
start.sh فقط دو کار میکند:
python update.py
exec python -m bot
مرحلهٔ اول، update.py:
config.pyرا میخواند. اگر این فایل نباشد، پیامConfig.py file is not Added! Checking ENVs..را ثبت میکند و سراغ متغیرهای محیطی میرود.- اگر
BOT_TOKENخالی باشد، با پیامBOT_TOKEN variable is missing! Exiting nowمتوقف میشود. - اگر
DATABASE_URLداشته باشید، تنظیمات ذخیرهشده در MongoDB را هم در نظر میگیرد. - اگر
UPSTREAM_REPOتنظیم شده باشد، کد را از آن مخزن و شاخهٔUPSTREAM_BRANCH(پیشفرضwzv3) بهروز میکند؛ وگرنهNo UPSTREAM_REPO set, skipping git updateرا ثبت میکند. جزئیات در بهروزرسانی. - چند فایل غیرضروری (مثل
gen_scriptsوREADME.md) را از داخل کانتینر پاک میکند و بستههای پایتون را باuv pip install -U -r requirements.txtبهروز میکند.
مرحلهٔ دوم، python -m bot:
- پیکربندی از
config.pyو متغیرهای محیطی بارگذاری میشود و بعد تنظیمات و فایلهای خصوصی ذخیرهشده در MongoDB روی آن اعمال میشوند. - ربات اصلی و در صورت تنظیم، حساب کاربری (
USER_SESSION_STRING) و رباتهای کمکی (HELPER_TOKENS،STREAM_TOKENS) به تلگرام وصل میشوند. - اسکریپت
setpkgs.shاجرا میشود: Aria2 را بهصورت سرویس پسزمینه با RPC روی پورت6800بالا میآورد، فهرست ترکرهای عمومی را ازngosang/trackerslistمیگیرد و به Aria2 میدهد، و اگرDISABLE_NZBخاموش باشد، SABnzbd را روی پورت8070اجرا میکند. - اگر
accounts.zipوجود داشته باشد، استخراج میشود؛ اگر پوشهٔaccountsنباشد،USE_SERVICE_ACCOUNTSخاموش میشود. - qBittorrent (مگر اینکه
DISABLE_TORRENTSروشن باشد) با پروفایلconfigs/qbittorrentاجرا میشود. - وبسرور (gunicorn با FastAPI) روی پورت متغیر محیطی
PORTیا در نبود آن روی8080بالا میآید و سرور پخش (مگر اینکهDISABLE_STREAMروشن باشد) روی127.0.0.1:8091اجرا میشود. - آدرس تونل خوانده و در
BASE_URLگذاشته میشود، تنظیمات در MongoDB ذخیره میشوند، JDownloader (اگرDISABLE_JDخاموش باشد) بوت میشود، پوشهٔ دانلودها خالی میشود (Cleaning Download Directory) و در آخر پلاگینها بارگذاری میشوند. - آدرس پنلهای qBittorrent و SABnzbd به شکل
Web UI: qBittorrent: /qbit/?pass=…وWeb UI: SABnzbd: /nzb/?pass=…در لاگ چاپ میشود.
پورتهای داخل کانتینر
هیچکدام از این پورتها در docker-compose.yml روی سرور منتشر نمیشوند؛ همه داخل کانتینر هستند و دسترسی بیرونی فقط از طریق تونل و رابط وب است.
| پورت | سرویس |
|---|---|
8080 | رابط وب (قابل تغییر با متغیر محیطی PORT) |
6800 | RPC برنامهٔ Aria2 |
8090 | رابط وب qBittorrent (از مسیر /qbit/ رابط وب در دسترس است) |
8070 | SABnzbd (از مسیر /nzb/ رابط وب در دسترس است) |
8091 | سرور پخش، فقط روی 127.0.0.1 (قابل تغییر با متغیر محیطی STREAM_PORT) |
8081 | rclone serve (پیشفرض RCLONE_SERVE_PORT)؛ فقط وقتی RCLONE_SERVE_URL تنظیم شده و rclone.conf وجود دارد. |
تونل نامدار: آدرس ثابت با دامنهٔ خودتان
اگر دامنهای دارید که DNS آن در Cloudflare است، میتوانید بهجای تونل سریع از تونل نامدار استفاده کنید تا آدرس رابط وب با هر ریاستارت عوض نشود. مراحل از توضیحات داخل خود docker-compose.yml:
- در داشبورد Cloudflare به Networking ← Tunnels ← Create a tunnel بروید.
- نوع اتصال Cloudflared را انتخاب کنید، برای تونل نام بگذارید و ذخیره کنید.
- در بخش Connectors، توکن داخل دستور نصب (رشتهای که با
eyJشروع میشود) را کپی کنید. - در بخش Public Hostname یک آدرس مثل
subdomain.yourdomain.comبسازید که با نوع HTTP بهlocalhost:8080اشاره کند. - در
docker-compose.yml، سرویسtunnelفعلی را کامنت کنید و بلوک تونل نامدار را از حالت کامنت خارج کنید و توکن را جایگزین<YOUR_TOKEN>کنید:
tunnel:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel --no-autoupdate run --token <YOUR_TOKEN>
network_mode: "service:app"
در این حالت فایل آدرس تونل نوشته نمیشود، پس BASE_URL را خودتان در config.py (یا از /bsetting) برابر آدرس دامنهتان قرار دهید، مثلاً https://subdomain.yourdomain.com.
قدم بعدی
- تنظیمات ربات را با
/bsetting(کوتاهشده:/bs) بررسی کنید. - برای استفاده از VPN صفحهٔ VPN با Gluetun را ببینید.
- برای اجرای چند ربات روی یک سرور، چند نمونه را بخوانید.
- اگر مشکلی پیش آمد، به عیبیابی سر بزنید.