بلاگ/راه‌اندازی سرور گیت اختصاصی با Gitea روی سرور مجازی و اختصاصی
به‌روز شده

راه‌اندازی سرور گیت اختصاصی با Gitea روی سرور مجازی و اختصاصی

1405/06/190 بازدید
راه‌اندازی سرور گیت اختصاصی با Gitea روی سرور مجازی و اختصاصی

راه‌اندازی سرور گیت اختصاصی با Gitea روی سرور مجازی و اختصاصی

نمای کلی سرور گیت اختصاصی مبتنی بر Gitea برای میزبانی کدهای یک تیم همیشه لازم نیست مخزن‌ها را به سرویس‌هایی مانند GitHub یا GitLab بسپارید. با راه‌اندازی Gitea روی سرور می‌توانید مخزن‌های خصوصی، حساب‌های کاربران، کلیدهای SSH و دسترسی اعضای تیم را روی زیرساخت خودتان مدیریت کنید. Gitea یک سرویس سبک برای میزبانی Git است و امکاناتی مانند رابط وب، Pull Request، Issue، Webhook، مدیریت سازمان و احراز هویت دومرحله‌ای دارد. مصرف منابع آن نیز معمولاً از پلتفرم‌های بزرگ‌تر کمتر است؛ بنابراین برای تیم‌های کوچک و متوسط، پروژه‌های داخلی و محیط‌هایی که کنترل داده اهمیت دارد، گزینه مناسبی است. در این راهنما Gitea را با Docker Compose روی Ubuntu نصب می‌کنیم، PostgreSQL را به‌عنوان پایگاه داده در نظر می‌گیریم و با Nginx و گواهی رایگان Let’s Encrypt دسترسی HTTPS می‌سازیم. دستورها برای VPS و سرور اختصاصی یکسان‌اند.

انتخاب VPS یا سرور اختصاصی برای Gitea

نوع سرور را باید بر اساس تعداد کاربران، حجم مخزن‌ها، تعداد عملیات هم‌زمان و سرویس‌های جانبی انتخاب کنید. خود Gitea سبک است، اما Git LFS، رجیستری پکیج‌ها، Actions و تعداد زیاد عملیات clone یا push می‌توانند مصرف دیسک، شبکه و پردازنده را افزایش دهند. برای یک تیم کوچک با چند ده مخزن، یک VPS با ۲ هسته پردازنده، ۲ تا ۴ گیگابایت رم و فضای SSD معمولاً نقطه شروع مناسبی است. اگر فایل‌های حجیم نگه می‌دارید یا runnerهای CI را روی همان ماشین اجرا می‌کنید، منابع بیشتری لازم خواهید داشت.

نوع زیرساختکاربرد مناسبمزیت اصلیمحدودیت
سرور مجازیتیم کوچک، پروژه شخصی و محیط توسعههزینه کمتر و ارتقای ساده منابعمنابع پردازنده ممکن است اشتراکی باشد
سرور اختصاصیتیم بزرگ، مخزن‌های حجیم و بار زیادمنابع پایدار و کنترل کامل سخت‌افزارهزینه و مسئولیت نگهداری بیشتر
سرویس SaaS عمومیتیمی که مدیریت زیرساخت نمی‌خواهدشروع سریع و نگهداری کمترکنترل کمتر روی داده و محدودیت‌های سرویس‌دهنده

بهتر است runnerهای سنگین CI را از سرور اصلی Gitea جدا کنید. اجرای buildهای پرمصرف روی همان سرور می‌تواند پاسخ‌گویی رابط وب، عملیات Git و پایگاه داده را مختل کند.

پیش‌نیازهای نصب

در این آموزش فرض می‌کنیم موارد زیر آماده‌اند: - یک سرور Ubuntu 22.04 یا 24.04 با دسترسی کاربر دارای مجوز sudo - یک دامنه یا زیردامنه مانند git.example.com - رکورد DNS از نوع A که به IPv4 سرور اشاره می‌کند - دسترسی ورودی به پورت‌های 22، 80 و 443 - فضای ذخیره‌سازی کافی برای مخزن‌ها و نسخه‌های پشتیبان اگر سرور IPv6 دارد، رکورد AAAA را نیز فقط زمانی اضافه کنید که مسیر IPv6 و فایروال آن درست تنظیم شده باشد. وجود رکورد AAAA معیوب ممکن است دسترسی برخی کاربران و صدور گواهی را با مشکل مواجه کند. ابتدا بسته‌های سیستم را به‌روز کنید:

