<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-09T00:05:50+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Algoritma Yarışmalarının Perde Arkası: DOMjudge, DMOJ ve CMS</title><link href="https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms/" rel="alternate" type="text/html" title="Algoritma Yarışmalarının Perde Arkası: DOMjudge, DMOJ ve CMS" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms</id><content type="html" xml:base="https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms/"><![CDATA[<p>Bir algoritma yarışmasında çözümünüzü gönderip birkaç saniye sonra “Accepted” sonucunu gördüğünüzde arka planda küçük bir yazılım orkestrası çalışır. Kaynak kod derlenir, izole bir ortamda test edilir, süre ve bellek tüketimi ölçülür, çıktı karşılaştırılır ve puan hesaplanır. DOMjudge, DMOJ ve CMS, bu orkestrayı yöneten en popüler açık kaynak yarışma sistemleri arasındadır.
``</p>

<h2 id="online-judge-nasıl-çalışır">Online judge nasıl çalışır?</h2>

<p>Bir değerlendirme sisteminin temel girdileri kaynak kod, programlama dili ve problem kimliğidir. Sistem önce kodu derler, ardından her test için programı çalıştırır. En basit toplam değerlendirme süresi şöyle düşünülebilir:</p>

\[T_{toplam} = T_{derleme} + \sum_{i=1}^{n} T_{test_i}\]

<p>Programın herhangi bir testte süre sınırını aşması <strong>TLE</strong>, fazla bellek kullanması <strong>MLE</strong>, hatalı çıktı üretmesi ise <strong>WA</strong> sonucuna yol açar. Doğru sonuç yalnızca çıktının doğru olması değildir; programın belirlenen kaynak sınırları içinde çalışması da gerekir.</p>

<p>Gönderilen kod güvenilir kabul edilmez. Sonsuz döngüye girebilir, süreç oluşturmaya çalışabilir veya dosya sistemine erişmek isteyebilir. Bu nedenle judge sunucuları Linux kullanıcıları, cgroups, chroot, container veya benzeri izolasyon mekanizmalarından yararlanır. Kısacası değerlendirme sunucusu, yarışmacının koduna “Seni çalıştırırım ama evin anahtarını vermem” der.</p>

<h2 id="üç-platformun-karşılaştırması">Üç platformun karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>DOMjudge</th>
      <th>DMOJ</th>
      <th>CMS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana kullanım</td>
      <td>ICPC tarzı yarışmalar</td>
      <td>Eğitim ve çevrim içi arşiv</td>
      <td>IOI tarzı olimpiyatlar</td>
    </tr>
    <tr>
      <td>Puanlama</td>
      <td>Genellikle problem bazlı</td>
      <td>Esnek, kısmi puan destekli</td>
      <td>Alt görev odaklı</td>
    </tr>
    <tr>
      <td>Teknoloji</td>
      <td>PHP, Symfony, MariaDB</td>
      <td>Python, Django, C++ judge</td>
      <td>Python tabanlı servisler</td>
    </tr>
    <tr>
      <td>Kurulum</td>
      <td>Orta</td>
      <td>Orta-zor</td>
      <td>Zor</td>
    </tr>
    <tr>
      <td>Kullanıcı arayüzü</td>
      <td>Yarışma odaklı</td>
      <td>Topluluk ve arşiv odaklı</td>
      <td>Yönetim odaklı</td>
    </tr>
    <tr>
      <td>Güçlü yanı</td>
      <td>Kararlı takım yarışmaları</td>
      <td>Dil ve problem çeşitliliği</td>
      <td>Gelişmiş olimpiyat değerlendirmesi</td>
    </tr>
  </tbody>
</table>

<h2 id="domjudge-icpc-ruhunun-temsilcisi">DOMjudge: ICPC ruhunun temsilcisi</h2>

<p>DOMjudge, takım yarışmaları ve klasik ICPC kuralları için oldukça uygundur. Yanlış gönderimler ceza süresine eklenir; problem çözüldüğünde süre hesabı kesinleşir. Basitleştirilmiş ceza modeli şöyledir:</p>

\[P = T_{kabul} + 20 \times W\]

<p>Burada $T_{kabul}$ kabul dakikası, $W$ ise kabulden önceki yanlış gönderim sayısıdır. DOMjudge; yarışma yönetimi, canlı sıralama, hakem işlemleri ve ayrı judgehost makineleriyle ölçeklendirme konusunda güçlüdür. Üniversite kulübünde gerçekçi bir ICPC provası düzenlemek istiyorsanız genellikle ilk adaydır.</p>

<h2 id="dmoj-esnek-ve-geliştirici-dostu">DMOJ: Esnek ve geliştirici dostu</h2>

<p>DMOJ, sürekli açık problem arşivleri ve eğitim platformları için öne çıkar. Çok sayıda dili destekler; özel checker, interaktif problem ve kısmi puanlama gibi özellikler sunar. Django tabanlı web uygulaması ile değerlendirme düğümleri birbirinden ayrılabilir.</p>

<p>Bir problemin basit yapılandırması kavramsal olarak şöyle görünebilir:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">archive</span><span class="pi">:</span> <span class="s">data.zip</span>
<span class="na">time</span><span class="pi">:</span> <span class="m">2</span>
<span class="na">memory</span><span class="pi">:</span> <span class="m">256</span>
<span class="na">test_cases</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">points</span><span class="pi">:</span> <span class="m">20</span>
    <span class="na">input</span><span class="pi">:</span> <span class="s">sample.in</span>
    <span class="na">output</span><span class="pi">:</span> <span class="s">sample.out</span>
  <span class="pi">-</span> <span class="na">points</span><span class="pi">:</span> <span class="m">80</span>
    <span class="na">batched</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">input</span><span class="pi">:</span> <span class="s">secret.in</span>
        <span class="na">output</span><span class="pi">:</span> <span class="s">secret.out</span>
</code></pre></div></div>

<p>Bu yapı süreyi, bellek sınırını ve testlerin puan ağırlığını tanımlar. Gerçek sözdizimi sürüme ve problem paketine göre değişebilse de temel fikir aynıdır: değerlendirme davranışı kod yerine yapılandırmayla açıklanır.</p>

<h2 id="cms-olimpiyat-seviyesinde-kontrol">CMS: Olimpiyat seviyesinde kontrol</h2>

<p>Contest Management System, özellikle IOI biçimindeki yarışmalara yöneliktir. Alt görevler, geri bildirim düzeyleri, token sistemi ve ayrıntılı puanlama senaryolarında çok başarılıdır. Örneğin çözüm ilk alt görevden 20, ikinci alt görevden 30 puan alabilir; en zor grup başarısız olsa bile toplam puan korunur.</p>

<p>CMS güçlüdür ancak kurulumu ve işletimi diğer seçeneklere göre daha fazla sistem yönetimi bilgisi ister. Servislerin dağıtılması, worker makinelerinin hazırlanması ve yarışma verilerinin doğru modellenmesi dikkat gerektirir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Tek günlük ICPC benzeri bir etkinlik için <strong>DOMjudge</strong>, okul veya topluluk tabanlı sürekli bir soru platformu için <strong>DMOJ</strong>, ulusal olimpiyat düzeyinde alt görevli yarışmalar için <strong>CMS</strong> daha doğal seçimdir. Platformdan bağımsız olarak yedekleme, HTTPS, kaynak izolasyonu ve yarışma öncesi yük testi ihmal edilmemelidir. Çünkü en zor algoritma sorusu bile çözülebilir; yarışma ortasında çöken judge sunucusu ise herkese aynı anda sistem tasarımı dersi verir.</p>

<p><img src="/img/algoritma-yarismalarinin-perde-38.svg" alt="algoritma-yarismalarinin-perde-38" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="online-judge" /><category term="domjudge" /><category term="dmoj" /><category term="cms" /><category term="programlama-yarışmaları" /><summary type="html"><![CDATA[Bir algoritma yarışmasında çözümünüzü gönderip birkaç saniye sonra “Accepted” sonucunu gördüğünüzde arka planda küçük bir yazılım orkestrası çalışır. Kaynak kod derlenir, izole bir ortamda test edilir, süre ve bellek tüketimi ölçülür, çıktı karşılaştırılır ve puan hesaplanır. DOMjudge, DMOJ ve CMS, bu orkestrayı yöneten en popüler açık kaynak yarışma sistemleri arasındadır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/algoritma-yarismalarinin-perde-38.png" /><media:content medium="image" url="https://program.sonsuz.us/img/algoritma-yarismalarinin-perde-38.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">API Dokümantasyon Sistemi Kurmak: Swagger UI, Redoc ve Docusaurus</title><link href="https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus/" rel="alternate" type="text/html" title="API Dokümantasyon Sistemi Kurmak: Swagger UI, Redoc ve Docusaurus" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus</id><content type="html" xml:base="https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus/"><![CDATA[<p>Bir API geliştirmek yalnızca çalışan endpoint’ler yazmak değildir; diğer geliştiricilerin bu endpoint’leri keşfedebilmesini, deneyebilmesini ve doğru kullanabilmesini sağlamak da işin parçasıdır. Swagger UI, Redoc ve Docusaurus aynı dokümantasyon evreninde yaşasa da farklı sorunları çözer. Gelin bu araçları yarıştırmak yerine birlikte çalıştırabileceğimiz sürdürülebilir bir sistem tasarlayalım.
``</p>
<h2 id="önce-temel-openapi-nedir">Önce temel: OpenAPI nedir?</h2>

<p>OpenAPI, REST tabanlı bir API’nin insanlar ve makineler tarafından okunabilen sözleşmesidir. Endpoint yolları, HTTP metotları, parametreler, veri modelleri, kimlik doğrulama yöntemleri ve olası yanıtlar YAML veya JSON biçiminde tanımlanır.</p>

<p>Bir API sözleşmesini kabaca şu fonksiyonla düşünebiliriz:</p>

\[S = P + R + M + A + E\]

<p>Burada $P$ yolları, $R$ istekleri, $M$ veri modellerini, $A$ kimlik doğrulamayı ve $E$ hata yanıtlarını temsil eder. Sözleşme ne kadar eksiksizse istemci üretimi, test otomasyonu ve geliştirici deneyimi o kadar başarılı olur.</p>

<p>Swagger UI ve Redoc bu sözleşmeyi görselleştirir. Docusaurus ise rehberler, eğitimler, sürüm notları ve kavramsal açıklamalar için genel bir dokümantasyon sitesi sunar.</p>

<h2 id="araçların-karşılaştırması">Araçların karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Swagger UI</th>
      <th>Redoc</th>
      <th>Docusaurus</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana amaç</td>
      <td>API’yi etkileşimli denemek</td>
      <td>Okunabilir API referansı</td>
      <td>Tam dokümantasyon portalı</td>
    </tr>
    <tr>
      <td>OpenAPI desteği</td>
      <td>Doğrudan</td>
      <td>Doğrudan</td>
      <td>Eklentiyle</td>
    </tr>
    <tr>
      <td>İstek gönderme</td>
      <td>Güçlü</td>
      <td>Sınırlı veya sürüme bağlı</td>
      <td>Yerleşik değil</td>
    </tr>
    <tr>
      <td>Özelleştirme</td>
      <td>Orta</td>
      <td>Güçlü tema seçenekleri</td>
      <td>React ile çok güçlü</td>
    </tr>
    <tr>
      <td>En uygun kullanım</td>
      <td>Test ve keşif</td>
      <td>Referans dokümanı</td>
      <td>Rehber ve içerik yönetimi</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/api-dokumantasyon-sistemi-62.svg" alt="api-dokumantasyon-sistemi-62" /></p>

<p>Kısacası Swagger UI laboratuvar, Redoc düzenli bir ansiklopedi, Docusaurus ise bütün kampüstür.</p>

<h2 id="küçük-bir-openapi-sözleşmesi">Küçük bir OpenAPI sözleşmesi</h2>

<p>Aşağıdaki dosya, kullanıcı bilgisini kimliğe göre döndüren bir endpoint tanımlar:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">openapi</span><span class="pi">:</span> <span class="s">3.0.3</span>
<span class="na">info</span><span class="pi">:</span>
  <span class="na">title</span><span class="pi">:</span> <span class="s">Kullanıcı API</span>
  <span class="na">version</span><span class="pi">:</span> <span class="s">1.0.0</span>
<span class="na">paths</span><span class="pi">:</span>
  <span class="s">/users/{id}</span><span class="err">:</span>
    <span class="na">get</span><span class="pi">:</span>
      <span class="na">summary</span><span class="pi">:</span> <span class="s">Kimliğe göre kullanıcı getirir</span>
      <span class="na">parameters</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">id</span>
          <span class="na">in</span><span class="pi">:</span> <span class="s">path</span>
          <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
          <span class="na">schema</span><span class="pi">:</span>
            <span class="na">type</span><span class="pi">:</span> <span class="s">integer</span>
      <span class="na">responses</span><span class="pi">:</span>
        <span class="s1">'</span><span class="s">200'</span><span class="err">:</span>
          <span class="na">description</span><span class="pi">:</span> <span class="s">Kullanıcı bulundu</span>
          <span class="na">content</span><span class="pi">:</span>
            <span class="na">application/json</span><span class="pi">:</span>
              <span class="na">schema</span><span class="pi">:</span>
                <span class="na">$ref</span><span class="pi">:</span> <span class="s1">'</span><span class="s">#/components/schemas/User'</span>
      <span class="err">  </span><span class="s1">'</span><span class="s">404'</span><span class="err">:</span>
          <span class="na">description</span><span class="pi">:</span> <span class="s">Kullanıcı bulunamadı</span>
<span class="na">components</span><span class="pi">:</span>
  <span class="na">schemas</span><span class="pi">:</span>
    <span class="na">User</span><span class="pi">:</span>
      <span class="na">type</span><span class="pi">:</span> <span class="s">object</span>
      <span class="na">required</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">id</span><span class="pi">,</span> <span class="nv">name</span><span class="pi">]</span>
      <span class="na">properties</span><span class="pi">:</span>
        <span class="na">id</span><span class="pi">:</span>
          <span class="na">type</span><span class="pi">:</span> <span class="s">integer</span>
        <span class="na">name</span><span class="pi">:</span>
          <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
</code></pre></div></div>

<p>Bu tanım tek bir doğruluk kaynağıdır. Aynı dosya arayüz oluşturmak, sözleşme testi yapmak veya istemci SDK’sı üretmek için kullanılabilir.</p>

<h2 id="swagger-ui-ve-redocu-çalıştırmak">Swagger UI ve Redoc’u çalıştırmak</h2>

<p>En hızlı yöntem Docker kullanmaktır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Etkileşimli Swagger UI</span>

docker run <span class="nt">--rm</span> <span class="nt">-p</span> 8080:8080 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">SWAGGER_JSON</span><span class="o">=</span>/spec/openapi.yaml <span class="se">\</span>
  <span class="nt">-v</span> <span class="s2">"</span><span class="nv">$PWD</span><span class="s2">:/spec"</span> swaggerapi/swagger-ui

<span class="c"># Okuma odaklı Redoc</span>

docker run <span class="nt">--rm</span> <span class="nt">-p</span> 8081:80 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">SPEC_URL</span><span class="o">=</span>openapi.yaml redocly/redoc
</code></pre></div></div>

<p>İlk komut API’yi <code class="language-plaintext highlighter-rouge">localhost:8080</code> üzerinde deneyebilmenizi sağlar. İkinci komut aynı sözleşmeyi daha sade ve referans odaklı bir görünümle sunar. Gerçek projede dosyayı Redoc sunucusunun erişebileceği dizine kopyalamak veya bir URL üzerinden yayımlamak gerekir.</p>

<h2 id="docusaurus-ile-merkezi-portal">Docusaurus ile merkezi portal</h2>

<p>Docusaurus projesinde kavramsal rehberleri Markdown ile tutabilir, API referansına menüden bağlantı verebilirsiniz:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// docusaurus.config.js</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
  <span class="na">themeConfig</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">navbar</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">items</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> <span class="na">to</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/docs/intro</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Rehberler</span><span class="dl">'</span> <span class="p">},</span>
        <span class="p">{</span> <span class="na">href</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/api/redoc.html</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">API Referansı</span><span class="dl">'</span> <span class="p">},</span>
        <span class="p">{</span> <span class="na">href</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/swagger/</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">API’yi Dene</span><span class="dl">'</span> <span class="p">}</span>
      <span class="p">]</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu yapı kullanıcıya üç katman sunar: “Neden kullanmalıyım?” sorusunu rehberler, “Hangi alanlar var?” sorusunu Redoc, “Bu istek gerçekten çalışıyor mu?” sorusunu Swagger UI cevaplar.</p>

<h2 id="sürdürülebilir-iş-akışı">Sürdürülebilir iş akışı</h2>

<p>OpenAPI dosyasını uygulama koduyla aynı depoda saklayın. CI sürecinde sözdizimini doğrulayın, kırıcı değişiklikleri karşılaştırın ve başarılı derlemeden sonra üç aracı da yayımlayın. Sürüm numarasını URL’ye eklemek, eski istemcilerin dokümantasyona erişmesini kolaylaştırır.</p>

<p>Ayrıca örneklerde gerçek erişim anahtarları kullanmayın. Swagger UI üzerindeki yetkilendirme alanlarını yalnızca güvenli test ortamlarına bağlayın. Böylece güzel görünen değil; güncel, test edilebilir ve güvenilir bir API dokümantasyon sistemi elde edersiniz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="api" /><category term="swagger-ui" /><category term="redoc" /><category term="docusaurus" /><category term="openapi" /><category term="dokümantasyon" /><summary type="html"><![CDATA[Bir API geliştirmek yalnızca çalışan endpoint’ler yazmak değildir; diğer geliştiricilerin bu endpoint’leri keşfedebilmesini, deneyebilmesini ve doğru kullanabilmesini sağlamak da işin parçasıdır. Swagger UI, Redoc ve Docusaurus aynı dokümantasyon evreninde yaşasa da farklı sorunları çözer. Gelin bu araçları yarıştırmak yerine birlikte çalıştırabileceğimiz sürdürülebilir bir sistem tasarlayalım.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/api-dokumantasyon-sistemi-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/api-dokumantasyon-sistemi-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">API Test Arenası: Hoppscotch, Bruno ve Insomnia Karşılaştırması</title><link href="https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi/" rel="alternate" type="text/html" title="API Test Arenası: Hoppscotch, Bruno ve Insomnia Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi/"><![CDATA[<p>Bir API geliştirirken yalnızca endpoint’in çalışması yetmez; doğru durum kodunu, beklenen veriyi ve kabul edilebilir sürede yanıt verdiğini de doğrulamak gerekir. Postman dışında bir araç arıyorsanız Hoppscotch, Bruno ve Insomnia oldukça güçlü üç adaydır. Üstelik her biri API testine farklı bir pencereden bakar: biri hızlı ve web tabanlı, biri Git dostu, diğeri ise kapsamlı bir masaüstü çalışma alanıdır.</p>

<p><img src="/img/api-test-arenasi-95.svg" alt="api-test-arenasi-95" /></p>

<p>``</p>

<h2 id="api-testi-aslında-neyi-doğrular">API testi aslında neyi doğrular?</h2>

<p>Bir istemci API’ye HTTP isteği gönderir; sunucu ise durum kodu, başlıklar ve gövde içeren bir yanıt üretir. Test aracının temel görevi bu alışverişi görünür ve tekrar edilebilir hâle getirmektir.</p>

<p>Örneğin bir kullanıcı endpoint’i için yalnızca <code class="language-plaintext highlighter-rouge">200 OK</code> almak yeterli değildir. Yanıt gövdesindeki <code class="language-plaintext highlighter-rouge">id</code> alanının bulunması, içerik türünün JSON olması ve sürenin belirlenen sınırı aşmaması da kontrol edilmelidir.</p>

<p>Performansı basitçe şöyle değerlendirebiliriz:</p>

\[T_{toplam} = T_{ağ} + T_{sunucu} + T_{aktarım}\]

<p>Bir test 400 ms sürüyorsa bunun tamamı sunucunun işlem süresi değildir. Ağ gecikmesi ve yanıt boyutu da sonucu etkiler. Çoklu isteklerde ortalama süre ise</p>

\[\bar{T} = \frac{\sum_{i=1}^{n} T_i}{n}\]

<p>formülüyle hesaplanabilir. Bu nedenle tek bir hızlı yanıt görüp zafer dansına başlamak yerine testi birkaç kez çalıştırmak daha sağlıklıdır.</p>

<h2 id="üç-aracın-karakteri">Üç aracın karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Hoppscotch</th>
      <th>Bruno</th>
      <th>Insomnia</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çalışma biçimi</td>
      <td>Web ve masaüstü</td>
      <td>Masaüstü ve CLI</td>
      <td>Masaüstü</td>
    </tr>
    <tr>
      <td>Başlangıç hızı</td>
      <td>Çok yüksek</td>
      <td>Yüksek</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Git uyumu</td>
      <td>Sınırlı</td>
      <td>Çok güçlü</td>
      <td>Projeye göre değişir</td>
    </tr>
    <tr>
      <td>Yerel dosya yaklaşımı</td>
      <td>İkincil</td>
      <td>Temel özellik</td>
      <td>Kısmen</td>
    </tr>
    <tr>
      <td>Otomasyon</td>
      <td>Temel/orta</td>
      <td>CLI ile güçlü</td>
      <td>Eklenti ve CLI seçenekleri</td>
    </tr>
    <tr>
      <td>İdeal kullanıcı</td>
      <td>Hızlı deneme yapanlar</td>
      <td>Kod odaklı ekipler</td>
      <td>Geniş çalışma alanı isteyenler</td>
    </tr>
  </tbody>
</table>

<h3 id="hoppscotch-tarayıcıyı-aç-ve-isteği-gönder">Hoppscotch: Tarayıcıyı aç ve isteği gönder</h3>

<p>Hoppscotch, kurulumla uğraşmadan REST, GraphQL ve WebSocket istekleri denemek isteyenler için idealdir. Arayüzü hafiftir; URL’yi, metodu ve gerekli başlıkları girerek saniyeler içinde sonuç alabilirsiniz. Özellikle eğitimlerde, hata ayıklamada ve geçici kontrollerde parıldar.</p>

<p>Ancak hassas token’larla çalışırken ekip politikalarını ve verinin nerede saklandığını incelemek gerekir. Tarayıcı kolaylığı, güvenlik değerlendirmesini ortadan kaldırmaz.</p>

<h3 id="bruno-koleksiyonlar-da-kod-gibi-yaşasın">Bruno: Koleksiyonlar da kod gibi yaşasın</h3>

<p>Bruno, koleksiyonları düz metin dosyalarında saklayarak Git üzerinden sürümlemeyi kolaylaştırır. Böylece API değişiklikleri pull request içinde görülebilir; “Bu header’ı kim değiştirdi?” sorusu polisiye romana dönüşmez.</p>

<p>Örnek bir Bruno isteği şöyle görünebilir:</p>

<pre><code class="language-bru">meta {
  name: Kullanıcı Getir
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/users/42
  body: none
  auth: bearer
}

assert {
  res.status: eq 200
  res.body.id: eq 42
}
</code></pre>

<p>Bu dosya isteğin adresini tanımlar ve yanıtın durum koduyla kullanıcı kimliğini doğrular. CLI desteği sayesinde aynı koleksiyon CI/CD hattında da çalıştırılabilir.</p>

<h3 id="insomnia-düzenli-ve-kapsamlı-çalışma-masası">Insomnia: Düzenli ve kapsamlı çalışma masası</h3>

<p>Insomnia; ortam değişkenleri, kimlik doğrulama yöntemleri, GraphQL desteği ve koleksiyon organizasyonuyla kapsamlı projelerde rahat bir deneyim sunar. Çok sayıda servisi olan ekipler için klasörlü yapı ve yeniden kullanılabilir değişkenler önemlidir.</p>

<p>Örneğin geliştirme ve üretim adreslerini ayrı ayrı yazmak yerine şu mantık kullanılabilir:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"base_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.example.com"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"token"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{{ secret_token }}"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Böylece isteklerde `` kullanılır ve ortam değiştirirken her endpoint’i elle düzenlemek gerekmez. Token değerlerini repoya eklememek ise temel güvenlik kuralıdır.</p>

<h2 id="hangisini-seçmelisiniz">Hangisini seçmelisiniz?</h2>

<p>Hızlı, kurulumsuz denemeler için <strong>Hoppscotch</strong>; koleksiyonları Git ile yönetmek ve testleri pipeline’a taşımak için <strong>Bruno</strong>; kapsamlı masaüstü deneyimi ve düzenli proje yönetimi için <strong>Insomnia</strong> öne çıkar. En iyi araç, en fazla düğmeye sahip olan değil, ekibinizin testleri düzenli çalıştırmasını sağlayandır. Küçük bir örnek API’yi üçünde de deneyin; ardından hız, paylaşım, güvenlik ve otomasyon ihtiyaçlarınıza göre karar verin.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="api" /><category term="hoppscotch" /><category term="bruno" /><category term="insomnia" /><category term="rest" /><category term="yazılım-testi" /><summary type="html"><![CDATA[Bir API geliştirirken yalnızca endpoint’in çalışması yetmez; doğru durum kodunu, beklenen veriyi ve kabul edilebilir sürede yanıt verdiğini de doğrulamak gerekir. Postman dışında bir araç arıyorsanız Hoppscotch, Bruno ve Insomnia oldukça güçlü üç adaydır. Üstelik her biri API testine farklı bir pencereden bakar: biri hızlı ve web tabanlı, biri Git dostu, diğeri ise kapsamlı bir masaüstü çalışma alanıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/api-test-arenasi-95.png" /><media:content medium="image" url="https://program.sonsuz.us/img/api-test-arenasi-95.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dijital Hafızanı Kur: Linkwarden, Linkding ve Shaarli Karşılaştırması</title><link href="https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi/" rel="alternate" type="text/html" title="Dijital Hafızanı Kur: Linkwarden, Linkding ve Shaarli Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi/"><![CDATA[<p>Tarayıcı yer imleri bir süre sonra çekmecedeki kablolara benzer: Hepsinin önemli olduğuna eminsindir ama hangisinin ne işe yaradığını bulamazsın. Linkwarden, Linkding ve Shaarli; bağlantıları etiketleyerek saklamayı, aramayı ve kendi sunucunda yönetmeyi sağlayan açık kaynaklı yer imi araçlarıdır. Böylece tarayıcıya veya ticari bir servise bağımlı kalmadan kişisel bir dijital kütüphane kurabilirsin.
``</p>
<h2 id="yer-imi-sistemi-aslında-ne-yapar">Yer imi sistemi aslında ne yapar?</h2>

<p>İyi bir bookmark sistemi yalnızca URL depolamaz. Bir bağlantıyı; başlık, açıklama, etiket, eklenme tarihi ve arşivlenmiş içerikle birlikte saklar. Teorik olarak her kaydı şu kümeyle gösterebiliriz:</p>

\[B = \{u, t, d, E, z, a\}\]

<p>Burada $u$ adresi, $t$ başlığı, $d$ açıklamayı, $E$ etiketler kümesini, $z$ eklenme zamanını ve $a$ arşiv kopyasını temsil eder. Etiketleme sayesinde arama alanı küçülür. Toplam $N$ bağlantının yalnızca belirli bir etikete ait $k$ tanesini incelemek, zihinsel yükü kabaca $N$ öğeden $k$ öğeye indirir.</p>

<p>Örneğin <code class="language-plaintext highlighter-rouge">python</code>, <code class="language-plaintext highlighter-rouge">veritabanı</code> ve <code class="language-plaintext highlighter-rouge">okunacak</code> etiketlerinin kesişimi şöyle düşünülebilir:</p>

\[S = E_{python} \cap E_{veritabanı} \cap E_{okunacak}\]

<p>Bu yaklaşım klasörlerden daha esnektir; çünkü aynı bağlantı birden fazla bağlama ait olabilir.</p>

<h2 id="üç-aracın-karakteri">Üç aracın karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Linkwarden</th>
      <th>Linkding</th>
      <th>Shaarli</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Arayüz</td>
      <td>Modern ve görsel</td>
      <td>Sade ve hızlı</td>
      <td>Minimal, klasik</td>
    </tr>
    <tr>
      <td>Sayfa arşivleme</td>
      <td>Güçlü; ekran görüntüsü ve belge</td>
      <td>Temel kullanım odaklı</td>
      <td>Sınırlı</td>
    </tr>
    <tr>
      <td>Çoklu kullanıcı</td>
      <td>Uygun</td>
      <td>Daha çok kişisel kullanım</td>
      <td>Temelde kişisel</td>
    </tr>
    <tr>
      <td>Kaynak tüketimi</td>
      <td>Görece yüksek</td>
      <td>Düşük</td>
      <td>Çok düşük</td>
    </tr>
    <tr>
      <td>Teknoloji</td>
      <td>Next.js, PostgreSQL</td>
      <td>Python, SQLite</td>
      <td>PHP, dosya tabanlı</td>
    </tr>
    <tr>
      <td>En iyi senaryo</td>
      <td>Ekip ve kalıcı arşiv</td>
      <td>Hızlı kişisel koleksiyon</td>
      <td>Küçük sunucu</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/dijital-hafizani-kur-71.svg" alt="dijital-hafizani-kur-71" /></p>

<h3 id="linkwarden">Linkwarden</h3>

<p>Linkwarden, bağlantı çürümesine karşı en güçlü seçenektir. Bir web sayfası silinse bile ekran görüntüsü veya PDF benzeri arşivleri koruyabilir. Koleksiyon paylaşımı ve kullanıcı yönetimi sayesinde ekipler için de uygundur. Bunun bedeli daha fazla RAM, depolama ve kurulum bileşenidir.</p>

<h3 id="linkding">Linkding</h3>

<p>Linkding, “yer imimi ekleyeyim ve hemen bulayım” yaklaşımını benimser. Arayüzü dikkat dağıtmaz; etiketleme, arama, içe aktarma ve tarayıcı eklentileri günlük kullanımda oldukça yeterlidir. SQLite kullanması yedeklemeyi de kolaylaştırır: Çoğu durumda veritabanı dosyasını güvenli biçimde kopyalamak yeterlidir.</p>

<h3 id="shaarli">Shaarli</h3>

<p>Shaarli, eski bir dizüstünü sunucuya dönüştürenlerin kahramanıdır. PHP çalıştırabilen mütevazı bir sunucuda yaşayabilir ve veritabanı sunucusu gerektirmez. Arayüzü rakipleri kadar modern değildir; fakat taşınabilirlik ve sadelik konusunda oldukça güçlüdür.</p>

<h2 id="docker-ile-linkding-kurulumu">Docker ile Linkding kurulumu</h2>

<p>Aşağıdaki <code class="language-plaintext highlighter-rouge">compose.yaml</code>, Linkding servisini başlatır ve verileri kalıcı bir klasörde tutar:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">services</span><span class="pi">:</span>
  <span class="na">linkding</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">sissbruecker/linkding:latest</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">linkding</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">9090:9090"</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">./data:/etc/linkding/data</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">LD_SUPERUSER_NAME=admin</span>
      <span class="pi">-</span> <span class="s">LD_SUPERUSER_PASSWORD=guclu-bir-parola</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
</code></pre></div></div>

<p>Dosyanın bulunduğu dizinde şu komutu çalıştır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker compose up <span class="nt">-d</span>
</code></pre></div></div>

<p>Ardından <code class="language-plaintext highlighter-rouge">http://sunucu-adresi:9090</code> üzerinden giriş yapabilirsin. <code class="language-plaintext highlighter-rouge">volumes</code> bölümü, konteyner silinse bile kayıtların <code class="language-plaintext highlighter-rouge">data</code> klasöründe kalmasını sağlar. Gerçek kullanımda güçlü parola, HTTPS ve düzenli yedekleme şarttır; yönetim panelini doğrudan internete açmak iyi bir macera türü değildir.</p>

<h2 id="hangisini-seçmelisin">Hangisini seçmelisin?</h2>

<p>Kalıcı web arşivi ve ekip paylaşımı istiyorsan <strong>Linkwarden</strong>, hızlı ve dengeli bir kişisel sistem arıyorsan <strong>Linkding</strong>, en düşük kaynak tüketimiyle bağımsızlık hedefliyorsan <strong>Shaarli</strong> seç. En iyi araç, yüzlerce özelliği olan değil, yeni bağlantı eklemeyi erteletmeyecek kadar rahat olandır. Sistemi seçtikten sonra az sayıda tutarlı etiket belirle, tarayıcıdaki eski yer imlerini içe aktar ve otomatik yedekleme kur. Dijital çekmecen sonunda gerçekten düzenli kalabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yer imi" /><category term="linkwarden" /><category term="linkding" /><category term="shaarli" /><category term="self-hosted" /><category term="docker" /><summary type="html"><![CDATA[Tarayıcı yer imleri bir süre sonra çekmecedeki kablolara benzer: Hepsinin önemli olduğuna eminsindir ama hangisinin ne işe yaradığını bulamazsın. Linkwarden, Linkding ve Shaarli; bağlantıları etiketleyerek saklamayı, aramayı ve kendi sunucunda yönetmeyi sağlayan açık kaynaklı yer imi araçlarıdır. Böylece tarayıcıya veya ticari bir servise bağımlı kalmadan kişisel bir dijital kütüphane kurabilirsin.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/dijital-hafizani-kur-71.png" /><media:content medium="image" url="https://program.sonsuz.us/img/dijital-hafizani-kur-71.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dosyalar Güvende: Duplicati, BorgBackup ve Restic Karşılaştırması</title><link href="https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi/" rel="alternate" type="text/html" title="Dosyalar Güvende: Duplicati, BorgBackup ve Restic Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi/"><![CDATA[<p>Bir diskin bozulması, yanlışlıkla çalıştırılan bir silme komutu veya fidye yazılımı, yılların verisini saniyeler içinde erişilemez hâle getirebilir. Neyse ki Duplicati, BorgBackup ve Restic; şifreleme, sıkıştırma ve artımlı yedekleme gibi modern özelliklerle “Keşke yedek alsaydım!” cümlesini tarihe gömmeyi amaçlıyor.
``</p>

<h2 id="sağlam-bir-yedekleme-sisteminin-mantığı">Sağlam bir yedekleme sisteminin mantığı</h2>

<p>Yedekleme, dosyaları başka bir klasöre kopyalamaktan ibaret değildir. Güvenilir bir plan için yaygın <strong>3-2-1 kuralı</strong> uygulanabilir:</p>

<ul>
  <li>Verinin en az <strong>3 kopyası</strong> bulunmalı.</li>
  <li>Kopyalar <strong>2 farklı ortamda</strong> tutulmalı.</li>
  <li>Kopyalardan <strong>1 tanesi uzak konumda</strong> olmalı.</li>
</ul>

<p>Depolama ihtiyacını azaltmak için üç araç da artımlı yedekleme yaklaşımından yararlanır. İlk çalıştırmada tüm veri saklanırken sonraki çalıştırmalarda yalnızca değişiklikler gönderilir. Basitleştirilmiş depolama hesabı şöyledir:</p>

\[S = F + \sum_{i=1}^{n} \Delta_i\]

<p>Burada $F$ ilk tam yedeğin boyutunu, $\Delta_i$ ise her çalıştırmada değişen veri miktarını temsil eder. Tekilleştirme sayesinde aynı veri bloklarının tekrar saklanması önlenebilir. Örneğin 10 GB’lık bir dosyanın yalnızca küçük bir bölümü değiştiğinde yeniden 10 GB göndermek gerekmez.</p>

<h2 id="üç-aracın-karşılaştırması">Üç aracın karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Duplicati</th>
      <th>BorgBackup</th>
      <th>Restic</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kullanım biçimi</td>
      <td>Web arayüzü ve CLI</td>
      <td>Komut satırı</td>
      <td>Komut satırı</td>
    </tr>
    <tr>
      <td>İşletim sistemi</td>
      <td>Windows, Linux, macOS</td>
      <td>Özellikle Linux/macOS</td>
      <td>Windows, Linux, macOS</td>
    </tr>
    <tr>
      <td>Tekilleştirme</td>
      <td>Var</td>
      <td>Çok güçlü</td>
      <td>Var</td>
    </tr>
    <tr>
      <td>Şifreleme</td>
      <td>AES-256</td>
      <td>Yerleşik</td>
      <td>Yerleşik</td>
    </tr>
    <tr>
      <td>Uzak depolama</td>
      <td>Çok sayıda bulut servisi</td>
      <td>Genellikle SSH</td>
      <td>S3, SFTP ve çeşitli servisler</td>
    </tr>
    <tr>
      <td>İdeal kullanıcı</td>
      <td>Görsel arayüz isteyenler</td>
      <td>Performans odaklı Linux kullanıcıları</td>
      <td>Taşınabilirlik isteyenler</td>
    </tr>
  </tbody>
</table>

<p><strong>Duplicati</strong>, tarayıcıdan yönetilen arayüzü sayesinde zamanlama, hedef seçimi ve geri yükleme işlemlerini kolaylaştırır. Google Drive, OneDrive ve S3 gibi hedeflere doğrudan bağlanabilmesi önemli bir avantajdır. Buna karşılık büyük yedek kümelerinde veritabanı bakımı gerekebilir.</p>

<p><strong>BorgBackup</strong>, içerik tanımlı parçalama ve güçlü tekilleştirme özellikleriyle özellikle Linux sunucularında parlar. Depoların SSH üzerinden kullanılabilmesi güvenli ve hızlı bir yapı sunar. Ancak grafik arayüz bekleyen kullanıcılar için biraz fazla terminal kokabilir.</p>

<p><strong>Restic</strong> ise sade komutları, tek dosyalık kurulumu ve platformlar arası desteğiyle öne çıkar. Şifreleme varsayılan tasarımın parçasıdır; yedek deposu ele geçirilse bile parola olmadan içerik okunamaz.</p>

<h2 id="borgbackup-ile-örnek-yedekleme">BorgBackup ile örnek yedekleme</h2>

<p>Önce şifreli bir depo oluşturulur, ardından proje dizini arşivlenir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>borg init <span class="nt">--encryption</span><span class="o">=</span>repokey-blake2 /mnt/backup/borg-repo
borg create <span class="nt">--stats</span> /mnt/backup/borg-repo::proje-<span class="o">{</span>now<span class="o">}</span> ~/projeler
</code></pre></div></div>

<p>İlk komut şifreli depoyu hazırlar. İkinci komut, tarih bilgisini taşıyan yeni bir anlık görüntü oluşturur. Eski yedekleri kontrollü biçimde temizlemek için şu politika uygulanabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>borg prune <span class="nt">--list</span> /mnt/backup/borg-repo <span class="se">\</span>
  <span class="nt">--keep-daily</span><span class="o">=</span>7 <span class="nt">--keep-weekly</span><span class="o">=</span>4 <span class="nt">--keep-monthly</span><span class="o">=</span>6
</code></pre></div></div>

<p>Bu komut son yedi günlük, dört haftalık ve altı aylık yedeği korur.</p>

<h2 id="restic-ile-uzak-hedef-kullanımı">Restic ile uzak hedef kullanımı</h2>

<p>Restic deposu SFTP üzerinde hazırlanabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">RESTIC_REPOSITORY</span><span class="o">=</span>sftp:user@sunucu:/yedekler/restic
restic init
restic backup ~/Belgeler ~/Fotoğraflar
restic check
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">backup</code> verileri şifreleyerek gönderirken <code class="language-plaintext highlighter-rouge">check</code>, depo bütünlüğünü denetler. Parola otomasyon sırasında açıkça yazılmamalı; izinleri sınırlandırılmış bir parola dosyası veya güvenli sır yönetim sistemi kullanılmalıdır.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Masaüstünde kolay yönetim ve bulut bağlantıları için <strong>Duplicati</strong>, Linux sunucusunda yüksek verimlilik için <strong>BorgBackup</strong>, farklı sistemlerde sade ve güvenli kullanım için <strong>Restic</strong> güçlü adaydır. Hangi araç seçilirse seçilsin, yalnızca yedek almak yeterli değildir. Düzenli geri yükleme testi yapılmayan bir yedek, açılana kadar Schrödinger’in yedeğidir: Hem vardır hem yoktur!</p>

<p><img src="/img/dosyalar-guvende-duplicati-70.svg" alt="dosyalar-guvende-duplicati-70" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yedekleme" /><category term="duplicati" /><category term="borgbackup" /><category term="restic" /><category term="veri güvenliği" /><category term="linux" /><summary type="html"><![CDATA[Bir diskin bozulması, yanlışlıkla çalıştırılan bir silme komutu veya fidye yazılımı, yılların verisini saniyeler içinde erişilemez hâle getirebilir. Neyse ki Duplicati, BorgBackup ve Restic; şifreleme, sıkıştırma ve artımlı yedekleme gibi modern özelliklerle “Keşke yedek alsaydım!” cümlesini tarihe gömmeyi amaçlıyor.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/dosyalar-guvende-duplicati-70.png" /><media:content medium="image" url="https://program.sonsuz.us/img/dosyalar-guvende-duplicati-70.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Görsel Bulmacalar Olmadan CAPTCHA: ALTCHA, Friendly Captcha ve mCaptcha</title><link href="https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha/" rel="alternate" type="text/html" title="Görsel Bulmacalar Olmadan CAPTCHA: ALTCHA, Friendly Captcha ve mCaptcha" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha</id><content type="html" xml:base="https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha/"><![CDATA[<p>Trafik ışığı seçmekten motosiklet aramaya kadar klasik CAPTCHA’lar kullanıcıları küçük bir sınava sokar. ALTCHA, Friendly Captcha ve mCaptcha ise “İnsan olduğunu kanıtla” yaklaşımını tersine çevirir: Kullanıcı yerine tarayıcı, arka planda küçük bir hesaplama yapar. Böylece erişilebilirlik, gizlilik ve kullanıcı deneyimi açısından daha dost canlısı bir savunma katmanı ortaya çıkar.</p>

<p>``</p>

<h2 id="temel-fikir-proof-of-work">Temel fikir: Proof of Work</h2>

<p>Bu sistemlerin merkezinde <strong>iş ispatı</strong> veya benzeri görünmez doğrulama mekanizmaları bulunur. Sunucu, istemciye çözülmesi ölçülü miktarda işlem gerektiren bir problem verir. Tarayıcı çözümü bulur; sunucu ise sonucu çok daha düşük maliyetle doğrular.</p>

<p>Basitleştirilmiş bir problem şöyle düşünülebilir:</p>

\[H(\text{challenge} \parallel n) &lt; T\]

<p>Burada $H$ bir özet fonksiyonu, $n$ tarayıcının aradığı sayı ve $T$ zorluk eşiğidir. Eşik küçüldükçe uygun sayı bulmak zorlaşır. Ortalama hesaplama maliyeti yaklaşık olarak:</p>

\[E[\text{deneme}] \approx \frac{2^b}{T}\]

<p>şeklinde yorumlanabilir. Meşru bir kullanıcı için birkaç yüz milisaniyelik iş önemsizdir; milyonlarca sahte istek gönderen bot açısından aynı maliyet çarpılarak büyür. Yine de bu yöntem botları sihirli biçimde yok etmez, yalnızca saldırının ekonomisini bozar.</p>

<h2 id="üç-çözümün-karşılaştırması">Üç çözümün karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>ALTCHA</th>
      <th>Friendly Captcha</th>
      <th>mCaptcha</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana yaklaşım</td>
      <td>Proof of Work tabanlı challenge</td>
      <td>Arka planda kriptografik puzzle</td>
      <td>Uyarlanabilir Proof of Work</td>
    </tr>
    <tr>
      <td>Kullanıcı etkileşimi</td>
      <td>Genellikle tek kutu veya görünmez akış</td>
      <td>Çoğunlukla görünmez</td>
      <td>Görünmez doğrulama</td>
    </tr>
    <tr>
      <td>Self-hosting</td>
      <td>Güçlü ve esnek</td>
      <td>Ürüne/plana göre değerlendirilir</td>
      <td>Temel odak noktalarından biri</td>
    </tr>
    <tr>
      <td>Entegrasyon tarzı</td>
      <td>Açık kaynak kütüphane ve widget</td>
      <td>Yönetilen servis ve SDK’lar</td>
      <td>Açık kaynak sunucu kurulumu</td>
    </tr>
    <tr>
      <td>Uygun senaryo</td>
      <td>Kontrol isteyen geliştiriciler</td>
      <td>Hızlı SaaS entegrasyonu</td>
      <td>Tam bağımsız altyapı isteyenler</td>
    </tr>
  </tbody>
</table>

<p><strong>ALTCHA</strong>, sade protokolü ve self-hosting seçeneğiyle uygulama mimarisine kolayca yerleşir. <strong>Friendly Captcha</strong>, operasyon yükünü azaltmak isteyen ekipler için yönetilen hizmet deneyimine odaklanır. <strong>mCaptcha</strong> ise açık kaynaklı, bağımsız ve uyarlanabilir bir CAPTCHA altyapısı kurmak isteyenler açısından dikkat çekicidir.</p>

<h2 id="altcha-ile-örnek-sunucu-akışı">ALTCHA ile örnek sunucu akışı</h2>

<p>Aşağıdaki Express örneği bir challenge üretir ve tarayıcıdan gelen çözümü doğrular:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">express</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">express</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">createChallenge</span><span class="p">,</span> <span class="nx">verifySolution</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">altcha-lib</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">json</span><span class="p">());</span>

<span class="kd">const</span> <span class="nx">hmacKey</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">ALTCHA_HMAC_KEY</span><span class="p">;</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">"</span><span class="s2">/captcha/challenge</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">challenge</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">createChallenge</span><span class="p">({</span>
    <span class="nx">hmacKey</span><span class="p">,</span>
    <span class="na">maxNumber</span><span class="p">:</span> <span class="mi">100000</span>
  <span class="p">});</span>

  <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">(</span><span class="nx">challenge</span><span class="p">);</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/contact</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">valid</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">verifySolution</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">altcha</span><span class="p">,</span> <span class="nx">hmacKey</span><span class="p">);</span>

  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">valid</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nf">status</span><span class="p">(</span><span class="mi">400</span><span class="p">).</span><span class="nf">json</span><span class="p">({</span> <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">CAPTCHA doğrulanamadı</span><span class="dl">"</span> <span class="p">});</span>
  <span class="p">}</span>

  <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">({</span> <span class="na">success</span><span class="p">:</span> <span class="kc">true</span> <span class="p">});</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">maxNumber</code>, istemcinin yapabileceği maksimum arama miktarını sınırlar. HMAC anahtarı challenge’ın sunucu tarafından üretildiğini kanıtlar; bu anahtar istemciye kesinlikle gönderilmemelidir. Kullanılan kütüphane sürümüne göre fonksiyon imzalarının kontrol edilmesi de önemlidir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Hızlı entegrasyon ve yönetilen altyapı istiyorsanız Friendly Captcha pratik olabilir. Veriyi, anahtarları ve doğrulama sürecini kendi sisteminizde tutmak istiyorsanız ALTCHA daha hafif bir seçenek sunar. Tamamen açık kaynak bir CAPTCHA servisini bağımsız çalıştırmak ve iş yükünü dinamik ayarlamak istiyorsanız mCaptcha güçlü bir adaydır.</p>

<p>Hiçbiri tek başına yeterli savunma değildir. CAPTCHA’yı <strong>rate limiting</strong>, IP ve hesap bazlı kota, tekrar saldırısı engelleme, kısa challenge süresi ve davranışsal sinyallerle destekleyin. Mobil cihazlarda aşırı zorluk pil tüketebilir; çok düşük zorluk ise bot maliyetini artırmaz. En iyi ayar, güvenlik ile gerçek kullanıcıların bekleme süresi arasındaki dengedir.</p>

<p><img src="/img/gorsel-bulmacalar-olmadan-80.svg" alt="gorsel-bulmacalar-olmadan-80" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="captcha" /><category term="altcha" /><category term="friendly-captcha" /><category term="mcaptcha" /><category term="web-güvenliği" /><category term="proof-of-work" /><summary type="html"><![CDATA[Trafik ışığı seçmekten motosiklet aramaya kadar klasik CAPTCHA’lar kullanıcıları küçük bir sınava sokar. ALTCHA, Friendly Captcha ve mCaptcha ise “İnsan olduğunu kanıtla” yaklaşımını tersine çevirir: Kullanıcı yerine tarayıcı, arka planda küçük bir hesaplama yapar. Böylece erişilebilirlik, gizlilik ve kullanıcı deneyimi açısından daha dost canlısı bir savunma katmanı ortaya çıkar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/gorsel-bulmacalar-olmadan-80.png" /><media:content medium="image" url="https://program.sonsuz.us/img/gorsel-bulmacalar-olmadan-80.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hatalar Kaçmadan Yakalayın: Sentry, GlitchTip ve Bugsink Karşılaştırması</title><link href="https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi/" rel="alternate" type="text/html" title="Hatalar Kaçmadan Yakalayın: Sentry, GlitchTip ve Bugsink Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi/"><![CDATA[<p>Uygulamanız geliştirme ortamında kusursuz çalışırken üretimde beklenmedik bir hata verebilir. Kullanıcının yalnızca “sayfa açılmadı” diye tarif ettiği bu olayın nedenini bulmak ise samanlıkta istisna aramaya benzer. Hata takip sistemleri; istisnaları, çağrı yığınlarını, kullanıcı etkileşimlerini ve ortam bilgilerini merkezi bir yerde toplayarak bu süreci hızlandırır. Bu alandaki popüler seçeneklerden Sentry, GlitchTip ve Bugsink aynı probleme farklı ölçek ve sadelik seviyeleriyle yaklaşır.</p>

<p><img src="/img/hatalar-kacmadan-yakalayin-56.svg" alt="hatalar-kacmadan-yakalayin-56" /></p>

<p>``</p>

<h2 id="hata-takip-sistemi-nasıl-çalışır">Hata takip sistemi nasıl çalışır?</h2>

<p>Uygulamaya eklenen SDK, yakalanmamış bir istisna oluştuğunda bir <strong>hata olayı</strong> üretir. Bu olay genellikle hata mesajını, stack trace bilgisini, sürümü, çalışma ortamını ve isteğe bağlı kullanıcı bağlamını içerir. Veriler bir DSN adresi üzerinden sunucuya gönderilir.</p>

<p>Sistem, benzer olayları tek bir sorun altında gruplandırmaya çalışır. Böylece aynı <code class="language-plaintext highlighter-rouge">NullReferenceException</code> hatası bin kez oluştuğunda panelde bin bağımsız kayıt yerine, gerçekleşme sayacı yükselen tek bir sorun görürüz.</p>

<p>Belirli sürede oluşan olay sayısını $E$, süreyi dakika cinsinden $t$ kabul edersek hata yoğunluğu şöyle ifade edilebilir:</p>

\[R = \frac{E}{t}\]

<p>Örneğin 10 dakikada 500 olay alınması, $R = 50$ olay/dakika anlamına gelir. Ancak yüksek sayı her zaman daha kritik hata demek değildir. Etkilenen kullanıcı sayısı, hata oranı ve işlemin önemi birlikte değerlendirilmelidir.</p>

<h2 id="üç-aracın-kısa-karşılaştırması">Üç aracın kısa karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Sentry</th>
      <th>GlitchTip</th>
      <th>Bugsink</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel yaklaşım</td>
      <td>Kapsamlı gözlemlenebilirlik platformu</td>
      <td>Açık kaynaklı, Sentry uyumlu alternatif</td>
      <td>Hafif ve sade hata takibi</td>
    </tr>
    <tr>
      <td>Barındırma</td>
      <td>Bulut veya self-hosted</td>
      <td>Bulut veya self-hosted</td>
      <td>Özellikle self-hosted kullanım</td>
    </tr>
    <tr>
      <td>Kurulum yükü</td>
      <td>Self-hosted sürümde daha yüksek</td>
      <td>Orta düzey</td>
      <td>Görece düşük</td>
    </tr>
    <tr>
      <td>Performans izleme</td>
      <td>Gelişmiş</td>
      <td>Temel ve orta seviye ihtiyaçlara uygun</td>
      <td>Hata takibine odaklı</td>
    </tr>
    <tr>
      <td>İdeal kullanım</td>
      <td>Büyük ekipler ve ayrıntılı analiz</td>
      <td>Açık kaynak ve maliyet dengesi</td>
      <td>Küçük ekipler, kişisel sunucular</td>
    </tr>
  </tbody>
</table>

<p><strong>Sentry</strong>, hata takibinin yanında performans izleme, dağıtık tracing, sürüm takibi ve oturum tekrarı gibi geniş özellikler sunar. Yönetilen bulut hizmeti operasyon yükünü azaltır; fakat yoğun trafik, veri kotası ve gizlilik gereksinimleri dikkatle değerlendirilmelidir.</p>

<p><strong>GlitchTip</strong>, Sentry SDK’larıyla uyumlu açık kaynaklı bir deneyim sağlamayı amaçlar. Arayüzü daha sade, self-hosted kurulumu ise genellikle daha ulaşılabilirdir. Sentry’nin bütün ileri analiz özelliklerini beklemeyen ekipler için güçlü bir dengedir.</p>

<p><strong>Bugsink</strong>, “önce hatayı yakalayalım” yaklaşımına yakındır. Daha az bileşenle çalışması, küçük sunucularda yönetimi kolaylaştırabilir. Kapsamlı observability platformu yerine anlaşılır bir hata kutusu isteyen projelere uygundur.</p>

<h2 id="python-uygulamasına-sdk-eklemek">Python uygulamasına SDK eklemek</h2>

<p>Üç ürün de Sentry protokolüyle uyumlu kurulum senaryoları sunabildiğinden Python tarafında çoğunlukla resmi SDK kullanılabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">sentry_sdk</span>

<span class="n">sentry_sdk</span><span class="p">.</span><span class="nf">init</span><span class="p">(</span>
    <span class="n">dsn</span><span class="o">=</span><span class="sh">"</span><span class="s">https://anahtar@hata-sunucusu.example/1</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">environment</span><span class="o">=</span><span class="sh">"</span><span class="s">production</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">release</span><span class="o">=</span><span class="sh">"</span><span class="s">magaza-api@2.4.0</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">traces_sample_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
<span class="p">)</span>

<span class="k">def</span> <span class="nf">fiyat_hesapla</span><span class="p">(</span><span class="n">toplam</span><span class="p">,</span> <span class="n">adet</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">toplam</span> <span class="o">/</span> <span class="n">adet</span>

<span class="nf">fiyat_hesapla</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kodda DSN, olayların gideceği projeyi belirtir. <code class="language-plaintext highlighter-rouge">environment</code> üretim ve test kayıtlarını ayırır; <code class="language-plaintext highlighter-rouge">release</code> ise hatanın hangi sürümde başladığını bulmayı kolaylaştırır. <code class="language-plaintext highlighter-rouge">traces_sample_rate=0.1</code>, performans işlemlerinin yaklaşık yüzde 10’unu örnekler. Ürün ve sürüme göre desteklenen SDK özellikleri değişebileceğinden uyumluluk belgeleri kontrol edilmelidir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Hazır servis, gelişmiş analiz ve minimum bakım istiyorsanız Sentry mantıklı başlangıçtır. Veriyi kendi altyapınızda tutmak, açık kaynak kullanmak ve daha ölçülü kaynak tüketmek istiyorsanız GlitchTip değerlendirilebilir. Yalnızca temel hata toplama, gruplama ve bildirim özelliklerine ihtiyacınız varsa Bugsink sadeliğiyle öne çıkar.</p>

<p>Seçimden önce günlük olay hacmini, saklama süresini ve örnekleme oranını hesaplayın. Ayrıca parola, erişim belirteci ve kişisel veri gibi hassas bilgileri SDK filtreleriyle temizleyin. Çünkü iyi bir hata takip sistemi yalnızca çok veri toplayan değil, doğru veriyi güvenli biçimde anlamlı hale getiren sistemdir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="sentry" /><category term="glitchtip" /><category term="bugsink" /><category term="hata-takibi" /><category term="observability" /><category term="python" /><summary type="html"><![CDATA[Uygulamanız geliştirme ortamında kusursuz çalışırken üretimde beklenmedik bir hata verebilir. Kullanıcının yalnızca “sayfa açılmadı” diye tarif ettiği bu olayın nedenini bulmak ise samanlıkta istisna aramaya benzer. Hata takip sistemleri; istisnaları, çağrı yığınlarını, kullanıcı etkileşimlerini ve ortam bilgilerini merkezi bir yerde toplayarak bu süreci hızlandırır. Bu alandaki popüler seçeneklerden Sentry, GlitchTip ve Bugsink aynı probleme farklı ölçek ve sadelik seviyeleriyle yaklaşır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/hatalar-kacmadan-yakalayin-56.png" /><media:content medium="image" url="https://program.sonsuz.us/img/hatalar-kacmadan-yakalayin-56.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi Bug Bounty ve Güvenli Hata Bildirim Sistemini Tasarlamak</title><link href="https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak/" rel="alternate" type="text/html" title="Kendi Bug Bounty ve Güvenli Hata Bildirim Sistemini Tasarlamak" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak/"><![CDATA[<p><img src="/img/kendi-bug-bounty-46.svg" alt="kendi-bug-bounty-46" /></p>

<p>Bir güvenlik araştırmacısı kritik bir açık bulduğunda kime, nasıl ve hangi kanıtlarla ulaşacağını bilmelidir. Open Bug Bounty veya HackerOne benzeri özel bir sistem; araştırmacıları, güvenlik ekiplerini ve ürün sahiplerini aynı iş akışında buluşturur. Fakat bu proje, sıradan bir destek talebi uygulamasından daha fazlasıdır: hassas verileri korumalı, mükerrer raporları yakalamalı ve kontrollü açıklama sürecini yönetmelidir.
``</p>

<h2 id="temel-iş-akışı">Temel iş akışı</h2>

<p>Bir raporun yaşam döngüsü durum makinesi olarak modellenebilir:</p>

<p><code class="language-plaintext highlighter-rouge">Taslak → Gönderildi → İnceleniyor → Doğrulandı → Çözüldü → Açıklandı</code></p>

<p>Rapor geçersizse <strong>Reddedildi</strong>, daha önce bildirilmişse <strong>Mükerrer</strong> durumuna taşınır. Durum makinesi kullanmak, örneğin çözülmüş bir raporun yanlışlıkla yeniden “gönderildi” yapılmasını engeller.</p>

<table>
  <thead>
    <tr>
      <th>Rol</th>
      <th>Yetki</th>
      <th>Görememesi gerekenler</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Araştırmacı</td>
      <td>Rapor oluşturma, kanıt ekleme</td>
      <td>Diğer özel raporlar</td>
    </tr>
    <tr>
      <td>Triyaj uzmanı</td>
      <td>Doğrulama, sınıflandırma</td>
      <td>Finansal yönetim ayarları</td>
    </tr>
    <tr>
      <td>Program sahibi</td>
      <td>Kapsam ve ödül yönetimi</td>
      <td>Gereksiz kişisel veriler</td>
    </tr>
    <tr>
      <td>Yönetici</td>
      <td>Rol ve sistem yönetimi</td>
      <td>Şifresiz gizli içerik</td>
    </tr>
  </tbody>
</table>

<p>Bu ayrım, <strong>en az ayrıcalık ilkesi</strong> üzerine kurulmalıdır. Yalnızca giriş yapmış olmak yeterli değildir; her API isteğinde rol, kaynak sahipliği ve program üyeliği ayrıca denetlenmelidir.</p>

<h2 id="önem-derecesi-ve-ödül-hesabı">Önem derecesi ve ödül hesabı</h2>

<p>Açıkların önceliği CVSS gibi standartlarla belirlenebilir. Daha sade bir özel puanlama için şu model kullanılabilir:</p>

\[Risk = Etki \times İstismarOlasılığı \times VarlıkKatsayısı\]

<p>Her değişken 1 ile 5 arasında seçilirse en yüksek risk puanı $5^3 = 125$ olur. Ödül ise taban tutar ve risk oranıyla hesaplanabilir:</p>

\[Ödül = TabanÖdül \times (Risk / 125)\]

<p>Ancak otomatik sonuç yalnızca öneri olmalıdır. Kaliteli açıklama, çalışan kavram kanıtı ve daha önce raporlanmış olma durumu nihai kararı değiştirebilir.</p>

<h2 id="veri-modeli-ve-güvenlik">Veri modeli ve güvenlik</h2>

<p>Temel tablolar <code class="language-plaintext highlighter-rouge">users</code>, <code class="language-plaintext highlighter-rouge">programs</code>, <code class="language-plaintext highlighter-rouge">assets</code>, <code class="language-plaintext highlighter-rouge">reports</code>, <code class="language-plaintext highlighter-rouge">comments</code>, <code class="language-plaintext highlighter-rouge">attachments</code>, <code class="language-plaintext highlighter-rouge">rewards</code> ve <code class="language-plaintext highlighter-rouge">audit_logs</code> olabilir. Rapor; başlık, etkilenen varlık, açıklık türü, tekrar üretme adımları, etki açıklaması ve çözüm önerisi içermelidir.</p>

<p>Kanıt dosyaları doğrudan herkese açık klasörlere konulmamalıdır. Nesne depolamada şifrelenmeli, kısa ömürlü imzalı bağlantılarla sunulmalı ve zararlı dosya taramasından geçirilmelidir. Parolalar Argon2id ile özetlenmeli; oturumlarda çok faktörlü kimlik doğrulama desteklenmelidir. Audit log kayıtları da “kim, neyi, ne zaman değiştirdi?” sorusunu yanıtlamalıdır.</p>

<h2 id="güvenli-durum-geçişi-örneği">Güvenli durum geçişi örneği</h2>

<p>Aşağıdaki FastAPI kodu, istemcinin istediği her duruma serbestçe geçmesini engeller:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
<span class="kn">from</span> <span class="n">fastapi</span> <span class="kn">import</span> <span class="n">FastAPI</span><span class="p">,</span> <span class="n">HTTPException</span>

<span class="n">app</span> <span class="o">=</span> <span class="nc">FastAPI</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Status</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
    <span class="n">submitted</span> <span class="o">=</span> <span class="sh">"</span><span class="s">submitted</span><span class="sh">"</span>
    <span class="n">triage</span> <span class="o">=</span> <span class="sh">"</span><span class="s">triage</span><span class="sh">"</span>
    <span class="n">confirmed</span> <span class="o">=</span> <span class="sh">"</span><span class="s">confirmed</span><span class="sh">"</span>
    <span class="n">resolved</span> <span class="o">=</span> <span class="sh">"</span><span class="s">resolved</span><span class="sh">"</span>
    <span class="n">rejected</span> <span class="o">=</span> <span class="sh">"</span><span class="s">rejected</span><span class="sh">"</span>

<span class="n">ALLOWED</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">submitted</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">triage</span><span class="p">,</span> <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">triage</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">confirmed</span><span class="p">,</span> <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">confirmed</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">resolved</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">resolved</span><span class="p">:</span> <span class="nf">set</span><span class="p">(),</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">:</span> <span class="nf">set</span><span class="p">()</span>
<span class="p">}</span>

<span class="nd">@app.post</span><span class="p">(</span><span class="sh">"</span><span class="s">/reports/{report_id}/transition</span><span class="sh">"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">transition</span><span class="p">(</span><span class="n">report_id</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">current</span><span class="p">:</span> <span class="n">Status</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span> <span class="n">Status</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">target</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ALLOWED</span><span class="p">[</span><span class="n">current</span><span class="p">]:</span>
        <span class="k">raise</span> <span class="nc">HTTPException</span><span class="p">(</span><span class="mi">409</span><span class="p">,</span> <span class="sh">"</span><span class="s">Geçersiz durum geçişi</span><span class="sh">"</span><span class="p">)</span>

    <span class="c1"># Burada rol kontrolü ve veritabanı güncellemesi yapılır.
</span>    <span class="k">return</span> <span class="p">{</span><span class="sh">"</span><span class="s">report_id</span><span class="sh">"</span><span class="p">:</span> <span class="n">report_id</span><span class="p">,</span> <span class="sh">"</span><span class="s">status</span><span class="sh">"</span><span class="p">:</span> <span class="n">target</span><span class="p">}</span>
</code></pre></div></div>

<p>Gerçek uygulamada <code class="language-plaintext highlighter-rouge">current</code> değeri kullanıcıdan alınmamalı, veritabanından okunmalıdır. Güncelleme atomik bir işlem içinde yapılmalı ve audit log kaydı aynı işlemde oluşturulmalıdır.</p>

<h2 id="sistemi-olgunlaştıran-özellikler">Sistemi olgunlaştıran özellikler</h2>

<p>Mükerrer rapor tespiti için başlık benzerliği, açıklık türü ve etkilenen varlık birlikte değerlendirilebilir; ancak gizlilik nedeniyle araştırmacıya başka raporun ayrıntıları gösterilmemelidir. Bildirimler e-posta ve uygulama içi kanallardan iletilebilir. Oran sınırlama, CAPTCHA ve kötüye kullanım tespiti de spam saldırılarını azaltır.</p>

<p>Son olarak açık bir kapsam politikası hazırlayın: test edilebilen alan adları, yasak yöntemler, hizmet kesintisi kuralları, yanıt süreleri ve güvenli liman şartları net olsun. İyi bir bug bounty platformunun asıl süper gücü yalnızca kodu değil, araştırmacıyla kurulan güveni de korumasıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="bug bounty" /><category term="siber güvenlik" /><category term="hata bildirimi" /><category term="güvenli yazılım" /><category term="api" /><category term="web geliştirme" /><summary type="html"><![CDATA[Bir güvenlik araştırmacısı kritik bir açık bulduğunda kime, nasıl ve hangi kanıtlarla ulaşacağını bilmelidir. Open Bug Bounty veya HackerOne benzeri özel bir sistem; araştırmacıları, güvenlik ekiplerini ve ürün sahiplerini aynı iş akışında buluşturur. Fakat bu proje, sıradan bir destek talebi uygulamasından daha fazlasıdır: hassas verileri korumalı, mükerrer raporları yakalamalı ve kontrollü açıklama sürecini yönetmelidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-bug-bounty-46.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-bug-bounty-46.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi İnternet Radyonu Kur: AzuraCast, LibreTime ve Icecast Rehberi</title><link href="https://program.sonsuz.us/posts/kendi-internet-radyonu-kur-azuracast-libretime-ve-icecast-rehberi/" rel="alternate" type="text/html" title="Kendi İnternet Radyonu Kur: AzuraCast, LibreTime ve Icecast Rehberi" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-internet-radyonu-kur-azuracast-libretime-ve-icecast-rehberi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-internet-radyonu-kur-azuracast-libretime-ve-icecast-rehberi/"><![CDATA[<p>İnternet radyosu kurmak, bir mikrofonu sunucuya bağlayıp müzik çalmaktan biraz daha fazlasıdır. Sesin kodlanması, yayın akışının yönetilmesi, dinleyicilere dağıtılması ve programların zamanlanması gerekir. Neyse ki AzuraCast, LibreTime ve Icecast sayesinde küçük bir odadan dünyanın dört bir yanına yayın yapmak artık oldukça erişilebilir.</p>

<p>``</p>

<h2 id="i̇nternet-radyosu-nasıl-çalışır">İnternet radyosu nasıl çalışır?</h2>

<p>Tipik bir sistemde ses önce bir <strong>kaynak istemci</strong> tarafından MP3, AAC veya Opus biçiminde kodlanır. Kodlanmış veri Icecast gibi bir yayın sunucusuna gönderilir. Dinleyiciler ise belirli bir bağlantıya bağlanarak aynı akışı küçük bir tampon gecikmesiyle alır.</p>

<p>Temel mimari şöyledir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mikrofon / Otomasyon
        |
        v
Kodlayıcı veya AutoDJ
        |
        v
Icecast Yayın Sunucusu
        |
        +----&gt; Web oynatıcı
        +----&gt; Mobil uygulama
        +----&gt; Masaüstü oynatıcı
</code></pre></div></div>

<p><img src="/img/kendi-internet-radyonu-19.svg" alt="kendi-internet-radyonu-19" /></p>

<p>Gerekli bant genişliği yaklaşık olarak şu formülle hesaplanabilir:</p>

\[B = N \times R\]

<p>Burada $N$ eş zamanlı dinleyici sayısını, $R$ ise kişi başına bit hızını ifade eder. Örneğin 100 dinleyiciye 128 kbps yayın yaparsak:</p>

\[100 \times 128 = 12800\text{ kbps} \approx 12.8\text{ Mbps}\]

<p>Sunucunun diğer trafiğini de düşünerek bunun üzerinde bir bağlantı kapasitesi seçmek gerekir.</p>

<h2 id="üç-araç-arasındaki-fark">Üç araç arasındaki fark</h2>

<p>Bu yazılımlar aynı problemi farklı katmanlarda çözer. Icecast dağıtım motorudur; AzuraCast ve LibreTime ise otomasyon, takvim ve yönetim özellikleri sunar.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>AzuraCast</th>
      <th>LibreTime</th>
      <th>Icecast</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Web yönetim paneli</td>
      <td>Gelişmiş</td>
      <td>Gelişmiş</td>
      <td>Temel durum sayfası</td>
    </tr>
    <tr>
      <td>AutoDJ</td>
      <td>Var</td>
      <td>Var</td>
      <td>Yok</td>
    </tr>
    <tr>
      <td>Program takvimi</td>
      <td>Var</td>
      <td>Var</td>
      <td>Yok</td>
    </tr>
    <tr>
      <td>Canlı yayın desteği</td>
      <td>Var</td>
      <td>Var</td>
      <td>Var</td>
    </tr>
    <tr>
      <td>Docker kurulumu</td>
      <td>Çok kolay</td>
      <td>Kuruluma bağlı</td>
      <td>Mümkün</td>
    </tr>
    <tr>
      <td>Ana rol</td>
      <td>Hepsi bir arada radyo</td>
      <td>Yayın otomasyonu</td>
      <td>Ses dağıtımı</td>
    </tr>
  </tbody>
</table>

<p><strong>AzuraCast</strong>, hızlı başlangıç isteyenler için en pratik seçenektir. İstasyon oluşturma, müzik yükleme, çalma listeleri, DJ hesapları, istatistikler ve web oynatıcı tek panelde bulunur. Arka planda genellikle Liquidsoap ve Icecast gibi bileşenleri birlikte yönetir.</p>

<p><strong>LibreTime</strong>, radyo programcılığı ve yayın akışı planlamasına odaklanır. Saatlik programlar, tekrarlar, önceden kaydedilmiş içerikler ve canlı stüdyo geçişleri için güçlüdür. Özellikle ekip halinde çalışan topluluk radyolarına uygundur.</p>

<p><strong>Icecast</strong> ise daha yalındır. Otomasyon sağlamaz; kendisine gönderilen sesi <code class="language-plaintext highlighter-rouge">/radio.mp3</code> gibi bir bağlama noktası, yani <em>mount point</em> üzerinden dinleyicilere ulaştırır. Kendi panelini geliştirmek veya yalnızca dağıtım katmanı kurmak isteyenler için idealdir.</p>

<h2 id="azuracast-ile-hızlı-kurulum">AzuraCast ile hızlı kurulum</h2>

<p>Docker destekli güncel bir Linux sunucusunda AzuraCast kurulum betiği kullanılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> /var/azuracast
<span class="nb">cd</span> /var/azuracast
curl <span class="nt">-fsSL</span> https://get.azuracast.com | bash
</code></pre></div></div>

<p>Bu komut kurulum yöneticisini indirir ve gerekli konteynerleri hazırlar. İşlem tamamlandığında tarayıcıdan sunucunun adresine giderek yönetici hesabı ve ilk istasyon oluşturulur. Çalma listesine parçalar eklendiğinde AutoDJ yayına başlayabilir.</p>

<p>Alan adı kullanıyorsanız HTTPS yapılandırmayı unutmayın. Yönetim panelini doğrudan internete açmak yerine güçlü parolalar, güvenlik duvarı ve düzenli yedekleme kullanmak önemlidir.</p>

<h2 id="icecast-bağlantısını-test-etmek">Icecast bağlantısını test etmek</h2>

<p>Sunucunun yayın durumunu terminalden kontrol etmek için şu komut kullanılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-I</span> https://radyo.example.com/radio.mp3
</code></pre></div></div>

<p>Başarılı bir bağlantıda <code class="language-plaintext highlighter-rouge">200 OK</code> yanıtı görülür. Akışı VLC ile denemek için bağlantıyı doğrudan açabilir veya şu komutu çalıştırabilirsiniz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vlc https://radyo.example.com/radio.mp3
</code></pre></div></div>

<h2 id="hangisini-seçmelisin">Hangisini seçmelisin?</h2>

<p>Tek sunucuda hızla çalışan modern bir istasyon istiyorsan <strong>AzuraCast</strong>, ayrıntılı yayın takvimi ve ekip iş akışı arıyorsan <strong>LibreTime</strong>, özel bir sistem geliştiriyor ve yalnızca güvenilir ses dağıtımı istiyorsan <strong>Icecast</strong> seçebilirsin. Küçük başlayıp ölçüm yapmak en sağlıklısıdır: düşük bit hızında deneme yayını aç, gecikmeyi gözlemle, ardından dinleyici sayısına göre işlemci ve bant genişliğini artır. Böylece dijital frekansın parazitsiz, sunucun da dumansız çalışır!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="internet radyo" /><category term="azuracast" /><category term="libretime" /><category term="icecast" /><category term="linux" /><category term="docker" /><category term="yayıncılık" /><summary type="html"><![CDATA[İnternet radyosu kurmak, bir mikrofonu sunucuya bağlayıp müzik çalmaktan biraz daha fazlasıdır. Sesin kodlanması, yayın akışının yönetilmesi, dinleyicilere dağıtılması ve programların zamanlanması gerekir. Neyse ki AzuraCast, LibreTime ve Icecast sayesinde küçük bir odadan dünyanın dört bir yanına yayın yapmak artık oldukça erişilebilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-internet-radyonu-19.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-internet-radyonu-19.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi Müzik Bulutunu Kur: Funkwhale, Navidrome ve Ampache Karşılaştırması</title><link href="https://program.sonsuz.us/posts/kendi-muzik-bulutunu-kur-funkwhale-navidrome-ve-ampache-karsilastirmasi/" rel="alternate" type="text/html" title="Kendi Müzik Bulutunu Kur: Funkwhale, Navidrome ve Ampache Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-muzik-bulutunu-kur-funkwhale-navidrome-ve-ampache-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-muzik-bulutunu-kur-funkwhale-navidrome-ve-ampache-karsilastirmasi/"><![CDATA[<p>Spotify rahat olabilir; ancak arşivinizin kontrolünü, dinleme geçmişinizi ve sunucunuzu başkasına bırakmak istemiyorsanız kendi müzik paylaşım sisteminizi kurabilirsiniz. Funkwhale, Navidrome ve Ampache bu işin üç güçlü adayıdır. Üçü de müziğinizi tarayıcıya ve mobil istemcilere ulaştırır, fakat mimarileri ve hedefledikleri kullanım biçimleri epey farklıdır.</p>

<p>``</p>

<h2 id="temel-mantık-dosyadan-müzik-servisine">Temel mantık: Dosyadan müzik servisine</h2>

<p>Bir müzik sunucusu yalnızca MP3 dosyalarını internete açmaz. Önce belirlediğiniz klasörleri tarar, ID3 veya Vorbis etiketlerinden sanatçı, albüm ve tür bilgilerini çıkarır, kapak görsellerini indeksler ve sonuçları bir veritabanına kaydeder. Kullanıcı oynat düğmesine bastığında dosya doğrudan gönderilebilir veya cihazın desteklediği formata <strong>transcode</strong> edilebilir.</p>

<p>Aynı anda dinleyen kullanıcıların ihtiyaç duyduğu yaklaşık bant genişliği şöyle hesaplanır:</p>

\[B_{toplam} = n \times b\]

<p>Burada $n$ eş zamanlı dinleyici sayısı, $b$ ise parça başına bit hızıdır. Örneğin 5 kullanıcı 320 kbps ses dinliyorsa gereken yükleme kapasitesi yaklaşık $5 \times 320 = 1600$ kbps olur. FLAC arşivlerinde bu değer hızla büyüdüğü için mobil kullanıcılara 128 veya 192 kbps dönüştürme yapmak mantıklıdır.</p>

<h2 id="üç-sistemin-karakteri">Üç sistemin karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Funkwhale</th>
      <th>Navidrome</th>
      <th>Ampache</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel teknoloji</td>
      <td>Python, Django, PostgreSQL</td>
      <td>Go, SQLite</td>
      <td>PHP, MySQL/MariaDB</td>
    </tr>
    <tr>
      <td>Kaynak tüketimi</td>
      <td>Görece yüksek</td>
      <td>Çok düşük</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Federasyon</td>
      <td>ActivityPub ile güçlü</td>
      <td>Yok</td>
      <td>Sınırlı/yok</td>
    </tr>
    <tr>
      <td>Subsonic istemcileri</td>
      <td>Desteklenir</td>
      <td>En güçlü yönlerinden biri</td>
      <td>Desteklenir</td>
    </tr>
    <tr>
      <td>İdeal kullanım</td>
      <td>Topluluk ve paylaşım</td>
      <td>Kişisel müzik sunucusu</td>
      <td>Kapsamlı web arşivi</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/kendi-muzik-bulutunu-29.svg" alt="kendi-muzik-bulutunu-29" /></p>

<p><strong>Funkwhale</strong>, müzik dünyasının federasyon meraklısıdır. ActivityPub sayesinde farklı Funkwhale sunucuları birbirleriyle iletişim kurabilir. Kanallar, kütüphaneler, takip ve paylaşım özellikleriyle yalnızca kişisel oynatıcı değil, küçük bir bağımsız müzik topluluğu oluşturabilirsiniz. Bunun bedeli daha fazla servis, daha karmaşık kurulum ve daha yüksek RAM tüketimidir.</p>

<p><strong>Navidrome</strong>, “klasörümü göster, gerisini hallet” yaklaşımını benimser. Go ile yazıldığı için tek çalıştırılabilir dosyayla bile ayağa kalkabilir. Subsonic ve OpenSubsonic uyumluluğu sayesinde Symfonium, Ultrasonic veya play:Sub gibi istemcilerle çalışır. Federasyon ya da sosyal ağ özellikleri sunmaz; buna karşılık hızlı, sade ve düşük güçlü ev sunucuları için idealdir.</p>

<p><strong>Ampache</strong> ise bu üçlünün deneyimli arşiv yöneticisidir. PHP tabanlı yapısı klasik bir web sunucusu ortamına kolayca yerleşir. Geniş katalog yönetimi, kullanıcı yetkileri, çalma listeleri ve API seçenekleri sunar. Arayüzü Navidrome kadar minimalist değildir; fakat büyük ve düzenli koleksiyonlarda güçlü kontrol sağlar.</p>

<h2 id="navidrome-ile-hızlı-başlangıç">Navidrome ile hızlı başlangıç</h2>

<p>En hafif seçeneği denemek için aşağıdaki Docker Compose dosyası yeterlidir:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">services</span><span class="pi">:</span>
  <span class="na">navidrome</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">deluan/navidrome:latest</span>
    <span class="na">user</span><span class="pi">:</span> <span class="s2">"</span><span class="s">1000:1000"</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">4533:4533"</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="na">ND_SCANSCHEDULE</span><span class="pi">:</span> <span class="s2">"</span><span class="s">1h"</span>
      <span class="na">ND_LOGLEVEL</span><span class="pi">:</span> <span class="s2">"</span><span class="s">info"</span>
      <span class="na">ND_ENABLETRANSCODINGCONFIG</span><span class="pi">:</span> <span class="s2">"</span><span class="s">true"</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">./data:/data</span>
      <span class="pi">-</span> <span class="s">/srv/music:/music:ro</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">/srv/music</code> arşivi salt okunur bağlanır; böylece uygulama yanlışlıkla parçalarınızı değiştiremez. <code class="language-plaintext highlighter-rouge">./data</code> ise veritabanını ve ayarları kalıcı tutar. <code class="language-plaintext highlighter-rouge">docker compose up -d</code> komutundan sonra <code class="language-plaintext highlighter-rouge">http://sunucu-adresi:4533</code> üzerinden ilk yönetici hesabı oluşturulur.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Raspberry Pi, mini PC veya NAS üzerinde kişisel Spotify alternatifiniz olsun istiyorsanız <strong>Navidrome</strong> en pratik tercihtir. Müzik paylaşımını sosyal ve federatif bir yapıya taşımak istiyorsanız <strong>Funkwhale</strong> daha heyecan vericidir. PHP ekosistemine hâkimseniz, ayrıntılı kullanıcı ve katalog yönetimi arıyorsanız <strong>Ampache</strong> güçlü bir seçenektir.</p>

<p>Hangi sistemi kurarsanız kurun HTTPS, güçlü parolalar, düzenli yedekleme ve mümkünse ters proxy kullanın. Ayrıca yalnızca paylaşma hakkına sahip olduğunuz içerikleri yayımlayın. Kendi müzik bulutunuzu kurmak özgürlük getirir; sunucu yöneticiliği sorumluluğunu da çalma listesine ekler.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="müzik" /><category term="self-hosted" /><category term="funkwhale" /><category term="navidrome" /><category term="ampache" /><category term="docker" /><summary type="html"><![CDATA[Spotify rahat olabilir; ancak arşivinizin kontrolünü, dinleme geçmişinizi ve sunucunuzu başkasına bırakmak istemiyorsanız kendi müzik paylaşım sisteminizi kurabilirsiniz. Funkwhale, Navidrome ve Ampache bu işin üç güçlü adayıdır. Üçü de müziğinizi tarayıcıya ve mobil istemcilere ulaştırır, fakat mimarileri ve hedefledikleri kullanım biçimleri epey farklıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-muzik-bulutunu-29.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-muzik-bulutunu-29.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>