Docker & DevOps

    Gitea ile Kendi Git Sunucunuz

    Kendi sunucunda Gitea kurup depolarını, SSH erişimini ve yedeklemeyi yönetme rehberi.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    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.

    KonuBarındırılan (GitHub/GitLab.com)Kendi Gitea sunucun
    Aylık maliyetKullanıcı başınaSabit sunucu kirası
    Veri konumuSağlayıcıdaSenin sunucunda
    ErişilebilirlikSağlayıcının sorumluluğuSenin sorumluluğun
    YedekSağlayıcıdaSenin kurman gerekir
    Özel ağ erişimiEk yapılandırmaDoğrudan
    Kurulum süresiYokYarı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:

    1. Kaydı kapat. DISABLE_REGISTRATION: "true" ayarını Compose dosyasına zaten koyduk. Ekibe kullanıcı eklemeyi yönetici panelinden yaparsın.
    2. Depo görünürlüğü varsayılanını özel yap. Yeni depoların kazara herkese açık oluşmasını engeller.
    3. İki adımlı doğrulamayı zorunlu tut. En azından yönetici hesapları için.
    4. 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.
    5. Git LFS'i bilinçli aç. Büyük ikili dosyalar diskini beklenenden hızlı doldurur; ihtiyacın yoksa kapalı bırak.
    6. 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.

    GiteaGitSelf-Hosted

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.