sudo apt update
sudo apt upgrade -y

سپس Docker و افزونه Compose را از مخزن Ubuntu نصب کنید:

sudo apt install -y docker.io docker-compose-v2 nginx certbot python3-certbot-nginx
sudo systemctl enable --now docker nginx

برای اطمینان از نصب صحیح، نسخه ابزارها را ببینید:

docker --version
docker compose version
nginx -v

ساخت ساختار پروژه و فایل Docker Compose

برای نگهداری تنظیمات، یک مسیر مشخص بسازید. در این نمونه تمام فایل‌های اجرایی در /opt/gitea قرار می‌گیرند:

sudo mkdir -p /opt/gitea
sudo chown "$USER":"$USER" /opt/gitea
cd /opt/gitea

رمز پایگاه داده را با یک مقدار طولانی و تصادفی جایگزین کنید. بهتر است متغیرهای حساس را در فایل .env نگه دارید:

nano .env

محتوای نمونه:

POSTGRES_DB=gitea
POSTGRES_USER=gitea
POSTGRES_PASSWORD=replace-with-a-long-random-password

دسترسی فایل را محدود کنید:

chmod 600 .env

اکنون فایل compose.yaml را بسازید:

services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - gitea-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
  server:
    image: gitea/gitea:1
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      USER_UID: "1000"
      USER_GID: "1000"
      GITEA__database__DB_TYPE: postgres
      GITEA__database__HOST: db:5432
      GITEA__database__NAME: ${POSTGRES_DB}
      GITEA__database__USER: ${POSTGRES_USER}
      GITEA__database__PASSWD: ${POSTGRES_PASSWORD}
      GITEA__server__DOMAIN: git.example.com
      GITEA__server__ROOT_URL: https://git.example.com/
      GITEA__server__SSH_DOMAIN: git.example.com
      GITEA__server__SSH_PORT: "2222"
      GITEA__server__START_SSH_SERVER: "true"
      GITEA__security__INSTALL_LOCK: "true"
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "2222:22"
    networks:
      - gitea-network
volumes:
  gitea-data:
  postgres-data:
networks:
  gitea-network:

مقادیر git.example.com را با دامنه واقعی خود جایگزین کنید. اتصال پورت 3000 فقط روی 127.0.0.1 باعث می‌شود رابط وب Gitea مستقیماً از اینترنت در دسترس نباشد و درخواست‌ها از Nginx عبور کنند. در این پیکربندی، SSH داخلی Gitea از پورت 2222 میزبان استفاده می‌کند؛ زیرا پورت 22 معمولاً در اختیار سرویس SSH سیستم‌عامل است. کاربران در این حالت مخزن را با نشانی مشابه زیر دریافت می‌کنند:

git clone ssh://git@git.example.com:2222/team/project.git

پورت 2222 را در فایروال باز کنید (برای پیکربندی دقیق‌تر قوانین، به راه‌اندازی فایروال nftables روی سرور لینوکس نگاه کنید):

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw allow 2222/tcp
sudo ufw enable

قبل از فعال‌کردن UFW مطمئن شوید قانون OpenSSH اضافه شده است؛ در غیر این صورت ممکن است نشست مدیریتی بعدی به سرور برقرار نشود.

اجرای Gitea و ساخت حساب مدیر

سرویس‌ها را اجرا کنید:

cd /opt/gitea
docker compose up -d

وضعیت کانتینرها را بررسی کنید:

docker compose ps
docker compose logs --tail=100 server

ارتباط کانتینر Gitea با PostgreSQL و پراکسی Nginx در پشت سرور وب به‌دلیل فعال‌بودن INSTALL_LOCK، نصب تعاملی وب غیرفعال است. حساب مدیر را از داخل کانتینر ایجاد کنید:

docker compose exec -u git server gitea admin user create \
  --username admin \
  --password 'replace-with-another-strong-password' \
  --email admin@example.com \
  --admin \
  --must-change-password

