Aynı Mac'te Apache ve Nginx'i birlikte çalıştırmak

80 portunu aynı anda tek süreç tutabilir. Bu tek olgu kurulumdaki her kararı belirliyor — ve işlerin ters gitme biçimlerinin çoğunu da açıklıyor.

macOS geliştiricileri için pratik rehber · portlar, alan adı başına yönlendirme, ters vekil ve reload tuzağı

Neden ikisi birden

Çoğu yığın bir sunucu seçip orada kalır. Ama birkaç yıldır kullanılan bir makinede nadiren tek tür proje bulunur. Eski bir WordPress sitesi Apache'nin .htaccess ve mod_rewrite davranışını bekler. Next.js ya da FastAPI uygulaması Nginx'e göre belgelenmiş, dağıtılmış ve hata ayıklanmıştır. Birinin yapılandırmasını diğerine uydurmak, karşılığı olmayan bir emektir.

Alternatif, ikisini birden çalıştırıp her alan adını yazıldığı sunucuya yönlendirmek.

Port sorunu

80 ve 443 portlarını tek süreç bağlayabilir. Önce başlayan kazanır; ikincisi Address already in use ile düşer ve bir servis yöneticisiyle başlattıysanız arka planda sessizce yeniden denemeye devam edebilir.

İşe yarayan düzen, bilinen portları bir sunucuya verip diğerini yukarı taşımak:

SunucuHTTPHTTPSAdres şöyle görünür
Apache80443https://eski.test
Nginx80808443https://uygulama.test:8443

Görünür bedel, ikinci sunucudaki sitelerin adresinde port taşıması. Kozmetik bir sorun ama mutlak adres üreten her şeye sızıyor — HTTP_HOST'tan bağlantı kuran çatılar bunu genelde doğru yapar, şemayı ve ana makineyi sabit yazanlar yapmaz.

Tek bir ön vekille çözmeye kalkışmayın, gerekmedikçe. Nginx'i 80'e koyup bazı adları Apache'ye vekillemek adreslerden portu kaldırır, ama artık her Apache isteği Nginx'ten geçer ve tek bir istek yanlış davrandığında iki sunucuyu birden ayıklarsınız. Yerel geliştirmede bu takas nadiren değer.

Portu gerçekte kim tutuyor

Yapılandırmayı değiştirmeden önce kimin dinlediğine bakın. Bu iş boyunca en çok işe yarayan tek komut budur:

$ sudo lsof -nP -iTCP:80 -sTCP:LISTEN
COMMAND   PID   USER   FD   TYPE  DEVICE NODE NAME
httpd    1234   root    4u  IPv6  0x...  TCP  *:80 (LISTEN)

Hiçbir şey listelenmiyorsa sunucu çalışmıyordur — ki bu yanlış yapılandırılmış olmakla aynı şey değil, çözümü de farklı. Beklemediğiniz bir şey listeleniyorsa çakışmayı bulmuşsunuz demektir.

Tek sertifika ikisini de kapsar

Sertifikalar ana makine adına bağlanır, porta değil. uygulama.test için üretilmiş sertifika 443'te de 8443'te de aynı ölçüde geçerlidir; sunucuyu standart dışı bir porta taşımak TLS açısından hiçbir şeyi değiştirmez. Sertifikaların nasıl üretilip güvenildiğini yerel HTTPS rehberinde anlattım.

Değişen şey, her sunucunun sertifikayı nasıl istediği:

# Apache — sertifika ve anahtar ayrı direktifler
SSLCertificateFile      /yol/uygulama.test.pem
SSLCertificateKeyFile   /yol/uygulama.test-key.pem

# Nginx — sertifika dosyasının zinciri içermesi beklenir
ssl_certificate         /yol/uygulama.test.pem;
ssl_certificate_key     /yol/uygulama.test-key.pem;

Ters vekil arkasındaki uygulamalar

PHP doğrudan sunulur, ama Node, Python ve .NET uygulamaları kendi portlarında dinler ve alan adının sahibi olan sunucunun arkasında durur. Bu, adı konmaya değer ikinci bir arıza biçimi ekliyor: uygulama kusursuz çalışırken site erişilemez olabilir, çünkü önündeki sunucu durmuştur.

Başlatma sırasını da tersine çeviriyor. Vekili uygulamadan önce başlatmak, uygulama ayağa kalkana kadar 502 üretir; önce uygulamayı başlatmak daha temizdir. Bunları sizin yerinize başlatan bir şey varsa, o sıralamayı kontrol etmeye değer.

# Nginx, 3001'deki bir uygulamanın önünde
location / {
    proxy_pass         http://127.0.0.1:3001;
    proxy_set_header   Host              $host;
    proxy_set_header   X-Forwarded-Proto $scheme;
}

Bu iki başlık göründüğünden önemli. Host olmadan uygulama 127.0.0.1'i görür ve kendini gösteren bağlantılar üretir. X-Forwarded-Proto olmadan, TLS'i vekilde sonlandıran bir çatı isteğin HTTP ile geldiğini sanıp döngüye giren yönlendirme yapabilir.

Reload tuzağı

İki sunucu da yeniden başlatmak yerine reload ile yapılandırmayı yeniden okur ve ikisi de include glob'larını o anda genişletir. Yani yeni eklenen bir sanal sunucu dosyası reload ile alınır; yeniden başlatmaya gerek yoktur.

nginx.conf:   include sites-available/*.conf;
httpd.conf:   Include */extra/httpd-vhosts.conf

Tuzak, reload'u koruyan kontrolde. Betikler genelde sunucunun çalışıp çalışmadığını sınar ve akla ilk gelen sınama Nginx için yanlıştır:

$ pgrep -x nginx        # çıktı yok — ama Nginx çalışıyor
$ ps -eo comm= | grep '^nginx'
nginx: master process /opt/homebrew/opt/nginx/bin/nginx -g daemon off;

Nginx master süreci kendi başlığını yeniden yazdığı için ada tam eşleşme onu asla bulmaz. Apache etkilenmez — onun süreç adı gerçekten httpd. pgrep -x kullanan bir betik reload'u sessizce atlar, yeni vhost hiç yüklenmez ve belirti şudur: "yeni alan adı ancak Nginx'i elle yeniden başlatınca görünüyor".

Reload'dan önce mutlaka doğrulayın. apachectl configtest ve nginx -t, çalışan sunucuya dokunmadan sözdizimi hatalarını bildirir. Bozuk bir yapılandırmayı reload etmek sizi duran ve bir daha kalkmayan bir sunucuyla baş başa bırakabilir.

Bozuk göründüğünde

Yanlış site açılıyor

Hiçbir ServerName eşleşmediğinde iki sunucu da ilk ya da varsayılan sanal sunucuya düşer. Alakasız bir proje — ya da fabrika karşılama sayfası — görüyorsanız bu genelde ana makine adının hiç eşleşmediği anlamına gelir, vhost'un bozuk olduğu değil.

Bir portta çalışıyor, diğerinde çalışmıyor

Vhost'un gerçekten test ettiğiniz portu dinlediğini kontrol edin. *:443 için tanımlanmış bir blok 8443'te hiçbir şeye yanıt vermez ve tarayıcı yapılandırma hatası değil bağlantı hatası bildirir.

Değişiklikler etkisiz

Ya reload atlandı (yukarıya bakın) ya da include edilmeyen bir dosyayı düzenlediniz. Sunucunun kendisine sorun: apachectl -S Apache'nin gerçekte yüklediği vhost'ları listeler, nginx -T yürürlükteki yapılandırmanın tamamını yazar.

BRAMPP bunu nasıl yapıyor

BRAMPP iki sunucuyu bu bölüşümle varsayılan olarak çalıştırıyor ve her alan adı için hangisinin servis edeceğini seçtiriyor. Vhost'u yazıyor, sertifikayı üretiyor, hosts kaydını ekliyor ve doğru sunucuyu yeniden yüklüyor — ayrıca bir alan adının bağlı web sunucusunu arkasındaki uygulamadan önce başlattığı için yukarıdaki ters vekil sıralaması şansa bırakılmıyor.

MIT lisanslı, ücretsiz ve açık kaynak. Kendi Apache'sini ya da Nginx'ini paketlemiyor; makinenizde zaten kurulu Homebrew formüllerini yönetiyor.

← BRAMPP'e dön