Giriş
Nginx dünyanın en popüler web sunucusu seçenekleri arasındadır. Çok sayıda eşzamanlı istemci bağlantısıyla başarılı bir şekilde başa çıkabilir. Aynı zamanda bir posta, web veya ters proxy sunucusu olarak da işlev görür.
Bu kılavuz, Nginx'in istemci isteklerini nasıl işlediğini yönlendiren perde arkasındaki yöntemleri özetlemeyi amaçlamaktadır. Sunucu ve konum blok tasarımını netleştirecek ve istekleri işlemenin görünürdeki öngörülemezliğini en iyi şekilde nasıl azaltacağınızı açıklayacağız.
Her şeyden önce, işte size Ubuntu sunucunuza Nginx'in nasıl kurulacağı hakkında kapsamlı bir eğitim. Şimdi başlayalım!
Nginx ile Blok Yapılandırması
Nginx'in mantıksal yaklaşımı, farklı amaçlara yönelik yapılandırmaları ayrı, daha mantıklı içerik bloklarına ayırmayı içerir. Bunlar hiyerarşik bir yapıda yer alacaktır. Bir istemci bir istek oluşturduğunda, Nginx bu yapılandırma bloklarından hangisinin bu isteği karşılamak için en uygun olduğunu belirlediği bir süreç başlatır. Biz bu karar sürecine odaklanacağız.
Tartışacağımız birincil bloklar server blokları ve location blokları olacaktır. Server blokları, Nginx'in tanımlanmış bir istek türünü işlemekten hangi sanal sunucunun sorumlu olacağını tanımlayan yapılandırmalarının bir alt kümesidir. En yaygın olarak gelen isteğin IP adresine, alan adına veya bağlantı noktasına (port) dayanırlar. Yöneticiler birden fazla server bloğu yapılandırır. Ardından, bağlantılardan hangisinin isteği işlemesi gerektiğine karar vermeleri gerekir.
Location blokları, server bloklarının içinde yer alır. Bunlar, ilgili üst sunucuya gelen istekleri işlemek için hangi kaynaklardan nasıl yararlanabileceğiniz konusunda karar vericilerdir. Bu model son derece esnektir. URI alanı, bu blokları yöneticinin en uygun gördüğü şekilde kullanacak şekilde yapılandırılabilir.
Nginx ile Hangi Bloğun Hangi İsteği İşleyeceğine Karar Verme
Nginx, birden fazla server bloğunun tanımlanmasına izin verir. Bunların hepsi farklı sanal web sunucuları olarak işlev görür. Bu nedenle, belirli gelen istekleri hangi sunucunun karşılayacağını belirleyen bir yöntem olmalıdır. Bu, tanımlanmış kontroller sistemi aracılığıyla istek performansı için en uygun olanı bularak yapılır.
Nginx öncelikle iki ana server bloğu yönergesiyle ilgilenir: listen ve server_name.
‘Listen’ Yönergesi ile Olası Eşleşmeleri Bulma
Nginx'in değerlendirdiği ilk şey, isteğin portu ve IP adresidir. Ardından, bunu her sunucunun listen yönergesiyle eşleştirir. Sunucu listesinin bu şekilde ayrıştırılması, yalnızca söz konusu isteği çözebilecek server bloklarının izole edilmesine yardımcı olur.
Tipik olarak listen yönergesi, belirli bir server bloğunun yanıt vermekten sorumlu olacağı portu ve IP adresini tanımlar. Bir listen yönergesi içermeyen bir server bloğu, varsayılan olarak 0.0.0.0:80 listen parametrelerini alır. Nginx normal, root olmayan bir kullanıcı tarafından çalıştırılıyorsa, listen parametresi 0.0.0.0:8080 olarak tanımlanır. Bu, arayüz ne olursa olsun, bloklar 80 portundan geliyorsa, bu şekilde tanımlanan blokların bunlara yanıt vereceği anlamına gelir. Ancak, bu varsayılan değer bir sunucu seçme sürecinde çok fazla ağırlığa sahip değildir.
Listen yönergesini şunlara göre yapılandırabilirsiniz:
- Varsayılan portta (80) istekleri dinleyen tek bir IP adresi.
- O porttaki herhangi bir arayüzü dinleyen tek bir port.
- Bir port ve IP adresi kombinasyonu.
- Belirlenmiş bir Unix soket yolu (bu seçenek yalnızca istekler farklı sunucular arasında geçtiğinde etkilidir).
Nginx, bir isteğin hangi server bloğuna gönderileceğine karar verirken bir dizi kural uygulayacaktır. Kurallar, listen yönergesinin özel yapılandırmasına bağlıdır. Bunlar aşağıdaki gibidir:
- Bir listen yönergesi eksikse, eksik parçalar varsayılan değerlerini alır. Bu, isteği işlemek için IP adresinin ve portun varsayılan değerlerle tamamlanmaya zorlanacağı anlamına gelir.
- Bu durumda, listen yönergesi içermeyen bir blok 0.0.0.0:80 varsayılan değerini kullanacaktır.
- Portu eksik olan ve 111.111.111.111 IP adresine sahip bir blok, 111.111.111.111:80 haline gelecektir.
- IP adresi olmadığında, 8888 portuna sahip bir blok, 0.0.0.0:8888'i oluşturmak üzere eklenecek varsayılan IP adresini alacaktır.
- Belirlenen IP adresine ve porta sahip olan Nginx, ardından bu portla eşleşen sunucu bloklarını arayacaktır.
- Yalnızca tek bir özel eşleşme bulursa, sunucu bloğu bu olacaktır. Uygun birden fazla blok varsa, Nginx söz konusu tam sunucu bloğunu daha da detaylandırmak için server_name yönergesine başvuracaktır.
Nginx, yalnızca listen yönergesinden tam özgüllük düzeyine sahip sunucu bloğunu bulamadığı takdirde server_name yönergesini değerlendirmeye başvuracaktır. Eğer example.com, 192.168.1.10 IP'si ile 80 numaralı port üzerindeyse, bu örnekteki ilk blok her zaman isteği karşılayan blok olacaktır. server_name yönergesinin ne söylediğinden bağımsız olarak durum böyledir:

Özgüllük eşleşmesine sahip birden fazla uygun hizmet bloğu varsa, server_name yönergesi dikkate alınacaktır.
‘Server_Name’ Yönergesi ile Olası Eşleşmeleri Bulma
Eğer listen yönergeleri eşit derecede özgül ise, Nginx isteğin’ ‘Host’ başlığını kontrol edecektir. Bu, istemcinin başlangıçta ulaşmak istediği alan adının IP'sine sahip olacak bir değerdir. Nginx, hala uygun olan her bir sunucu bloğu adayının içindeki server_name yönergesini kullanacaktır. Bu değerlendirmeleri bir formüle göre gerçekleştirir. Bu formül şu şekildedir:
- Nginx'in ilk girişimi, istekteki ‘Host’ başlığı değeriyle tam olarak eşleşen bir server_name'e sahip bir blok belirlemek olacaktır. Eğer bulursa, tam eşleşmeyi içeren blok isteğe hizmet eden blok olacaktır. Birden fazla blok bulması durumunda, listedeki ilk bloğu seçecektir.
- Tam eşleşme yoksa, Nginx yapılandırmadaki sunucu bloğu adının başında bir joker karakter olan * işaretini kullanarak eşleşen sunucu bloğunu bulmak için server_name'i kullanmayı deneyecektir. Bu yöntemle bir tane bulmak, sunucu bloğunun belirlendiği anlamına gelir. Birden fazla eşleşme bulursa, isteği yerine getirecek olan en uzun eşleşme olacaktır.
- Eşleşen bir ön joker karakter yoksa, Nginx eşleşen bir son joker karaktere sahip bir sunucu bloğu bulmaya çalışacaktır. Başka bir deyişle, bu, yapılandırmada sonunda * olan bir sunucu adı olacaktır. Eğer bir tane bulunursa, istek için kullanılır. Birden fazla bulunması durumunda ise Nginx bir kez daha en uzun eşleşmeyi kullanacaktır.
- Her iki joker karakter denemesinden sonra hala eşleşme olmaması durumunda, Nginx, server_name'i tipik ifadeler kullanarak (addan önce ~ ile belirtilir) tanımlayan sunucu bloklarını değerlendirecektir. ‘Host’ başlığıyla eşleşen bir ifadeye sahip ilk server_name örneği, isteğin işlenmesi için sunucu bloğu olarak kabul edilecektir.
- Bu noktada hala eşleşme yoksa, Nginx o port ve IP adresi kombinasyonu için varsayılan sunucu bloğunu kullanacaktır.
Her port/IP adresi kombinasyonunun belirlenmiş bir sunucu bloğu olacaktır. İstek işleme için uygun sunucu bloğunu belirleme kuralları sonuçsuz kalırsa bu blok kullanılacaktır. Bu, yapılandırmada listen yönergesinde bir default_server seçeneği içeren ilk blok olacaktır (başlangıçta bulunan algoritmayı geçersiz kılacaktır). Her IP adresi/port kombinasyonu en fazla bir default_server ayarına sahip olabilir.
Sunucu Bloğu Seçimi Örnekleri
Tanımlanan server_name, ‘Host’ başlığı değeriyle tam olarak eşleşirse, istek işleme için seçilen sunucu bloğu olacaktır. Aşağıdaki örnek, “host1.example.com” olarak belirlenmiş bir isteğin ‘Host’ başlığını göstermektedir. Bu durumda, ikinci sunucuyu seçecektir:

