Sunucu Yönetimi 10 dk okuma

LEMP Kurulumu: VDS Sunucuya Nginx, PHP, MariaDB ve Ücretsiz SSL (Certbot)

Kontrol paneli olmadan VDS'inizde web sitesi yayınlayın: Nginx, PHP-FPM ve MariaDB kurulumu, site için sunucu bloğu ve Certbot ile ücretsiz Let's Encrypt SSL. Ubuntu 24.04 ve Debian 13 için adım adım.

LEMP Kurulumu: VDS Sunucuya Nginx, PHP, MariaDB ve Ücretsiz SSL (Certbot)
AnkSOFT
Yayıncı

PHP ile yazılmış bir web sitesini ya da WordPress, Laravel gibi bir uygulamayı kontrol paneli kullanmadan kendi VDS'inizde yayınlamanın en yaygın yolu LEMP yığınıdır: Linux, Engine-X (Nginx), MariaDB ve PHP. Nginx az bellekle çok sayıda bağlantıyı karşılar, PHP-FPM PHP kodunu çalıştırır, MariaDB verileri saklar. Bu rehberde dördünü Ubuntu 24.04 veya Debian 13 bir VDS'e kuruyor, alan adınız için bir site tanımlıyor ve Certbot ile ücretsiz Let's Encrypt SSL sertifikası alıp otomatik yenilemeyi kontrol ediyoruz.

Örneklerde alan adı olarak ornek.com, sunucu IP adresi olarak 203.0.113.10 kullanıldı; bunları kendi bilgilerinizle değiştirin.


Başlamadan Önce

  • Alan adı: SSL sertifikası alabilmek için alan adınızın DNS yönetiminde ornek.com ve www.ornek.com için A kaydının VDS IP adresinizi göstermesi gerekir. DNS değişikliğinin yayılması birkaç dakikadan birkaç saate kadar sürebilir. Kontrol için kendi bilgisayarınızda nslookup ornek.com yazın; dönen adres VDS IP'niz olmalıdır.
  • Temel güvenlik: sudo yetkili bir kullanıcı, SSH anahtarı ve UFW ile başlamanızı öneririz. Adımlar Ubuntu Sunucu Güvenliği rehberimizde.
  • Panel mi, elle kurulum mu? Birden fazla siteyi, e-postayı ve DNS'i arayüzden yönetmek istiyorsanız Plesk veya CyberPanel daha uygun olabilir. Elle kurulum ise daha az kaynak harcar ve her ayarı sizin kontrolünüzde tutar.

LEMP yığını şeması: ziyaretçi, Nginx 80/443, PHP-FPM soketi ve yerel MariaDB


1. Adım: Nginx Kurulumu

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx

Güvenlik duvarında web portlarını (HTTP 80 ve HTTPS 443) açın:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

sudo ufw app list çıktısında Nginx Full profili görünüyorsa sudo ufw allow 'Nginx Full' komutu da aynı işi yapar.

Paneldeki Güvenlik Duvarı'nı "Engelle" politikasıyla kullanıyorsanız 80 ve 443'ü orada da açın; "Web sunucusu" hazır profili bu iki portu ekler.

Tarayıcınızda http://203.0.113.10 adresini açın. "Welcome to nginx!" sayfasını görüyorsanız Nginx çalışıyordur.


2. Adım: MariaDB Kurulumu ve Güvenli Hale Getirme

sudo apt install -y mariadb-server
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation

Güvenlik betiği sırayla şunları sorar. Önerilen yanıtlar:

Soru Yanıt Neden
Enter current password for root Enter (boş) Yeni kurulumda root şifresi yoktur
Switch to unix_socket authentication n Root zaten sistem root'uyla doğrulanır
Change the root password? n Root yalnız sudo mariadb ile girer, şifreye gerek yok
Remove anonymous users? Y Şifresiz anonim hesabı siler
Disallow root login remotely? Y Root uzaktan bağlanamaz
Remove test database? Y Herkese açık test veritabanını siler
Reload privilege tables now? Y Değişiklikleri hemen uygular

