Takip et

Temel Kavramlara Derin Dalış: Neden Docker Compose ve Bu Üçlü?

Laravel, Nginx ve MySQL’i Docker Compose ile Kurulum Rehberi

Modern web geliştirme dünyasında, projelerin karmaşıklığı arttıkça geliştirme ortamlarının kurulumu ve yönetimi de zorlaşabiliyor. Bağımlılık çakışmaları, farklı işletim sistemlerindeki uyumluluk sorunları veya yeni bir ekip üyesinin projeye adapte olma süreci, geliştiricilerin zamanını boşa harcayabilen yaygın problemlerdir. Bu makalede, bu zorlukların üstesinden gelmek için güçlü bir çözüm olan Docker Compose’u kullanarak Laravel, Nginx ve MySQL üçlüsünü nasıl kolayca kuracağınızı adım adım keşfedeceğiz. Kendi izole ve taşınabilir geliştirme ortamınızı oluşturarak verimliliğinizi artırın!

Temel Kavramlara Derin Dalış: Neden Docker Compose ve Bu Üçlü?

Web uygulamaları geliştirirken karşılaşılan en büyük zorluklardan biri, projenin tüm bağımlılıklarını ve hizmetlerini doğru bir şekilde kurmak ve yönetmektir. Geleneksel yaklaşımlar genellikle işletim sistemi düzeyinde manuel kurulumlar gerektirir; bu da farklı geliştiriciler arasında tutarsız ortamlara ve “benim makinemde çalışıyordu” sendromuna yol açar. İşte tam bu noktada Docker ve Docker Compose devreye girerek bu sorunlara modern ve etkili çözümler sunar.

Peki, tam olarak nedir bu Docker ve Docker Compose? Docker, uygulamaları ve bağımlılıklarını “konteyner” adı verilen izole edilmiş, hafif ve taşınabilir birimler halinde paketlemeye olanak tanıyan açık kaynaklı bir platformdur. Bir konteyner, uygulamanın çalışması için gereken her şeyi (kod, çalışma zamanı, sistem araçları, sistem kütüphaneleri vb.) içerir. Bu sayede uygulamanız, hangi ortamda çalışırsa çalışsın her zaman aynı şekilde davranır. Bu izolasyon, farklı projeler için farklı PHP versiyonlarına veya veritabanı sunucularına ihtiyaç duymanız durumunda büyük bir esneklik sağlar ve bağımlılık çakışmalarını tamamen ortadan kaldırır.

Docker Compose ise tek başına Docker’ın yeteneklerini bir adım öteye taşır. Tek bir uygulama genellikle birden fazla hizmetten oluşur; örneğin bir web uygulaması için bir web sunucusu (Nginx), bir uygulama çalışma zamanı (PHP-FPM) ve bir veritabanı (MySQL). Docker Compose, bu çoklu konteyner uygulamalarını tek bir YAML dosyası kullanarak tanımlamanıza ve tek bir komutla yönetmenize olanak tanır. Bu, tüm hizmetlerinizi aynı anda başlatmak, durdurmak veya yeniden oluşturmak için karmaşık komut dizileri yazma ihtiyacını ortadan kaldırır, geliştirme sürecinizi inanılmaz derecede hızlandırır ve basitleştirir.

Şimdi gelelim neden Laravel, Nginx ve MySQL üçlüsünü tercih ettiğimize. Laravel, PHP ekosisteminin en popüler ve güçlü web framework’lerinden biridir. Hızlı geliştirme, temiz kod yapısı ve zengin özellik setleri sayesinde geliştiricilerin favorisidir. Ancak Laravel uygulamalarının çalışması için bir PHP çalışma zamanına (genellikle PHP-FPM) ve genellikle bir veritabanına ihtiyaç duyar. Nginx, yüksek performanslı, hafif ve esnek bir web sunucusudur. Özellikle statik içerik sunumu ve ters proxy yetenekleriyle bilinir, Laravel gibi PHP tabanlı uygulamalar için mükemmel bir seçimdir. İstekleri doğrudan PHP-FPM’ye yönlendirerek uygulamanızın daha verimli çalışmasını sağlar. MySQL ise dünyanın en yaygın kullanılan açık kaynaklı ilişkisel veritabanı yönetim sistemlerinden biridir. Sağlamlığı, ölçeklenebilirliği ve geniş topluluk desteği sayesinde Laravel uygulamaları için ideal bir veritabanı çözümüdür.

