پرش به محتوای اصلی
تاپ گیفت
راه‌اندازی و کار با سرور

آموزش اجرای پروژه پایتون روی سرور مجازی لینوکس

از نصب پایتون تا ساخت محیط مجازی و تبدیل اسکریپت به یک سرویس سیستمی که بعد از راه‌اندازی مجدد خودش بالا می‌آید. همه دستورها روی لینوکس اجرا و بررسی شده‌اند.

9 دقیقه مطالعه
پنجره سرویس systemd با وضعیت فعال و نماد اجرای دوباره

اجرای یک اسکریپت پایتون روی سرور با python main.py شروع می‌شود و با بستن ترمینال تمام می‌شود. برای اینکه سرویس واقعاً بماند، سه چیز لازم است: محیط مجازی، سرویس سیستمی، و لاگ. این آموزش از نصب پایتون روی سرور لینوکس شروع می‌کند و به سرویسی می‌رسد که بعد از راه‌اندازی مجدد خودش بالا می‌آید.

فرض این آموزش اوبونتو یا دبیان است و اینکه کاربر غیر root به نام deploy ساخته‌اید. اگر نساخته‌اید، اول بعد از خرید سرور مجازی را ببینید. اگر هنوز سرور ندارید و نمی‌دانید سرور مجازی دقیقاً چه چیزی در اختیارتان می‌گذارد، سرور مجازی چیست را بخوانید.

1. پایتون را بررسی کنید

python3 -V

روی نسخه‌های جدید اوبونتو، پایتون از قبل نصب است. روی اوبونتو 24.04 خروجی چیزی شبیه Python 3.12.3 خواهد بود. دستور python (بدون 3) ممکن است اصلاً وجود نداشته باشد؛ همیشه python3 بنویسید.

پایتون سیستم را حذف یا با نسخه دیگری جایگزین نکنید؛ بخشی از ابزارهای خود سیستم‌عامل به آن وابسته‌اند. اگر پروژه‌تان نسخه دیگری لازم دارد، آن را کنار نسخه سیستم نصب کنید، نه به جایش.

2. بسته venv را نصب کنید

این قدمی است که بیشترین کسان را متوقف می‌کند. روی اوبونتو و دبیان، پایتون نصب است اما ابزار ساخت محیط مجازی جداگانه بسته‌بندی شده. اگر این قدم را رد کنید، ساخت محیط مجازی با این خطا متوقف می‌شود:

The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

پس اول:

sudo apt update
sudo apt install python3-venv python3-pip

چرا pip install مستقیم خطا می‌دهد؟

روی اوبونتو 23.04 به بعد و دبیان 12، اگر بیرون از محیط مجازی pip install بزنید، با خطای externally-managed-environment روبه‌رو می‌شوید. این خطا عمدی است: طبق مشخصات رسمی بسته‌بندی پایتون، پایتون سیستم در اختیار مدیر بسته سیستم‌عامل است و راه پیشنهادی برای نصب کتابخانه‌ها، ساختن محیط مجازی است. گزینه --break-system-packages را برای دور زدنش به کار نبرید؛ اسمش دقیقاً می‌گوید چه کاری می‌کند.

3. کد را روی سرور بگذارید

اول کد، بعد محیط مجازی. اگر برعکس عمل کنید، git clone در پوشه‌ای که محیط مجازی در آن ساخته شده با خطای «پوشه خالی نیست» متوقف می‌شود.

با git، اگر پروژه در یک مخزن است:

git clone https://example.com/user/myapp.git ~/myapp

یا با scp از کامپیوتر خودتان:

scp -r ./myapp deploy@203.0.113.10:~/

اگر پوشه .venv روی کامپیوتر خودتان هم هست، آن را منتقل نکنید؛ محیط مجازی قابل جابه‌جایی نیست و روی سرور از نو ساخته می‌شود.

4. محیط مجازی بسازید

محیط مجازی، وابستگی‌های پروژه شما را از بسته‌های سیستم جدا نگه می‌دارد. بدون آن، نصب یک کتابخانه برای یک پروژه می‌تواند پروژه دیگر یا حتی ابزارهای خود سیستم را از کار بیندازد.

cd ~/myapp
python3 -m venv .venv

برای فعال کردنش در جلسه فعلی:

source .venv/bin/activate

