Oracle VM & Sunucu Yönetim Rehberi

Bu kılavuz, Oracle VM sunucusu üzerindeki Docker konteynerlerini, Cloudflare tünellerini, PM2 servislerini ve sunucu bakım rutinlerini adım adım yönetmek, yeni projeler yayınlamak ve olası sorunları (senaryolarla) çözmek amacıyla hazırlanmıştır.


🖥️ 1. Sunucu Genel Bilgileri & SSH Erişimi

  • Sunucu IP Adresi: 92.5.112.114 (Oracle VM)
  • Kullanıcı Adı: ubuntu
  • SSH Key Konumu: https://github.com/imhalid/Library.git
  • SSH Yetkilendirme Anahtarı: ~/ssh-key-2026-06-04.key

🔑 SSH ile Bağlantı Kurma

Yerel makinenizden sunucuya terminal üzerinden güvenli bağlantı kurmak için:

# SSH Anahtarının izinlerini düzenleyin (Sadece bir kez)
chmod 600 ~/ssh-key-2026-06-04.key
 
# Sunucuya bağlanın
ssh -i ~/ssh-key-2026-06-04.key ubuntu@92.5.112.114

🐳 2. Aktif Sunucu Servisleri & Konteyner Listesi

Sunucu üzerinde servislerin büyük bölümü Docker konteynerleri olarak yönetilmektedir. Aktif durumdaki konteynerler, local portları ve Cloudflare tüneliyle eşleşen subdomain yönlendirmeleri aşağıdaki gibidir:

Konteyner AdıServis Portu (Local)Cloudflare DomainAçıklama
pa-reader8084 -> Container 80pa.halid.devPointers & Arrays C Kılavuzu (Bu proje)
c-guide-frontend8085 -> Container 80c.halid.devBeej’s Guide to C Programming Rehberi
library-frontend3000 -> Container 3000library.halid.devKütüphane Arayüz Uygulaması
library-backend3001 -> Container 3001-Kütüphane API Servisi
vaultwarden8081 -> Container 80vault.halid.devBitwarden Uyumlu Şifre Yöneticisi Sunucusu
silverbullet-silverbullet-18083 -> Container 3000database.halid.devSilverBullet Not Defteri Uygulaması
beszel-hub8090 -> Container 8090status.halid.devBeszel Sistem İzleme Paneli (Dashboard)
beszel-agent--Beszel Sunucu Kaynak İzleme Ajanı

☁️ 3. Cloudflare Tunnel (Argo Tunnel) Yönetimi

Sunucu üzerindeki servisleri doğrudan dış dünyaya port açmadan (firewall arkasında güvenli tutarak) internete çıkarmak için Cloudflare Tunnel kullanılır.

  • Tünel ID: 18f495df-1a5f-488d-8fc7-5dbd6d0b53fc
  • Tünel Servis Yöneticisi: PM2 (tunnel adıyla çalışır)
  • Yapılandırma Dosyası Konumu: /home/ubuntu/.cloudflared/config.yml

📝 Aktif config.yml İçeriği

tunnel: 18f495df-1a5f-488d-8fc7-5dbd6d0b53fc
credentials-file: /home/ubuntu/.cloudflared/18f495df-1a5f-488d-8fc7-5dbd6d0b53fc.json
 
originRequest:
  connectTimeout: 30s
  keepAliveConnections: 100
  keepAliveTimeout: 90s
 
ingress:
  - hostname: library.halid.dev
    service: http://localhost:3000
  - hostname: vault.halid.dev
    service: http://localhost:8081
  - hostname: status.halid.dev
    service: http://localhost:8090
  - hostname: database.halid.dev
    service: http://localhost:8083
  - hostname: c.halid.dev
    service: http://localhost:8085
    originRequest:
      connectTimeout: 30s
      keepAliveConnections: 100
      keepAliveTimeout: 90s
  - hostname: pa.halid.dev
    service: http://localhost:8084
  - service: http_status:404

🛠️ 4. PM2 Servis Yönetimi

Sunucuda Docker dışında doğrudan Node.js süreciyle veya tünel yönetimi için PM2 kullanılmaktadır:

# PM2 üzerindeki aktif süreçleri listeleyin
pm2 list
 
# Cloudflare tünel yapılandırması değiştikçe tüneli yeniden başlatın
pm2 restart tunnel
 
# Tünel loglarını canlı izleyin (Hata tespiti için)
pm2 logs tunnel --lines 50

📖 5. Senaryolar ve Sorun Giderme Rehberi

🚨 Senaryo A: “SQLite - Readonly Database” Hatası ve Çözümü

Eğer API uygulamalarında veritabanı yazma hatası (500 Internal Server Error) veya “database is locked/readonly” hatası alırsanız, bu SQLite dosyasının sahiplik izinlerinin sıfırlanmasından kaynaklanır.

Çözüm Adımları: Sunucuya bağlanın ve şu komutları sırasıyla çalıştırın:

# Klasör sahipliğini ubuntu kullanıcısına verin
sudo chown -R ubuntu:ubuntu ~/Library/server
 
# Yazma ve çalıştırma izinlerini atayın
chmod -R 775 ~/Library/server
chmod 666 ~/Library/server/data.db

🚨 Senaryo B: Disk Doluluk Oranının Artması ve Docker Temizliği

Sunucuda disk alanı azaldığında (df -h komutuyla kontrol edin), Docker imaj artıkları ve logları diski doldurmuş olabilir.

Çözüm Adımları:

# Sunucu disk alanını kontrol edin
df -h
 
# Docker disk kullanım detaylarına bakın
docker system df
 
# Kullanılmayan tüm konteyner, network ve askıda kalan imajları temizleyin
docker system prune -a --volumes -y
 
# Büyük docker log dosyalarını sıfırlamak için (Gerekirse):
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'

🚨 Senaryo C: Lokal Geliştirme Sonrası Hızlı Canlı Güncelleme (Deploy)

Lokal makinenizde yaptığınız kod değişikliklerini git kullanmadan veya doğrudan sunucuya yansıtmak istediğinizde uygulanacak hızlı deploy adımları.

Çözüm Adımları:

  1. Lokal makinenizde projeyi derleyin (Build alın):
    pnpm run build
  2. rsync ile yerel dosyaları sunucudaki ilgili klasöre kopyalayın:
    rsync -avz --exclude 'node_modules' --exclude '.git' --exclude '.pnpm-store' -e "ssh -o StrictHostKeyChecking=no -i ~/Library/ssh-key-2026-06-04.key" ./ ubuntu@92.5.112.114:~/pa-reader/
  3. Sunucudaki docker konteynerini yeniden build ederek ayağa kaldırın:
    ssh -i ~/Library/ssh-key-2026-06-04.key ubuntu@92.5.112.114 "cd ~/pa-reader && docker compose up -d --build"

🚨 Senaryo D: Cloudflare Tüneline Yeni Subdomain / Proje Ekleme

Sunucuya yeni bir docker projesi eklediniz (Örn: Port 8089 üzerinde çalışan test-app) ve bunu test.halid.dev adresiyle yayına almak istiyorsunuz.

Çözüm Adımları:

  1. Sunucuya bağlanın ve tünel config dosyasını düzenleyin:
    nano ~/.cloudflared/config.yml
  2. ingress bölümünün altına (en alttaki 404 kuralının üstüne gelecek şekilde) yeni yönlendirmeyi ekleyin:
      - hostname: test.halid.dev
        service: http://localhost:8089
  3. Yapılandırma dosyasını doğrulayın:
    cloudflared tunnel ingress validate ~/.cloudflared/config.yml
  4. Yeni subdomain için DNS kaydını tünel üzerinden Cloudflare’e bildirin:
    cloudflared tunnel route dns 18f495df-1a5f-488d-8fc7-5dbd6d0b53fc test.halid.dev
  5. Tünel servisini PM2 üzerinde yeniden başlatın:
    pm2 restart tunnel
  6. Tarayıcıdan https://test.halid.dev adresini test edin.

🚨 Senaryo E: Bir Konteynerin Çökmesi veya Loglarının İncelenmesi

Eğer bir domain üzerinden 502 Bad Gateway veya 504 Gateway Timeout hatası alıyorsanız, o domaine bakan lokal konteyner durmuş veya hata veriyor olabilir.

Çözüm Adımları:

# Tüm konteynerlerin durumlarını listeleyin (STATUS sütununa bakın)
docker ps -a
 
# Düşen veya çöken konteynerin loglarını inceleyin
docker logs --tail 100 pa-reader
 
# Konteyneri durdurup temizce yeniden ayağa kaldırın
docker compose -f ~/pa-reader/docker-compose.yml down
docker compose -f ~/pa-reader/docker-compose.yml up -d

🐳 6. Sunucu Projelerinin Genel Yapısı

Sunucu üzerindeki tüm ana projeler /home/ubuntu/ dizininde konumlandırılmış ve her biri bağımsız konteyner grupları olarak ayağa kaldırılmıştır. Projelerin genel dosya mimarisi ve özel yapılandırmaları şu şekildedir:

  • ~/pa-reader (Pointers & Arrays C Guide):
    • Yapı: Svelte 5 / Vite static uygulamasıdır. Yerel olarak build edilen static dist/ çıktıları sunucuya kopyalanarak Nginx Docker konteynerinde servis edilir.
    • Dosya Yapısı: Dockerfile, docker-compose.yml, nginx.conf, src/, md/ (İngilizce kılavuz), tr/ (Türkçe kılavuz).
  • ~/c-guide (Beej’s Guide to C Programming):
    • Yapı: Benzer şekilde, Svelte 5 / Vite tabanlı static Nginx Docker konteyneridir.
  • ~/Library (Kütüphane Sistemi):
    • Yapı: library-frontend (Svelte/Port 3000) ve library-backend (Node.js/Port 3001) çiftinden oluşur. SQLite veritabanı dosyası ~/Library/server/data.db konumundadır.
  • ~/vaultwarden (Şifre Kasası):
    • Yapı: Resmi Vaultwarden Docker imajı (vaultwarden/server) kullanılarak çalışır. Hassas veriler Docker volumes altında saklanır.
  • ~/silverbullet (Markdown Not Defteri):
    • Yapı: Silverbullet not tutma platformudur. Localde 8083 portunu kullanır. Not verileri ve döküman alanı ~/silverbullet/space altında saklanır ve Git ile senkronize edilir.