Bu üç teknolojinin Docker Compose ile bir araya gelmesi, geliştiricilere izole edilmiş, tutarlı, taşınabilir ve hızlı bir geliştirme ortamı sunar. Artık “benim makinemde çalışıyor” gibi sorunlarla uğraşmak yerine, her ekip üyesi aynı ortamda çalışabilir, bu da işbirliğini ve dağıtım süreçlerini büyük ölçüde kolaylaştırır. Örneğin, büyük bir e-ticaret platformu geliştiren bir ekip düşünün. Her bir mikroservis (ürün yönetimi, kullanıcı auth, ödeme sistemi) kendi Docker Compose dosyasıyla izole bir şekilde yönetilebilir. Bu sayede farklı ekipler birbirlerinin ortamlarını etkilemeden bağımsız olarak çalışabilir, yeni geliştiriciler saniyeler içinde tüm projeyi ayağa kaldırabilir ve üretim ortamına geçiş çok daha sorunsuz hale gelir. Bu sinerji, modern web geliştirmenin temel taşlarından biridir.

Proje Yapısını Oluşturma ve Temel Docker Compose Dosyası: Nereden Başlamalıyız?

Herhangi bir büyük projede olduğu gibi, Docker Compose ile Laravel uygulaması kurarken de düzenli bir proje yapısı oluşturmak, uzun vadede yönetilebilirliği ve anlaşılırlığı artırır. İlk adımımız, projemiz için ana bir dizin oluşturmak ve ardından Docker ile ilgili dosyaları ayrı bir klasörde tutmaktır. Bu yaklaşım, projenizin kök dizinini temiz tutarken, Docker konfigürasyonlarını da kolayca bulmanızı sağlar.

Öncelikle, terminalinizi açın ve projeniz için bir dizin oluşturun. Örneğin:


mkdir my-laravel-app
cd my-laravel-app

Bu ana dizin altında, Docker konfigürasyon dosyalarımızı barındıracak ayrı bir klasör oluşturmak iyi bir pratiktir:


mkdir docker

Şimdi, Laravel projemizi bu ana dizine kurabiliriz. Eğer zaten bir Laravel projeniz varsa, onu doğrudan my-laravel-app dizininin içine kopyalayabilirsiniz. Yoksa, Composer kullanarak yeni bir Laravel projesi oluşturabiliriz. Ancak burada dikkat etmemiz gereken bir nokta var: Laravel’i doğrudan Docker konteynerleri içinde kurmak daha iyi bir yaklaşımdır, çünkü bu, bağımlılıkları ve PHP versiyonunu konteyner ortamına göre optimize etmemizi sağlar. Şimdilik, sadece ana dizini oluşturalım ve Laravel projesini daha sonra Docker içinde ayağa kaldırırken kurarız.

Proje yapımız temel olarak şöyle görünecek:


my-laravel-app/
├── docker/
│   ├── nginx/
│   │   └── default.conf
│   └── php-fpm/
│       └── Dockerfile
├── docker-compose.yml
└── .env (Laravel'e özel ortam değişkenleri)

Şimdi, Docker Compose’un kalbi olan docker-compose.yml dosyasını ana dizinimizde oluşturalım. Bu dosya, tüm servislerimizi, ağ ayarlarımızı ve volume’lerimizi tanımlayacağımız yerdir. İlk başta temel bir yapı ile başlayacağız:


# my-laravel-app/docker-compose.yml
version: '3.8'

services:
  # Servisler buraya gelecek (mysql, nginx, app)

volumes:
  # Kalıcı veri depolama için volume'ler
  db_data:
    driver: local

networks:
  # Servisler arası iletişim için özel ağ
  app_network:
    driver: bridge

Bu temel yapı, Docker Compose dosyamızın iskeletini oluşturur. version: '3.8' ifadesi, Docker Compose dosyasının hangi sürüm sözdizimini kullandığını belirtir. services bloğu, uygulamamızın farklı bileşenlerini (veritabanı, web sunucusu, uygulama sunucusu vb.) tanımlayacağımız yerdir. volumes bloğu, konteynerler arasında veya konteynerler ile host makine arasında veri paylaşımı ve kalıcılığı için kullanılır. db_data adında bir volume tanımladık, bu sayede MySQL verilerimiz konteyner silinse bile kaybolmayacaktır. Son olarak, networks bloğu, servislerimizin birbirleriyle güvenli ve izole bir şekilde iletişim kurmasını sağlayan özel bir ağ oluşturmamızı sağlar. app_network adında bir köprü ağı (bridge network) tanımladık; tüm servislerimiz bu ağa bağlanacak ve birbirlerini isimleriyle tanıyabileceklerdir.

Bu adım, Docker Compose ile Laravel projemizi kurmanın temelini atar. Düzenli bir dizin yapısı ve iyi tanımlanmış bir docker-compose.yml iskeleti, ilerleyen adımlarda işimizi oldukça kolaylaştıracaktır. Ayrıca, .env dosyasının önemini unutmamak gerekir. Laravel’in veritabanı bağlantı bilgileri, uygulama anahtarı gibi hassas ve ortama özgü değişkenleri bu dosyada saklarız. Docker Compose ortamında, bu .env dosyasını konteynerlere doğru bir şekilde iletmek, uygulamanızın sorunsuz çalışması için kritik öneme sahiptir.

Uzman İpucu: Projenizin kök dizininde bir .dockerignore dosyası oluşturmak, Docker imajlarınızın boyutunu önemli ölçüde küçültebilir. Bu dosya, Docker’ın imaj oluşturma sırasında hangi dosya ve dizinleri göz ardı etmesi gerektiğini belirtir. Örneğin, node_modules, .git, .DS_Store gibi gereksiz dosyaları bu listeye ekleyerek build süresini ve imaj boyutunu optimize edebilirsiniz.

Servislerin Detaylı Tanımlaması: MySQL, Nginx ve PHP-FPM Konteynerleri Nasıl Yapılandırılır?

Docker Compose dosyamızın iskeletini oluşturduktan sonra, sıra uygulamamızın temel bileşenlerini, yani MySQL veritabanını, Nginx web sunucusunu ve PHP-FPM uygulama sunucusunu (Laravel için) tanımlamaya geldi. Her bir servis, kendi içinde bağımsız bir konteyneri temsil edecek ve belirli görevleri yerine getirecektir. Bu bölümde, her bir servisin docker-compose.yml dosyasında nasıl yapılandırılacağını ve ilgili yardımcı dosyaların (Dockerfile, Nginx config) nasıl oluşturulacağını detaylıca inceleyeceğiz.

MySQL Servisi

Veritabanı, çoğu web uygulamasının kalbidir. MySQL servisi için resmi Docker imajını kullanacağız ve bazı temel ortam değişkenlerini ayarlayarak kolayca yapılandıracağız. Veri kalıcılığı için bir Docker volume’ü tanımlamak kritik öneme sahiptir, aksi takdirde konteyner her yeniden başlatıldığında verileriniz kaybolur.


# my-laravel-app/docker-compose.yml (services bloğuna ekleyin)
services:
  mysql:
    image: mysql:8.0
    container_name: laravel_mysql
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: laravel_db
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_USER: laravel_user
      MYSQL_PASSWORD: laravel_password
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' # Geliştirme ortamı için
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306" # İsteğe bağlı, host'tan erişim için
    networks:
      - app_network

Burada image: mysql:8.0 ile MySQL 8.0 sürümünü kullanacağımızı belirtiyoruz. environment bloğu, veritabanı adı, root şifresi ve Laravel’in kullanacağı kullanıcı adı/şifresi gibi önemli ayarları yapar. volumes: - db_data:/var/lib/mysql satırı, db_data adlı volume’ü konteynerin /var/lib/mysql dizinine bağlar; bu sayede verileriniz konteyner yaşam döngüsünden bağımsız olarak kalıcı olur. ports ayarı, host makinenizden 3306 portu üzerinden MySQL’e erişmenizi sağlar, bu geliştirme sırasında veritabanı yöneticileri (örneğin DBeaver, MySQL Workbench) kullanmak için faydalıdır. Son olarak, app_network ağına bağlanarak diğer servislerle iletişim kurmasını sağlıyoruz.

PHP-FPM (Laravel Uygulaması) Servisi

Laravel uygulamamızın çalışacağı PHP ortamını PHP-FPM (FastCGI Process Manager) aracılığıyla sağlayacağız. Bu servis için özel bir Dockerfile oluşturarak, PHP’nin gerekli uzantılarını ve Composer’ı kuracağız.

Öncelikle, docker/php-fpm/Dockerfile dosyasını oluşturalım:


# my-laravel-app/docker/php-fpm/Dockerfile
FROM php:8.2-fpm-alpine

# Gerekli PHP uzantılarını ve bağımlılıklarını yükleyin
RUN apk add --no-cache \
    autoconf \
    build-base \
    libzip-dev \
    libpng-dev \
    jpeg-dev \
    git \
    oniguruma-dev \
    libxml2-dev \
    freetype-dev \
    icu-dev \
    $PHPIZE_DEPS \
    && docker-php-ext-install -j$(nproc) pdo_mysql zip gd exif pcntl bcmath opcache intl \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-enable opcache

# Composer'ı global olarak kurun
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Çalışma dizinini ayarlayın
WORKDIR /var/www/html

# Kullanıcı ve grup oluşturma (güvenlik için)
RUN addgroup -g 1000 laravel \
    && adduser -u 1000 -G laravel -s /bin/sh -D laravel

USER laravel

EXPOSE 9000
CMD ["php-fpm"]

Bu Dockerfile, PHP 8.2 FPM Alpine Linux tabanlı bir imaj kullanır. Gerekli PHP uzantılarını (pdo_mysql, zip, gd vb.) ve Composer’ı kurar. WORKDIR /var/www/html ile Laravel projemizin konumunu belirliyoruz. Güvenlik için laravel adında root olmayan bir kullanıcı oluşturup onu kullanıyoruz. Şimdi docker-compose.yml içindeki PHP-FPM servisini tanımlayalım:


# my-laravel-app/docker-compose.yml (services bloğuna ekleyin)
services:
  # ... mysql servisi ...

  app:
    build:
      context: ./docker/php-fpm
      dockerfile: Dockerfile
    container_name: laravel_app
    restart: unless-stopped
    volumes:
      - .:/var/www/html # Laravel projesini bağla
      - ./docker/php-fpm/php.ini:/usr/local/etc/php/conf.d/custom.ini # İsteğe bağlı, PHP ayarları
    environment:
      APP_ENV: local
      CONTAINER_ROLE: app
    networks:
      - app_network
    depends_on:
      - mysql

build anahtarı, Docker Compose’un bu servis için docker/php-fpm/Dockerfile dosyasını kullanarak bir imaj oluşturmasını sağlar. volumes: - .:/var/www/html satırı çok önemlidir; bu, projemizin kök dizinini (.) konteynerin /var/www/html dizinine bağlar. Bu sayede host makinede yaptığınız kod değişiklikleri anında konteyner içinde de görünür olur. depends_on: - mysql ile app servisinin mysql servisi başlamadan önce başlamamasını sağlıyoruz.

Nginx Servisi

Nginx, gelen HTTP isteklerini karşılayacak ve bunları PHP-FPM servisine yönlendirecek olan web sunucumuzdur. Nginx için de özel bir konfigürasyon dosyası oluşturmamız gerekiyor.

Öncelikle, docker/nginx/default.conf dosyasını oluşturalım:


# my-laravel-app/docker/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; # PHP-FPM servisi ve portu
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

Bu Nginx konfigürasyonu, tüm istekleri Laravel’in public dizinine yönlendirir ve .php uzantılı dosyaları app servisine (PHP-FPM) 9000 portu üzerinden iletir. fastcgi_pass app:9000 satırındaki app ifadesi, Docker Compose ağındaki PHP-FPM servisimizin adıdır. Şimdi docker-compose.yml içindeki Nginx servisini tanımlayalım:


# my-laravel-app/docker-compose.yml (services bloğuna ekleyin)
services:
  # ... mysql ve app servisleri ...

  nginx:
    image: nginx:stable-alpine
    container_name: laravel_nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - .:/var/www/html # Laravel projesini bağla
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf # Nginx config dosyasını bağla
    networks:
      - app_network
    depends_on:
      - app # Nginx, app servisi başladıktan sonra başlasın

Nginx için resmi nginx:stable-alpine imajını kullanıyoruz. ports: - "80:80" ile host makinenizin 80 portunu konteynerin 80 portuna bağlıyoruz, böylece tarayıcınızdan http://localhost adresine erişebilirsiniz. volumes bloğunda, hem Laravel projemizi hem de özel Nginx konfigürasyon dosyamızı bağlıyoruz. depends_on: - app ile Nginx’in PHP-FPM servisi başlamadan önce başlamamasını sağlıyoruz.

Bu detaylı tanımlamalarla, Laravel, Nginx ve MySQL’den oluşan eksiksiz bir Docker Compose ortamını yapılandırmış oluyoruz. Her bir servisin kendine ait bir sorumluluğu ve bağımsız bir yaşam döngüsü vardır, ancak networks ve depends_on sayesinde sorunsuz bir şekilde bir araya gelirler. Bu yapılandırma, hem geliştirme hem de daha sonraki dağıtım süreçleri için sağlam bir temel sunar.

Vaka Analizi: Birden Fazla Laravel Projesini Tek Nginx ile Yönetme
Büyük bir şirketin birden fazla mikroservis veya farklı Laravel projeleri geliştirdiğini düşünün. Her projenin kendi Docker Compose dosyası olabilir. Ancak, tüm bu projeleri tek bir Nginx konteyneri üzerinden yönetmek isteyebilirsiniz. Bu durumda, ana Nginx konteynerinizi bir ters proxy olarak yapılandırabilir ve her projenin kendi PHP-FPM servisine istekleri yönlendirebilirsiniz. Örneğin, app1.local isteklerini project1_app:9000‘e, app2.local isteklerini project2_app:9000‘e yönlendiren bir nginx.conf dosyası yazarak bu mimariyi kolayca kurabilirsiniz. Bu yaklaşım, geliştirme ortamınızda birden fazla projenin eş zamanlı ve izole bir şekilde çalışmasını sağlar.

Laravel Uygulamasını Docker Ortamına Hazırlama ve İlk Çalıştırma: Adım Adım Rehber

Önceki adımlarda, Docker Compose dosyamızı ve ilgili servis konfigürasyonlarımızı oluşturarak Laravel, Nginx ve MySQL için temel bir ortam hazırladık. Şimdi sıra, Laravel uygulamasını bu Docker ortamına entegre etmeye ve her şeyin sorunsuz bir şekilde çalıştığından emin olmaya geldi. Bu bölüm, adım adım kurulumu tamamlayacak ve uygulamanızı tarayıcınızda görüntülemenizi sağlayacak pratik bilgileri içermektedir.

1. Laravel Projesini Kopyalama (Eğer Mevcutsa)

Eğer zaten bir Laravel projeniz varsa, my-laravel-app dizininizin köküne kopyalayın. Eğer yeni bir proje oluşturduysanız, bu adımı atlayabilirsiniz. Docker Compose, projemizin kök dizinini (.) PHP-FPM konteynerinin /var/www/html dizinine bağladığı için, Laravel projenizin tüm dosyaları bu dizinde olmalıdır.

2. Laravel’in .env Dosyasını Düzenleme

Laravel’in .env dosyası, uygulamanın ortam değişkenlerini içerir. Veritabanı bağlantısı için bu dosyayı Docker Compose ortamımıza uygun şekilde düzenlememiz gerekiyor. Projenizin kök dizinindeki .env dosyasını açın ve aşağıdaki değişiklikleri yapın:


# my-laravel-app/.env
DB_CONNECTION=mysql
DB_HOST=mysql      # Docker Compose servis adı
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=laravel_password

Buradaki en önemli değişiklik DB_HOST değeridir. Docker Compose ağında, servisler birbirlerini servis adlarıyla tanır. Bu nedenle, mysql servisine erişmek için DB_HOST olarak mysql yazıyoruz. Diğer veritabanı değişkenleri, docker-compose.yml dosyasında mysql servisi için ayarladığımız environment değişkenleriyle eşleşmelidir.

3. Konteynerleri Ayağa Kaldırma

Artık her şey hazır! Projenizin kök dizininde (my-laravel-app/) terminalinizi açın ve aşağıdaki komutu çalıştırarak tüm servisleri başlatın:


docker compose up -d
  • up: Docker Compose dosyasında tanımlanan tüm servisleri oluşturur ve başlatır.
  • -d (detached mode): Konteynerleri arka planda çalıştırır, böylece terminaliniz serbest kalır.

Bu komut, Nginx, PHP-FPM ve MySQL konteynerlerini oluşturacak, gerekli imajları indirecek (eğer yerelde yoksa) ve onları başlatacaktır. İlk çalıştırmada biraz zaman alabilir, çünkü imajların indirilmesi ve PHP-FPM imajının oluşturulması gerekecektir.

4. Laravel Bağımlılıklarını Yükleme ve Veritabanını Hazırlama

Konteynerler çalışmaya başladıktan sonra, Laravel’in Composer bağımlılıklarını yüklememiz ve veritabanı tablolarını oluşturmamız gerekiyor. Bu işlemleri doğrudan PHP-FPM konteyneri içinde yapacağız. Bunun için docker compose exec komutunu kullanacağız:


# Composer bağımlılıklarını yükle
docker compose exec app composer install

# Laravel uygulama anahtarını oluştur
docker compose exec app php artisan key:generate

# Veritabanı tablolarını oluştur (migrations)
docker compose exec app php artisan migrate

docker compose exec app komutu, app (PHP-FPM) servisi içinde bir komut çalıştırmamızı sağlar. Bu sayede, Laravel’in ihtiyaç duyduğu tüm kurulum adımlarını izole Docker ortamında gerçekleştirebiliriz.

5. Dosya İzinlerini Ayarlama (Gerekirse)

Bazen Laravel’in storage ve bootstrap/cache dizinlerine yazma izinleri konusunda sorunlar yaşanabilir. Bu durumda, aşağıdaki komutları çalıştırarak izinleri düzeltebilirsiniz:


docker compose exec app chmod -R 775 storage bootstrap/cache
docker compose exec app chown -R laravel:laravel storage bootstrap/cache

Bu komutlar, ilgili dizinlere yazma izni verir ve sahipliği Dockerfile içinde oluşturduğumuz laravel kullanıcısına atar.

6. Uygulamayı Tarayıcıda Test Etme

Tüm bu adımları tamamladıktan sonra, tarayıcınızı açın ve http://localhost adresine gidin. Eğer her şey yolunda gittiyse, Laravel’in hoş geldiniz sayfasını görmelisiniz. Tebrikler! Laravel uygulamanız Docker Compose ile başarıyla çalışıyor.

Hata Ayıklama İpuçları: Eğer bir sorunla karşılaşırsanız, docker compose logs komutu ile tüm servislerin loglarını kontrol edebilirsiniz. Belirli bir servisin loglarını görmek için docker compose logs [servis_adı] (örneğin docker compose logs app) kullanabilirsiniz. Ayrıca, bir konteynerin içine girip manuel olarak komut çalıştırmak için docker compose exec [servis_adı] bash (veya sh) komutunu kullanabilirsiniz.

Vaka Analizi: Küçük Bir E-ticaret Uygulamasının Geliştirme Ortamı

Bir geliştirici, yeni bir e-ticaret uygulamasının prototipini oluşturmak istiyor. Geleneksel yöntemlerle PHP, Nginx ve MySQL’i manuel olarak kurmak saatlerini alabilir ve işletim sistemi uyumluluğu sorunlarıyla karşılaşabilir. Docker Compose kullanarak, yukarıdaki adımları takip ederek sadece 15-20 dakika içinde tüm geliştirme ortamını kurdu. Laravel projesini kopyaladı, .env dosyasını düzenledi, docker compose up -d komutunu çalıştırdı ve ardından Composer bağımlılıklarını ve veritabanı migrate işlemlerini yaptı. Artık uygulamasını anında geliştirmeye başlayabilir, bağımlılık sorunları veya ortam farklılıkları hakkında endişelenmesine gerek kalmaz. Bu, özellikle hızlı prototipleme ve MVP (Minimum Viable Product) geliştirme süreçlerinde inanılmaz bir zaman tasarrufu sağlar.

İleri Seviye Optimizasyonlar ve Geliştirme İpuçları: Performans ve Güvenlik

Docker Compose ile Laravel, Nginx ve MySQL ortamımızı kurduk ve çalıştırdık. Ancak, bu kurulumu daha da optimize etmek, performansını artırmak ve güvenlik açıklarını azaltmak için yapabileceğimiz bazı ileri seviye adımlar bulunmaktadır. Bu bölümde, hem geliştirme hem de potansiyel üretim ortamları için faydalı olabilecek ipuçlarına ve tekniklere odaklanacağız.

Dockerfile Optimizasyonları: Daha Küçük ve Hızlı İmajlar

PHP-FPM için kullandığımız Dockerfile, çoğu senaryo için yeterli olsa da, imaj boyutunu küçültmek ve build sürelerini hızlandırmak mümkündür. Bunun en etkili yollarından biri “çok aşamalı yapılar” (multi-stage builds) kullanmaktır. Bu teknik, imajın farklı aşamalarında geçici dosyaları veya derleme araçlarını kullanarak nihai imajın sadece gerekli bileşenleri içermesini sağlar.


# my-laravel-app/docker/php-fpm/Dockerfile (Multi-stage build örneği)
# Aşama 1: Bağımlılıkları yükle ve derle
FROM composer:2 as composer_builder

WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-autoloader --no-scripts --optimize-autoloader

# Aşama 2: Nihai imaj
FROM php:8.2-fpm-alpine

# Gerekli PHP uzantılarını ve bağımlılıklarını yükleyin
RUN apk add --no-cache \
    # ... önceki uzantı kurulumları ...

# Composer'ı global olarak kurun
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Önceki aşamadan Composer bağımlılıklarını kopyala
COPY --from=composer_builder /app/vendor /var/www/html/vendor

# Çalışma dizinini ayarlayın
WORKDIR /var/www/html

# Kullanıcı ve grup oluşturma (güvenlik için)
RUN addgroup -g 1000 laravel \
    && adduser -u 1000 -G laravel -s /bin/sh -D laravel

USER laravel

EXPOSE 9000
CMD ["php-fpm"]

Bu örnekte, Composer bağımlılıklarını ayrı bir composer:2 imajında kurup, sadece vendor dizinini nihai PHP-FPM imajına kopyalıyoruz. Bu, PHP-FPM imajının daha küçük olmasını sağlar, çünkü Composer’ın kendisi ve derleme sırasında kullanılan geçici dosyalar nihai imaja dahil edilmez. Ayrıca, RUN komutlarını birleştirerek ve apk add komutlarında --no-cache kullanarak katman sayısını ve önbellek boyutunu azaltabilirsiniz.

Nginx Performans Ayarları: Daha Hızlı Yanıtlar

Nginx, zaten oldukça hızlı bir web sunucusudur, ancak performansını daha da artırmak için bazı ayarlar yapabiliriz. docker/nginx/default.conf dosyanızı güncelleyerek sıkıştırma, önbellekleme ve HTTP/2 gibi özellikleri etkinleştirebilirsiniz.


# my-laravel-app/docker/nginx/default.conf (Performans ayarları eklendi)
server {
    listen 80;
    listen 443 ssl http2; # HTTP/2 ve SSL için
    # ... diğer ayarlar ...

    # Gzip sıkıştırmayı etkinleştir
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_comp_level 6;
    gzip_min_length 1000;

    # Statik dosyalar için önbellekleme (örn: resimler, CSS, JS)
    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
        expires 30d;
        log_not_found off;
    }

    # ... PHP-FPM ve diğer location blokları ...
}

HTTP/2 ve SSL için 443 portunu dinlemeyi ekledik (bunun için SSL sertifikası yapılandırmanız gerekir). gzip ayarları, sunucudan gönderilen metin tabanlı dosyaları sıkıştırarak bant genişliğini azaltır ve yükleme sürelerini hızlandırır. Statik dosyalar için expires başlığı belirleyerek tarayıcı önbelleklemesini teşvik edebilir, böylece tekrar eden ziyaretlerde bu dosyaların yeniden indirilmesini önleyebilirsiniz.

MySQL Optimizasyonları: Veritabanı Performansı

MySQL performansını artırmak için genellikle my.cnf dosyasında ayarlamalar yapılır. Docker ortamında, bu dosyayı bir volume olarak bağlayarak özelleştirebiliriz. Örneğin, innodb_buffer_pool_size gibi parametreler veritabanı performansını önemli ölçüde etkileyebilir.

Öncelikle docker/mysql/my.cnf dosyasını oluşturun (örnek):


# my-laravel-app/docker/mysql/my.cnf
[mysqld]
innodb_buffer_pool_size = 256M # Sistem RAM'ine göre ayarlanmalı
max_connections = 150
# ... diğer ayarlar ...

Ardından docker-compose.yml dosyanızdaki MySQL servisine bu volume’ü ekleyin:


