SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-13

انتخاب بهترین سرور Git خودمیزبان: Forgejo یا Gitea؟

بررسی 4 روش اجرای سرور Git شخصی بر اساس مصرف RAM. از مخازن bare روی SSH و cgit تا Forgejo و GitLab. ببینید کدام گزینه برای یک VPS با 1 GB رم مناسب است.

کدام سرور Git خودمیزبان را باید اجرا کنید

یک سرور Git خودمیزبان تنها یک محصول خاص نیست و میزان RAM (حافظه دسترسی تصادفی) در VPS شما تعیین می‌کند که کدام نسخه از آن را می‌توانید داشته باشید. Git به هیچ daemon اختصاصی نیاز ندارد: یک مخزن bare به همراه یک حساب SSH (پوسته امن)، همین حالا هم روی کوچک‌ترین سروری که می‌توانید اجاره کنید، یک سرور فعال است. هر چیزی فراتر از این، یک برنامه وب است که انتخاب می‌کنید در کنار آن اجرا شود و هر پله ارتقا، هزینه‌ای از حافظه را تحمیل می‌کند که ممکن است یک VPS کوچک از عهده آن برنیاید.

چهار سطح وجود دارد. یک مخزن bare روی SSH، بدون اینکه هیچ سرویس اضافه‌ای در حال گوش دادن باشد. cgit، یک نمایشگر وب سریع و فقط‌خواندنی بدون نیاز به دیتابیس. Forgejo یا Gitea، یک پلتفرم کامل مدیریت مخزن با قابلیت تعریف حساب کاربری، ثبت issue و pull request که به چند صد مگابایت حافظه نیاز دارد. GitLab، که انتظار دارد سروری با چندین برابر ظرفیت گزینه‌های دیگر در اختیار داشته باشد.

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

میزان رم مورد نیاز برای هر گزینه

تنها دو مورد از این پروژه‌ها عدد مشخصی برای سخت‌افزار منتشر کرده‌اند. ارقام منتشرشده را به عنوان حداقلِ مطلق در نظر بگیرید، نه یک تضمین؛ پس از راه‌اندازی، میزان مصرف نمونهٔ خود را با استفاده از systemd-cgtop یا ps -o rss= -C forgejo اندازه‌گیری کنید.

ChartRAM the projects document, official docs, August 2026
The data behind this chart
[
  {
    "label": "Gitea, small team",
    "ram_gb": 1
  },
  {
    "label": "GitLab, memory constrained",
    "ram_gb": 8
  },
  {
    "label": "GitLab, single node baseline",
    "ram_gb": 16
  }
]

Gitea برای تیم‌ها و پروژه‌های کوچک، 1 GB رم و 2 هسته CPU را کافی می‌داند و Raspberry Pi 3 را برای بارهای کاری سبک مناسب معرفی می‌کند. GitLab عدد 16 GB را به عنوان حداقل برای نصب روی یک گره (node) و 8 GB را به عنوان پایین‌ترین حد برای محیط‌هایی که در مستندات خود «محدود از نظر حافظه» نامیده، ذکر کرده است. Forgejo هیچ نیازمندی سخت‌افزاری منتشر نکرده است. از آنجا که این پروژه یک fork از Gitea است و رفتاری مشابه دارد، ارقام Gitea نزدیک‌ترین راهنمای موجود برای شماست.

این موضوع در یک VPS با 1 GB رم به این معناست: مخازن (repositories) خام و cgit بدون مشکل اجرا می‌شوند و فضای خالی هم باقی می‌ماند، زیرا هیچ‌کدام سرویس مقیم در حافظه ندارند. Forgejo یا Gitea اجرا می‌شوند و می‌توانند به یک تیم کوچک روی SQLite سرویس‌دهی کنند، اما چون دقیقاً روی حداقلِ اعلام‌شده هستید، PostgreSQL و CI (یکپارچه‌سازی مداوم) را روی آن سرور فعال نکنید. اگر رابط وب بدون نمایش خطا ناپدید شد، sudo dmesg -T | grep -i oom را اجرا کنید و به دنبال خطی مشابه Out of memory: Killed process 1181 (forgejo) بگردید؛ این یعنی kernel out of memory killer آن را متوقف کرده است. اجرای GitLab روی یک سرور 1 GB مشکلِ تنظیمات نیست؛ این برنامه اصلاً اجرا نخواهد شد.

سطح 0: مخزن خام (bare) روی SSH

Git هیچ daemon شبکه‌ای ندارد که نیاز به راه‌اندازی داشته باشد. git push روی SSH، دستور git-receive-pack را در سمت مقصد به عنوان یک پردازش معمولی Unix اجرا می‌کند، بنابراین هر حسابی که بتوانید با یک کلید به آن دسترسی پیدا کنید، از قبل یک Git remote محسوب می‌شود. یک حساب کاربری برای مخازن بسازید و مخازن را خارج از دایرکتوری home آن نگه دارید، زیرا در Ubuntu 24.04 دایرکتوری‌های home جدید با مجوز 0750 ایجاد می‌شوند و یک رابط وب که بعداً اضافه شود، نمی‌تواند محتویات آن را بخواند.

sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
  --group --disabled-password --home /home/git git
sudo install -d -m 0755 -o git -g git /srv/git
sudo -u git git init --bare /srv/git/project.git

دستور --bare یک مخزن بدون working copy ایجاد می‌کند که همان چیزی است که یک سرور نگهداری می‌کند. push کردن به مخزنی که دارای working copy است با خطای refusing to update checked out branch: refs/heads/main رد می‌شود و این رایج‌ترین اشتباه در این سطح است.

حالا به حساب کاربری یک کلید بدهید و آن را clone کنید.

sudo -u git install -d -m 700 /home/git/.ssh
sudo -u git tee -a /home/git/.ssh/authorized_keys <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice@laptop
EOF
sudo -u git chmod 600 /home/git/.ssh/authorized_keys
git remote add origin git@vps.example.com:/srv/git/project.git
git push -u origin main

اولین push موفق با * [new branch] main -> main پایان می‌یابد. موردی که با git@vps.example.com: Permission denied (publickey) تمام شود، احراز هویت نشده است؛ بنابراین لاگ سرور را با sudo journalctl -u ssh -n 20 بخوانید. خطی که Authentication refused: bad ownership or modes for file /home/git/.ssh/authorized_keys را نشان می‌دهد به این معنی است که مجوز فایل اشتباه است، زیرا sshd کلیدهایی که سایر کاربران امکان نوشتن در آن‌ها را دارند نادیده می‌گیرد.

سپس دسترسی shell را از حساب کاربری بگیرید.

command -v git-shell | sudo tee -a /etc/shells
sudo chsh -s "$(command -v git-shell)" git

git-shell فقط دستورات محدودی را که Git از طریق SSH ارسال می‌کند می‌پذیرد، بنابراین ورود تعاملی (interactive login) اکنون به جای نمایش prompt، با یک پیام متوقف می‌شود:

fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.

این کل سرور است. هیچ دیتابیس و هیچ پردازش وبی برای به‌روزرسانی وجود ندارد. آنچه از دست می‌دهید تمام امکاناتی است که یک پلتفرم مدیریت مخزن (forge) ارائه می‌دهد: بدون مرورگر فایل، بدون سیستم ردیابی issue، بدون pull request و بدون مجوزهای سطح کاربر. هر کلیدی که در آن فایل باشد می‌تواند تمام مخازنی را که کاربر git مالک آن‌هاست، بخواند و در آن‌ها بنویسد.

سطح 1: cgit نمای وب را بدون نیاز به پایگاه داده ارائه می‌دهد

cgit یک برنامه CGI (رابط دروازه مشترک) است که به زبان C نوشته شده است. وب‌سرور آن را به ازای هر درخواست اجرا می‌کند، مخازن را مستقیماً از روی دیسک می‌خواند و هیچ وضعیت (state) داخلی ذخیره نمی‌کند. توزیع Ubuntu 24.04 این برنامه را در بخش universe خود ارائه می‌دهد.

sudo apt update
sudo apt install -y cgit fcgiwrap nginx
sudo install -d -o www-data -g www-data /var/cache/cgit

آن را در /etc/cgitrc به دایرکتوری مخازن اشاره دهید:

root-title=Git on example.com
css=/cgit.css
logo=/cgit.png
cache-size=1000
cache-root=/var/cache/cgit
snapshots=tar.gz zip
scan-path=/srv/git

scan-path آن دایرکتوری را پیمایش کرده و تمام مخازن یافت‌شده را فهرست می‌کند، بنابراین یک مخزن bare جدید بدون نیاز به پیکربندی اضافی نمایش داده می‌شود. cache-size تعداد صفحات کش‌شده است و تا زمانی که روی 0 باشد، کش غیرفعال می‌ماند. پیش از افزودن خطوط جدید، محتویات فایلی که پکیج شما در /etc/cgitrc قرار داده است را مطالعه کنید، زیرا پکیج‌های Debian و Ubuntu به‌صورت پیش‌فرض تنظیماتی دارند.

هر ورودی، خط اول فایل description مخزن را نمایش می‌دهد، بنابراین یک مخزن bare جدید خود را با نام Unnamed repository; edit this file 'description' to name the repository. فهرست می‌کند. این مورد را برای هر مخزن یک‌بار اصلاح کنید:

echo 'Project X, internal tooling' | sudo -u git tee /srv/git/project.git/description
فایل سایت nginx و نحوه بررسی آن
server {
    listen 80;
    server_name git.example.com;
    root /usr/share/cgit;

    try_files $uri @cgit;

    location @cgit {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param QUERY_STRING $args;
        fastcgi_param HTTP_HOST $server_name;
        fastcgi_pass unix:/run/fcgiwrap.socket;
    }
}
sudo systemctl enable --now fcgiwrap.socket
sudo nginx -t && sudo systemctl reload nginx
systemctl show fcgiwrap.socket -p Listen

root /usr/share/cgit فایل‌های cgit.css و cgit.png را به‌عنوان فایل‌های ساده سرو می‌کند و try_files بقیه موارد را به CGI در /usr/lib/cgit/cgit.cgi می‌سپارد. مشاهده صفحه 502، همراه با connect() to unix:/run/fcgiwrap.socket failed (2: No such file or directory) در /var/log/nginx/error.log، به این معنی است که unit سوکت در حال اجرا نیست یا در مسیر دیگری گوش می‌دهد. خط systemctl show مسیری که واقعاً استفاده می‌شود را چاپ می‌کند.

پیش از توسعه بر پایه این ابزار، دانستن دو محدودیت ضروری است. cgit فقط خواندنی است و سیستم ورود (login) ندارد، بنابراین تمام محتویات تحت scan-path عمومی هستند: مخازن خصوصی را خارج از این دایرکتوری نگه دارید یا از احراز هویت HTTP basic در ابتدای کل سایت استفاده کنید. همچنین، CGI با کاربر وب‌سرور اجرا می‌شود، بنابراین آن کاربر باید اجازه پیمایش /srv/git و خواندن هر مخزن را داشته باشد. دایرکتوری‌هایی که کاربر اجازه ورود به آن‌ها را ندارد، به‌جای نمایش خطا، به‌صورت یک ایندکس خالی ظاهر می‌شوند.

لایه 2: استفاده از Forgejo یا Gitea برای مدیریت Issues و Pull Requests

Forgejo و Gitea از یک ایده پیروی می‌کنند: یک فایل باینری Go که یک پلتفرم توسعه وب شامل کاربران، سازمان‌ها، Issues، Pull Requests، نسخه‌های منتشر شده (releases)، مخزن پکیج و یک سیستم CI داخلی را ارائه می‌دهد. کل نصب شامل فایل باینری و SQLite است؛ به همین دلیل روی سخت‌افزارهایی که GitLab روی آن‌ها اجرا نمی‌شود، به‌خوبی کار می‌کنند. فایل Compose زیر همان فایلی است که در مستندات Forgejo آمده و از تگ ایمیجی استفاده می‌کند که در آگوست 2026 معرفی شده است.

networks:
  forgejo:
    external: false

services:
  server:
    image: codeberg.org/forgejo/forgejo:16
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - forgejo
    volumes:
      - ./forgejo:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - '3000:3000'
      - '222:22'