استفاده مستقیم از رمز در خط فرمان ممکن است آن را در تاریخچه پوسته نگه دارد. پس از ساخت حساب، دستور مربوط را از history حذف کنید یا حساب مدیر را با روش تعاملی و ملاحظات امنیتی محیط خود بسازید.

پیکربندی Nginx به‌عنوان Reverse Proxy

یک فایل تنظیمات برای دامنه Gitea ایجاد کنید:

sudo nano /etc/nginx/sites-available/gitea

تنظیم اولیه HTTP:

server {
    listen 80;
    listen [::]:80;
    server_name git.example.com;
    client_max_body_size 512M;
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300;
    }
}

مقدار client_max_body_size سقف اندازه بدنه درخواست در Nginx است. آن را متناسب با سیاست مخزن‌ها و Git LFS تنظیم کنید؛ عدد بزرگ‌تر به‌تنهایی محدودیت‌های دیگر Gitea یا شبکه را تغییر نمی‌دهد. برای تنظیمات تکمیلی worker و timeout می‌توانید به بهینه‌سازی Nginx هم مراجعه کنید. سایت را فعال و تنظیمات را آزمایش کنید:

sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/gitea
sudo nginx -t
sudo systemctl reload nginx

اکنون باید رابط Gitea از طریق http://git.example.com باز شود. اگر خطای 502 دریافت می‌کنید، ابتدا خروجی docker compose ps و سپس لاگ‌های کانتینر Gitea و Nginx را بررسی کنید.

فعال‌کردن HTTPS رایگان

بعد از انتشار رکورد DNS و دسترسی صحیح دامنه روی پورت 80، گواهی TLS را با Certbot دریافت کنید:

sudo certbot --nginx -d git.example.com

Certbot گواهی را دریافت می‌کند، تنظیمات Nginx را تغییر می‌دهد و امکان انتقال HTTP به HTTPS را پیشنهاد می‌کند. وضعیت تمدید خودکار را با این دستور آزمایش کنید:

sudo certbot renew --dry-run

پس از فعال‌شدن HTTPS، وارد پنل شوید و در بخش تنظیمات سرور بررسی کنید که URL عمومی با https://git.example.com/ یکسان باشد. مقدار نادرست ROOT_URL می‌تواند لینک‌های اعلان، callbackها، clone URL و تغییر مسیر ورود را خراب کند.

افزودن کلید SSH و ساخت اولین مخزن

روی رایانه کاربر یک کلید Ed25519 بسازید؛ اگر کلید مناسبی از قبل دارید، نیازی به ساخت دوباره نیست:

ssh-keygen -t ed25519 -C "developer@example.com"

محتوای کلید عمومی را نمایش دهید:

cat ~/.ssh/id_ed25519.pub

کلید عمومی را در Gitea از مسیر تنظیمات حساب و بخش SSH/GPG Keys اضافه کنید. سپس ارتباط را آزمایش کنید:

ssh -T -p 2222 git@git.example.com

برای انتقال یک پروژه موجود به مخزن تازه:

cd existing-project
git remote add origin ssh://git@git.example.com:2222/team/project.git
git push -u origin main

اگر شاخه اصلی پروژه master یا نام دیگری دارد، همان نام را در دستور push وارد کنید.

تنظیمات امنیتی پس از نصب