Tam bir eşleşme olmadığında, Nginx joker karakterli bir server_name olup olmadığını kontrol edecektir. Yoksa, joker karakterle başlayan en uzun eşleşme seçilecektir. Aşağıdakinde, “www.example.org” değeri “Host” başlığındadır. Bu, ikinci bloğu seçeceği anlamına gelir:

Joker karakterle başlayan bir eşleşme olmadığında, Nginx sondaki joker karakter kontrolüne geçer. İstek işleme için joker karakterle biten en uzun eşleşme seçilecektir. Bu durumda, “Host” başlığı “www.example.com”, so it will choose the third server block:

Hala eşleşme yoksa, Nginx standart ifadeleri kullanarak server_name yönergelerini eşleştirmeye çalışacaktır. Bu ifadelerden ilki istek işleme için seçilir. Eğer “Host” değeri “www.example.com,” ise, isteğe yanıt vermek için ikinci sunucu bloğu tercih edilecektir:

Hala eşleşme olmaması durumunda, istek, eşleşen varsayılan sunucu kurulumuna sahip IP adresi ve port kombinasyonuna gidecektir.
Location Bloğu Eşleştirme
Nginx'in ayrıca, sunucudaki hangi location bloğunun bir isteğe yanıt vermekten sorumlu olacağına karar vereceği bir algoritma belirlemesi gerekir.
Location Blokları için Sözdizimi
Nginx'in istekleri işleyecek location bloğunu nasıl belirleyeceğini açıklamadan önce, location bloğu tanımlarındaki sözdizimini gözden geçireceğiz. Daha önce belirtildiği gibi, location blokları server bloklarının (ve diğer location bloklarının) içinde yer alır. Amaçları, istek URI'sinin nasıl işleneceğine dair kararlar almaktır. URI, isteğin IP adresi ve portundan veya alan adından sonra gelen kısmıdır.
Location blokları genellikle şu şekilde görünür:

Nginx, isteğin URI'sini location_match ile karşılaştıracaktır. Yukarıdaki değiştiricinin (modifier) mevcut olup olmaması, Nginx'in blokları eşleştirmeye çalışma şeklini belirleyecektir. Değiştiriciye bağlı olarak, location blokları aşağıdaki kurallara göre yorumlanacaktır:
- Değiştirici yoksa: Herhangi bir değiştirici olmadığında, location bir ön ek (prefix) eşleşmesi olarak yorumlanacaktır. Bu, doğru bir eşleşme belirlemek için sağlanan location değerinin, istekteki URI'nin başlangıcıyla eşleştirileceği anlamına gelir.
- =: Eşittir işareti, isteğin URI'si sağlanan location değeriyle tam olarak eşleştiği sürece bu bloğun bir eşleşme olarak kabul edileceğini belirtir.
- ~: Tilde değiştiricisi, location bloğu eşleşmesinin büyük/küçük harfe duyarlı olacağını temsil eder.
- ~*: Tilde ve yıldız işareti değiştiricilerinin kombinasyonu, location bloğunun bir eşleşme ararken büyük/küçük harfe duyarsız olacağını temsil eder.
- ^~: Tilde değiştiricisinin önünde bir şapka (carat) işareti varsa, bu blok en iyi düzenli ifade dışı (non-regular expression) eşleşme olarak seçildiği sürece düzenli ifade eşleştirmesi gerçekleşmeyecektir.
Location Bloğu Sözdizimi Örnekleri
Ön ek eşleştirmesine bir örnek sunmak gerekirse, location bloğu; /site, /site/page1/index.html veya /site/index/html biçimindeki bir istek URI'sine yanıt vermek için seçilecek olan bloktur:

Gerekli URI eşleştirmesinin bu gösterimi amacıyla, blok her zaman /page1 biçimindeki URI isteklerine yanıt vermek için kullanılacak, /page1/index.html istek URI'si için kullanılmayacaktır. Eğer seçilen blok buysa ve isteği bir dizin sayfası kullanarak karşılıyorsa, isteğin asıl işleyicisi dahili olarak başka bir konuma (location) yönlendirilecektir:

Örneğin, büyük/küçük harfe duyarlı bir ifadeyle yorumlanması gereken bir location için, aşağıdaki blok /FLOWER.PNG isteklerini işleyemez. Ancak, /tortoise.jpg isteklerini işleyecektir:

Ardından, yukarıdakine benzer şekilde büyük/küçük harfe duyarsız eşleşmeye izin verecek bir bloğu inceleyin. Bu durumda blok, hem //tortoise.jpg hem de /FLOWER.PNG isteklerini işleyebilir:

Son varyant ise, yapılan değerlendirmede en uygun düzenli ifade dışı eşleşme olduğu belirlenirse, bir bloğun düzenli ifade eşleştirmesinin gerçekleşmesini engelleyeceği durumdur. Bu blok, /costumes/ninja.html isteklerini işleyebilir:

Özetlemek gerekirse, değiştiriciler location bloklarının nasıl belirleneceğini dikte eder. Ancak bu, Nginx'in bir isteğin gönderileceği location bloğunu tanımlamak için karar verme algoritması olarak neyi kullandığını bize söylemez. Şimdi bu konuyu ele alalım.
Nginx Tarafından İstekleri İşleyecek Location'ın Seçilmesi
Nginx'in bir isteği işleyen location'ı seçme yöntemi, server bloklarının seçilme şekline benzer. Diğer bir deyişle, bir süreç işleterek her istek için en uygun location'ı belirler. Nginx'i doğru ve buna uygun şekilde yapılandırmak için bu süreci anlamanız şarttır.
Daha önce ele alınan location tanımlamalarını akılda tutarak, Nginx benzer şekilde, gelen bir istekteki URI'yi her bir location ile karşılaştırıp uygunluğunu kontrol ederek potansiyel location bağlamlarını kullanır. Bu işlemde aşağıdaki algoritmayı uygular:
- İlk olarak Nginx, düzenli ifade (regular expression) içermeyen tüm location türlerini kontrol eder. Bunu, tüm location tabanlı önek (prefix) eşleşmelerini arayarak yapar. Bunun için location'ı isteğin tam URI'sine karşı kontrol eder.
- Nginx tam bir eşleşme aramaya başlar. = değiştiricisini kullanan bir location bloğu belirlendiğinde, bu blok istek URI'si ile karşılaştırılır. Eğer ikisi tam olarak eşleşirse, isteği hemen o anda işlemek üzere bu location bloğu seçilir.
- Eliyle = değiştirici karşılaştırmasıyla tam olarak eşleşen hiçbir location yoksa, Nginx tam olmayan önekleri değerlendirmeye geçer. İsteğin URI'si ile eşleşen en uzun önek location'ını belirledikten sonra aşağıdaki değerlendirmeleri gerçekleştirecektir:
- En uzun önek eşleşmesine sahip location ^~ değiştiricisini kullanıyorsa, bu location hemen seçilecektir.
- En uzun öneğe sahip location ^~ değiştiricisini kullanmıyorsa, aramanın odağının kaydırılmasına izin vermek için eşleşme Nginx tarafından geçici olarak tutulur.
- En uzun önek location eşleşmesi bulunup saklandıktan sonra Nginx, düzenli ifade location'larının değerlendirilmesine geçer. Bunlar hem büyük/küçük harfe duyarlı hem de duyarsız eşleşmeleri içerir. En uzun eşleşen önek location'ının içinde herhangi bir düzenli location varsa, Nginx bu konumları listenin üst sıralarına yerleştirmek için listeyi yeniden şekillendirir. Yeniden sıralanan listeden bir isteğin URI'si ile eşleşen ilk ifade, isteğe hizmet etmek için seçilen location olacaktır.
- İstek RI'sini karşılayacak hiçbir düzenli ifade bulunamazsa, isteği işlemek için daha önce saklanan location seçilecektir.
Nginx, varsayılan olarak düzenli ifade eşleşmelerine öncelikli öneklere göre öncelik tanır. Ancak, yönetici tarafın = ve ^~ değiştiricileriyle bu eğilimi geçersiz kılabilmesi için önce önek location'larını değerlendirir.
Çıkarılacak diğer bir önemli sonuç ise, önek location'ları genellikle bulunan en spesifik, en uzun eşleşmeye dayanırken, düzenli ifade kontrolünün ilk eşleşme belirlenir belirlenmez durdurulmasıdır. Bu, yapılandırma içindeki konumlandırmanın düzenli ifade location'ları için gerçek etkileri olduğu anlamına gelir.
Değinilmesi gereken son bir nokta, en uzun öneğe sahip eşleşme içindeki düzenli ifade eşleşmelerinin, Nginx'in location değerlendirmeleri sırasında esasen sıranın önüne geçeceğidir. Bunlar listenin en üstüne yerleştirilecek ve diğer düzenli ifadelerden önce değerlendirilecektir.
Location Bloğu Değerlendirmelerinde Diğer Location'lara Geçiş Ne Zaman Gerçekleşir?
Tipik olarak, bir istek değerlendirilip onu işleyecek bir location bloğu seçildikten sonra, tamamen bu bağlam içinde ele alınacaktır. Bu, kardeş location bloklarının herhangi bir girdisi olmaksızın, isteğin işlenmesinde yalnızca devralınan yönergelerin ve seçilen location'ların belirleyici olduğu anlamına gelir.
Bu, location bloklarının öngörülebilir şekilde tasarlanmasına izin veren genel bir kural olsa da, bazen location içindeki belirli yönergeler de yeni bir aramayı tetikleyebilir. Diğer bir deyişle, 'yalnızca tek bir location bloğu' kuralının birkaç istisnası vardır. Bu istisnalar location bloklarının beklentileriyle uyuşmayabilir. Bu nedenle, isteği beklendiği gibi ele almayabilirler.
Bu dahili yönlendirmeler, aşağıdakiler de dahil olmak üzere bazı yönergeler nedeniyle ortaya çıkabilir:
- index
- rewrite
- error_page
- try_files
Eğer index yönergesini kullanırsanız, bu durum istek işleme sırasında her zaman dahili bir yönlendirmeyle sonuçlanacaktır. Konum eşleşmelerini bulmak, seçim sürecini hızlandırmak için genellikle algoritma yürütmesini sonlandırsa da, bulunan konum eşleşmesi bir dizinse, istek resmi olarak işlenmek üzere muhtemelen başka bir konuma yönlendirilecektir.
Örneğin, aşağıdaki ilk konum /exact istek URI’si ile eşleşir. Ancak, isteği işlemek için, konum bloğunun devraldığı index yönergesi isteği ikincil bir bloğa yönlendirir:

Bu senaryo için, yürütmenin birincil blok içinde kalması gerekiyorsa, dizine yönelik isteği işlemek için başka bir şema gerekecektir. Bunu yapmanın bir yolu, söz konusu blok için geçersiz bir dizin ayarlamak ve bunun yerine otomatik dizini etkinleştirmektir:

Bu yöntem birkaç durumda işe yarayabilse de, çoğu bağlamda genel olarak pratik bir şekilde uygulanamaz. Tam bir dizin eşleşmesi, isteğin yeniden yazılması gereken durumlar için yararlı olabilir. Bu, yepyeni bir konum araması tetikleyecektir.
İşleme konumunu yeniden değerlendirmek için kullanılabilecek bir diğer yönerge de try_files yönergesidir. Nginx’e, belirli bir dosya veya dizin kümesinin var olup olmadığını özellikle kontrol etmesini söyler; buradaki son arama kriteri, Nginx’in dahili olarak yönlendireceği URI’dir.
Aşağıdaki yapılandırmayı düşünelim:

/blahblah için bir istek gelirse, bunu ilk konum alacaktır. /var/www/main dizininde blahblah dosyasının bulunamaması, blahblah.html için takip eden bir aramayı tetikleyecektir. Ardından, /var/www/main dizininde blahblah adında bir alt dizin arayacaktır. Tüm bu kontroller başarısız olursa, /fallback/index.html adresine yönlendirecektir. Bu, başka bir konum bloğunun yakalayacağı başka bir konum aramasını tetikleyecektir. Ardından, /var/www/another/fallback/index.html dosyasını işleyecektir.
Başka bir konum bloğuna yönlendirmeyle sonuçlanan bir diğer yönerge de rewrite yönergesidir. Nginx, last parametresi kullanıldığında rewrite yönergesinin sonucuna göre yeni bir eşleşen konum arayacaktır. Son örnek, şimdi bu rewrite yönergesini içerecek şekilde değiştirilirse, isteğin try_files yönergesi uygulanmadan başka bir konuma yönlendirilebileceği açıkça görülür:

Bu örnek için, /rewrite/hello isteği başlangıçta ilk konum tarafından ele alınacaktır. /hello olarak yeniden yazıldıktan sonra, ikincil bir konum araması tetiklenecektir. Bu, ilk konumla eşleşecektir. try_file yönergesi tarafından işlenecek ve herhangi bir sonuç vermezse potansiyel olarak /fallback/index.html adresine geri dönecektir.
Ancak, /rewrite/fallback/hello için bir istek yapılırsa, ilk blokla bir eşleşme bulunacaktır. Böylece, rewrite işlemi tekrar gerçekleştirilecek, ancak bu kez sonuç olarak /fallback/hello değerini verecektir. İstek başka bir konum bloğunda işlenecektir.
Benzer durumlar, 301 veya 302 durum kodlarını göndermek için return yönergesini kullandığınızda da ortaya çıkar. Tek fark, yeni bir isteğin oluşması ve bunun çok belirgin bir yönlendirme şeklinde kendini göstermesidir. Benzer şekilde bu durum, permanent veya redirect bayraklarını uyguladığınızda rewrite yönergesiyle de gerçekleşebilir.
try_again’inkine benzer dahili yönlendirmelere yol açabilen bir diğer yönerge de error_page yönergesidir. Bunu, işlemede belirli hata kodlarıyla karşılaştığınızda kullanabilirsiniz. Bir try_files yönergesi ayarlandığında, error_page yönergesi muhtemelen hiçbir zaman yürütülmeyecektir. Bunun nedeni, o yönergenin isteğin tüm yaşam döngüsünü yönetecek olmasıdır.
Aşağıdaki örneği ele alalım:

Bu durumda, her istek /var/www/main dizininden dosyaları sunan ilk blok tarafından işlenecektir. Bu, /another ile başlayan istekler için geçerli değildir. Ancak bir dosya bulunamayacak olursa, /another/whoops/html adresine dahili bir yönlendirme başlatılacaktır. Bu, başka bir konum aramasına yol açacaktır. Buna karşılık, isteği ikincil bir bloğa yönlendirecek ve bu dosya /var/www/another/whoops.html dışından ele alınacaktır.
Görüldüğü üzere, Nginx'in ne zaman yeni bir konum araması tetikleyeceğini anlamak, istekler işlenirken sistem davranışını daha iyi tahmin etmeye yardımcı olabilir.
Sonuç
Yöneticilerin işleri, Nginx'in istemci isteklerini ele alma yöntemlerini anladıklarında son derece kolaylaşır. Bu, yöneticilerin isteğin hangi sunucu bloğuna gideceğini kesin olarak belirlemesini sağlar. Ayrıca istek URI'sine göre hangi konum bloğunun seçileceğini de belirleyebilirler. Genel olarak bu, yöneticilere her bir isteği ele alırken Nginx tarafından uygulanan bağlamları izleme yeteneği de kazandırır.
Son olarak, blogumuzdaki Nginx odaklı diğer eğitimlere göz atabilirsiniz. Dünyanın en popüler web sunucularından birinden daha iyi yararlanmanıza yardımcı olacaklardır:
- Web Sunucuları Dünyası: Apache vs. Nginx
- Ubuntu 20.04 üzerinde Let’s Encrypt ile Nginx Nasıl Güvenli Hale Getirilir
- Nginx için LetsEncrypt SSL Sertifikası Yenilemelerini Otomatikleştirme
- Docker Compose ile Laravel, Nginx ve MySQL Dağıtımı
Keyifli Çalışmalar!
Yorumlar
Henüz yorum yapılmamış. İlk siz olun.