docker compose up -d
docker compose ps
curl -sI http://127.0.0.1:3000 | head -1

دستور curl باید یک خط وضعیت HTTP چاپ کند. پیش از آنکه تنظیمات اولیه (first-run setup) را به پایان برسانید، ممکن است با یک تغییر مسیر (redirect) به /install مواجه شوید که همچنان به معنای فعال بودن سرویس است. اگر کانتینر متوقف (exit) می‌شود، دلیل معمول آن مالکیت فایل‌هاست: دایرکتوری ./forgejo باید متعلق به UID (شناسه کاربری) تعریف شده در USER_UID باشد، در غیر این صورت پردازش نمی‌تواند در دایرکتوری داده‌های خود بنویسد. بخش Docker Compose on a VPS این ساختار فایل و قانون مالکیت volume را به‌طور کامل پوشش می‌دهد.

دو پاسخ در صفحه تنظیمات تعیین می‌کنند که آیا URLهای clone کار می‌کنند یا خیر. پورت SSH باید 222 باشد، زیرا فایل Compose پورت 222 میزبان را به پورت 22 کانتینر نگاشت می‌کند و دامنه باید همان نامی باشد که کاربران واقعاً تایپ می‌کنند. اگر هر کدام از این‌ها اشتباه باشد، صفحه هر مخزن، دستور cloneای را ارائه می‌دهد که برای هر کسی که آن را کپی کند، با شکست مواجه می‌شود. هر دو مورد بعداً در بخش [server] از فایل app.ini، تحت عنوان SSH_PORT، SSH_DOMAIN و ROOT_URL قابل تغییر هستند.

برای یک نمونه عمومی (public instance)، پورت وب را فقط روی آدرس loopback ('127.0.0.1:3000:3000') منتشر کنید و nginx را برای مدیریت TLS (امنیت لایه انتقال) در مقابل آن قرار دهید. Gitea نیز به همین روش از طریق ایمیج gitea/gitea نصب می‌شود، یا می‌تواند به عنوان یک فایل باینری واحد با یک unit فایل systemd و یک فایل app.ini اجرا شود. نسخه پایدار فعلی آن در آگوست 2026 برابر با 1.27.1 است.

تا زمانی که می‌توانید از SQLite استفاده کنید. این کار باعث می‌شود نمونه شما به یک پردازش و یک فایل محدود بماند و پس از reboot بدون نیاز به نظارت بر سرویس اضافی، به کار خود ادامه دهد. PostgreSQL زمانی ارزش هزینه کردن را دارد که چندین نفر همزمان در حال نوشتن باشند، زیرا SQLite عملیات نوشتن را سریال‌سازی می‌کند و اجرای طولانی‌مدت CI باعث نوشتن مداوم می‌شود. هر دو پروژه امکان انتقال یک نمونه موجود به PostgreSQL را در آینده فراهم می‌کنند، بنابراین این تصمیمی نیست که در آن گیر بیفتید.

Forgejo یا Gitea: تفاوت واقعی در چیست

این دو پروژه ریشه مشترکی دارند. Gitea در سال 2016 از Gogs منشعب شد. در اواخر سال 2022، کنترل دامنه و علامت تجاری Gitea به شرکتی به نام Gitea Ltd واگذار شد و تعدادی از نگهدارندگان پروژه به همراه Codeberg، پروژه Forgejo را آغاز کردند. Forgejo توسط Codeberg e.V. منتشر می‌شود که یک انجمن غیرانتفاعی ثبت‌شده در آلمان است و در سال 2024 مجوز خود را از MIT به GPLv3 (مجوز عمومی همگانی گنو نسخه 3) تغییر داد. Gitea همچنان تحت مجوز MIT باقی مانده و با پشتوانه تجاری توسعه می‌یابد.