در دسترس قرارگرفتن صفحه ورود پایان کار نیست. برای کاهش ریسک، ثبت‌نام عمومی را غیرفعال کنید و حساب‌ها را مدیر سیستم بسازد. همچنین احراز هویت دومرحله‌ای را برای مدیران و کاربران دارای دسترسی حساس فعال کنید. چند اقدام عملی دیگر عبارت‌اند از: - دسترسی مدیریتی SSH سرور را به کلید عمومی محدود کنید (جزئیات کامل‌تر در امن‌سازی دسترسی SSH به سرور لینوکس). - ورود مستقیم کاربر root و ورود با رمز را پس از آزمایش کلید SSH ببندید. - Docker، سیستم‌عامل، Nginx، PostgreSQL و تصویر Gitea را منظم به‌روزرسانی کنید. - دسترسی سازمان‌ها و مخزن‌ها را بر پایه حداقل مجوز لازم تعریف کنید. - برای تلاش‌های مکرر ورود، ابزارهایی مانند Fail2ban یا محدودسازی نرخ در پراکسی را بررسی کنید. - Gitea Actions را فقط در صورت نیاز فعال کنید و runner را یک محیط قابل اعتماد فرض نکنید. Runner کد workflow را اجرا می‌کند. اگر کاربران غیرقابل اعتماد اجازه تغییر workflow داشته باشند، اجرای runner روی همان میزبان Gitea می‌تواند دامنه آسیب را بیشتر کند. جداسازی runner در ماشین یا شبکه‌ای مستقل انتخاب امن‌تری است؛ برای نمونه‌ای از راه‌اندازی یک runner خودمیزبان جدا، به راه‌اندازی GitLab Runner خودمیزبان روی سرور مجازی و اختصاصی نگاه کنید.

نسخه پشتیبان و بازیابی

مخزن گیت تنها بخش داده نیست. حساب‌ها، Issueها، Pull Requestها، Webhookها و تنظیمات در پایگاه داده و مسیر داده Gitea نگهداری می‌شوند. بنابراین کپی‌کردن پوشه repositoryها به‌تنهایی نسخه پشتیبان کامل نمی‌سازد. اگر می‌خواهید در دسترس‌بودن پایگاه داده را هم فراتر از بکاپ دوره‌ای تضمین کنید، راه‌اندازی Replication و Failover خودکار در PostgreSQL را ببینید. برای تهیه خروجی منطقی از PostgreSQL می‌توانید از دستور زیر استفاده کنید:

cd /opt/gitea
docker compose exec -T db pg_dump \
  -U gitea \
  -d gitea > gitea-database.sql

علاوه بر پایگاه داده، از volume مربوط به gitea-data نیز نسخه پشتیبان بگیرید. روش دقیق آن به ابزار بکاپ و محل ذخیره‌سازی شما بستگی دارد. فایل‌های پشتیبان را روی همان دیسک سرور نگه ندارید؛ خرابی دیسک یا حذف سرور می‌تواند نسخه اصلی و بکاپ را هم‌زمان از بین ببرد. بازیابی را دوره‌ای روی یک سرور آزمایشی تمرین کنید. بکاپی که فرایند restore آن آزمایش نشده باشد، تضمینی برای بازگشت سرویس نیست. بهتر است دوره نگهداری، رمزنگاری فایل‌ها و زمان قابل‌قبول بازیابی نیز از قبل مشخص شود.

به‌روزرسانی Gitea با وقفه کنترل‌شده

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

cd /opt/gitea
docker compose pull
docker compose up -d
docker compose logs -f --tail=100 server

استفاده از برچسب کلی 1 ارتقاهای همان شاخه اصلی را دریافت می‌کند. برای کنترل بیشتر می‌توانید نسخه دقیق تصویر را در فایل Compose ثبت کنید و پس از آزمایش، آن را مرحله‌به‌مرحله تغییر دهید. این روش بازتولید محیط و بررسی تغییرات را ساده‌تر می‌کند.

خطاهای رایج در راه‌اندازی Gitea روی سرور

خطای 502 Bad Gateway معمولاً یعنی Nginx به پورت 3000 دسترسی ندارد یا کانتینر Gitea هنوز آماده نشده است. اتصال محلی را با دستور زیر آزمایش کنید:

curl -I http://127.0.0.1:3000

اگر clone از طریق SSH کار نمی‌کند، بازبودن پورت 2222 در فایروال، نگاشت پورت Docker و مقدار SSH_PORT را بررسی کنید. دستور ssh -v نیز جزئیات مذاکره اتصال و کلید انتخاب‌شده را نشان می‌دهد. اگر لینک‌ها به HTTP برمی‌گردند یا callback ورود اشتباه است، مقادیر ROOT_URL، DOMAIN و هدر X-Forwarded-Proto در Nginx را کنترل کنید. برای خطاهای push فایل‌های بزرگ نیز محدودیت Nginx، فضای آزاد دیسک، تنظیمات Git LFS و timeout پراکسی را جداگانه بررسی کنید.

جمع‌بندی

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