Ubuntu 24.04 deposu MariaDB 10.11, Debian 13 deposu MariaDB 11.8 sürümünü kurar; ikisi de uzun süreli destek (LTS) sürümüdür.

Site için veritabanı ve kullanıcı oluşturun

Uygulamanızı asla MariaDB root kullanıcısıyla çalıştırmayın. Her site için ayrı bir veritabanı ve yalnız o veritabanına yetkili bir kullanıcı açın:

sudo mariadb
CREATE DATABASE ornek_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ornek_kullanici'@'localhost' IDENTIFIED BY 'BurayaUzunVeRastgeleBirSifre';
GRANT ALL PRIVILEGES ON ornek_db.* TO 'ornek_kullanici'@'localhost';
FLUSH PRIVILEGES;
EXIT;

@'localhost' kullanıcının yalnız sunucunun içinden bağlanabileceği anlamına gelir. MariaDB varsayılan olarak yalnız 127.0.0.1 üzerinde dinler; 3306 portunu güvenlik duvarında açmanız gerekmez ve açmamalısınız.


3. Adım: PHP-FPM Kurulumu

sudo apt install -y php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip php-intl
php -v

Ubuntu 24.04 deposu PHP 8.3, Debian 13 deposu PHP 8.4 kurar. Nginx ile PHP-FPM bir Unix soketi üzerinden konuşur; soket dosyasının adı PHP sürümünü içerir. Kendi sunucunuzdaki adı öğrenmek için:

ls /run/php/

Çıktıda php8.3-fpm.sock (Ubuntu 24.04) ya da php8.4-fpm.sock (Debian 13) görürsünüz. Bir sonraki adımda bu adı kullanacağız.

Büyük dosya yüklemesi gereken siteler için /etc/php/8.3/fpm/php.ini dosyasında (Debian'da 8.4) şu değerleri artırabilirsiniz:

upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M

Değişiklikten sonra sudo systemctl restart php8.3-fpm ile PHP-FPM'i yeniden başlatın.

systemctl ile nginx, php8.3-fpm ve mariadb servislerinin çalıştığını doğrulama ve nginx -t çıktısı


4. Adım: Site İçin Nginx Sunucu Bloğu

Site dosyaları için bir klasör açın ve sahipliğini web sunucusu kullanıcısına verin:

sudo mkdir -p /var/www/ornek.com/public
sudo chown -R www-data:www-data /var/www/ornek.com

Sunucu bloğu dosyasını oluşturun:

sudo nano /etc/nginx/sites-available/ornek.com
server {
    listen 80;
    listen [::]:80;
    server_name ornek.com www.ornek.com;

    root /var/www/ornek.com/public;
    index index.php index.html;

    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known) {
        deny all;
    }
}
  • fastcgi_pass satırındaki soket adını bir önceki adımda ls /run/php/ ile gördüğünüz adla aynı yapın.
  • try_files ... /index.php?$args satırı WordPress ve Laravel gibi "güzel URL" kullanan uygulamalar için gereklidir.
  • Son location bloğu .env, .git gibi gizli dosyaların tarayıcıdan okunmasını engeller; Let's Encrypt'in kullandığı .well-known klasörünü ise açık bırakır.

Nginx sunucu bloğu: server_name, root, try_files ve PHP-FPM soket ayarı

Siteyi etkinleştirin, varsayılan siteyi kapatın ve ayarları test edin:

sudo ln -s /etc/nginx/sites-available/ornek.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

nginx -t çıktısında syntax is ok ve test is successful görmeden reload yapmayın.

PHP'nin çalıştığını test edin

echo "<?php phpinfo();" | sudo tee /var/www/ornek.com/public/info.php

Tarayıcıda http://ornek.com/info.php adresini açın. PHP bilgi sayfası görünüyorsa Nginx ile PHP-FPM bağlantısı doğrudur. Test bittikten hemen sonra bu dosyayı silin; sunucunuz hakkında saldırganların işine yarayacak ayrıntılar içerir:

