Neden Docker Compose ile Laravel, Nginx ve MySQL Kurulumu Yapmalıyız?
Modern web geliştirme dünyasında, projelerinizi tutarlı ve izole ortamlarda çalıştırmak her zamankinden daha önemli hale geldi. Genellikle, geliştiriciler farklı işletim sistemleri ve yerel yapılandırma sorunlarıyla boğuşmak zorunda kalır; bu da “benim bilgisayarımda çalışıyordu” sendromuna yol açar. Peki, bu karmaşayı ortadan kaldırarak geliştirme sürecinizi nasıl hızlandırabilir, ekip üyeleri arasındaki tutarsızlıkları nasıl giderebilir ve hatta dağıtım süreçlerinizi nasıl kolaylaştırabilirsiniz? İşte tam da bu noktada Docker Compose devreye giriyor. Bu kapsamlı rehberde, Laravel tabanlı bir uygulamanın Nginx web sunucusu ve MySQL veritabanı ile Docker Compose kullanarak nasıl kurulacağını adım adım inceleyeceğiz. Bu sayede, hem yeni başlayanlar hem de deneyimli geliştiriciler için güçlü, esnek ve taşınabilir bir geliştirme ortamı oluşturmanın tüm inceliklerini keşfedeceğiz.
Geleneksel geliştirme yaklaşımlarında, bir projenin bağımlılıklarını (PHP, Nginx, MySQL gibi) manuel olarak kurmak ve yapılandırmak zaman alıcı ve hata yapmaya açık bir süreçtir. Örneğin, farklı projeler farklı PHP sürümleri gerektirebilir veya veritabanı sunucusu yapılandırmaları çatışabilir. Bu durum, özellikle büyük ekiplerde veya birden fazla proje üzerinde çalışan geliştiriciler için ciddi verimlilik kayıplarına neden olabilir. Docker ve Docker Compose, bu tür sorunlara kökten bir çözüm sunar. Her hizmeti (Laravel uygulaması, Nginx, MySQL) kendi izole konteynerinde çalıştırarak, bağımlılık çakışmalarını ortadan kaldırır ve her geliştiricinin aynı ortamda çalışmasını garanti eder. Bu yaklaşım, sadece geliştirme sürecini değil, aynı zamanda test ve üretim ortamlarına geçişi de büyük ölçüde basitleştirir. Böylece, projenizin yaşam döngüsünün her aşamasında tutarlılık ve güvenilirlik sağlarsınız.
Bu rehber boyunca, sadece teknik adımları değil, aynı zamanda her bir bileşenin neden bu şekilde yapılandırılması gerektiğini de açıklayacağız. Gerçek dünya senaryolarıyla desteklenen vaka analizleri sayesinde, öğrendiklerinizi kendi projelerinize nasıl uygulayabileceğinizi daha iyi anlayacaksınız. Amacımız, sizi sadece bir kurulum sihirbazı olmaktan çıkarıp, Docker Compose’un gücünü tam anlamıyla kavrayan ve kendi ihtiyaçlarınıza göre uyarlayabilen bir geliştiriciye dönüştürmektir. Hazırsanız, bu heyecan verici yolculuğa başlayalım ve modern web geliştirmenin temel taşlarından biri olan konteynerizasyon dünyasına adım atalım.
Temel Kavramlar Nelerdir? Docker ve Docker Compose’a Hızlı Bir Bakış
Konteynerizasyon dünyasına adım atmadan önce, bu teknolojinin temelini oluşturan kavramları anlamak önemlidir. Docker ve Docker Compose, birbirini tamamlayan iki araçtır ve modern uygulama geliştirme ile dağıtım süreçlerini kökten değiştirmiştir. Peki, bu araçlar tam olarak nedir ve Laravel, Nginx, MySQL üçlüsüyle nasıl bir araya gelir?
Docker Nedir ve Konteyner Kavramı Ne Anlama Gelir?
Docker, uygulamaları ve bağımlılıklarını konteyner adı verilen izole edilmiş, hafif ve taşınabilir paketler içinde paketlemeye olanak tanıyan açık kaynaklı bir platformdur. Bir konteyner, sanal makinelere benzer şekilde uygulamanın çalışması için gereken her şeyi (kod, çalışma zamanı, sistem araçları, kütüphaneler ve ayarlar) içerir. Ancak sanal makinelerden farklı olarak, konteynerler işletim sisteminin çekirdeğini paylaşır ve bu da onları çok daha hafif ve hızlı yapar. Her konteyner, ana makinenin kaynaklarını daha verimli kullanır ve saniyeler içinde başlatılabilir. Bu izolasyon sayesinde, bir konteynerde çalışan uygulamanın bağımlılıkları veya yapılandırması, başka bir konteynerdeki uygulamayı etkilemez. Bu, geliştiriciler için “benim makinemde çalışıyordu” sorununu ortadan kaldıran en büyük avantajlardan biridir.
Örneğin, bir Laravel uygulamasının PHP 8.1’e, başka bir uygulamanın ise PHP 7.4’e ihtiyacı olduğunu varsayalım. Geleneksel yaklaşımlarda bu durum karmaşık versiyon yönetimi sorunlarına yol açabilir. Ancak Docker ile her iki PHP sürümünü de ayrı konteynerlerde çalıştırabilir ve her uygulamanın kendi özel ortamına sahip olmasını sağlayabilirsiniz. Bu esneklik, özellikle birden fazla proje üzerinde çalışan geliştiriciler veya mikroservis mimarileri kullanan ekipler için paha biçilmezdir.
Docker Compose Nedir ve Çoklu Konteyner Yönetimi Nasıl Yapılır?
Docker Compose, birden fazla Docker konteynerinden oluşan uygulamaları tanımlamak ve çalıştırmak için kullanılan bir araçtır. Tek bir YAML dosyası kullanarak, uygulamanızın tüm hizmetlerini (örneğin, Laravel uygulaması, Nginx web sunucusu, MySQL veritabanı), ağlarını ve depolama birimlerini yapılandırabilirsiniz. Docker Compose, bu hizmetleri tek bir komutla başlatmanıza, durdurmanıza ve yeniden oluşturmanıza olanak tanır. Bu sayede, karmaşık çok katmanlı uygulamaların yönetimini inanılmaz derecede basitleştirir.
Bizim senaryomuzda, Laravel uygulamasını çalıştıran bir PHP-FPM konteyneri, HTTP isteklerini yönlendiren bir Nginx konteyneri ve verileri depolayan bir MySQL konteyneri gibi üç ana hizmetimiz olacak. Docker Compose, bu üç hizmeti birbirine bağlayacak, aralarındaki iletişimi sağlayacak ve hepsini tek bir birim olarak yönetmemize olanak tanıyacak. Bu entegrasyon, geliştirme ortamınızı hızlıca ayağa kaldırmanın ve tüm ekibin aynı, tutarlı ortamda çalışmasını sağlamanın anahtarıdır.
Nginx, MySQL ve Laravel’in Bu Ekosistemdeki Rolleri Nelerdir?
- Laravel: PHP tabanlı, modern web uygulamaları geliştirmek için popüler bir MVC (Model-View-Controller) framework’üdür. Konteyner içinde çalışacak olan ana uygulamamızdır. Biz, Laravel’i bir PHP-FPM (FastCGI Process Manager) konteyneri içinde çalıştıracağız. PHP-FPM, PHP kodunu işlemekten sorumludur.
- Nginx: Yüksek performanslı bir web sunucusu ve ters proxy’dir. Gelen HTTP isteklerini karşılayacak, statik dosyaları sunacak ve dinamik PHP isteklerini (yani Laravel uygulamamızın isteklerini) PHP-FPM konteynerimize yönlendirecektir. Bu yapılandırma, PHP kodunun doğrudan web sunucusu tarafından işlenmesi yerine, özel bir PHP işlem yöneticisi tarafından işlenmesini sağlar, bu da performansı ve güvenliği artırır.
- MySQL: Açık kaynaklı, ilişkisel bir veritabanı yönetim sistemidir. Laravel uygulamamızın tüm verilerini (kullanıcılar, ürünler, siparişler vb.) depolayacağı yerdir. Ayrı bir konteynerde çalışacak ve Laravel uygulamamız bu konteynere ağ üzerinden bağlanacaktır.
Bu üç bileşeni Docker Compose ile bir araya getirerek, sadece izole ve tutarlı bir geliştirme ortamı oluşturmakla kalmayacak, aynı zamanda uygulamanızın dağıtımını da basitleştireceksiniz. Her bir bileşen kendi sorumluluğunu üstlenirken, Docker Compose onları sorunsuz bir şekilde entegre ederek güçlü bir ekosistem yaratır. Bu sayede, geliştiriciler altyapı detaylarıyla boğuşmak yerine, doğrudan iş mantığına odaklanabilirler.
Geliştirme Ortamınızı Hazırlama: Adım Adım Kurulum Süreci
Artık temel kavramları anladığımıza göre, Docker Compose ile Laravel, Nginx ve MySQL ortamımızı kurmaya başlayabiliriz. Bu bölümde, gerekli önkoşulları tamamlayacak, proje dizin yapısını oluşturacak ve temel yapılandırma dosyalarını hazırlayacağız. Her adımı dikkatlice takip etmek, sorunsuz bir kurulum için kritik öneme sahiptir.
Önkoşullar: Docker ve Docker Compose Kurulumu
Bu rehbere başlamadan önce, sisteminizde Docker ve Docker Compose’un kurulu olması gerekmektedir. Eğer kurulu değilse, aşağıdaki adımları izleyerek kurulumu gerçekleştirebilirsiniz:
- Docker Desktop Kurulumu: Windows veya macOS kullanıyorsanız, Docker Desktop‘ı indirip kurmanız en kolay yoldur. Docker Desktop, hem Docker Engine’i hem de Docker Compose’u içerir. Linux kullanıyorsanız, Docker Engine’i ve Docker Compose’u Docker’ın resmi belgelerinden yükleyebilirsiniz.
-
Kurulumu Doğrulama: Kurulum tamamlandıktan sonra, terminalinizi veya komut istemcinizi açın ve aşağıdaki komutları çalıştırarak Docker ve Docker Compose’un doğru şekilde kurulduğunu doğrulayın:
docker --version docker compose versionBu komutlar, kurulu Docker ve Docker Compose sürümlerini göstermelidir. Eğer hata alıyorsanız, kurulum adımlarını tekrar kontrol edin.
Proje Yapısını Oluşturma
Şimdi projemiz için gerekli dizin yapısını oluşturalım. Bu yapı, Laravel uygulamamızın kodunu, Nginx yapılandırmasını ve Docker ile ilgili dosyaları düzenli bir şekilde barındıracaktır.
mkdir laravel-docker-app
cd laravel-docker-app
# Laravel uygulaması için ana dizin
mkdir app
# Nginx yapılandırması için dizin
mkdir nginx
# MySQL verileri için dizin (isteğe bağlı ama önerilir)
mkdir db_data
Bu komutları çalıştırdıktan sonra, proje dizininiz aşağıdaki gibi görünmelidir:
laravel-docker-app/
├── app/
├── nginx/
├── db_data/
└── docker-compose.yml (henüz oluşturmadık)
Laravel Uygulamasını Oluşturma (İsteğe Bağlı, Mevcutsa Atla)
Eğer mevcut bir Laravel projeniz yoksa, app dizini içine yeni bir Laravel projesi oluşturalım. Bunu Docker konteyneri içinde de yapabiliriz, ancak ilk kurulum için yerel olarak yapmak daha pratik olabilir. Eğer mevcut bir Laravel projeniz varsa, app dizininin içine kopyalamanız yeterlidir.
# app dizinine geçiş yapın
cd app
# Laravel kurucusu kuruluysa:
composer create-project laravel/laravel .
# Eğer composer kurulu değilse, Docker üzerinden de kurabilirsiniz:
# docker run --rm -v $(pwd):/app composer create-project laravel/laravel .
Laravel projeniz app dizini içinde oluştuktan sonra, laravel-docker-app ana dizinine geri dönün:
cd ..
Nginx Yapılandırmasını Hazırlama (nginx/default.conf)
Nginx, gelen HTTP isteklerini Laravel uygulamamıza yönlendirmekten sorumlu olacaktır. nginx dizini içinde default.conf adında bir dosya oluşturalım ve aşağıdaki içeriği ekleyelim:
# nginx/default.conf
server {
listen 80;
server_name localhost;
root /var/www/html/public; # Laravel'in public dizini
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000; # 'app' hizmetine (PHP-FPM) yönlendir
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Bu yapılandırma dosyasında dikkat etmeniz gereken önemli noktalar:
listen 80;: Nginx’in 80 numaralı porttan gelen istekleri dinlemesini sağlar.root /var/www/html/public;: Laravel uygulamasınınpublicdizinini web kök dizini olarak ayarlar.fastcgi_pass app:9000;: PHP dosyası isteklerini, Docker Compose dosyamızda tanımlayacağımızapphizmetinin (PHP-FPM) 9000 numaralı portuna yönlendirir. Docker Compose içindeki hizmetler, hizmet adları üzerinden birbirleriyle iletişim kurabilirler.
PHP için Dockerfile Oluşturma (app/Dockerfile)
Laravel uygulamamızın çalışacağı PHP-FPM konteynerini tanımlamak için app dizini içinde bir Dockerfile oluşturalım. Bu dosya, PHP konteynerimizin nasıl inşa edileceğini belirler.
# app/Dockerfile
FROM php:8.2-fpm-alpine
# Gerekli sistem bağımlılıklarını yükle
RUN apk add --no-cache \
git \
curl \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
libzip-dev \
oniguruma-dev \
libpq \
libwebp-dev \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql zip exif pcntl \
&& docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install -j$(nproc) gd \
&& rm -rf /var/cache/apk/*
# Composer'ı kur
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Çalışma dizinini ayarla
WORKDIR /var/www/html
# Geliştirme için PHP-FPM yapılandırmasını kopyala
COPY php-fpm.conf /etc/php/8.2/fpm/pool.d/www.conf
# Kullanıcı ve grup oluştur
RUN addgroup -g 1000 laravel && adduser -u 1000 -G laravel -s /bin/sh -D laravel
RUN chown -R laravel:laravel /var/www/html
USER laravel
EXPOSE 9000
CMD ["php-fpm"]
Bu Dockerfile, PHP 8.2 FPM Alpine tabanlı bir imaj kullanır, gerekli PHP eklentilerini kurar, Composer’ı ekler ve Laravel uygulamasının çalışacağı /var/www/html dizinini ayarlar. Ayrıca, güvenlik için bir laravel kullanıcısı oluşturup uygulamanın bu kullanıcı altında çalışmasını sağlarız.
Ek olarak, app dizini içinde php-fpm.conf adında bir dosya oluşturup aşağıdaki içeriği ekleyelim. Bu dosya, PHP-FPM’in nasıl davranacağını yapılandırır.
# app/php-fpm.conf
[www]
user = laravel
group = laravel
listen = 9000
listen.owner = laravel
listen.group = laravel
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
catch_workers_output = yes
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/fpm_error.log
php_admin_flag[log_errors] = on
Bu yapılandırma, PHP-FPM’in 9000 numaralı porttan dinlemesini, hata günlüklerini belirtilen dosyaya yazmasını ve geliştirme ortamında hataları göstermesini sağlar.
Bu adımları tamamladıktan sonra, projenizin temel iskeleti hazır hale gelmiş demektir. Bir sonraki bölümde, tüm bu bileşenleri bir araya getirecek olan docker-compose.yml dosyasını oluşturacağız.
Docker Compose Dosyasını Oluşturma: Hizmetleri Tanımlama
Şimdi projemizin kalbi olan docker-compose.yml dosyasını oluşturma zamanı geldi. Bu dosya, Laravel uygulamamızın, Nginx web sunucumuzun ve MySQL veritabanımızın Docker konteynerlerini nasıl tanımlayacağımızı, birbirleriyle nasıl iletişim kuracaklarını ve hangi kaynakları kullanacaklarını belirler. Ana dizinimizde (laravel-docker-app/) docker-compose.yml adında bir dosya oluşturalım ve aşağıdaki içeriği adım adım inceleyelim.
# docker-compose.yml
version: '3.8'
services:
# Laravel Uygulama Hizmeti (PHP-FPM)
app:
build:
context: ./app
dockerfile: Dockerfile
container_name: laravel_app
restart: unless-stopped
volumes:
- ./app:/var/www/html
networks:
- laravel_network
environment:
# Laravel .env dosyasındaki veritabanı bağlantı bilgilerini burada tanımlayacağız
DB_CONNECTION: mysql
DB_HOST: db # MySQL hizmetinin adı
DB_PORT: 3306
DB_DATABASE: laravel_db
DB_USERNAME: laravel_user
DB_PASSWORD: supersecretpassword
APP_ENV: local
APP_DEBUG: "true"
# Diğer Laravel ortam değişkenleri buraya eklenebilir
# Nginx Web Sunucusu Hizmeti
nginx:
image: nginx:stable-alpine
container_name: laravel_nginx
restart: unless-stopped
ports:
- "80:80" # Host'un 80. portunu konteynerin 80. portuna yönlendir
volumes:
- ./nginx:/etc/nginx/conf.d
- ./app:/var/www/html # Laravel uygulamasının kodunu Nginx'e bağla
networks:
- laravel_network
depends_on:
- app # Nginx'in app hizmetine bağımlı olduğunu belirtir
# MySQL Veritabanı Hizmeti
db:
image: mysql:8.0
container_name: laravel_db
restart: unless-stopped
environment:
MYSQL_DATABASE: laravel_db
MYSQL_USER: laravel_user
MYSQL_PASSWORD: supersecretpassword
MYSQL_ROOT_PASSWORD: rootpassword
volumes:
- db_data:/var/lib/mysql # Veritabanı verilerini kalıcı hale getir
networks:
- laravel_network
volumes:
db_data: # MySQL verileri için isimlendirilmiş bir volume tanımla
networks:
laravel_network:
driver: bridge
Bu YAML dosyasını adım adım açıklayalım:
-
version: '3.8': Docker Compose dosyasının versiyonunu belirtir. Genellikle en yeni stabil sürüm kullanılır. -
services:: Uygulamamızın tüm bileşenlerini (hizmetlerini) burada tanımlarız. Her hizmet kendi konteynerinde çalışacaktır.-
app:(Laravel Uygulama Hizmeti):build:: Bu hizmet için bir Docker imajının nasıl oluşturulacağını belirtir.context: ./app: Docker imajını oluştururkenappdizinini temel alır.dockerfile: Dockerfile:appdizini içindekiDockerfiledosyasını kullanır.container_name: laravel_app: Konteyner için okunabilir bir isim atar.restart: unless-stopped: Konteynerin durdurulmadığı sürece otomatik olarak yeniden başlamasını sağlar.volumes:: Ana makine ile konteyner arasında dosya veya dizin paylaşımı sağlar../app:/var/www/html: Ana makinedekiappdizinini, konteyner içindeki Laravel uygulamasının çalışacağı/var/www/htmldizinine bağlar. Bu sayede, kod değişiklikleri anında konteyner içinde yansır ve geliştirme sürecini kolaylaştırır.
networks:: Konteynerin hangi ağlara bağlı olacağını belirtir.environment:: Konteyner içinde kullanılacak ortam değişkenlerini tanımlar. Burada Laravel’in veritabanı bağlantı bilgileri ve diğer önemli ayarları bulunur.DB_HOST: dbifadesi,dbadındaki MySQL hizmetine bağlanacağımızı gösterir.
-
nginx:(Nginx Web Sunucusu Hizmeti):image: nginx:stable-alpine: Nginx’in resmi stabil-alpine imajını kullanırız. Alpine tabanlı imajlar daha küçüktür ve kaynakları daha verimli kullanır.ports:: Ana makine ile konteyner arasındaki port eşleştirmelerini yapar."80:80": Ana makinenin 80 numaralı portundan gelen istekleri Nginx konteynerinin 80 numaralı portuna yönlendirir. Böylece tarayıcınızdanhttp://localhostadresine erişebilirsiniz.
volumes::./nginx:/etc/nginx/conf.d: Ana makinedekinginxdizinini, Nginx’in yapılandırma dosyalarını barındıran konteyner dizinine bağlar. Daha önce oluşturduğumuzdefault.confdosyası bu sayede okunur../app:/var/www/html: Laravel uygulama kodunu Nginx’e de bağlar, böylece Nginx statik dosyaları sunabilir ve PHP-FPM’e istekleri yönlendirebilir.
depends_on: - app: Nginx’inapphizmeti başlamadan önce başlamamasını sağlar. Bu, servisler arası başlatma sırasını yönetmeye yardımcı olur.
-
db:(MySQL Veritabanı Hizmeti):image: mysql:8.0: MySQL veritabanının 8.0 sürümünü kullanırız.environment:: MySQL için gerekli ortam değişkenlerini ayarlar. Veritabanı adı, kullanıcı adı, şifre ve root şifresi burada tanımlanır. Bu değerlerin Laravel uygulamasının ortam değişkenleriyle eşleştiğinden emin olun.volumes::db_data:/var/lib/mysql: Bu, MySQL verilerinin kalıcı olmasını sağlayan kritik bir adımdır.db_dataadında bir named volume tanımlarız. Konteyner silinse bile, bu volume içindeki veriler korunur ve bir sonraki başlatmada tekrar kullanılabilir.
-
-
volumes:: Docker Compose dosyasının sonunda, tüm named volume’leri tanımlarız.db_data:: MySQL için kullandığımız named volume’ü burada tanımlarız. Docker bu volume’ü otomatik olarak oluşturur ve yönetir.
-
networks:: Tüm hizmetlerin iletişim kurabileceği özel bir Docker ağı tanımlarız.laravel_network:: Tüm hizmetlerimiz bu ağa bağlanır.driver: bridgevarsayılan ağ sürücüsüdür ve hizmetlerin birbirini isimleriyle bulmasını sağlar (örneğin,apphizmetidbhizmetinedbadıyla erişebilir).
Bu docker-compose.yml dosyası, uygulamanızın tüm altyapısını tek bir dosyada tanımlamanıza olanak tanır. Artık tüm bileşenler bir araya geldiğine göre, bir sonraki adımda bu ortamı nasıl başlatacağımızı ve Laravel uygulamasını nasıl çalıştıracağımızı göreceğiz.
Laravel Uygulamasını Konteynerize Etme ve Başlatma
Tüm yapılandırma dosyalarımızı hazırladığımıza göre, artık Laravel uygulamamızı Docker Compose ile başlatmaya hazırız. Bu bölüm, Docker Compose ortamını nasıl ayağa kaldıracağımızı, Laravel’in bağımlılıklarını nasıl kuracağımızı ve veritabanı bağlantısını nasıl test edeceğimizi detaylandıracak. Ayrıca, küçük bir e-ticaret uygulamasının başlangıç kurulumu üzerinden bir vaka analizi sunacağız.
Ortamı Başlatma: Sihirli Komut
Proje ana dizininizde (laravel-docker-app/) terminali açın ve aşağıdaki komutu çalıştırın:
docker compose up -d --build
Bu komutun ne anlama geldiğini açıklayalım:
docker compose up: Docker Compose dosyasında tanımlanan tüm hizmetleri (app,nginx,db) başlatır.-d(detach): Konteynerleri arka planda çalıştırır, böylece terminalinizi serbest bırakır.--build: Hizmetler için Docker imajlarını (özellikleapphizmeti içinDockerfile‘ı kullanarak) yeniden oluşturur. Bu, ilk çalıştırma veyaDockerfile‘da değişiklik yaptığınızda önemlidir.
Komutu çalıştırdıktan sonra, Docker Compose imajları indirecek (eğer yerel olarak yoksa), app hizmeti için Dockerfile’ı kullanarak imajı oluşturacak ve tüm konteynerleri başlatacaktır. Bu işlem biraz zaman alabilir, özellikle ilk çalıştırmada.
Konteynerlerin durumunu kontrol etmek için aşağıdaki komutu kullanabilirsiniz:
docker compose ps
Tüm hizmetlerin Up (çalışıyor) durumda olduğunu görmelisiniz.
Laravel Bağımlılıklarını Kurma ve Uygulamayı Hazırlama
Konteynerler çalışmaya başladıktan sonra, Laravel uygulamasının bağımlılıklarını (Composer paketleri) kurmamız ve diğer başlangıç ayarlarını yapmamız gerekiyor. Bu işlemleri, Laravel uygulamasının çalıştığı app konteyneri içinde yapacağız.
Laravel konteynerine bağlanmak için aşağıdaki komutu kullanın:
docker compose exec app bash
Bu komut, laravel_app adlı konteynerin içine bir bash oturumu açar. Artık konteynerin içindesiniz ve Laravel projenizin kök dizini olan /var/www/html konumundasınız.
Şimdi Laravel için gerekli adımları tamamlayalım:
-
Composer Bağımlılıklarını Kurma:
composer installBu komut,
composer.jsondosyasındaki tüm bağımlılıkları yükleyecektir. Eğer daha öncecomposer create-projectile Laravel’i kurduysanız bu adım zaten yapılmış olabilir, ancak yine de çalıştırmak zarar vermez. -
.envDosyasını Oluşturma:cp .env.example .envLaravel’in ortam değişkenleri için
.envdosyasını oluşturur. Bu dosya,docker-compose.ymliçinde tanımladığımızenvironmentdeğişkenlerini geçersiz kılabilir. Bu yüzden dikkatli olun. -
Uygulama Anahtarını Oluşturma:
php artisan key:generateLaravel uygulamanız için benzersiz bir şifreleme anahtarı oluşturur. Bu adım güvenlik için zorunludur.
-
Veritabanı Migrasyonlarını Çalıştırma:
php artisan migrateBu komut, Laravel’in veritabanı şemalarını MySQL veritabanımıza uygular. Eğer bu adımda bir hata alırsanız, genellikle veritabanı bağlantı bilgilerinizde (
.envdosyasında veyadocker-compose.yml‘dekienvironmentkısmında) bir sorun olduğu anlamına gelir.DB_HOST‘undbolduğundan emin olun.
Bu adımları tamamladıktan sonra, exit yazarak konteynerden çıkabilirsiniz.
Uygulamayı Tarayıcıda Görüntüleme
Tüm adımları başarıyla tamamladıysanız, web tarayıcınızı açın ve http://localhost adresine gidin. Laravel’in varsayılan karşılama sayfasını görmelisiniz. Bu, Laravel uygulamanızın Nginx üzerinden başarıyla çalıştığı ve veritabanı bağlantısının da doğru olduğu anlamına gelir.
Vaka Analizi: Küçük Bir E-Ticaret Uygulamasının Başlangıç Kurulumu
Hayal edelim ki, “ShopEase” adında yeni bir e-ticaret platformu geliştiriyorsunuz. Bu platformun ürün listeleme, sepet ve ödeme gibi temel özelliklere sahip olması gerekiyor. Geliştirme ekibiniz üç kişiden oluşuyor ve herkesin aynı ortamda çalışması kritik. Geleneksel yöntemlerle, her geliştiricinin kendi makinesinde PHP, Nginx ve MySQL’i kurması, versiyon farklılıkları ve bağımlılık çakışmaları nedeniyle zaman kaybına yol açacaktı.
Docker Compose ile bu süreci nasıl basitleştirebiliriz?
-
Tutarlılık: Yukarıdaki
docker-compose.ymldosyasını veDockerfile‘ı kullanarak, tüm ekip üyeleri aynı PHP sürümü, Nginx yapılandırması ve MySQL versiyonuyla çalışır.git clonevedocker compose up -d --buildkomutları, herkesin saniyeler içinde geliştirme ortamını kurmasını sağlar. -
Hızlı Geliştirme:
volumessayesinde, geliştiriciler ana makinedeki kod dosyalarını düzenlerken, değişiklikler anında konteyner içinde yansır. Bu, anlık geri bildirim sağlar ve geliştirme döngüsünü hızlandırır. -
Veritabanı Yönetimi:
db_datavolume’ü sayesinde, veritabanı verileri kalıcı hale gelir. Geliştiriciler konteynerleri durdurup başlatsa bile verileri kaybolmaz. Ayrıca,php artisan migratekomutuyla veritabanı şeması kolayca yönetilebilir.
ShopEase projesinin ilk aşamasında, bu kurulum sayesinde ekip, altyapı sorunlarıyla uğraşmak yerine doğrudan ürün kataloglama ve kullanıcı kimlik doğrulama gibi temel e-ticaret özelliklerini geliştirmeye odaklanabilir. Bu, projenin daha hızlı ilerlemesini ve pazara daha erken çıkmasını sağlar.
İleri Düzey İpuçları ve Optimizasyonlar: Performans ve Güvenlik
Docker Compose ile temel Laravel, Nginx ve MySQL kurulumunu başarıyla tamamladık. Ancak, geliştirme ortamınızı daha verimli, güvenli ve gerçek dünya senaryolarına daha uygun hale getirmek için yapabileceğiniz bazı ileri düzey optimizasyonlar ve ipuçları bulunmaktadır. Bu bölümde, performansı artırmak, güvenliği sağlamak ve geliştirme sürecinizi daha da kolaylaştırmak için kullanabileceğiniz tekniklere değineceğiz.
Volume Bağlamanın Önemi ve Kalıcı Veri Yönetimi
Daha önce MySQL verileri için bir “named volume” (db_data) tanımlamıştık. Bu, konteynerler silinse bile veritabanı verilerinizin kaybolmamasını sağlar. Ancak, sadece veritabanı verileri değil, uygulamanızın diğer kalıcı verileri (örneğin, kullanıcı tarafından yüklenen dosyalar, loglar) için de volume kullanmak önemlidir.
Örneğin, Laravel uygulamanızın storage dizini içine yüklenen resimler veya diğer dosyalar varsa, bu dizini de kalıcı hale getirmek isteyebilirsiniz. docker-compose.yml dosyanızda app hizmeti altına ek bir volume tanımlayabilirsiniz:
# docker-compose.yml (app hizmeti altında)
app:
# ... diğer ayarlar ...
volumes:
- ./app:/var/www/html
- app_storage:/var/www/html/storage # Yeni volume
# ...
# ...
volumes:
db_data:
app_storage: # Yeni named volume tanımı
Bu şekilde, app_storage adında yeni bir named volume oluşturulur ve Laravel’in storage dizini bu volume’e bağlanır. Böylece, kullanıcılar tarafından yüklenen dosyalar konteynerin yaşam döngüsünden bağımsız olarak kalıcı hale gelir.
Özel Docker Ağları ve Hizmetler Arası İletişim
Docker Compose ile varsayılan olarak bir köprü ağı (bridge network) oluşturulur ve tüm hizmetler bu ağa bağlanır. Bu, hizmetlerin birbirini isimleriyle bulmasını sağlar (örneğin, app konteyneri db konteynerine db host adıyla bağlanabilir). Bu yapılandırma çoğu geliştirme ortamı için yeterlidir.
Ancak, daha karmaşık senaryolarda veya mikroservis mimarilerinde, farklı hizmet grupları için özel ağlar tanımlamak isteyebilirsiniz. Örneğin, bir API hizmeti ile bir UI hizmetini farklı ağlarda izole edebilir ve sadece belirli kapılar üzerinden iletişim kurmalarına izin verebilirsiniz. Bu, ağ güvenliğini artırır.
Mevcut laravel_network tanımımız zaten özel bir ağdır ve hizmetlerin güvenli bir şekilde iletişim kurmasını sağlar. Bu, varsayılan Docker ağına göre daha iyi bir izolasyon sunar.
Ortam Değişkenleri ve .env Dosyasının Etkin Kullanımı
Hassas bilgileri (veritabanı şifreleri, API anahtarları) doğrudan docker-compose.yml dosyasına yazmak yerine, Laravel’in kendi .env dosyasını kullanmak daha iyi bir yaklaşımdır. docker-compose.yml dosyasında environment bölümünde tanımladığınız değişkenler, Laravel’in konteynerinde ortam değişkenleri olarak ayarlanır. Laravel, kendi .env dosyasındaki değerleri bu ortam değişkenleriyle birleştirir ve genellikle .env dosyasındaki değerler önceliklidir.
Üretim ortamlarında ise, hassas bilgileri Docker Secret’lar veya bulut sağlayıcısının gizli yönetim hizmetleri aracılığıyla yönetmek çok daha güvenlidir. Geliştirme ortamında, .env dosyasını .gitignore‘a ekleyerek hassas bilgilerin versiyon kontrol sistemine girmesini engelleyin ve ekip üyelerinin kendi yerel .env dosyalarını oluşturmalarını sağlayın.
Performans İpuçları: Caching ve OPcache
Laravel uygulamalarının performansını artırmak için PHP’nin OPcache’ini ve Laravel’in kendi caching mekanizmalarını kullanmak önemlidir. Dockerfile’ınızda OPcache’i etkinleştirebilirsiniz:
# app/Dockerfile (mevcut RUN komutuna eklenebilir)
# ...
RUN apk add --no-cache \
# ... diğer bağımlılıklar ...
&& docker-php-ext-install opcache \
&& { \
echo "opcache.enable=1"; \
echo "opcache.revalidate_freq=0"; \
echo "opcache.use_cwd=1"; \
echo "opcache.validate_timestamps=1"; \
echo "opcache.max_accelerated_files=10000"; \
echo "opcache.memory_consumption=128"; \
echo "opcache.interned_strings_buffer=8"; \
echo "opcache.fast_shutdown=1"; \
} > /usr/local/etc/php/conf.d/opcache.ini \
&& rm -rf /var/cache/apk/*
# ...
Ayrıca, Laravel’in kendi önbellekleme komutlarını çalıştırarak (konteyner içinde):
php artisan config:cache
php artisan route:cache
php artisan view:cache
Uygulamanızın daha hızlı yanıt vermesini sağlayabilirsiniz. Bu komutları genellikle dağıtım öncesi üretim ortamında çalıştırırsınız. Geliştirme ortamında ise, kod değişikliklerinin anında görünmesi için genellikle önbellek devre dışı bırakılır veya sık sık temizlenir.
Güvenlik Önlemleri: Root Kullanıcıdan Kaçınma ve Portları Sınırlama
-
Root Kullanıcıdan Kaçınma:
Dockerfile‘daUSER laravelkomutunu kullanarak, uygulamanızınrootolmayan bir kullanıcı altında çalışmasını sağladık. Bu, bir güvenlik ihlali durumunda saldırganın sistem üzerinde tam yetki elde etmesini zorlaştırır. Bu iyi bir uygulamadır ve her zaman uygulanmalıdır. -
Portları Sınırlama:
docker-compose.ymldosyasında sadece gerekli portları dışarıya açtık (Nginx için 80). Veritabanı (MySQL 3306) veya PHP-FPM (9000) gibi hizmetlerin portlarını doğrudan ana makineye açmadık. Bu, dışarıdan gelebilecek saldırılara karşı yüzeyi küçültür ve güvenliği artırır. Hizmetler, Docker ağları üzerinden kendi içlerinde güvenli bir şekilde iletişim kurabilirler.
Vaka Analizi: Yüksek Trafikli Bir Blog Sitesinin Docker Compose ile Optimize Edilmesi
Bir haber portalı olan “HaberJet”in binlerce günlük ziyaretçisi olduğunu ve Docker Compose ile yönetildiğini düşünelim. İlk kurulum, Laravel, Nginx ve MySQL’i içeriyor ancak trafik arttıkça performans sorunları yaşanmaya başlıyor.
Optimizasyon Adımları:
-
Redis Caching Entegrasyonu: HaberJet, okuyucuların yorumlarını ve makale içeriklerini önbelleğe almak için Redis’i kullanmaya karar verdi.
docker-compose.ymldosyasına yeni birredishizmeti eklendi ve Laravel’in.envdosyasındaCACHE_DRIVER=redisolarak ayarlandı. Bu, veritabanı üzerindeki yükü önemli ölçüde azalttı.# docker-compose.yml (services altına eklenecek) redis: image: redis:alpine container_name: laravel_redis restart: unless-stopped networks: - laravel_network -
PHP-FPM Ayarlarının İyileştirilmesi:
app/php-fpm.confdosyasındakipm.max_children,pm.start_serversgibi ayarlar, sunucunun kaynaklarına ve beklenen trafik yüküne göre optimize edildi. Bu, eş zamanlı istekleri daha iyi yönetmeye yardımcı oldu. -
Nginx Ayarları: Nginx’in
default.confdosyasındaclient_max_body_sizegibi ayarlar, büyük resim yüklemeleri için artırıldı ve statik dosya önbellekleme süreleri ayarlandı. -
Veritabanı Optimizasyonu: MySQL konteyneri için daha fazla kaynak ayrıldı ve MySQL yapılandırması (örneğin,
innodb_buffer_pool_size) yüksek trafik için ayarlandı. Bu,dbhizmetininenvironmentbölümüne eklenebilir veya özel bir MySQL yapılandırma dosyası bağlanabilir.
Bu ileri düzey optimizasyonlar sayesinde, HaberJet, artan trafik yükünü sorunsuz bir şekilde yönetebildi ve kullanıcı deneyimini önemli ölçüde iyileştirdi. Docker Compose, bu tür karmaşık altyapı değişikliklerini kolayca entegre etme ve yönetme esnekliği sunar.
Sonuç ve Sıkça Sorulan Sorular
Bu kapsamlı rehber boyunca, Laravel, Nginx ve MySQL’i Docker Compose ile nasıl kuracağımızı adım adım öğrendik. Konteynerizasyonun temel kavramlarından başlayarak, proje yapısını oluşturduk, hizmetleri tanımladık, uygulamamızı başlattık ve hatta performansı ve güvenliği artıracak ileri düzey ipuçlarını keşfettik. Artık geliştirme ortamınızı tutarlı, izole ve taşınabilir bir şekilde yönetmek için güçlü bir araca sahipsiniz. Docker Compose, sadece geliştirme sürecini hızlandırmakla kalmaz, aynı zamanda ekip içi işbirliğini kolaylaştırır ve uygulamalarınızın üretim ortamlarına daha sorunsuz bir şekilde dağıtılmasını sağlar.
Konteynerizasyon, modern yazılım geliştirme metodolojilerinin vazgeçilmez bir parçası haline gelmiştir. Bu rehberde edindiğiniz bilgilerle, kendi Laravel projelerinizi Dockerize edebilir, farklı hizmetleri entegre edebilir ve daha karmaşık altyapıları yönetme konusunda sağlam bir temel oluşturabilirsiniz. Unutmayın, Docker ekosistemi sürekli gelişiyor ve yeni araçlar, en iyi uygulamalar ortaya çıkıyor. Bu nedenle, öğrenmeye ve keşfetmeye devam etmek, bu alanda uzmanlaşmanın anahtarıdır. Umarız bu rehber, Docker Compose ile yolculuğunuza güçlü bir başlangıç yapmanıza yardımcı olmuştur.
Sıkça Sorulan Sorular
Docker Compose’u üretimde kullanmak güvenli midir?
Docker Compose, genellikle geliştirme ve test ortamları için tasarlanmıştır. Küçük ölçekli üretim ortamları için kullanılabilse de, yüksek kullanılabilirlik, ölçeklenebilirlik ve otomatik hata kurtarma gibi özellikler gerektiren büyük ölçekli üretim dağıtımları için Docker Swarm veya Kubernetes gibi konteyner orkestrasyon araçları daha uygun ve önerilen çözümlerdir. Docker Compose, hızlı bir başlangıç ve basit dağıtımlar için harikadır, ancak üretimde daha güçlü yönetim ve ölçeklendirme yetenekleri sunan araçlar tercih edilmelidir.
Veritabanı yedeklemesini nasıl yapmalıyım?
Veritabanı yedeklemesi için birkaç yöntem bulunmaktadır. En yaygın olanı, MySQL konteynerine bağlanıp mysqldump komutunu kullanmaktır. Örneğin:
docker compose exec db mysqldump -u laravel_user -p laravel_db > backup.sql
Bu komut, veritabanınızı backup.sql dosyasına yedekleyecektir. Düzenli yedeklemeler için bu komutu bir cron job veya otomasyon aracı ile çalıştırabilirsiniz. Ayrıca, db_data volume’ünü ana makinenize bağlayarak veya düzenli aralıklarla yedekleme servislerine otomatik olarak gönderecek üçüncü taraf araçları kullanarak da yedekleme yapabilirsiniz.
Konteynerler arasında iletişim nasıl sağlanır?
Docker Compose, aynı docker-compose.yml dosyasında tanımlanan hizmetler arasında varsayılan olarak bir köprü ağı (bridge network) oluşturur. Bu ağ sayesinde, hizmetler birbirleriyle hizmet adlarını (örneğin, app hizmeti db hizmetine db adıyla erişebilir) kullanarak iletişim kurabilirler. Bu, DNS çözümlemesi sayesinde otomatik olarak gerçekleşir ve IP adreslerini bilmenize gerek kalmaz. Bu rehberde de DB_HOST: db şeklinde bu iletişim modelini kullandık.
Laravel artisan komutlarını nasıl çalıştırabilirim?
Laravel artisan komutlarını çalıştırmak için, uygulamanızın çalıştığı PHP-FPM konteynerine bağlanmanız gerekir. Bunu docker compose exec komutuyla yapabilirsiniz:
docker compose exec app php artisan [komutunuz]
Örneğin, yeni bir Controller oluşturmak için:
docker compose exec app php artisan make:controller MyController
Bu komut, app konteyneri içinde php artisan komutunu çalıştırır ve çıktıyı terminalinize yansıtır.