در استفاده روزمره، مجموعه قابلیت‌های این دو بسیار به هم نزدیک است، اما مسیر مهاجرت بین آن‌ها این‌طور نیست. نسخه Forgejo v10.0 که در ژانویه 2025 منتشر شد، آخرین نسخه‌ای بود که می‌توانست دیتابیس Gitea را مستقیماً بپذیرد و این تنها برای Gitea v1.22 یا قدیمی‌تر امکان‌پذیر بود. Gitea تا آگوست 2026 به نسخه 1.27.1 رسیده است، بنابراین برای یک نمونه فعلی Gitea، هیچ روش پشتیبانی‌شده‌ای برای تغییر مستقیم به Forgejo وجود ندارد. پیش از آنکه دیتابیس خود را با داده پر کنید، یکی را انتخاب کنید و هرگونه جابه‌جایی بعدی را به عنوان یک عملیات export و re-import در نظر بگیرید.

یک قاعده کلی برای انتخاب: اگر حاکمیت پروژه برای شما اهمیت دارد یا می‌خواهید پروژه تحت مدیریت یک نهاد غیرانتفاعی باقی بماند، از Forgejo استفاده کنید. اگر به دنبال پایگاه نصب بزرگ‌تر و گزینه پشتیبانی تجاری هستید، Gitea را انتخاب کنید. هر دو پروژه به‌صورت متن‌باز نگهداری می‌شوند و به‌طور مرتب نسخه جدید ارائه می‌دهند: Forgejo هر سه ماه یک نسخه پایدار و هر سال یک نسخه LTS (پشتیبانی بلندمدت) منتشر می‌کند، به‌طوری که تا آگوست 2026، نسخه v16.0.2 نسخه جاری و v15.0.6 نسخه LTS است.

سطح 3: هزینه‌های GitLab پیش از هرگونه استفاده

نرم‌افزار GitLab CE در ردهٔ متفاوتی قرار دارد. هر نمونه (instance) از این نرم‌افزار، مجموعه‌ای از سرویس‌های همکار است: Puma برای اپلیکیشن وب، Sidekiq برای پردازش‌های پس‌زمینه، PostgreSQL، Redis، Gitaly برای دسترسی به مخازن و nginx در لایهٔ جلویی. بستهٔ Omnibus تمامی این موارد را یکجا نصب می‌کند که باعث سادگی نصب، اما افزایش حداقل حافظهٔ مورد نیاز می‌شود.

صفحهٔ نیازمندی‌های GitLab، مقدار 16 GB رم و 8 vCPU را به عنوان حداقل استاندارد برای نصب روی یک گره (node) تعیین کرده است و 8 GB را به عنوان کفِ حافظه در محیط‌های محدود پیشنهاد می‌دهد. همین صفحه توصیه می‌کند که swap را غیرفعال کنید، زیرا استفاده از swap تحت بار کاری، عملکرد نمونه را به‌شدت کاهش می‌دهد. این ارقام تا اوت 2026 معتبر هستند و با گذشت سال‌ها افزایش یافته‌اند؛ بنابراین پیش از انتخاب اندازهٔ سرور، حتماً دوباره آن صفحه را مطالعه کنید.

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

مدل دسترسی SSH: یک کاربر git و چندین کلید

تمام سطوح در اینجا به روش یکسانی احراز هویت می‌شوند. یک حساب کاربری یونیکس به نام git وجود دارد و تمام کلیدهای عمومی در فایل ~/.ssh/authorized_keys آن حساب قرار می‌گیرند. احراز هویت بر عهده کلید است. مجوزدهی نیز همان گزینه‌هایی است که در ابتدای همان خط و پیش از کلید می‌نویسید.

یک خط کلید ساده، هر دسترسی که آن حساب داشته باشد را به دارنده کلید می‌دهد. یک دستور اجباری (forced command) دسترسی را به Git محدود می‌کند:

restrict,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice@laptop

گزینه restrict که از نسخه OpenSSH 7.2 در دسترس است، port forwarding، agent forwarding، X11 و تخصیص PTY (ترمینال مجازی) را در یک کلمه غیرفعال می‌کند. گزینه command= هر درخواستی که کلاینت ارسال کند را با دستوری که شما نام می‌برید جایگزین می‌کند و Git همچنان کار می‌کند، زیرا Git درخواست خود را در $SSH_ORIGINAL_COMMAND ارسال می‌کند.

یک سرویس مدیریت مخزن (forge) این فایل را برای شما می‌نویسد و این تفاوت اصلی بین سطح 0 و سطح 2 است. Forgejo و Gitea فایل authorized_keys را با یک خط به ازای هر کلید ثبت‌شده بازنویسی می‌کنند که هر کدام شامل یک دستور اجباری است که کلید را با شناسه پایگاه‌داده‌اش مشخص می‌کند:

command="/usr/local/bin/forgejo --config=/etc/forgejo/app.ini serv key-3",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice

آن دستور اجباری روشی است که یک حساب کاربری یونیکس مشترک به مجوزهای اختصاصی هر کاربر تبدیل می‌شود: key-3 به سرویس مدیریت مخزن می‌گوید کدام کاربر در حال اتصال است و پیش از جابه‌جایی هرگونه آبجکت، دسترسی آن کاربر به مخزن را بررسی می‌کند. این فایل را در سروری که توسط یک forge مدیریت می‌شود به‌صورت دستی ویرایش نکنید، زیرا فایل از روی پایگاه‌داده بازنویسی می‌شود و خطی که اضافه کرده‌اید حذف خواهد شد. کلیدهای deploy نیز از همین مکانیزم استفاده می‌کنند: یک deploy key یک کلید SSH معمولی است که برای یک مخزن واحد ثبت شده و معمولاً فقط‌خواندنی است؛ در این حالت بررسی دسترسی به‌جای sshd، در داخل خودِ forge انجام می‌شود.

دو عادت از هر پیکربندی دیگری مهم‌تر هستند. برای هر شخص یا هر دستگاه یک کلید اختصاصی صادر کنید و هرگز از کلید مشترک استفاده نکنید، زیرا ابطال یک کلید مشترک به معنای تعویض آن برای همه افراد به‌طور همزمان است. همچنین کلیدها را در همان روزی که شخصی سازمان را ترک می‌کند حذف کنید، زیرا یک کلید قدیمی در آن فایل، یک راه ورود دائمی است که هیچ‌کس بر آن نظارت ندارد. مدیریت صحیح کلیدهای SSH روی سرور انواع کلیدها و عبارات عبور (passphrase) را پوشش می‌دهد و تمام موارد آن در اینجا نیز بدون تغییر صدق می‌کند. اگر سرور جدید است، ده دقیقه اول روی یک VPS جدید کاری است که باید پیش از قرار دادن مخازن روی آن انجام دهید.

آیا می‌توانم GitHub Actions را روی سرور Git شخصی خود اجرا کنم؟

شما می‌توانید workflowهایی را که با سینتکس GitHub Actions نوشته شده‌اند، اجرا کنید. اما امکان اجرای خودِ GitHub وجود ندارد. قابلیت Forgejo Actions از نسخه Forgejo v1.21 به‌صورت پیش‌فرض فعال شده است و فایل‌های workflow را از مسیر .forgejo/workflows در هر مخزن (repository) می‌خواند. Gitea Actions نیز به همین شیوه عمل می‌کند و فایل‌ها را از .gitea/workflows می‌خواند. هر دو سیستم به یک برنامه جانبی به نام runner نیاز دارند که باید نصب شده و با استفاده از توکنی که از تنظیمات مدیریتی دریافت می‌شود، در instance شما ثبت گردد. بسیاری از actionهای منتشرشده بدون تغییر اجرا می‌شوند؛ اما هر چیزی که GitHub API را فراخوانی کند یا انتظار زیرساخت‌های میزبانی‌شده توسط GitHub را داشته باشد، کار نخواهد کرد.

دو پیامد را در نظر بگیرید. runner برای هر job یک container راه‌اندازی می‌کند، بنابراین به یک موتور container و بودجه حافظه (RAM) اختصاصی نیاز دارد؛ به همین دلیل نباید آن را روی همان سرور 1 GB که forge روی آن قرار دارد، نصب کرد. همچنین، runner هر دستوری را که در فایل workflow نوشته شده باشد اجرا می‌کند؛ مستندات Forgejo به‌صراحت بیان می‌کنند که runner در واقع اجرای کد از راه دور (remote code execution) را انجام می‌دهد. تا حد امکان آن را روی یک میزبان (host) مجزا قرار دهید، یا حداقل از یک کاربر بدون دسترسی‌های ویژه (unprivileged user) و یک توکن ثبت که محدود به یک مخزن خاص است، استفاده کنید.