sudo rm /var/www/ornek.com/public/info.php

5. Adım: Certbot ile Ücretsiz SSL Sertifikası

Let's Encrypt ücretsiz SSL sertifikası verir; Certbot bu sertifikayı alır, Nginx ayarınıza ekler ve otomatik yeniler.

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d ornek.com -d www.ornek.com

İlk çalıştırmada bir e-posta adresi ve kullanım koşullarını onaylamanız istenir. Certbot alan adınızı 80 portu üzerinden doğrular, sertifikayı alır ve sunucu bloğunuza 443 ayarlarını ekler. Ayrıca HTTP isteklerini HTTPS'e yönlendiren bir blok oluşturur.

certbot --nginx çıktısı: sertifika alındı ve ornek.com için HTTPS etkinleştirildi

Otomatik yenilemeyi kontrol edin

Let's Encrypt sertifikaları kısa ömürlüdür (şu an 90 gün) ve önümüzdeki yıllarda süre daha da kısalacak. Let's Encrypt artık sertifika süresi dolmak üzereyken uyarı e-postası da göndermiyor; bu yüzden otomatik yenilemenin çalıştığından emin olmanız şarttır. Certbot paketi bunun için bir zamanlayıcı kurar:

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

--dry-run gerçek sertifikaya dokunmadan yenilemeyi dener. Çıktının sonunda "Congratulations, all simulated renewals succeeded" görüyorsanız yenileme otomatik çalışacaktır. Mevcut sertifikalarınızı ve bitiş tarihlerini sudo certbot certificates ile görebilirsiniz.


6. Adım: Uygulamanızı Yükleyin

Altyapı hazır. Şimdi site dosyalarınızı /var/www/ornek.com/public klasörüne koyabilirsiniz:

  • Kendi dosyalarınız: SFTP (FileZilla, WinSCP) ile bağlanıp yükleyin; yükleme sonrası sudo chown -R www-data:www-data /var/www/ornek.com ile sahipliği düzeltin.
  • WordPress: wordpress.org'dan son sürümü indirip public klasörüne açın, kurulum sihirbazında 2. adımda oluşturduğunuz veritabanı adını, kullanıcıyı ve şifreyi girin. Veritabanı sunucusu olarak localhost yazın.
  • Laravel: Laravel'de herkese açık klasör public alt klasörüdür; sunucu bloğundaki root satırını projenin public klasörünü gösterecek şekilde ayarlayın.

Veritabanı bağlantısında hata alırsanız WordPress veritabanı bağlantı hatası rehberimiz en sık nedenleri anlatır.


AlmaLinux 8 Kullanıyorsanız Neler Farklı?

Bu rehberdeki mantık AlmaLinux 8'de de aynıdır, ancak paket adları ve dosya yolları değişir:

Konu Ubuntu / Debian AlmaLinux 8
Paket yöneticisi apt dnf
Güncel PHP / Nginx Depodaki sürüm sudo dnf module enable php:8.2 nginx:1.24 ile güncel akışı seçin
PHP-FPM soketi /run/php/php8.x-fpm.sock /run/php-fpm/www.sock
Site ayarları sites-available + sites-enabled /etc/nginx/conf.d/ornek.com.conf
Web kullanıcısı www-data nginx (PHP-FPM havuzunda user/group değerlerini nginx yapın)
Güvenlik duvarı UFW firewall-cmd --permanent --add-service=http --add-service=https ve firewall-cmd --reload

AlmaLinux'ta ayrıca SELinux açıktır. Site dosyalarını /var/www dışında bir klasöre koyarsanız ya da PHP uygulamanızın dışarıya bağlantı kurması gerekiyorsa SELinux izinlerini ayarlamanız gerekir; örneğin sudo setsebool -P httpd_can_network_connect 1. SELinux'u kapatmak yerine gereken izni vermek daha güvenlidir.