وقتی فعال باشد، نام محیط در ابتدای خط فرمان نمایش داده می‌شود. طبق مستندات venv، محیط مجازی یک‌بارمصرف است: کد پروژه را داخلش نمی‌گذارید، آن را جابه‌جا یا کپی نمی‌کنید، و هر وقت لازم شد پاکش می‌کنید و از روی requirements.txt دوباره می‌سازید. اگر پروژه با git مدیریت می‌شود، .venv/ را به فایل .gitignore اضافه کنید.

5. وابستگی‌ها را نصب کنید

pip install -r requirements.txt

اگر فایل requirements.txt ندارید، بسته‌ها را مستقیم نصب کنید و بعد فهرستشان را بسازید:

pip install requests
pip freeze > requirements.txt

6. یک بار دستی اجرا کنید

قبل از ساختن سرویس، مطمئن شوید برنامه با مفسر محیط مجازی و بدون فعال‌سازی اجرا می‌شود — همان کاری که systemd قرار است انجام دهد:

~/myapp/.venv/bin/python ~/myapp/main.py

اگر اینجا خطا می‌دهد، در سرویس هم خطا خواهد داد؛ اینجا رفع کردنش ساده‌تر است. با Ctrl + C متوقفش کنید.

7. آن را به یک سرویس سیستمی تبدیل کنید

این چیزی است که اسکریپت را از یک برنامه در حال اجرا به یک سرویس تبدیل می‌کند: بعد از راه‌اندازی مجدد سرور خودش بالا می‌آید و اگر خطا داد، دوباره اجرا می‌شود.

اگر برنامه کلید یا رمزی لازم دارد، اول آن را در یک فایل جدا بگذارید که فقط صاحبش بتواند بخواندش:

nano ~/myapp/.env
chmod 600 ~/myapp/.env

محتوای فایل، هر متغیر در یک خط، مثلاً API_KEY=.... بعد فایل /etc/systemd/system/myapp.service را بسازید:

[Unit]
Description=My Python service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/home/deploy/myapp
EnvironmentFile=/home/deploy/myapp/.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/home/deploy/myapp/.venv/bin/python /home/deploy/myapp/main.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

چند نکته که معمولاً اشتباه نوشته می‌شوند:

  • مسیرها باید کامل باشند. systemd متغیرهای محیط پوسته شما را ندارد و ~ را هم در ExecStart باز نمی‌کند.
  • مفسر پایتون را از داخل محیط مجازی صدا بزنید — همان .venv/bin/python. با این کار نیازی به فعال کردن محیط نیست.
  • نام کاربر را بنویسید. بدون User، سرویس با دسترسی root اجرا می‌شود.
  • فایل EnvironmentFile باید وجود داشته باشد. اگر نباشد، سرویس اجرا نمی‌شود. اگر برنامه‌تان راز یا تنظیمی ندارد، آن خط را حذف کنید، یا با گذاشتن - در ابتدای مسیر (EnvironmentFile=-/home/deploy/myapp/.env) نبودن فایل را مجاز کنید.
  • PYTHONUNBUFFERED=1 را فراموش نکنید. وقتی خروجی پایتون به ترمینال نمی‌رود، چاپ‌ها بافر می‌شوند و لاگ با تأخیر یا بعد از کرش ناقص می‌رسد. طبق مستندات پایتون، این متغیر همان اثر گزینه -u را دارد.
  • Restart=always یا on-failure؟ طبق مستندات systemd، on-failure فقط وقتی دوباره اجرا می‌کند که برنامه با خطا خارج شود؛ always حتی خروج عادی را هم دوباره اجرا می‌کند. برای ربات یا سرویسی که نباید هیچ‌وقت متوقف شود، always مناسب‌تر است. توقفی که خودتان با systemctl stop انجام دهید، در هر دو حالت دوباره اجرا نمی‌شود.

حالا سرویس را فعال و اجرا کنید. --now یعنی هم برای راه‌اندازی بعدی فعال شود و هم همین حالا اجرا شود:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp

و وضعیتش را ببینید:

systemctl status myapp

هر بار فایل .service را ویرایش کردید، دوباره daemon-reload و بعد restart لازم است؛ وگرنه systemd هنوز نسخه قبلی را اجرا می‌کند.

8. لاگ‌ها

هر چیزی که برنامه چاپ کند در ژورنال سیستم ثبت می‌شود:

journalctl -u myapp -f

