نصب Git روی سرور و ساخت مخزن خصوصی با SSH

برای نصب Git روی سرور و داشتن یک مخزن خصوصی، فقط به SSH و بسته git نیاز دارید: Git را نصب می‌کنید، یک کاربر اختصاصی مثل git می‌سازید، کلید عمومی اعضای تیم را به آن اضافه می‌کنید و یک مخزن خالی از نوع bare می‌سازید. بعد هر کسی با git clone git@آدرس-سرور:/srv/git/project.git کد را می‌گیرد و push می‌کند. این روش بدون هیچ پنل اضافه‌ای کار می‌کند و برای تیم‌های کوچک و پروژه‌هایی که نمی‌خواهند کدشان روی سرویس خارجی باشد، کافی است.

اگر هنوز کلید SSH نساخته‌اید، ابتدا آموزش SSH Key را ببینید. تمام دستورها برای Ubuntu 22.04 و 24.04 نوشته شده‌اند و در Debian هم همین‌طورند.

مرحله اول: نصب Git روی سرور

sudo apt update
sudo apt install git
git --version

نسخه نصب‌شده را ببینید. برای ساخت مخزن با نام شاخه اصلی دلخواه (مثلاً main) به Git نسخه 2.28 به بعد نیاز دارید که در نسخه‌های جدید Ubuntu هست.

مرحله دوم: ساخت کاربر git

کاربر جداگانه باعث می‌شود دسترسی به کد از حساب مدیر سرور جدا بماند:

sudo adduser --disabled-password --gecos "" git
sudo -u git mkdir -p /home/git/.ssh
sudo -u git chmod 700 /home/git/.ssh
sudo -u git touch /home/git/.ssh/authorized_keys
sudo -u git chmod 600 /home/git/.ssh/authorized_keys

کلید عمومی هر عضو تیم را در یک خط به authorized_keys اضافه کنید:

echo "ssh-ed25519 AAAA... alice@laptop" | sudo -u git tee -a /home/git/.ssh/authorized_keys

برای اینکه این کاربر فقط بتواند کارهای Git انجام دهد و وارد شل کامل نشود، شل آن را به git-shell تغییر دهید:

sudo chsh -s $(which git-shell) git

اگر فایل git-shell در /etc/shells نیست، ابتدا مسیر آن را اضافه کنید: which git-shell | sudo tee -a /etc/shells.

مرحله سوم: ساخت مخزن bare

مخزن bare فقط تاریخچه را نگه می‌دارد و پوشه کاری ندارد؛ برای سرور مرکزی همین لازم است:

sudo mkdir -p /srv/git/project.git
sudo git init --bare --initial-branch=main /srv/git/project.git
sudo chown -R git:git /srv/git

مسیر /srv/git نمونه است. مخازن را در هر پوشه دلخواه می‌توانید نگه دارید، به شرط اینکه کاربر git به آن دسترسی داشته باشد.

مرحله چهارم: clone و push از کامپیوتر خودتان

git clone git@203.0.113.10:/srv/git/project.git
cd project
echo "hello" > README.md
git add README.md
git commit -m "first commit"
git push origin main

آدرس نمونه است. اگر از پورت غیراستاندارد SSH استفاده می‌کنید: git clone ssh://git@203.0.113.10:2222/srv/git/project.git. برای مخزنی که از قبل روی کامپیوتر دارید:

git remote add origin git@203.0.113.10:/srv/git/project.git
git push -u origin main

محدود کردن دسترسی هر عضو

در authorized_keys می‌توان برای هر کلید محدودیت گذاشت تا حتی با کلید معتبر، فقط کار Git انجام شود:

restrict ssh-ed25519 AAAA... alice@laptop

گزینه restrict فوروارد پورت، X11 و agent را می‌بندد. برای حذف دسترسی یک نفر، فقط خط کلیدش را پاک کنید. اگر تعداد اعضا زیاد است یا به مدیریت دسترسی ریزتر (فقط خواندن برای بعضی افراد) نیاز دارید، ابزارهایی مثل Gitolite یا Gitea بهتر از دستی نگه داشتن کلیدها هستند.

استقرار خودکار با hook

در مخزن bare پوشه hooks هست. فایل post-receive بعد از هر push اجرا می‌شود؛ می‌توان کد را در پوشه سایت به‌روز کرد:

#!/bin/bash
TARGET=/var/www/example.com
GIT_DIR=/srv/git/project.git
while read oldrev newrev ref; do
  if [ "$ref" = "refs/heads/main" ]; then
    git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f main
  fi
done

فایل را اجرایی کنید (chmod +x) و مطمئن شوید کاربر git به پوشه مقصد دسترسی نوشتن دارد. این روش برای سایت‌های ساده خوب است؛ برای برنامه‌های بزرگ‌تر، فرآیند CI/CD جدا بهتر است. دسترسی‌ها را بر اساس مدیریت دسترسی در لینوکس تنظیم کنید و به فایل‌های پروژه، دسترسی بیش از لازم ندهید.

بکاپ از مخازن

مخزن bare فقط یک پوشه است و با rsync یا tar قابل بکاپ است:

sudo tar czf /backup/git-$(date +%F).tar.gz -C /srv git

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

خطاهای رایج

پیامعلت و راه حل
Permission denied (publickey)کلید در authorized_keys کاربر git نیست یا دسترسی .ssh درست نیست
fatal: '/srv/git/project.git' does not appear to be a git repositoryمسیر اشتباه است یا مخزن ساخته نشده
fatal: detected dubious ownershipمالک پوشه کاربر دیگری است؛ chown به git یا safe.directory
git-shell اجازه ورود شل نمی‌دهدرفتار درست است؛ برای مدیریت با کاربر دیگری وارد شوید
push رد می‌شود (non-fast-forward)ابتدا pull بگیرید یا تاریخچه را همگام کنید
hook اجرا نمی‌شودفایل اجرایی نیست یا مسیر بالای shebang اشتباه است

سوالات متداول

فرق مخزن bare و معمولی چیست؟

مخزن معمولی پوشه کاری و پوشه .git دارد. مخزن bare فقط محتوای .git است و برای اشتراک‌گذاری مناسب است، چون push مستقیم به شاخه فعال مخزن معمولی مشکل ایجاد می‌کند.

آیا بدون SSH هم می‌شود؟

بله، با HTTP(S) از طریق وب‌سرور و Git Smart HTTP، ولی راه‌اندازی آن پیچیده‌تر است. برای تیم کوچک SSH ساده‌تر و امن‌تر است.

چطور از GitHub به سرور خودم منتقل کنم؟

یک clone با گزینه --mirror بگیرید و آن را با git push --mirror به مخزن جدید بفرستید.

آیا باید رابط وب داشته باشم؟

اگر می‌خواهید Pull Request و مدیریت Issue داشته باشید، نرم‌افزارهایی مثل Gitea یا GitLab لازم است. برای فقط نگه‌داری کد، همین راه‌اندازی کافی است.

منابع

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *