GitHub Pages ile Ücretsiz Web Sitesi Yayınlama

Bir müşterinin “site yok, domain çalışmıyor, ne yapıyorsunuz” mesajıyla saat 23:00’de uyandığım geceleri düşününce, bazen en basit çözümlerin ne kadar değerli olduğunu anlıyorum. GitHub Pages tam da o nokta: ücretsiz, güvenilir, CDN’li, SSL’li bir hosting çözümü. Peki neden herkes kullanmıyor? Çünkü “statik site” kelimesi insanları korkutuyor. Oysa portfolyo sayfası, dokümantasyon sitesi, ürün landing page’i, hatta basit bir blog için GitHub Pages mükemmel bir seçenek.

GitHub Pages Nedir, Ne Değildir

Önce sınırları netleştirelim. GitHub Pages statik içerik sunar. PHP çalıştıramazsınız, veritabanına bağlanamazsınız, sunucu tarafı kod yapamazsınız. Ama HTML, CSS, JavaScript, Jekyll şablonları ve bunların ürettiği her şeyi çalıştırabilirsiniz. Ayda 100GB bant genişliği, 1GB depolama alanı ve aylık 10 build limiti var (Actions üzerinden build yapıyorsanız bu limit kalkar, aşağıda anlatacağım).

Kullanım senaryoları:

  • Kişisel portfolyo siteleri: kullaniciadi.github.io adresiyle yayına alırsınız
  • Proje dokümantasyonu: Her repository’nin kendi Pages’i olabilir
  • Takım/şirket siteleri: Organization account’larla çalışır
  • Statik bloglar: Jekyll, Hugo, Eleventy ile üretilen içerikler
  • Landing page’ler: Tek sayfalık ürün tanıtım siteleri

Temel Kurulum: İlk 10 Dakika

En basit senaryo ile başlayalım. GitHub hesabınız var, bir site yapmak istiyorsunuz.

Önce repository oluşturun. Kişisel site için repository ismi kritik: kullaniciadi.github.io formatında olmalı. Başka bir isim verirseniz adres kullaniciadi.github.io/repo-adi formatına kayar, bu da kökde çalışmasını engelleyebilir.

# Lokal olarak başlatıyorsanız
mkdir benim-site
cd benim-site
git init
git remote add origin https://github.com/kullaniciadi/kullaniciadi.github.io.git

Sonra temel bir HTML dosyası oluşturun:

cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Benim Sitem</title>
</head>
<body>
    <h1>Merhaba, GitHub Pages!</h1>
    <p>Bu site GitHub Pages üzerinde çalışıyor.</p>
</body>
</html>
EOF

git add index.html
git commit -m "İlk commit: ana sayfa eklendi"
git push -u origin main

Sonra GitHub’da repository ayarlarına gidin: Settings > Pages > Source bölümünde branch seçin (main veya gh-pages), klasör olarak / (root) seçin, kaydedin. 2-3 dakika içinde siteniz canlıya çıkar.

Branch Stratejisi: main mi, gh-pages mi?

İki popüler yaklaşım var ve hangisini seçeceğiniz iş akışınıza göre değişir.

main branch yaklaşımı: Basit projelerde veya sitenin kendisi zaten repository’nin ana içeriğiyse kullanılır. Her push direkt yayına gider. Portfolyo siteleri için ideal.

gh-pages branch yaklaşımı: Kaynak kodunuz main‘de, derlenmiş statik dosyalar gh-pages‘de yaşar. Bu yaklaşım özellikle build süreci olan projelerde (React, Vue, Jekyll) tercih edilir.

gh-pages branch’ini elle yönetmek zahmetlidir. Bunun için git subtree veya gh-pages npm paketi kullanılır:

# npm gh-pages paketi ile (React/Vue projeleri için yaygın)
npm install --save-dev gh-pages

# package.json içine ekleyin:
# "scripts": {
#   "predeploy": "npm run build",
#   "deploy": "gh-pages -d build"
# }

npm run deploy

Bu komut build/ klasörünün içeriğini alır, gh-pages branch’i oluşturur veya günceller, ve GitHub’a push eder. Kaynak kodunuz main‘de temiz kalır.

Jekyll ile Statik Blog Kurmak

GitHub Pages Jekyll’i natively destekler, yani _config.yml ve Markdown dosyalarınız varsa GitHub sunucularında otomatik build alır. Bu çok güçlü bir özellik.

# Jekyll'i lokal olarak kurun (Ruby gerekli)
gem install jekyll bundler

# Yeni Jekyll projesi
jekyll new blog-site
cd blog-site

# Lokal test
bundle exec jekyll serve
# http://localhost:4000 adresinde görüntüleyin

Temel _config.yml yapısı:

title: "Sistem Yöneticisinin Notu"
description: "Linux, DevOps ve altyapı üzerine pratik yazılar"
baseurl: ""
url: "https://kullaniciadi.github.io"
author:
  name: "Ahmet Yılmaz"
  email: "[email protected]"

markdown: kramdown
highlighter: rouge
permalink: /:year/:month/:day/:title/

plugins:
  - jekyll-feed
  - jekyll-sitemap
  - jekyll-seo-tag

Yazı eklemek için _posts/ klasörüne YYYY-MM-DD-baslik.md formatında dosya oluşturun:

cat > _posts/2024-01-15-nginx-kurulumu.md << 'EOF'
---
layout: post
title: "Ubuntu 22.04'te Nginx Kurulumu"
date: 2024-01-15 10:00:00 +0300
categories: linux nginx
tags: [web-sunucu, ubuntu, nginx]
---

Bu yazıda Nginx kurulumunu adım adım anlatıyorum...

## Kurulum

apt update && apt install nginx -y

EOF

Push ettiğinizde GitHub otomatik olarak Jekyll build çalıştırır. Uyarı: GitHub’ın Jekyll versiyonu bazen geride kalabiliyor. Sorun yaşarsanız GitHub Actions’a geçmenizi öneririm (aşağıda).

GitHub Actions ile Özel Build Pipeline

Jekyll dışında bir static site generator kullanıyorsanız (Hugo, Eleventy, Next.js static export vs.) veya Jekyll’in kısıtlamalarından kurtulmak istiyorsanız GitHub Actions kullanmanız gerekiyor.

Hugo için örnek workflow:

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.121.0'
          extended: true

      - name: Build
        run: hugo --minify

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./public

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Bu yaklaşımın avantajı: her şey sizin kontrolünüzde. Hugo versiyonunu siz seçiyorsunuz, build öncesi testler ekleyebiliyorsunuz, birden fazla ortam yönetebiliyorsunuz.

Özel Domain Bağlamak

kullaniciadi.github.io adresi bazen yeterli olmayabiliyor. Kendi domaininizi bağlamak için şu adımları izleyin.

Önce repository root’una CNAME dosyası oluşturun:

echo "www.benim-site.com" > CNAME
git add CNAME
git commit -m "CNAME dosyası eklendi"
git push

Sonra domain sağlayıcınızın DNS panelinde kayıtları ekleyin.

Apex domain (benim-site.com) için A kayıtları:

  • 185.199.108.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.199.111.153

www subdomain için CNAME kaydı:

  • www CNAME kullaniciadi.github.io

DNS değişikliklerinin yayılması 15 dakika ile 48 saat arasında sürebilir. GitHub, repository Settings > Pages bölümünde domain doğrulama durumunu gösterir. “DNS check successful” mesajını gördükten sonra “Enforce HTTPS” kutusunu işaretleyin. Let’s Encrypt sertifikası otomatik olarak atanacak.

Önemli bir not: Eğer Cloudflare kullanıyorsanız, CNAME kaydını “DNS only” (gri bulut) modunda bırakın, proxy modunda bırakmayın. GitHub Pages kendi SSL’ini yönetiyor, Cloudflare proxy aktifken sertifika doğrulaması bozulabiliyor. Tabii Cloudflare’i tamamen by-pass etmek istemiyorsanız farklı yaklaşımlar var ama bu ayrı bir yazı konusu.

Gerçek Dünya Senaryosu: Takım Dokümantasyonu

Bir startup’ta çalıştığınızı düşünün. API dokümantasyonunuzu, deployment rehberlerinizi, onboarding dökümanlarınızı GitHub Pages’de yayınlamak istiyorsunuz. Hem versiyon kontrolünde olsun, hem erişimi kolay olsun.

# Organizasyon altında repo oluşturun
# github.com/sirketiniz/docs

# MkDocs kullanarak güzel bir dokümantasyon sitesi kuralım
pip install mkdocs mkdocs-material

mkdocs new docs-site
cd docs-site

mkdocs.yml dosyasını düzenleyin:

site_name: Şirket Dokümantasyonu
site_url: https://sirketiniz.github.io/docs
theme:
  name: material
  language: tr
  palette:
    primary: indigo
  features:
    - navigation.tabs
    - search.suggest
    - content.code.copy

nav:
  - Ana Sayfa: index.md
  - API Referans: api/
  - Deployment: deployment/
  - Onboarding: onboarding/

plugins:
  - search:
      lang: tr

GitHub Actions workflow’u:

name: Dokümantasyon Deploy

on:
  push:
    branches:
      - main
    paths:
      - 'docs/**'
      - 'mkdocs.yml'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v4
        with:
          python-version: '3.x'
      - run: pip install mkdocs-material
      - run: mkdocs gh-deploy --force

mkdocs gh-deploy komutu build alır ve otomatik olarak gh-pages branch’ine push eder. Güzel tarafı: her PR merge edildiğinde dokümantasyon otomatik güncelleniyor. Artık “dökümantasyon güncel değil” şikayetleri bitiyor.

Yaygın Sorunlar ve Çözümleri

Sayfa güncellenmedi, eski içerik geliyor: GitHub CDN’i agresif cache kullanıyor. Tarayıcı önbelleğini temizleyin, birkaç dakika bekleyin. Hala sorun varsa Actions tab’ından build’in başarılı olup olmadığını kontrol edin.

404 hatası: Birkaç nedeni olabilir:

  • index.html yok veya yanlış klasörde
  • Branch ya da source klasörü yanlış seçilmiş
  • Repository ismi ile GitHub kullanıcı adı arasında büyük/küçük harf uyumsuzluğu
# Branch ve remote durumunu kontrol edin
git remote -v
git branch -a
git log --oneline -5

Jekyll build hatası: Settings > Pages bölümünde “Your site had a problem building” mesajı görünüyorsa Actions sekmesine geçin, hata detaylarını oradan okuyun. Yaygın sorunlar: desteklenmeyen gem, Liquid template sözdizimi hatası, geçersiz front matter.

Özel domain SSL sorunu: Enforce HTTPS seçeneği griyse DNS henüz tam yayılmamış demektir. 24 saat bekleyin. Hala sorun varsa CNAME dosyasının içeriğinin doğru olduğundan emin olun (protokol yazmayın, sadece alan adı: www.benim-site.com değil benim-site.com).

Güvenlik ve Kısıtlamalar

GitHub Pages public repository’lerde tamamen herkese açık. Gizli içerik yayınlamayamazsınız. Private repository ile Pages kullanmak için GitHub Pro, Team veya Enterprise planına ihtiyacınız var.

Bir diğer önemli nokta: .env dosyaları, API anahtarları, şifreler kesinlikle repository’ye girmemeli. Statik sitede zaten server-side kod yok ama JavaScript ile API çağrısı yapıyorsanız bu anahtarlar client-side’da görünür hale gelir.

Sitenize erişim kısıtlaması getiremezsiniz (Basic Auth gibi). Eğer sadece belirli kişilerin görmesi gereken içerik varsa, GitHub Pages doğru araç değil. Netlify Identity veya benzeri çözümlere bakmanız gerekir.

Pages Sitesini İzlemek

Sitenizi deploy etmek bir şey, sağlığını takip etmek ayrı bir şey. Birkaç pratik yöntem:

GitHub Actions’ta basit bir uptime check ekleyebilirsiniz:

name: Site Uptime Check

on:
  schedule:
    - cron: '*/30 * * * *'  # Her 30 dakikada

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: HTTP kontrol
        run: |
          STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://www.siteniz.com)
          if [ "$STATUS" != "200" ]; then
            echo "Site cevap vermiyor! HTTP Status: $STATUS"
            exit 1
          fi
          echo "Site sağlıklı. HTTP Status: $STATUS"

Bu workflow başarısız olursa GitHub sizi e-posta ile bilgilendiriyor. Basit ama etkili. Daha gelişmiş monitoring için UptimeRobot’un ücretsiz planı zaten yeterli olacaktır.

Sonuç

GitHub Pages’in en büyük gücü sadeliğinde. Karmaşık bir hosting altyapısı kurmadan, domain alma ve DNS yönetimi dışında hiçbir para ödemeden ciddi bir web sitesi yayınlayabiliyorsunuz. SSL otomatik, CDN otomatik, uptime garantisi pratikte çok yüksek.

Elbette her şeye uygun değil. Dinamik içerik, kullanıcı oturumu, veritabanı gerektiren projelerde başka çözümlere bakmanız gerekiyor. Ama portfolyo sitesi, dokümantasyon, blog, landing page kategorisindeki projelerin büyük çoğunluğu için GitHub Pages’i atlayıp daha karmaşık çözümlere geçmek gereksiz bir efor. Önce bunu deneyin, yetmediğinde yükseltirsiniz.

Ekibinizdeki geliştiricilerin portfolyo sayfaları yoksa, projelerinizin dokümantasyonu dağınıksa ya da bir ürün için hızlı bir landing page lazımsa: bir öğleden sonra ayırın, bu yazıyı baştan okuyun ve yayına çıkın. Beklenenden çok daha hızlı olduğunu göreceksiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir