تفاوت WSL و VPS برای توسعهدهندگان
WSL و VPS برای نیازهای متفاوتی هستند. این مقاله تفاوتهای کلیدی در آپتایم، دسترسی عمومی، سرعت فایلسیستم و مدیریت systemd را بررسی میکند تا بهترین انتخاب را داشته باشید.
آیا باید برای توسعه از WSL استفاده کرد یا یک VPS؟
تفاوت بین WSL و یک VPS برای توسعه، به یک ویژگی اصلی برمیگردد: در دسترس بودن. WSL (زیرسیستم ویندوز برای لینوکس) اوبونتو را درون یک ماشین مجازی اجرا میکند که با نشست ویندوز شما شروع و پایان مییابد. یک VPS (سرور مجازی خصوصی) همان اوبونتو را روی یک آدرس IP عمومی اجرا میکند که حتی زمانی که لپتاپ شما بسته است، روشن میماند. اکثر توسعهدهندگان در نهایت از هر دو استفاده میکنند، بهطوری که سرور به عنوان ماشینی که همیشه در دسترس است عمل میکند.
سیستمعامل تفاوت اصلی نیست، زیرا هر دو اوبونتو هستند. آنچه تفاوت ایجاد میکند، زمان آپتایم (uptime)، قابلیت دسترسی از اینترنت، آنچه systemd میتواند تضمین کند، سرعت فایلها، رفتار شبکه و این است که چه کسی مسئولیت پشتیبانگیری را بر عهده دارد. هر بخش زیر تفاوتی است که میتوانید شخصاً روی ماشین خود مشاهده کنید.
چرا با بستن لپتاپ، WSL متوقف میشود؟
نسخه WSL 2 یک هسته لینوکس واقعی را در یک ماشین مجازی سبک اجرا میکند که ویندوز آن را در صورت نیاز راهاندازی میکند. آن ماشین مجازی تنها زمانی وجود دارد که یک توزیع در حال اجرا باشد و توزیع نیز تنها زمانی اجرا میشود که چیزی در حال استفاده از آن باشد. وضعیت را از طریق PowerShell بررسی کنید:
wsl --version
wsl --list --runningتمام ترمینالهای WSL را ببندید، یک دقیقه صبر کنید و سپس دوباره wsl --list --running را اجرا کنید. هنگامی که گزارش میدهد هیچ توزیعی در حال اجرا نیست، شلی که باز کرده بودید و هر چیزی که در آن در حال اجرا بود، متوقف شده است. دستور wsl --shutdown نیز همین کار را بلافاصله انجام میدهد که روشی مفید برای تست رفتار تنظیمات شما پس از راهاندازی مجدد است.
حالتهای Sleep و Hibernate نیز ماشین مجازی را متوقف میکنند. تایمری که برای dump گرفتن از یک دیتابیس در ساعت 03:00 تنظیم شده است، در حالی که درب لپتاپ بسته است اجرا نمیشود، زیرا هستهای که باید آن را اجرا کند در حال فعالیت نیست. هیچ چیزی خطایی ثبت نمیکند، بنابراین به نظر میرسد که آن وظیفه هرگز زمانبندی نشده است. همین رفتار واحد باعث میشود کاربران به سراغ دستگاه دوم بروند: صف ساخت (build queue)، ربات چت، پشتیبانگیری شبانه یا دریافتکننده webhook، همگی به کامپیوتری نیاز دارند که روشن بماند.
آیا systemd در WSL کار میکند؟
بله. پشتیبانی از آن در نسخه 0.67.6 از WSL اضافه شد و در نصبهای قدیمیتر بهصورت پیشفرض غیرفعال است. بدون آن، systemctl status ssh این خطا را چاپ میکند:
System has not been booted with systemd as init system (PID 1). Can't operate.ابتدا فایل پیکربندی را بخوانید، زیرا ممکن است از قبل فایلی داشته باشید. اگر بخش [boot] وجود ندارد، آن را اضافه کنید؛ اگر وجود دارد، خط مربوطه را درون همان بخش موجود قرار دهید.
cat /etc/wsl.conf
sudo tee -a /etc/wsl.conf >/dev/null <<'EOF'
[boot]
systemd=true
EOFدستور wsl --shutdown را در PowerShell اجرا کنید، یک shell جدید Ubuntu باز کنید و سپس با systemctl list-units --type=service --state=running وضعیت را بررسی کنید. مشاهده لیستی از واحدها (units) به این معنی است که systemd به عنوان PID 1 در حال اجراست و از آن لحظه به بعد journalctl -b کار میکند.
نکته مهم این است که enable در هر ماشین چه وعدهای میدهد. در یک VPS، عبارت sudo systemctl enable --now caddy به این معنی است که سرویس در زمان بوت سیستم شروع میشود، بنابراین پس از reboot یا ارتقای هسته (kernel) و حتی زمانی که هیچ کاربری وارد سیستم نشده است، سرویس دوباره بالا میآید. در WSL، این به آن معناست که سرویس با شروع توزیع (distribution) آغاز میشود و توزیع زمانی شروع میشود که شما یک ترمینال باز کنید. بنابراین سرویس فقط زمانی فعال است که شما در حال کار هستید، که این دقیقاً برعکس دلیلی است که سرویسها برای آن وجود دارند. کانتینرها نیز همین محدودیت را به ارث میبرند؛ به همین دلیل است که اجرای خودکار سرویسهای Docker Compose در زمان بوت به بوتی وابسته است که WSL تنها زمانی آن را انجام میدهد که شما درخواست کنید.
آیا یک webhook میتواند به سروری که در WSL اجرا میشود دسترسی پیدا کند؟
بدون کمک خیر، و دلیل آن ساختار شبکه است. در حالت پیشفرض، WSL 2 ماشین مجازی را پشت NAT (ترجمه آدرس شبکه) روی آداپتور مجازی اختصاصی خود قرار میدهد. به این آدرس نگاه کنید:
ip -4 addr show eth0
ip route show defaultاین آدرس خصوصی است و هر بار که ماشین مجازی شروع به کار میکند دوباره تخصیص مییابد، بنابراین تغییر میکند. ویندوز همچنان میتواند به localhost:3000 دسترسی داشته باشد، زیرا WSL اتصالات localhost را به توزیع (distribution) هدایت میکند. ماشین دیگری در شبکه شما نمیتواند به آن دسترسی داشته باشد، مگر اینکه یک قانون پروکسی از طریق یک PowerShell با دسترسی Administrator اضافه کنید:
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.24.108.3آن قانون یک آدرس مشخص را نام میبرد، بنابراین با تغییر آدرس در دفعات بعدی، آن قانون از کار میافتد. شبکه آینهای (Mirrored networking) گزینه بهتری است: توزیع همان اینترفیسها و آدرسهای ویندوز را دریافت میکند. از اوت 2026، این قابلیت به Windows 11 22H2 یا جدیدتر نیاز دارد. این تنظیمات را در %UserProfile%\.wslconfig قرار دهید و wsl --shutdown را اجرا کنید:
[wsl2]
networkingMode=mirroredحالت آینهای مشکل شبکه محلی را حل میکند. این حالت به شما یک آدرس عمومی نمیدهد. روتر شما دوباره NAT را اجرا میکند، اکثر اتصالات خانگی هیچ پورت ورودی ندارند که شما کنترل کنید، و بسیاری از ISPها یک لایه NAT دیگر نیز در بالای آن اضافه میکنند. بنابراین GitHub نمیتواند یک رویداد را به لپتاپ شما POST کند و یک همکار نمیتواند لینک دموی شما را باز کند. یک سرویس تونل این مشکل را دور میزند، اما کلاینت تونل روی لپتاپ اجرا میشود، که یعنی لپتاپ همچنان ماشینی است که باید روشن بماند.
یک VPS از سمت دیگر این مشکل شروع میشود. این سرور دارای یک آدرس IPv4 عمومی و معمولاً یک آدرس IPv6 عمومی است، که فقط پورتهایی که شما باز میکنید در دسترس هستند. یک رکورد A را به آن اشاره دهید، پورتهای 80 و 443 را باز کنید، و از هر جایی پاسخ میدهد. این همچنین شرط لازم برای یک گواهی عمومی است، زیرا چالش HTTP-01 از Let's Encrypt میخواهد که یک فایل را از طریق پورت 80 روی نام عمومی دریافت کند. دریافت گواهی Let's Encrypt با Certbot و nginx روی یک سرور کاری پنج دقیقهای است و در WSL غیرممکن است. برای کارهای محلی، همچنان میتوانید با افزودن CA اختصاصی خود به Ubuntu trust store، به HTTPS مورد اعتماد مرورگر در داخل WSL دست یابید.
چرا git روی /mnt/c کند است؟
دلیل این است که فایلها روی سیستم فایل لینوکس قرار ندارند. WSL دو فضای ذخیرهسازی با هزینههای بسیار متفاوت در اختیار شما میگذارد. دایرکتوری home شما روی یک سیستم فایل ext4 در داخل یک دیسک مجازی قرار دارد و مانند یک دیسک معمولی لینوکس عمل میکند. /mnt/c همان درایو ویندوز است که از طریق پروتکل 9P (پروتکل سیستم فایل Plan 9) توسط مؤلفهای در سمت ویندوز ارائه میشود، بنابراین هر عملیات باز کردن یا stat، از این مرز عبور میکند.
یک فایل مشکلی ایجاد نمیکند. git status روی یک مخزن بزرگ، هزاران فراخوانی stat ایجاد میکند و هر کدام هزینه عبور از این مرز را میپردازند. به جای اعتماد به اعداد دیگران، از جمله این صفحه، آن را اندازهگیری کنید:
cd /mnt/c/Users/you/code/myrepo && time git status
cp -r /mnt/c/Users/you/code/myrepo ~/myrepo
cd ~/myrepo && time git statusهر کدام را دو بار اجرا کنید و اجرای دوم را مقایسه کنید تا هر دو در حالت warm باشند. اسکن آنتیویروس بلادرنگ ویندوز هزینه بیشتری به سمت /mnt/c اضافه میکند؛ به همین دلیل است که یک مخزن مشابه ممکن است روی لپتاپ شرکتی کندتر از لپتاپ شخصی به نظر برسد.
راه حل در داخل WSL این است که working copy را در ~ نگه دارید و آن را با حالت WSL remote ویرایشگر خود باز کنید، که سرور ویرایشگر را به جای عبور از مرز، در داخل توزیع اجرا میکند. Explorer همچنان میتواند این فایلها را در \\wsl.localhost\Ubuntu\home\you مرور کند. یک VPS این مشکل را ندارد، زیرا تنها یک سیستم فایل وجود دارد و آن هم لینوکس است. هزینهای که در آنجا میپردازید، تأخیر شبکه هنگام ویرایش است، بنابراین افراد در یک terminal multiplexer یا یک نشست ویرایشگر از راه دور کار میکنند. CPU اشتراکی تنها نکته مهم در یک سرور کوچک است و steal time from a noisy neighbour در top به عنوان ستون st ظاهر میشود.
جایی که WSL برتری مطلق دارد
- رایگان است و از قبل روی دستگاه شما قرار دارد. آن را فعال کنید، Ubuntu را نصب کنید و در عرض یک دقیقه آماده کار خواهید بود؛ بدون هیچ هزینهای و بدون نیاز به محافظت از سطح دسترسی عمومی.
- برخلاف سرور، به راحتی قابل دور ریختن است.
wsl --export Ubuntu D:\wsl-backups\ubuntu.tarکل توزیع را در یک فایل مینویسد وwsl --importآن را بازیابی یا با نامی دیگر شبیهسازی میکند. امتحان کردن یک نسخه جدید Ubuntu در اینجا به سادگی یک clone و rollback است، در حالی که ارتقای یک VPS از 24.04 به 26.04 یک مسیر یکطرفه است که باید آن را با توجه به سرویسهای در حال اجرا روی سرور زمانبندی کنید. - کار با GPU مستقیم است. با درایور فعلی GPU در ویندوز، کارت گرافیک داخل توزیع در دسترس است، بنابراین بارهای کاری CUDA و ROCm روی سختافزاری که از قبل دارید اجرا میشوند. اجاره همان کلاس GPU به صورت ساعتی هزینه واقعی دارد.
- حلقه ویرایش کوتاهتر است. فایلها و مرورگر شما هر دو محلی هستند، بنابراین یک سرور توسعه روی
localhost:5173در مرورگری باز میشود که از قبل در آن وارد شدهاید.
اینها مزایای واقعی هستند و به همین دلیل است که پاسخ معمول، استفاده از هر دو دستگاه به جای یکی است.
چه کسی مالک پشتیبانها است؟
شما مالک آنها هستید، در هر دو ماشین؛ و WSL جایی است که این موضوع افراد را غافلگیر میکند. توزیع (distribution) در واقع یک فایل دیسک مجازی (ext4.vhdx) در داخل پروفایل کاربری ویندوز شماست. هیچ ارائهدهندهای از آن برای شما اسنپشات نمیگیرد. wsl --unregister Ubuntu آن را بدون امکان بازگشت حذف میکند و نصب مجدد ویندوز نیز آن را به همراه سایر دادهها از بین میبرد. آن را طبق برنامهای که واقعاً به آن پایبند هستید، اکسپورت کنید:
wsl --export Ubuntu D:\wsl-backups\ubuntu-2026-08-18.tarدر یک VPS، اسنپشات ارائهدهنده از شما در برابر خرابی میزبان (host) محافظت میکند. این اسنپشات از شما در برابر اجرای rm -rf در دایرکتوری اشتباه محافظت نمیکند و اسنپشاتی که در همان حساب کاربری سرور نگهداری میشود، تنها به اندازه یک ورود غیرمجاز با نابودی فاصله دارد. پشتیبانهای سطح فایل را به خارج از سرور منتقل کنید و پیش از آنکه به آن نیاز پیدا کنید، یک بار عملیات بازیابی (restore) را تست کنید. مسئولیت در هر دو حالت بر عهده شماست. تفاوت عملی این است که یک سرور میتواند پشتیبان خود را در ساعت 03:00 بدون نیاز به روشن ماندن لپتاپ کسی، ارسال کند.
پل ارتباطی: SSH از WSL به VPS
داشتن ماشین دوم تنها تا زمانی که اتصال بهدرستی برقرار شود، دشوار به نظر میرسد. این مراحل را یکبار در WSL انجام دهید.
کلید را در توزیع لینوکسی (و نه در سمت ویندوز) تولید کنید تا کلید خصوصی روی فایلسیستم ext4 باقی بماند و مجوزهای یونیکسی مورد تأیید ssh را داشته باشد:
ssh-keygen -t ed25519 -C "dev@laptop"
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10کلیدهای Ed25519 کوتاه و سریع هستند و ssh-copy-id کلید عمومی را با مجوزهای صحیح به ~/.ssh/authorized_keys در سرور اضافه میکند. اصول مدیریت کلید SSH به نحوه چرخش و ابطال آنها در آینده میپردازد.
برای سرور در فایل ~/.ssh/config یک نام انتخاب کنید:
Host dev
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ForwardAgent yes
ServerAliveInterval 30اکنون ssh dev متصل میشود. IdentitiesOnly yes مانع از آن میشود که کلاینت تمام کلیدهای موجود خود را ارائه دهد؛ این همان چیزی است که هنگام بارگذاری چندین کلید در agent، باعث بروز Too many authentication failures میشود. ServerAliveInterval 30 از قطع شدن نشست در اتصالات خانگی بدون نمایش پیام جلوگیری میکند.
ForwardAgent yes خطی است که گردش کار را آسان میکند. با بارگذاری کلید در agent روی لپتاپ، git clone git@github.com:you/app.git بدون نیاز به انتقال کلید خصوصی به سرور، کار میکند. این مورد را با ssh -T git@github.com از داخل VPS تست کنید که باید پاسخ Hi you! You've successfully authenticated را برگرداند. agent را فقط به سرورهایی که به آنها اعتماد دارید Forward کنید، زیرا کاربر root در آن ماشین میتواند در زمان اتصال شما از سوکت agent استفاده کند. در سروری که با دیگران به اشتراک میگذارید، استفاده از deploy key مخصوص هر مخزن انتخاب امنتری است.
WSL یک agent را بین شلهای مختلف زنده نگه نمیدارد، بنابراین هر ترمینال جدید دوباره درخواست کلید میکند. keychain این مشکل را حل میکند:
sudo apt update && sudo apt install -y keychain
echo 'eval "$(keychain --eval --quiet id_ed25519)"' >> ~/.bashrcیک شل جدید باز کنید و ssh-add -l را اجرا کنید. این دستور باید اثر انگشت (fingerprint) کلید را چاپ کند. مشاهده Error connecting to agent به این معنی است که خط مربوطه خوانده نمیشود، پس بررسی کنید که شل شما واقعاً فایل ~/.bashrc را source میکند.
کارها را در سرور داخل یک ترمینال مالتیپلکسر اجرا کنید تا با قطع شدن اتصال، فرآیندها متوقف نشوند:
tmux new -s dev
# Ctrl-b then d to detach
tmux attach -t devفرآیند ساخت (build) حتی پس از بستن لپتاپ ادامه مییابد؛ این دقیقاً همان دلیلی است که به ماشین دوم نیاز داریم. همین الگو روشی است که افراد Claude Code را در یک VPS داخل tmux اجرا میکنند و نشست را از دستگاه دیگری دوباره در دست میگیرند.
پیش از قرار دادن هر چیزی روی سرور، آن را ایمن کنید. ده دقیقه اول روی یک VPS جدید مراحل ایجاد کاربر غیر-root، استفاده از SSH فقط با کلید، تنظیم فایروال و بهروزرسانیهای امنیتی خودکار را به ترتیبی که باعث قفل شدن دسترسی شما نشود، توضیح میدهد.
کدام ماشین برای کدام کار؟
هنگامی که کار روی صفحه نمایش شما انجام میشود، از WSL استفاده کنید. ویرایش کد، اجرای مجموعه تستها، سرور توسعه روی localhost، نوتبوکها، آزمایشهای GPU و هر چیزی که آن را شروع میکنید و سپس نظارت میکنید.
هنگامی که کار باید در دسترس باشد یا باید فراتر از نشست (session) شما باقی بماند، از VPS استفاده کنید. یک URL مرحلهبندی (staging) که مشتری بتواند باز کند، یک endpoint برای webhook، یک cron job با ساعت واقعی، یک ربات، یک دیتابیس کوچک که سرویس دیگری با آن در ارتباط است، یا یک عملیات import که عصر جمعه شروع میکنید.
اگر هنوز در حال تصمیمگیری هستید که ماشین دوم برای چه کاری است، مواردی که افراد واقعاً روی VPS اجرا میکنند فهرستی مفیدتر از مقایسه مشخصات فنی است، و VPS چیست مجازیسازی زیرساخت آن را توضیح میدهد. اگر ابزارهای شما فقط روی Windows اجرا میشوند، این یک تصمیم جداگانه است و مقایسه Linux با Windows Server صفحه مربوط به آن است.
یک عادت باعث میشود دو ماشین به دو ماشین با پیکربندی ناقص تبدیل نشوند: کد در git قرار دارد و هر دو ماشین کلاینتهای آن مخزن هستند. هیچ چیز مهمی نباید فقط در یکی از آنها وجود داشته باشد.
FAQ
آیا میتوانم از طریق WSL یک وبسایت با دامنه واقعی میزبانی کنم؟
بهطور قابلاطمینان خیر. WSL 2 پشت NAT در داخل دستگاه شما قرار دارد، روتر شما نیز دوباره NAT را اجرا میکند و اکثر اتصالات خانگی هیچ پورت ورودی برای Forward کردن به شما نمیدهند. یک سرویس تونل میتواند یک پورت محلی را در معرض دید قرار دهد، اما کلاینت تونل روی لپتاپ اجرا میشود، بنابراین هر زمان که لپتاپ به حالت خواب (sleep) برود، سایت از دسترس خارج میشود. گواهیها کار را دشوارتر میکنند، زیرا چالش HTTP-01 مستلزم آن است که Let's Encrypt فایلی را از طریق پورت 80 روی نام عمومی دریافت کند. یک VPS با آدرس IP عمومی و یک رکورد A، هر دو شرط را بدون نیاز به راهکارهای جانبی برآورده میکند.
آیا systemctl enable در WSL کار میکند؟
این ابزار زمانی کار میکند که systemd فعال باشد، که به معنای تنظیم systemd=true تحت [boot] در فایل /etc/wsl.conf و سپس اجرای wsl --shutdown است. بدون آن، systemctl پاسخ System has not been booted with systemd as init system (PID 1). Can't operate. را برمیگرداند. حتی با اجرای systemd، دستور enable سرویس را هنگام شروع توزیع (distribution) اجرا میکند و توزیع زمانی شروع میشود که شما یک shell باز کنید. در یک سرور، همان دستور به این معناست که سرویس پس از reboot، حتی بدون ورود هیچ کاربری به سیستم، دوباره بالا میآید.
چرا آدرس IP من در WSL مدام تغییر میکند؟
در حالت پیشفرض NAT، ماشین مجازی هر بار که شروع به کار میکند، یک آدرس خصوصی جدید از آداپتور مجازی WSL دریافت میکند. هر قانون netsh interface portproxy یا آدرس hard-coded پس از wsl --shutdown از کار میافتد. آدرس فعلی را با ip -4 addr show eth0 بررسی کنید. حالت شبکه Mirrored در Windows 11 با دادن همان رابطهای ویندوز به توزیع، آدرس جداگانه را حذف میکند: networkingMode=mirrored را تحت [wsl2] در %UserProfile%\.wslconfig تنظیم کنید.
آیا مسیر /mnt/c واقعاً کندتر است یا این فقط یک باور غلط است؟
این مسیر کندتر است و یک دقیقه تست روی دستگاه خودتان این موضوع را ثابت میکند. فایلهای تحت ~ روی یک دیسک مجازی ext4 قرار دارند. فایلهای تحت /mnt/c از طریق پروتکل 9P توسط یک مؤلفه در سمت ویندوز ارائه میشوند، بنابراین هر فراخوانی stat از مرز عبور میکند و git status روی یک درخت بزرگ، هزاران مورد از این فراخوانیها را ایجاد میکند. مخزن (repository) را به ~ کپی کنید، time git status را در هر دو مکان دو بار اجرا کنید و نتایج اجرای دوم (warm runs) را مقایسه کنید. نسخههای کاری را تحت ~ نگه دارید و از حالت WSL remote در ویرایشگر خود استفاده کنید.
آیا پس از داشتن VPS همچنان به WSL نیاز دارم؟
بیشتر افراد هر دو را نگه میدارند. WSL رایگان است و فوراً اجرا میشود، بنابراین همچنان مکانی برای ویرایش و تست باقی میماند و کارهای مربوط به GPU نیز در آنجا انجام میشود. سرور ماشینی است که همیشه روشن میماند: نام عمومی را میزبانی میکند و وظایفی را اجرا میکند که باید پس از بستن لپتاپ همچنان فعال بمانند. کد را در git نگه دارید و با هر دو به عنوان کلاینتهای مخزن رفتار کنید؛ در این صورت انتقال کار بین آنها هیچ هزینهای نخواهد داشت.