⏰ 7. Cron Job (Zamanlanmış Görevler) & Eşitleme Otomasyonu

⚙️ Aktif Cron Job Yapılandırması

crontab -l çıktısı:

*/2 * * * * /home/ubuntu/silverbullet-sync.sh >/dev/null 2>&1
  • Açıklama: Bu görev, her 2 dakikada bir /home/ubuntu/silverbullet-sync.sh scriptini arka planda çalıştırır. Standart çıktı (stdout) ve hata çıktıları (stderr) sistem çöplüğüne (>/dev/null 2>&1) gönderilerek temiz tutulur.

📜 Eşitleme Scripti (/home/ubuntu/silverbullet-sync.sh)

Bu script, Silverbullet not alanı (~/silverbullet/space) ile uzak GitHub deposunu çift yönlü (2-Way Git Sync) otomatik olarak senkronize eder:

  • Çalışma Mantığı:
    1. Tekil Çalışma Güvencesi: /tmp/silverbullet_sync.lock dosyası üzerinden kilit (flock) kontrolü yaparak, önceki çalışan script bitmeden yenisinin başlamasını engeller.
    2. Yerel Değişiklik Kontrolü: git status --porcelain ile yeni notlar yazılmış mı diye bakar. Değişiklik varsa Auto sync: [Tarih Saat] mesajıyla otomatik commit oluşturur.
    3. Uzak Depo Senkronizasyonu: git fetch origin main ile uzak sunucuyu çeker. Yerel hash ile uzak hash farklıysa, git pull --rebase ile değişiklikleri yerel ile birleştirir. Eğer rebase hata verirse, otomatik olarak merge işlemi uygulayarak git push ile uzak depoya (origin main) gönderir.
    4. Log Sınırlaması (Truncate): İşlem logları /home/ubuntu/silverbullet/sync.log dosyasına yazılır. Log dosyasının boyutu 1MB’ı aşarsa, dosya otomatik olarak kırpılarak sadece son 500 satır saklanır.

📂 Log ve Kilitleme Yolları

  • Senkronizasyon Log Dosyası: /home/ubuntu/silverbullet/sync.log
  • Süreç Kilitleme Dosyası: /tmp/silverbullet_sync.lock
  • Not Alanı Dizin Yolu: /home/ubuntu/silverbullet/space

🏗️ 8. Kesinlikle Uyulması Gereken Derleme ve Dağıtım Kuralları

Sunucu kararlılığı, kaynak yönetimi ve temiz sürüm kontrolü sağlamak amacıyla geliştirme ve yayına alma (deployment) süreçlerinde aşağıdaki kurallara kesinlikle uyulmalıdır:

  1. Sunucu Üzerinde Asla Build Alınmamalıdır:
    • Oracle VM sunucusunun ana işletim sisteminde (host üzerinde) hiçbir şekilde npm run build, pnpm build veya benzeri frontend derleme komutları çalıştırılmamalıdır.
    • Bu kural sunucu kaynaklarının (CPU/RAM) derleme sırasında tükenmesini ve çakışmaları engellemek için kritiktir.
  2. Veriler Yalnızca GitHub Üzerinden Çekilmelidir:
    • Sunucuya (VM) kod veya veri aktarımı, doğrudan yerelden dosya kopyalamak yerine yalnızca GitHub uzak deposundan çekilerek (git pull/fetch) yapılmalıdır.
  3. .gitignore ve dist Klasörü Kuralı:
    • Eğer projede bir derleme (build) işlemi gerekiyorsa, derlenen çıktıların bulunduğu dist/ (veya benzer derleme klasörleri) kesinlikle .gitignore dosyasında yer almalıdır.
    • Derlenmiş statik dosyalar asla Git deposuna (GitHub’a) commit edilmemeli ve gönderilmemelidir.
    • Derleme işlemi, Docker imajı oluşturulurken Docker çok aşamalı derleme (multi-stage build) yöntemiyle doğrudan Docker konteyneri içerisinde gerçekleştirilmelidir. Böylece sunucu üzerinde gereksiz Node/Build araçları çalıştırmaya gerek kalmadan temiz bir dağıtım sağlanır.