En Sık Yapılan Hatalar

  1. 502 Bad Gateway. Nginx PHP-FPM'e ulaşamıyor. fastcgi_pass satırındaki soket adını ls /run/php/ çıktısıyla karşılaştırın ve systemctl status php8.3-fpm ile servisin çalıştığını kontrol edin.
  2. PHP dosyasının indirilmesi ya da kod olarak görünmesi. location ~ \.php$ bloğu eksik ya da site etkinleştirilmemiş. sites-enabled altındaki bağlantıyı ve nginx -t çıktısını kontrol edin.
  3. Certbot'un "Connection refused" ya da "Timeout" hatası. 80 portu kapalıdır ya da DNS henüz VDS IP'nizi göstermiyordur. UFW'de ve paneldeki güvenlik duvarında 80'in açık olduğundan, nslookup sonucunun doğru olduğundan emin olun.
  4. 403 Forbidden. Klasörde index.php veya index.html yok ya da dosya sahipliği yanlış. ls -la /var/www/ornek.com/public ile kontrol edin.
  5. Uygulamayı MariaDB root ile bağlamak. Root ile çalışan bir uygulamadaki tek açık tüm veritabanlarını tehlikeye atar. Her site için ayrı kullanıcı kullanın.
  6. 3306 portunu internete açmak. Uzaktan veritabanı yönetimi için portu açmak yerine SSH tüneli kullanın: ssh -L 3306:127.0.0.1:3306 yonetici@203.0.113.10.
  7. info.php dosyasını unutmak. Test dosyası sunucu yapınızı herkese gösterir; işiniz bitince silin.

Ek Sıkılaştırma ve Performans Ayarları

Nginx sürüm bilgisini gizleyin ve güvenlik başlıkları ekleyin

Nginx varsayılan olarak hata sayfalarında ve yanıt başlıklarında sürüm numarasını gösterir. /etc/nginx/nginx.conf dosyasının http { ... } bölümünde server_tokens off; satırının başındaki # işaretini kaldırın. Ardından sitenizin sunucu bloğuna, Certbot'un eklediği 443 bölümünün içine şu başlıkları ekleyebilirsiniz:

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Her değişiklikten sonra sudo nginx -t && sudo systemctl reload nginx çalıştırın.

PHP-FPM süreç sayısını RAM'e göre ayarlayın

