برای نصب 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 لازم است. برای فقط نگهداری کد، همین راهاندازی کافی است.