# my-laravel-app/docker-compose.yml (mysql servisine ekleyin)
services:
  mysql:
    # ... diğer ayarlar ...
    volumes:
      - db_data:/var/lib/mysql
      - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf # Yeni eklenen satır

Bu şekilde, MySQL konteyneriniz özel ayarlarınızla başlayacaktır. Unutmayın, bu ayarlar sistem kaynaklarınıza ve uygulamanızın ihtiyaçlarına göre dikkatlice yapılmalıdır.

Geliştirme ve Üretim Ortamı Farkları: Xdebug ve Güvenlik

Geliştirme ve üretim ortamları arasında belirgin farklar vardır. Geliştirme sırasında hata ayıklama (debugging) için Xdebug gibi araçlara ihtiyaç duyarken, üretimde bu araçlar performansı düşürebilir ve güvenlik açıkları oluşturabilir. Xdebug’ı PHP-FPM konteynerinize dahil etmek için Dockerfile‘ınıza eklemeler yapabilir ve php.ini dosyasında etkinleştirebilirsiniz.


# my-laravel-app/docker/php-fpm/Dockerfile (Xdebug kurulumu)
# ... diğer RUN komutları ...
RUN apk add --no-cache php8-pecl-xdebug \
    && docker-php-ext-enable xdebug