PHP-FPM, aynı anda kaç PHP isteğini işleyeceğini pm.max_children değeriyle belirler. Değer çok düşükse yoğun anlarda ziyaretçiler bekler, çok yüksekse sunucunun belleği tükenir. Ayar /etc/php/8.3/fpm/pool.d/www.conf dosyasındadır (Debian'da 8.4).

Kaba bir hesap: PHP'ye ayırabileceğiniz RAM'i, bir PHP sürecinin ortalama bellek kullanımına bölün. WordPress gibi bir uygulamada bir süreç genellikle 40-80 MB kullanır. Örneğin 4 GB RAM'li bir VDS'te MariaDB ve sistem için 1,5 GB ayırırsanız, kalan yaklaşık 2,5 GB için pm.max_children = 30 makul bir başlangıçtır. Süreçlerin gerçek bellek kullanımını görmek için:

ps -o rss,cmd -C php-fpm8.3 | awk 'NR>1 {s+=$1; n++} END {print n " süreç, ortalama " int(s/n/1024) " MB"}'

Değişiklikten sonra sudo systemctl restart php8.3-fpm ile PHP-FPM'i yeniden başlatın. Loglarda server reached pm.max_children setting uyarısı görüyorsanız değeri artırmanız ya da RAM'i büyütmeniz gerekir.

Statik dosyaları tarayıcıda önbellekleyin

Görsel, CSS ve JavaScript dosyalarının her ziyarette yeniden indirilmemesi için sunucu bloğuna şu bölümü ekleyin:

location ~* \.(jpg|jpeg|png|webp|gif|svg|css|js|woff2)$ {
    expires 30d;
    access_log off;
}

Bakım İçin Kısa Notlar

  • Güncellemeler: sudo apt update && sudo apt upgrade Nginx, PHP ve MariaDB güvenlik yamalarını getirir. PHP'deki kritik açıklar hakkında PHP güvenlik güncelleme rehberimize göz atabilirsiniz.
  • Yedek: Veritabanını sudo mariadb-dump ornek_db > ornek_db.sql ile, dosyaları tar ile düzenli yedekleyin ve yedekleri sunucu dışına kopyalayın.
  • Loglar: Hata ayıklarken /var/log/nginx/error.log ilk bakmanız gereken yerdir: sudo tail -f /var/log/nginx/error.log.
  • Aynı sunucuda başka siteler: her site için 4. adımı yeni bir dosya, yeni bir klasör ve yeni bir veritabanıyla tekrarlayın, ardından certbot --nginx -d yenisite.com çalıştırın.

Uygulamalarınızı kapsayıcılarla çalıştırmayı tercih ederseniz Docker Kurulumu rehberimizde Nginx'i ters vekil olarak kullanmayı anlattık; bu rehberdeki SSL adımları orada da aynen geçerlidir.


Özet

  1. DNS'te alan adınızı VDS IP'nize yönlendirin.
  2. nginx, mariadb-server ve php-fpm paketlerini kurun; mariadb-secure-installation çalıştırın.
  3. Site için ayrı veritabanı ve kullanıcı açın.
  4. Nginx sunucu bloğunu doğru PHP-FPM soketiyle yazın, nginx -t ile test edin.
  5. certbot --nginx ile SSL alın, certbot renew --dry-run ile yenilemeyi doğrulayın.

Web sitenizi kendi kurduğunuz LEMP yığınıyla yayınlamak için NVMe diskli, Türkiye lokasyonlu VDS paketlerimizi inceleyin. Kurulumun herhangi bir adımında takılırsanız destek talebi açın; talebinize nginx -t çıktısını ve hata mesajını ekleyin.


Kaynaklar

Sıkça Sorulan Sorular

LEMP ile LAMP arasındaki fark nedir?

İkisi de Linux, MariaDB/MySQL ve PHP kullanır; fark web sunucusundadır. LEMP'te Nginx, LAMP'ta Apache kullanılır. Nginx az bellekle çok sayıda bağlantıyı karşıladığı için VDS'lerde sık tercih edilir; PHP'yi PHP-FPM üzerinden çalıştırır.

Certbot ile alınan SSL sertifikası ne kadar geçerli?

Let's Encrypt sertifikaları kısa ömürlüdür (şu an 90 gün) ve Certbot'un kurduğu zamanlayıcı süresi dolmadan otomatik yeniler. Yenilemenin çalıştığını sudo certbot renew --dry-run komutuyla kontrol edin.

Nginx 502 Bad Gateway hatası neden olur?

Genellikle Nginx PHP-FPM'e ulaşamıyordur. Sunucu bloğundaki fastcgi_pass satırında yazan soket adını ls /run/php/ çıktısıyla karşılaştırın ve PHP-FPM servisinin çalıştığını systemctl status ile kontrol edin.

MariaDB'ye uzaktan bağlanmak için 3306 portunu açmalı mıyım?

Hayır. Veritabanı portunu internete açmak yerine SSH tüneli kullanın: ssh -L 3306:127.0.0.1:3306 kullanici@sunucu_ip komutundan sonra veritabanı aracınızla 127.0.0.1:3306 adresine bağlanırsınız.

Ubuntu 24.04 ve Debian 13'te hangi PHP sürümü kurulur?

Ubuntu 24.04 deposu PHP 8.3, Debian 13 deposu PHP 8.4 kurar. Nginx ayarındaki PHP-FPM soket adı da bu sürüme göre php8.3-fpm.sock ya da php8.4-fpm.sock olur.

TR| EN