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.

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.comvewww.ornek.comiç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ızdanslookup ornek.comyazı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.

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.

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_passsatırındaki soket adını bir önceki adımdals /run/php/ile gördüğünüz adla aynı yapın.try_files ... /index.php?$argssatırı WordPress ve Laravel gibi "güzel URL" kullanan uygulamalar için gereklidir.- Son
locationbloğu.env,.gitgibi gizli dosyaların tarayıcıdan okunmasını engeller; Let's Encrypt'in kullandığı.well-knownklasörünü ise açık bırakır.

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.

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.comile sahipliği düzeltin. - WordPress:
wordpress.org'dan son sürümü indirippublicklasörüne açın, kurulum sihirbazında 2. adımda oluşturduğunuz veritabanı adını, kullanıcıyı ve şifreyi girin. Veritabanı sunucusu olaraklocalhostyazın. - Laravel: Laravel'de herkese açık klasör
publicalt klasörüdür; sunucu bloğundakirootsatırını projeninpublicklasö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
- 502 Bad Gateway. Nginx PHP-FPM'e ulaşamıyor.
fastcgi_passsatırındaki soket adınıls /run/php/çıktısıyla karşılaştırın vesystemctl status php8.3-fpmile servisin çalıştığını kontrol edin. - PHP dosyasının indirilmesi ya da kod olarak görünmesi.
location ~ \.php$bloğu eksik ya da site etkinleştirilmemiş.sites-enabledaltındaki bağlantıyı venginx -tçıktısını kontrol edin. - 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,
nslookupsonucunun doğru olduğundan emin olun. - 403 Forbidden. Klasörde
index.phpveyaindex.htmlyok ya da dosya sahipliği yanlış.ls -la /var/www/ornek.com/publicile kontrol edin. - 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.
- 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. info.phpdosyası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 upgradeNginx, 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.sqlile, dosyalarıtarile düzenli yedekleyin ve yedekleri sunucu dışına kopyalayın. - Loglar: Hata ayıklarken
/var/log/nginx/error.logilk 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
- DNS'te alan adınızı VDS IP'nize yönlendirin.
nginx,mariadb-servervephp-fpmpaketlerini kurun;mariadb-secure-installationçalıştırın.- Site için ayrı veritabanı ve kullanıcı açın.
- Nginx sunucu bloğunu doğru PHP-FPM soketiyle yazın,
nginx -tile test edin. certbot --nginxile SSL alın,certbot renew --dry-runile 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
- Configuring HTTPS servers – nginx documentation
- PHP Manual: FastCGI Process Manager (FPM)
- Certbot Instructions (nginx): Let's Encrypt sertifikası alma
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.