Ve docker/php-fpm/php.ini dosyanıza (veya custom.ini dosyanıza):


# my-laravel-app/docker/php-fpm/php.ini
[XDebug]
xdebug.mode=develop,debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal # Docker Desktop için
xdebug.client_port=9003

Üretim ortamında ise Xdebug’ı kesinlikle devre dışı bırakmalı veya hiç kurmamalısınız. Ayrıca, üretimde MYSQL_ALLOW_EMPTY_PASSWORD gibi ayarları kullanmamalı, güçlü parolalar ve root olmayan kullanıcılar tercih etmelisiniz. Nginx için SSL sertifikaları kullanmak ve güvenlik başlıklarını (Content Security Policy, X-XSS-Protection) eklemek de önemlidir.

Mobil Uyumluluk ve Geliştirme: Docker Compose ortamınız, mobil uyumlu web siteleri geliştirirken de büyük kolaylık sağlar. Tarayıcınızda http://localhost adresinden uygulamanıza erişebilir, tarayıcı geliştirici araçlarını kullanarak mobil görünümü test edebilirsiniz. Hatta bazı ileri düzey araçlar (örn. BrowserSync) ile Docker konteynerinizde çalışan uygulamanızı mobil cihazlarınızdan direkt olarak test edebilir, yaptığınız kod değişikliklerinin anında mobil cihazda da güncellendiğini görebilirsiniz. Bu, özellikle responsive tasarım geliştirirken iş akışınızı hızlandırır.

Bu ileri seviye optimizasyonlar ve ipuçları, Docker Compose ile kurduğunuz ortamın sadece çalışır durumda olmasını değil, aynı zamanda daha performanslı, güvenli ve sürdürülebilir olmasını sağlar. Geliştirme ve üretim ortamları arasındaki farkları anlamak ve buna göre yapılandırma yapmak, başarılı bir dağıtım stratejisinin anahtarıdır.

Sonuç ve Sıkça Sorulan Sorular: Gelecek Adımlarınız Neler Olmalı?

Bu makale boyunca, Laravel, Nginx ve MySQL’i Docker Compose ile nasıl kuracağımızı adım adım öğrendik. Geleneksel kurulum yöntemlerinin getirdiği karmaşıklık ve bağımlılık sorunlarının üstesinden gelmek için Docker’ın konteynerizasyon gücünü ve Docker Compose’un çoklu servis yönetim yeteneklerini kullandık. Temel kavramlardan başlayarak, proje yapısını oluşturduk, servisleri detaylıca tanımladık ve uygulamamızı Docker ortamında başarıyla çalıştırdık. Ayrıca, performans optimizasyonları ve güvenlik ipuçları gibi ileri seviye konulara da değinerek, ortamımızı daha sağlam ve verimli hale getirme yollarını keşfettik.