اگر مخازن شما در GitHub باقی می‌مانند و فقط می‌خواهید پردازش روی سخت‌افزار تحت کنترل شما انجام شود، این یک سناریوی متفاوت با مراحل جداگانه است: یک runner خودمیزبان برای GitHub Actions به یک مخزن GitHub متصل می‌شود و به هیچ‌کدام از این تنظیمات نیاز ندارد. اگر هنوز در حال بررسی هزینه‌های خروج از GitHub هستید، آنچه GitHub واقعاً به شما ارائه می‌دهد تفاوت بین میزبانی Git و شبکه پیرامون آن را مشخص می‌کند.

پشتیبان‌گیری: مخازن تنها نیمی از وضعیت هستند

یک مخزن bare در واقع یک دایرکتوری است، بنابراین کپی کردن آن، تمام محتویاتش را کپی می‌کند. یک mirror clone از دستگاهی دیگر، یک پشتیبان واقعی محسوب می‌شود و به‌صورت درجا به‌روزرسانی می‌گردد:

git clone --mirror git@vps.example.com:/srv/git/project.git
cd project.git && git remote update

این دستور تمام refها و تمام objectها را دریافت می‌کند. این دستور hookهای سمت سرور یا فایل description را دریافت نمی‌کند، بنابراین اگر از hookها استفاده می‌کنید، یک کپی در سطح فایل از دایرکتوری نیز تهیه کنید.

یک سرویس میزبانی کد (forge)، مسائل (issues)، درخواست‌های ادغام (pull requests)، کاربران، کلیدها و مجوزها را در پایگاه‌داده خود نگه می‌دارد و کپی کردن صرفِ مخازن، تمام این موارد را از دست می‌دهد. هر دو پروژه یک دستور dump ارائه می‌دهند که پایگاه‌داده، مخازن، پیکربندی و پیوست‌ها را در یک آرشیو می‌نویسد:

sudo -u git forgejo dump -c /etc/forgejo/app.ini -f /var/backups/forgejo-dump.zip

در Docker، همین دستور داخل کانتینر اجرا می‌شود و مسیر پیکربندی به image بستگی دارد، بنابراین پیش از تایپ کردن بررسی کنید:

docker compose exec server ls /data/gitea/conf
docker compose exec -u git server forgejo dump -c /data/gitea/conf/app.ini

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

انتخاب بر اساس سناریو

یک نفر با یک لپ‌تاپ و یک VPS، بدون نیاز به مرورگر: استفاده از مخازن bare روی SSH. هیچ سرویس اضافه‌ای در حال اجرا نیست و نیازی به به‌روزرسانی وجود ندارد.

همان سناریو، به‌علاوه نیاز به خواندن کد در مرورگر و ارسال لینک به آن: اضافه کردن cgit. همچنان بدون پایگاه داده و بدون سرویس‌های مقیم در حافظه.

یک تیم که کدهای یکدیگر را بازبینی کرده و مشکلات (issues) را پیگیری می‌کنند: استفاده از Forgejo یا Gitea، با حداقل 2 GB رم یا بیشتر. پس از سنگین شدن پردازش‌ها، CI runner را به یک سرور دوم منتقل کنید.

یک سازمان که به container registry و مسیرهای حسابرسی (audit trails) نیاز دارد، با بودجه 16 GB رم برای سرور: GitLab. با بودجه کمتر از این مقدار، آن را راه‌اندازی نکنید.

ارتقا در سه سطح اول ارزان است، زیرا در همه آن‌ها مخازن، دایرکتوری‌های معمولی Git روی دیسک هستند. از پایین‌ترین سطحی که نیاز شما را برطرف می‌کند شروع کنید. اگر در حال بررسی این هستید که چه سرویس‌های دیگری ارزش فضای سرور شما را دارند، فهرست کوتاه سرویس‌های مناسب برای self-hosting یک سرور Git را در کنار سایر سرویس‌هایی که برای تصاحب آن رم رقابت می‌کنند، قرار می‌دهد.

FAQ

