Müşteri projelerinin kaynak kodunu üçüncü bir servisin diskinde tutmak istemiyorsan ya da özel depo sayısına göre ödediğin abonelik artık mantıklı gelmiyorsa, kendi Git sunucunu kurmanın vakti gelmiş demektir. Gitea tam olarak bunun için tasarlanmış: Go ile yazılmış tek bir ikili dosya, birkaç yüz megabayt bellekle çalışıyor ve GitHub'a çok benzeyen bir arayüz sunuyor.
Bu rehberde Gitea ile kendi Git sunucunu sıfırdan kuracağız. Docker Compose ile PostgreSQL'li sağlam bir kurulum yapacağız, ters vekil ve TLS'i doğru yapılandıracağız, konteyner kurulumlarının en can sıkıcı tarafı olan SSH erişimini çözeceğiz, güvenlik ayarlarını sıkılaştıracağız ve yedekleme ile güncelleme rutinini oturtacağız. Sonunda da CI/CD entegrasyonuna ve üretimde sık karşılaşılan tuzaklara bakacağız.
Neden Kendi Git Sunucun#
Kendi Git sunucunu kurmanın üç somut gerekçesi var. Veri sahipliği: kaynak kodu, sorun kayıtları ve çekme istekleri kendi diskinde durur; hangi ülkedeki hangi sunucuda olduğunu sen bilirsin. Maliyet öngörülebilirliği: kullanıcı ve depo başına ücretlendirme yerine sabit bir sunucu kirası ödersin, on kişilik bir ekipte fark ciddi olur. Ağ yakınlığı: CI sunucun, dağıtım hedefin ve Git sunucun aynı özel ağdaysa hem hız kazanırsın hem de dışarı hiç veri çıkmaz.
Karşılığında bir sorumluluk alırsın: sunucunun yedeği, güncellemesi ve erişilebilirliği artık senin işindir. Git sunucusu ekibin kritik altyapısıdır; çöktüğünde kimse iş yapamaz. Bu yüzden bu rehberde yedekleme bölümünü es geçme.
| Konu | Barındırılan (GitHub/GitLab.com) | Kendi Gitea sunucun |
|---|---|---|
| Aylık maliyet | Kullanıcı başına | Sabit sunucu kirası |
| Veri konumu | Sağlayıcıda | Senin sunucunda |
| Erişilebilirlik | Sağlayıcının sorumluluğu | Senin sorumluluğun |
| Yedek | Sağlayıcıda | Senin kurman gerekir |
| Özel ağ erişimi | Ek yapılandırma | Doğrudan |
| Kurulum süresi | Yok | Yarım gün |
Paylaşımlı hosting üzerinde çalışıyor ve tam bir Git sunucusu yerine yalnızca dağıtım için sürüm kontrolü istiyorsan, cPanel Git sürüm kontrolü yazısı daha hafif bir alternatif anlatıyor.
Kaynak İhtiyacı ve Kurulum Seçenekleri#
Gitea'nın en sevilen tarafı iştahının küçük olması. Beş on kişilik bir ekip için 1 çekirdek ve 1 GB bellek teknik olarak yeter; rahat çalışmak istersen 2 çekirdek ve 2 GB bellekli bir sunucu fazlasıyla iyi bir başlangıçtır. Asıl planlaman gereken disktir: depolarınız, yükledikleri dosyalar ve zamanla biriken Git nesneleri büyür.
Kurulum için üç yol var: ikili dosyayı doğrudan indirmek, dağıtımın paketini kullanmak ya da Docker ile kurmak. Docker'ı öneriyorum çünkü sürüm yükseltme ve geri alma tek etiket değişikliğine iner. Veritabanı tarafında ise varsayılan SQLite küçük ekipler için gerçekten yeterlidir, ama on kişiyi geçtiğinde ve CI sürekli webhook tetiklediğinde PostgreSQL'e geçmek daha sağlıklıdır — kurulumda baştan PostgreSQL seçmek, sonradan taşımaktan çok daha kolaydır.
Docker Compose ile Kurulum#
Aşağıdaki dosya Gitea'yı PostgreSQL ile birlikte ayağa kaldırır. Dikkat etmen gereken en kritik iki satır USER_UID/USER_GID ile SSH portudur; ikisini de aşağıda ayrıca açıklayacağım.
services:
gitea:
image: gitea/gitea:1
restart: unless-stopped
depends_on: [db]
environment:
USER_UID: "1000" # ana makinedeki dosya sahipliği
USER_GID: "1000"
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: db:5432
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: ${DB_PAROLA}
GITEA__server__DOMAIN: git.firmaniz.com
GITEA__server__ROOT_URL: https://git.firmaniz.com/
GITEA__server__SSH_DOMAIN: git.firmaniz.com
GITEA__server__SSH_PORT: "2222" # kullanıcılara duyurulan port
GITEA__service__DISABLE_REGISTRATION: "true"
volumes:
- gitea-veri:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "127.0.0.1:3000:3000" # arayüz, ters vekil arkasında
- "2222:22" # SSH doğrudan dışarı açık
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: gitea
POSTGRES_PASSWORD: ${DB_PAROLA}
POSTGRES_DB: gitea
volumes:
- gitea-db:/var/lib/postgresql/data
volumes:
gitea-veri:
gitea-db:
Parolayı yanına koyacağın .env dosyasında tut ve o dosyayı asla depoya ekleme. Güçlü bir değer üretmek için şifre üretici aracımızı kullanabilirsin.
# .env
DB_PAROLA=uzun-ve-rastgele-bir-deger
docker compose up -d
docker compose logs -f gitea | head -30
GITEA__bolum__ANAHTAR biçimindeki değişkenler doğrudan app.ini dosyasına yazılır; çift alt çizgi bölüm ayracıdır. Bu, yapılandırmayı Compose dosyasında tutmanın en temiz yoludur ve konteyner içine girip dosya düzenlemekten kurtarır. Compose dosyalarının yapısı konusunda derinleşmek istersen Docker Compose kullanımı yazısı iyi bir tamamlayıcı; kalıcı hacimlerin yönetimi için de Docker volume veri yönetimi yazısına bakabilirsin.
Ters Vekil ve TLS#
Arayüzü 127.0.0.1:3000 üzerinde tuttuk; dışarıya Nginx üzerinden HTTPS ile açacağız. Buradaki tek incelik yükleme boyutu sınırıdır: varsayılan Nginx sınırı 1 MB'dır ve büyük bir depo push edildiğinde ya da bir sürüm dosyası yüklendiğinde 413 hatası alırsın.
server {
listen 443 ssl;
server_name git.firmaniz.com;
ssl_certificate /etc/letsencrypt/live/git.firmaniz.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.firmaniz.com/privkey.pem;
# Büyük push ve dosya yüklemeleri için sınırı kaldır
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:3000;
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;
# Uzun süren git işlemleri kesilmesin
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
ROOT_URL değerinin buradaki adresle birebir aynı olması zorunludur; yanlış yazıldığında klon adresleri, webhook'lar ve OAuth geri dönüşleri hatalı üretilir ve sorunu bulmak zaman alır. Ters vekil seçimi konusunda kararsızsan Apache ve Nginx karşılaştırması yazısı iki seçeneği ayrıntılı ele alıyor.
SSH Erişimini Doğru Kurmak#
Konteyner kurulumlarının en çok sorun çıkaran tarafı burasıdır, çünkü sunucunun kendi SSH servisi zaten 22 portunu tutar. İki çözüm var ve ilkini öneririm.
Yöntem 1 — Farklı port (basit ve sağlam). Compose dosyasında yaptığımız gibi konteynerin 22 portunu ana makinede 2222'ye bağlarsın ve SSH_PORT değerini 2222 yaparsın. Gitea, klon adreslerini bu porta göre üretir. Kullanıcı tarafında ek ayar gerekmez ama adres biraz uzundur:
# Klon adresi bu biçimde olur
git clone ssh://[email protected]:2222/ekip/proje.git
# Kısaltmak isteyen kullanıcı ~/.ssh/config dosyasına ekler
# Host git.firmaniz.com
# Port 2222
# User git
Yöntem 2 — Ana makinenin SSH'ını kullanmak. Ana makinedeki sshd'yi Gitea'ya vekillik edecek biçimde yapılandırırsın. Standart 22 portunu kullanmanı sağlar ama kurulumu daha kırılgandır ve sunucunun SSH yapılandırmasına dokunmanı gerektirir. Ekstra bir kazanç sağlamadığı için çoğu kurulumda gereksizdir.
Hangi yöntemi seçersen seç, güvenlik duvarında ilgili portu açmayı unutma:
# firewalld kullanan dağıtımlarda
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
# Bağlantıyı test et (başarılı olursa Gitea karşılama mesajı döner)
ssh -T -p 2222 [email protected]
İlk Yapılandırma ve Güvenlik Sıkılaştırma#
Tarayıcıdan adrese gittiğinde Gitea bir kurulum ekranı gösterir; veritabanı bilgileri Compose'dan geldiği için çoğu alan doludur. Bu ekranda ilk yönetici hesabını mutlaka oluştur — atlarsan, kayıt olan ilk kullanıcı yönetici olur ve kayıt açık kaldıysa bu ciddi bir açıktır.
Kurulumdan sonra yapman gereken sıkılaştırmalar:
- Kaydı kapat.
DISABLE_REGISTRATION: "true"ayarını Compose dosyasına zaten koyduk. Ekibe kullanıcı eklemeyi yönetici panelinden yaparsın. - Depo görünürlüğü varsayılanını özel yap. Yeni depoların kazara herkese açık oluşmasını engeller.
- İki adımlı doğrulamayı zorunlu tut. En azından yönetici hesapları için.
- Webhook hedeflerini sınırla. Gitea, webhook gönderebileceği adresleri kısıtlayabilir; iç ağdaki servislere istek atılmasını engellemek istiyorsan bu listeyi daralt.
- Git LFS'i bilinçli aç. Büyük ikili dosyalar diskini beklenenden hızlı doldurur; ihtiyacın yoksa kapalı bırak.
- Yerleşik kayıt defteri ve paket depolarını kapat. Kullanmıyorsan saldırı yüzeyini gereksiz büyütürler.
Sunucunun genel sıkılaştırması da bu işin parçası: SSH'ta parola girişini kapat, güvenlik duvarını yalnızca 80, 443 ve seçtiğin SSH portlarına aç, otomatik güvenlik güncellemelerini etkinleştir. Kaynak kodunun yanlışlıkla yayına açılmasının ne kadar hızlı istismar edildiğini görmek istersen .git klasörü ve .env dosyası ifşası yazısı iyi bir hatırlatma.
Yedekleme ve Güncelleme#
Git sunucusu ekibin en kritik altyapısıdır ve yedeği olmayan bir kurulum, bir gün mutlaka acı bir ders verir. Yedeklemen gereken üç şey var: depoların bulunduğu veri dizini, veritabanı ve yapılandırma dosyası.
Gitea'nın kendi yedek komutu üçünü tek arşivde toplar:
# Konteyner içinden yedek al (git kullanıcısıyla çalıştırılmalı)
docker compose exec -u git gitea gitea dump -c /data/gitea/conf/app.ini -f /data/yedek.zip
# Arşivi ana makineye kopyala
docker compose cp gitea:/data/yedek.zip ./gitea-$(date +%F).zip
Büyük kurulumlarda gitea dump yavaş kalabilir; alternatif olarak veritabanını pg_dump ile, depo dizinini de rsync ile ayrı ayrı yedekleyebilirsin. Hangi yöntemi seçersen seç iki kural geçerlidir: yedeği başka bir makinede sakla ve yılda en az bir kez gerçekten geri yükle. Test edilmemiş yedek, yedek sayılmaz. Konteynerli uygulamalarda yedekleme ve geri yükleme yöntemleri için Docker uygulama yedekleme ve geri yükleme yazısına bakabilirsin.
Güncelleme, Docker kurulumunda oldukça sadedir ama sırayı bozma:
# 1) Önce yedek al
# 2) Yeni imajı çek ve yeniden oluştur
docker compose pull
docker compose up -d
# 3) Log'ları izle: veritabanı göçleri burada çalışır
docker compose logs -f gitea
Majör sürüm atlarken sürüm notlarını okumak şart; Gitea zaman zaman yapılandırma anahtarlarını taşır ve göçler geri alınamaz. Bu yüzden gitea/gitea:1 gibi majör sürüme sabitlenmiş bir etiket kullanmak, latest kullanmaktan çok daha güvenlidir.
CI/CD ve Diğer Araçlarla Entegrasyon#
Gitea'yı kurduktan sonraki doğal adım, push'ta test ve dağıtım çalıştırmaktır. Üç seçeneğin var. Gitea'nın yerleşik Actions desteği, GitHub Actions'a çok benzeyen bir söz dizimi kullanır ve ayrı bir sunucu kurmadan çalışır; yalnızca bir runner kaydetmen gerekir. İkinci seçenek Woodpecker CI, üçüncüsü Drone CI — ikisi de Gitea ile OAuth üzerinden entegre olur ve kurulumları birer Compose dosyasına iner.
Hangisini seçersen seç, Gitea tarafında yapman gereken tek şey bir OAuth uygulaması oluşturmaktır: Ayarlar → Uygulamalar → OAuth2 Uygulamaları yolundan CI aracının beklediği geri dönüş adresini girersin. Webhook'lar depo etkinleştirildiğinde otomatik kurulur.
Yerleşik Actions'ı kullanacaksan runner'ı ayrı bir konteyner olarak çalıştırırsın ve .gitea/workflows/ dizinindeki YAML dosyaları GitHub Actions söz dizimine çok yakındır — bu, GitHub Actions ile CI/CD kurulumu yazısındaki bilgilerin doğrudan buraya taşınabileceği anlamına gelir.
Sık Yapılan Hatalar ve Tuzaklar#
ROOT_URL değerini yanlış vermek. Klon adresleri, webhook'lar ve OAuth geri dönüşleri bu değerden üretilir. Ters vekilde HTTPS varsa https:// ile başlamalı ve sondaki eğik çizgi olmalıdır.
client_max_body_size sınırını unutmak. Nginx varsayılanı 1 MB'dır; büyük bir depoyu push ederken 413 hatası alırsın ve hata Git tarafında anlaşılmaz görünür.
USER_UID/USER_GID uyuşmazlığı. Bind mount kullanıyorsan ve bu değerler ana makinedeki dosya sahibiyle uyuşmuyorsa Gitea veri dizinine yazamaz. Adlandırılmış volume kullanmak bu sorunu tamamen ortadan kaldırır.
SSH portunu duyurmayı unutmak. Konteynerde 2222'ye bağlayıp SSH_PORT değerini güncellemezsen, arayüzdeki klon adresi 22 portunu gösterir ve kullanıcılar bağlanamaz.
Yedeği aynı sunucuda tutmak. Disk arızasında hem depoları hem yedeği aynı anda kaybedersin. Yedeği farklı bir makineye ya da nesne deposuna gönder.
latest etiketiyle çalışmak. Bir sabah gelen majör sürüm, geri alınamayan bir veritabanı göçüyle birlikte gelebilir. Majör sürüme sabitlenmiş etiket kullan ve yükseltmeleri planlı yap.
Disk izlemeyi atlamak. Depolar, LFS nesneleri ve CI artefaktları sessizce büyür. Disk kullanımını izleyen basit bir uyarı kurmak, sunucunun bir gece dolmasını önler.
Sıkça Sorulan Sorular#
Gitea ücretsiz mi#
Evet, Gitea MIT lisansıyla dağıtılan tamamen açık kaynak bir projedir. Kullanıcı sayısı, depo sayısı veya özel depo adedi için hiçbir ücret ödemezsin. Tek maliyetin çalıştığı sunucudur. Kurumsal destek isteyenler için ticari paketler sunan sağlayıcılar var, ancak yazılımın kendisi her zaman ücretsizdir.
Gitea için ne kadar sunucu gerekir#
Beş on kişilik bir ekip için 1 çekirdek ve 1 GB bellek teknik olarak yeterlidir; 2 çekirdek ve 2 GB ile rahat çalışırsın. Asıl planlaman gereken disktir ve depo sayısına, dosya boyutlarına ve LFS kullanımına göre değişir. CI sunucusunu aynı makinede çalıştıracaksan kaynağı en az iki katına çıkarmanı öneririm; derlemeler Git servisini yavaşlatmamalı.
SQLite mi PostgreSQL mi kullanmalıyım#
Birkaç kişilik bir ekipte SQLite gerçekten yeterlidir ve kurulumu en basit seçenektir. Ancak on kişiyi geçtiğinde, CI sürekli webhook tetiklediğinde ve çok sayıda eşzamanlı işlem olduğunda SQLite'ın yazma kilidi darboğaz yaratır. Baştan PostgreSQL seçmek, sonradan taşımaktan çok daha kolaydır; kurulum maliyeti de Compose dosyasına birkaç satır eklemekten ibarettir.
GitHub'dan Gitea'ya nasıl geçerim#
Gitea'nın arayüzünde depo taşıma (migration) özelliği vardır: kaynak deponun adresini ve bir erişim token'ını verirsin, Gitea depoyu klonlar ve isteğe bağlı olarak sorun kayıtlarını, etiketleri, sürümleri ve çekme isteklerini de aktarır. Aktarımın kapsamı kaynağa göre değişir; GitHub'dan gelen taşımalarda sorun ve çekme isteği geçmişi genellikle aktarılabilir. Taşımadan sonra ekibin uzak adresleri güncellemesi gerekir.
Gitea ile CI/CD nasıl kurarım#
Üç seçeneğin var. Gitea'nın yerleşik Actions desteği GitHub Actions'a çok benzer bir söz dizimi kullanır ve yalnızca bir runner kaydetmeni gerektirir. Alternatif olarak Woodpecker CI ya da Drone CI kurabilirsin; ikisi de Gitea ile OAuth üzerinden entegre olur ve pipeline tanımını deponun içinde tutar. Küçük ekipler için yerleşik Actions en az bileşen gerektiren yoldur.
Gitea'yı nasıl güncellerim#
Docker ile kurduysan docker compose pull ve docker compose up -d komutları yeterlidir; veritabanı göçleri konteyner açılışında otomatik çalışır. Ama güncellemeden önce mutlaka yedek al, çünkü göçler geri alınamaz. Majör sürüm atlarken sürüm notlarını oku; yapılandırma anahtarları zaman zaman taşınır. latest yerine majör sürüme sabitlenmiş bir etiket kullanmak, beklenmedik yükseltmeleri önler.
Kapanış#
Kendi Git sunucunu işletmek düşündüğünden kolay ama sorumluluğu gerçek. Sağlam bir Gitea kurulumu için şu beşine dikkat et: ROOT_URL ve SSH_PORT değerlerini gerçek erişim adresleriyle birebir uyumlu tut, ters vekilde client_max_body_size sınırını kaldır, kayıt olmayı kapatıp kullanıcıları elle ekle, imaj etiketini majör sürüme sabitle ve düzenli yedeği başka bir makinede sakla — yılda bir kez de gerçekten geri yükleyerek test et.
Gitea'yı barındırmak için tam root erişimli VDS ya da ihtiyacın büyüdükçe genişleyen bulut sunucu paketlerimiz uygun bir zemin sunuyor; CI sunucusunu ayrı tutmak istersen sanal sunucu ekonomik bir ikinci makine olur. Sunucu kurulumu, güvenlik sıkılaştırması ve güncellemelerle uğraşmak istemiyorsan sunucu yönetimi, yedeklerin düzenli ve sunucu dışında tutulmasını istiyorsan yedekleme hizmetlerimiz bu işi sizin yerinize üstlenir.