گزینه -f یعنی همان‌طور که خطوط جدید می‌آیند نمایش بده. برای دیدن 50 خط آخر، یا هر چه در یک ساعت اخیر ثبت شده:

journalctl -u myapp -n 50 --no-pager
journalctl -u myapp --since "1 hour ago"

به فیلتر -p err برای پیدا کردن خطاهای پایتون تکیه نکنید: systemd خروجی برنامه را، چه stdout و چه stderr، به‌طور پیش‌فرض با سطح info ثبت می‌کند، پس traceback پایتون با این فیلتر دیده نمی‌شود.

9. بعد از هر به‌روزرسانی کد

cd ~/myapp
git pull
.venv/bin/pip install -r requirements.txt
sudo systemctl restart myapp

اگر سرویس بالا نیامد

نشانهعلت محتمل
status=203/EXEC در خروجی statusمسیر ExecStart اشتباه است یا فایل مفسر وجود ندارد؛ مسیر .venv/bin/python را با ls بررسی کنید
status=200/CHDIRپوشه WorkingDirectory وجود ندارد یا کاربر به آن دسترسی ندارد
ModuleNotFoundError در لاگکتابخانه در محیط مجازی نصب نشده، یا ExecStart به جای پایتون محیط مجازی به پایتون سیستم اشاره می‌کند
Permission denied در لاگفایل‌ها متعلق به root‌اند؛ با sudo chown -R deploy:deploy /home/deploy/myapp صاحبشان را درست کنید
لاگ دیر یا ناقص می‌رسدخروجی بافر می‌شود؛ PYTHONUNBUFFERED=1 را اضافه کنید
سرویس مدام بالا و پایین می‌رودبرنامه در شروع کرش می‌کند و Restart دوباره اجرایش می‌کند؛ علت را در journalctl -u myapp -n 50 ببینید

چند نکته عملی

  • حافظه را نگاه کنید. با free -h ببینید چقدر باقی مانده. سرویس پایتونی که حافظه‌اش تمام شود، معمولاً بدون پیام روشنی کشته می‌شود.
  • کلیدها و رمزها را در کد ننویسید. از فایل EnvironmentFile با دسترسی 600 استفاده کنید و آن را در مخزن git قرار ندهید. مستندات systemd یادآوری می‌کند که متغیرهای محیطی روش کاملاً امنی برای رازها نیستند؛ برای موارد حساس‌تر، گزینه LoadCredential= در systemd ساخته شده است.
  • اگر برنامه وب است، آن را مستقیم روی پورت 80 اجرا نکنید. روی 127.0.0.1 و یک پورت محلی اجرا کنید و یک وب‌سرور جلویش بگذارید.

مشخصات پلن‌های در دسترس را در خرید سرور مجازی می‌بینید. اگر سرویس شما سبک است و مطمئن نیستید کدام اندازه کافی است، سرور مجازی با رم 1 یا 2 گیگابایت را ببینید، و اگر پروژه‌تان ربات تلگرام است، سرور مجازی برای ربات تلگرام نکات مخصوص آن را دارد.

پرسش‌های متداول

چرا python3 -m venv خطا می‌دهد؟
روی اوبونتو و دبیان، ابزار ساخت محیط مجازی در بسته جداگانه‌ای است. با apt install python3-venv نصبش کنید و دوباره امتحان کنید.
حتماً باید از محیط مجازی استفاده کنم؟
عملاً بله. بدون آن، نصب بسته برای یک پروژه می‌تواند پروژه دیگر یا ابزارهای خود سیستم را خراب کند.
چطور مطمئن شوم برنامه بعد از راه‌اندازی مجدد بالا می‌آید؟
اگر systemctl enable را اجرا کرده باشید، خودکار بالا می‌آید. برای اطمینان یک بار سرور را راه‌اندازی مجدد کنید و systemctl status را ببینید.
اشتراک‌گذاری: اشتراک در تلگرام

مقالات مرتبط

بعد از خرید سرور مجازی چه کارهایی باید انجام دهیم؟

سروری که تازه تحویل گرفته‌اید روی اینترنت باز است و از همان دقیقه اول آزمایش می‌شود. این فهرست، کارهای اولیه‌ای را که قبل از هر چیز دیگری باید انجام دهید مرتب می‌کند.

9 دقیقه مطالعه
ادامه مطلب