Bu kurulum sayesinde elde ettiğimiz en büyük kazanımlar şunlardır:

  • Hızlı ve Tutarlı Ortam Kurulumu: Yeni bir projeye başlarken veya yeni bir ekip üyesi katıldığında, tüm geliştirme ortamı dakikalar içinde ayağa kaldırılabilir. “Benim makinemde çalışıyordu” sorunları artık geçmişte kaldı.
  • İzolasyon ve Bağımsızlık: Her servis kendi konteynerinde izole bir şekilde çalıştığı için, farklı projeler farklı PHP versiyonları veya veritabanı sunucuları kullanabilir, bağımlılık çakışmaları yaşanmaz.
  • Taşınabilirlik: Docker Compose dosyası sayesinde, tüm ortamınızı herhangi bir Docker yüklü makineye kolayca taşıyabilir ve aynı şekilde çalıştırabilirsiniz.
  • Versiyon Kontrolü ve İşbirliği: docker-compose.yml ve Dockerfile gibi konfigürasyon dosyaları versiyon kontrol sistemlerine (Git) dahil edilebilir, bu da ekip içinde işbirliğini ve ortam tutarlılığını artırır.

Artık sağlam bir temeliniz olduğuna göre, gelecekteki adımlarınız şunları içerebilir:

  • CI/CD Entegrasyonu: Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) süreçlerinize Docker Compose’u entegre ederek otomatik test ve dağıtım yapabilirsiniz.
  • Orkestrasyon Araçları: Uygulamanız büyüdükçe ve daha fazla konteynere ihtiyaç duydukça Kubernetes gibi daha gelişmiş konteyner orkestrasyon araçlarını keşfedebilirsiniz.
  • Gözetim ve Log Yönetimi: Konteynerlerinizin performansını izlemek ve loglarını merkezi bir yerde toplamak için Prometheus, Grafana, ELK Stack gibi araçları inceleyebilirsiniz.
  • Gelişmiş Ağ Yapılandırması: Docker ağlarını daha derinlemesine öğrenerek daha karmaşık servis iletişim senaryolarını yönetebilirsiniz.

Sıkça Sorulan Sorular

1. Docker Compose ile kurduğum ortam üretim ortamı için uygun mu?

Docker Compose, genellikle geliştirme ortamları ve küçük ölçekli üretim dağıtımları için harikadır. Tek bir sunucuda birden fazla servis çalıştırmak için idealdir. Ancak, yüksek kullanılabilirlik, otomatik ölçeklendirme ve karmaşık orkestrasyon gerektiren büyük ölçekli üretim ortamları için Kubernetes gibi daha gelişmiş konteyner orkestrasyon platformları daha uygun olabilir. Docker Compose’u üretimde kullanacaksanız, güvenlik, yedekleme, izleme ve otomatik yeniden başlatma gibi konulara ekstra özen göstermelisiniz.

2. Farklı PHP versiyonlarını veya veritabanlarını nasıl yönetirim?

Docker’ın en büyük avantajlarından biri izolasyondur. Her proje için ayrı bir docker-compose.yml dosyası oluşturarak farklı PHP versiyonlarına (örneğin, php:7.4-fpm veya php:8.2-fpm) sahip PHP-FPM konteynerleri veya farklı veritabanı sistemleri (PostgreSQL, MongoDB) kullanabilirsiniz. Her bir projenin kendi ortamı tamamen izole olacaktır, bu da bağımlılık çakışmalarını önler.

3. Veritabanı verilerim konteyner silindiğinde kaybolur mu?

Hayır, eğer volumes kullanarak veritabanı verilerini kalıcı hale getirdiyseniz. Makalemizde MySQL servisi için db_data adında bir volume tanımladık (db_data:/var/lib/mysql). Bu volume, Docker’ın yönettiği bir alanda verileri saklar. Konteyneriniz silinse veya yeniden oluşturulsa bile, bu volume’e bağlı olduğu sürece verileriniz güvende kalır.

4. Xdebug’ı Docker Compose ortamına nasıl entegre edebilirim?

Xdebug’ı entegre etmek için PHP-FPM’in Dockerfile‘ına Xdebug uzantısını kurmalı ve php.ini dosyasında gerekli ayarları yapmalısınız. xdebug.client_host ayarı, Docker konteynerinizin host makine ile iletişim kurabilmesi için önemlidir. Genellikle host.docker.internal (Docker Desktop için) veya host makinenizin IP adresi kullanılır. Makalemizdeki “İleri Seviye Optimizasyonlar” bölümünde Xdebug kurulumuna dair bir örnek bulabilirsiniz.

5. Konteynerler arasında iletişim nasıl kurulur?

Docker Compose, varsayılan olarak tüm servisleri aynı özel ağa (bizim örneğimizde app_network) bağlar. Bu ağ içinde, servisler birbirleriyle servis adlarını kullanarak iletişim kurabilirler. Örneğin, Laravel uygulaması MySQL’e bağlanırken DB_HOST=mysql kullanır, çünkü mysql servisi bu ağda bu isimle tanınır. Nginx de PHP-FPM’e fastcgi_pass app:9000 ile erişir. Bu, IP adresleri yerine anlamlı isimler kullanarak kolay ve esnek bir iletişim sağlar.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.