نصب OpenHands روی VPS با Docker
آموزش نصب OpenHands روی Ubuntu 24.04. یادگیری روش امن اجرای Docker socket برای جلوگیری از دسترسی root و مدیریت صحیح کانتینرهای Sandbox.
OpenHands چیست و اولین ریسک آن را باید درک کرد
OpenHands که قبلاً OpenDevin نام داشت، یک عامل خودگردان مهندسی نرمافزار است. شما یک وظیفه را به زبان ساده به آن میدهید و این عامل برنامهریزی کار، نوشتن کد، اجرای دستورات، خواندن خروجی و تکرار مراحل را تا اتمام وظیفه انجام میدهد. شما آن را با استفاده از Docker روی سرور خود اجرا میکنید و آن را به یک مدل زبانی متصل میکنید. در یک VPS، این ابزار به یک عامل کدنویسی تبدیل میشود که در زمان نبود شما، کار میکند.
یک واقعیت وجود دارد که باید تمام تنظیمات شما را تحت تأثیر قرار دهد. OpenHands فقط کد پیشنهاد نمیدهد، بلکه آن را اجرا میکند؛ برای این کار، کانتینر کنترلکننده (controller container) سوکت Docker میزبان را در /var/run/docker.sock mount میکند تا بتواند برای هر وظیفه، کانتینرهای Sandbox ایجاد کند. هر چیزی که بتواند با سوکت Docker ارتباط برقرار کند، میتواند یک کانتینر جدید ایجاد کند که تمام فایلسیستم میزبان شما را mount کند؛ این یعنی دسترسی به سوکت، در واقع دسترسی root در ماشین است. بنابراین با سروری که کدهای غیرقابل اعتماد را اجرا میکند برخورد کنید، زیرا این دقیقاً کاری است که انجام میدهد. تمام انتخابهای مربوط به سختسازی (hardening) در ادامه، بر اساس این اصل است.
آنچه نیاز دارید
شما به یک VPS با سیستمعامل Ubuntu 24.04 و یک Docker Engine جدید، حداقل 4 GB RAM و یک API key برای یک مدل زبانی (OpenAI، Anthropic یا Google) نیاز دارید، یا یک مدل محلی که توسط Ollama روی همان VPS ارائه شده باشد. OpenHands از دهها backend مدل پشتیبانی میکند، بنابراین انتخاب با شماست. اگر تا به حال کانتینرها را راهاندازی نکردهاید، مبانی Docker در یک VPS مفاهیمی را پوشش میدهد که این راهنما بر اساس آنها نوشته شده است.
نصب با Docker
OpenHands در قالب دو image عرضه میشود: image اپلیکیشن که اجرا میکنید، و image agent-server که برای اجرای sandbox هر وظیفه، آن را pull میکند. آن را به صورت زیر اجرا کنید و تگهای فعلی را از مستندات پروژه جایگزین کنید:
docker run -it --rm --pull=always \
-e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
-e AGENT_SERVER_IMAGE_TAG=1.26.0-python \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 127.0.0.1:3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands \
docker.openhands.dev/openhands/openhands:1.8دو نکته شما را از یک ساعت سردرگمی نجات میدهد. image اپلیکیشن و image agent-server عمداً شماره نسخه متفاوتی دارند، بنابراین سعی نکنید آنها را یکسان کنید: از تگ agent-server که در مستندات با نسخه اپلیکیشن شما جفت شده است، استفاده کنید. همچنین به جای -p 3000:3000 از -p 127.0.0.1:3000:3000 استفاده کنید. همین یک تغییر، تفاوت بین یک Web UI است که فقط شما به آن دسترسی دارید و یک رابط که کل اینترنت میتواند به آن دسترسی داشته باشد؛ موضوع بخش بعدی همین است.
Web UI را از اینترنت عمومی دور نگه دارید
OpenHands رابط کاربری خود را روی پورت 3000 ارائه میدهد. این رابط کاربری عاملی را هدایت میکند که کد اجرا میکند، بنابراین انتشار آن در اینترنت به هر کسی که آن را پیدا کند، یک مسیر از راه دور به فرآیندی که دستورات را اجرا میکند، میدهد. آن را مانند دستور اجرای بالا به loopback bind کنید و از طریق یک تونل SSH از لپتاپ خود به آن دسترسی داشته باشید:
ssh -L 3000:127.0.0.1:3000 you@your-vpsسپس http://127.0.0.1:3000 را در ماشین خود باز کنید. ترافیک از طریق نشست SSH موجود شما منتقل میشود و هیچ سرویس جدیدی در اینترنت عمومی گوش به زنگ (listen) نخواهد بود. برای یک تنظیمات دائمیتر، به جای آن از یک VPN استفاده کنید. در هر صورت، یک فایروال با سیاست default-deny در مقابل سرور قرار دهید تا هیچ چیزی به طور تصادفی در دسترس نباشد، و به یاد داشته باشید که فایروالی که فقط IPv4 را پوشش میدهد، همان پورت را در IPv6 باز میگذارد، که این همان شکاف فایروال IPv6 است که باعث گرفتار شدن افراد زیادی میشود.
ایزوله کردن کلید مدل و هرگونه اعتبارنامهی مخزن (repo)
OpenHands برای مدل خود به یک API key و اغلب به یک توکن برای clone و push کردن به مخازن شما نیاز دارد. هر دو میتوانند هزینه ایجاد کنند و به عنوان شما عمل کنند، بنابراین با آنها مانند رمز عبور برخورد کنید. آنها را در یک فایل محیطی (environment file) نگه دارید که فقط حساب کاربری مجاز بتواند آن را بخواند؛ هرگز آنها را در دستور اجرا قرار ندهید، زیرا در تاریخچه شل (shell history) و لیست فرآیندها (process list) ثبت میشوند، و هرگز آنها را در فایلی داخل یک مخزن git قرار ندهید.
آن را روی سیستمی اجرا کنید که قابل دور انداختن باشد
از آنجایی که کنترلکننده باید سوکت Docker را در اختیار داشته باشد، نمیتوانید OpenHands را کاملاً از میزبان خود ایزوله کنید. راه حل واقعی، ایزولاسیون از طریق مکان قرارگیری است: OpenHands را روی یک VPS اختصاصی اجرا کنید که هیچ چیز مهم دیگری در آن نباشد، نه روی سروری که پایگاه داده یا وبسایت شما نیز روی آن اجرا میشود. قبل از شروع یک snapshot بگیرید و به جای اعتماد به سیستمی که یک هفته است کدهای نوشته شده توسط عامل را اجرا کرده، از آن snapshot بازسازی کنید. یک VPS ارزان، یکبار مصرف و تکمنظوره، خانه مناسب برای آن است.
سختسازی سرور اطراف آن
بقیه موارد مربوط به بهداشت استاندارد سرور است و در اینجا اهمیت بیشتری نسبت به حالت عادی دارد، زیرا حجم کاری خطرناکتر از حالت معمول است. به جای کار با کاربر root، یک کاربر ادمین بدون امتیاز (unprivileged) بسازید، مطابق با اجرای سرویسها به عنوان کاربر بدون امتیاز. احراز هویت SSH را فقط به حالت key-only تغییر دهید. سپس چکلیست زیر را اجرا کنید و آن را جایی نگه دارید که دوباره آن را ببینید.
برای درک اجزای متحرک به جای فقط اجرای آنها، ساخت عامل هوش مصنوعی خود در یک VPS را ببینید؛ برای یک پلتفرم با کدنویسی کمتر، میزبانی خودکار Dify ورود سادهتری است.
FAQ
آیا اجرای OpenHands روی یک سرور ایمن است؟
با احتیاط میتواند ایمن باشد، اما نسبت به یک اپلیکیشن وب معمولی خطرناکتر است، زیرا کد مینویسد و اجرا میکند و کنترلکننده آن سوکت Docker میزبان را در اختیار دارد که در واقع همان root در ماشین است. آن را روی یک VPS اختصاصی و یکبار مصرف که هیچ چیز ارزشمند دیگری ندارد اجرا کنید، رابط Web UI را روی loopback پشت یک تونل SSH یا VPN نگه دارید، کلیدهای آن را ایزوله کنید و سرور را سختسازی کنید. آن را در کنار سرویسهای مهم خود اجرا نکنید.
چرا OpenHands به سوکت Docker نیاز دارد؟
OpenHands هر وظیفه را در یک کانتینر Sandbox تازه اجرا میکند و از daemon Docker میزبان میخواهد که با mount کردن /var/run/docker.sock در کنترلکننده خود، آن کانتینرها را ایجاد کند. این کار به کانتینر کنترلکننده کنترل Docker روی میزبان را میدهد که قدرتمند و خطرناک است، بنابراین خودِ میزبان باید به عنوان سیستمی که کدهای غیرقابل اعتماد را اجرا میکند، در نظر گرفته شود.
آیا OpenHands میتواند به جای یک API پولی از یک مدل محلی استفاده کند؟**
بله. OpenHands از مدلهای محلی ارائه شده توسط Ollama یا vLLM پشتیبانی میکند، بنابراین میتوانید آن را کاملاً به صورت خود-میزبانی شده (self-hosted) بدون هزینه هر توکن و بدون خروج داده از سرور خود اجرا کنید. شما به ماشینی با حافظه کافی برای یک مدل کدنویسی توانمند نیاز دارید، که همان بحث حجم حافظه است که در راهنمای Ollama پوشش داده شده است.
آیا باید OpenHands را روی سرور اصلی خود اجرا کنم؟
خیر. از آنجایی که این ابزار کدهای نوشته شده توسط عامل را اجرا میکند و سوکت Docker را در اختیار دارد، آن را روی یک VPS مجزا و تکمنظوره نگه دارید که حاضر به بازسازی آن باشید. قرار دادن آن در کنار پایگاه داده، وبسایت یا سایر سرویسهای خود به این معناست که یک اشتباه از سوی عامل، یا یک باگ در آن، میتواند به چیزهایی دسترسی پیدا کند که هرگز نباید به آنها دسترسی داشته باشد.