آیا یک VPS با 1 GB رم می‌تواند Forgejo یا Gitea را اجرا کند؟

بله، برای یک تیم کوچک، با استفاده از SQLite و در صورتی که هیچ سرویس سنگین دیگری روی سرور نباشد. مستندات Gitea بیان می‌کنند که 1 GB رم و 2 هسته CPU معمولاً برای تیم‌ها و پروژه‌های کوچک کافی است؛ Forgejo نیز انشعابی (fork) از Gitea است و ساختار مشابهی دارد. PostgreSQL یا CI runner را به این ماشین اضافه نکنید. اگر سرویس بدون ثبت هیچ خطایی در لاگ خود ناپدید شد، دستور sudo dmesg -T | grep -i oom را اجرا کنید: مشاهده نام پردازش در خروجی به این معناست که OOM Killer هسته سیستم‌عامل آن را متوقف کرده است؛ در این صورت، راهکار ارتقای پلن سرور است، نه تغییر فلگ‌های تنظیمات.

تفاوت Forgejo و Gitea در چیست؟

آن‌ها تاریخچه کد منبع و اکثر قابلیت‌های یکسانی دارند. Gitea در سال 2016 از Gogs منشعب شد و Forgejo در اواخر سال 2022، پس از آنکه کنترل علامت تجاری Gitea به یک شرکت واگذار شد، از Gitea انشعاب یافت. Forgejo توسط Codeberg e.V.، یک سازمان غیرانتفاعی در آلمان، تحت مجوز GPLv3 منتشر می‌شود؛ در حالی که Gitea با مجوز MIT و پشتیبانی تجاری باقی مانده است. تفاوت عملی در مسیر مهاجرت است. نسخه Forgejo v10.0 که در ژانویه 2025 منتشر شد، آخرین نسخه‌ای بود که می‌توانست دیتابیس Gitea را مستقیماً بپذیرد (آن هم فقط از Gitea v1.22 یا قدیمی‌تر)؛ بنابراین، نمونه‌های فعلی Gitea مسیر مهاجرت مستقیم و پشتیبانی‌شده‌ای ندارند.

آیا می‌توانم ورک‌فلوهای GitHub Actions را روی یک سرور Git شخصی اجرا کنم؟

Forgejo Actions و Gitea Actions هر دو ورک‌فلوهای نوشته‌شده با سینتکس YAML در GitHub Actions را که از مسیرهای .forgejo/workflows و .gitea/workflows خوانده می‌شوند، اجرا می‌کنند. شما باید یک برنامه runner جداگانه نصب کرده و آن را در نمونه (instance) خود ثبت کنید. بسیاری از اکشن‌های منتشرشده بدون تغییر کار می‌کنند، اما مواردی که از API گیت‌هاب استفاده می‌کنند، خیر. این runner کدهای دلخواه را از مخازن شما اجرا کرده و برای هر job یک کانتینر جداگانه می‌سازد؛ بنابراین آن را روی یک میزبان مجزا یا حداقل با یک کاربر بدون دسترسی‌های ویژه (unprivileged) اجرا کنید و از قرار دادن آن روی سرور 1 GB که در حال اجرای خودِ سرویس Git است، خودداری کنید.

چگونه از یک سرور Git شخصی نسخه پشتیبان تهیه کنم؟

برای مخازن خام (bare repositories)، دستور git clone --mirror از یک ماشین دیگر تمام refها و objectها را کپی می‌کند و دستور git remote update در داخل آن mirror، محتوا را به‌روزرسانی می‌کند. برای Forgejo یا Gitea، مخازن تنها بخشی از وضعیت سیستم هستند، زیرا issues، pull requests، کاربران و کلیدها در دیتابیس ذخیره می‌شوند. از ابزار داخلی dump یعنی sudo -u git forgejo dump -c /etc/forgejo/app.ini استفاده کنید (یا همین دستور را در داخل کانتینر برای نصب‌های Docker اجرا کنید). آرشیو را از سرور خارج کنید و یک بار آن را روی یک ماشین یدکی بازیابی کنید تا از صحت فرآیند اطمینان حاصل شود.

#git#self-hosting#forgejo#gitea#ssh