Ubuntu 22.04 üzerinde Docker Compose ile Laravel Nasıl Kurulur ve Ayarlanır
Giriş
Bir uygulamayı konteynerleştirmek, bir uygulamayı ve bileşenlerini, konteyner olarak bilinen hafif ortamlarda çalıştırılabilir hale getirme sürecine atıfta bulunur. Bu tür ortamlar izole ve geçicidir ve uygulamaları geliştirmek, test etmek ve üretime dağıtmak için kullanılabilir.
Bu rehberde, geliştirme için bir Laravel uygulamasını konteynerleştirmek amacıyla Docker Compose kullanacağız. İşinizi bitirdiğinizde, üç ayrı servis konteynerinde çalışan bir demo Laravel uygulamanız olacak:
- PHP7.4-FPM çalıştıran bir
appservisi; - MySQL 8.0 çalıştıran bir
dbservisi; - Laravel uygulamasını son kullanıcıya sunmadan önce PHP kodunu işlemek için
appservisini kullanan birnginxservisi.
Daha akıcı bir geliştirme süreci sağlamak ve uygulama hata ayıklamayı kolaylaştırmak için, uygulama dosyalarını paylaşılan hacimler kullanarak senkronize tutacağız. Ayrıca docker compose exec komutlarını kullanarak app konteynerinde Composer ve Artisan çalıştırmanın nasıl yapılacağını göreceğiz.
Frontend uygulamalarınızı GitHub üzerinden Linux-Console.net Uygulama Platformu ile dağıtın. Linux-Console.net, uygulamanızın ölçeklenmesine odaklansın.
Öne Çıkan Noktalar:
- Konteynerleştirme geliştirmeyi öngörülebilir kılar: Laravel’i Docker’da çalıştırmak, makineler arasında tutarlı ortamlar sağlar, “Bilgisayarımda çalışıyor” sorunlarını ortadan kaldırır ve iş birliğini kolaylaştırır.
- Hizmetlerin ayrılması bakım kolaylığını artırır: PHP, MySQL ve Nginx'i ayrı konteynerlere ayırmak, sorunları izole etmeye yardımcı olur, güncellemeleri basitleştirir ve gerçek dünya üretim ortamlarını yansıtır.
- Çevresel değişkenler, esnek yapılandırmanın merkezindedir: Bir
.envdosyası kullanmak, geliştiricilerin uygulama koduna dokunmadan veritabanı kimlik bilgilerini ve diğer ayarları değiştirmelerine olanak tanır. - Özel Docker imajları kontrol ve güvenliği artırır: Kendi PHP imajınızı oluşturmak, projenizin ihtiyacı olanları yüklemenizi sağlar ve böylece ortamı hafif ve güvenli tutar.
- Dosya izinleri konteyner kullanıcılarıyla eşleşmelidir: Laravel’in yazılabilir dizinleri için doğru sahiplik ve izinlerin ayarlanması, çalışma zamanı hatalarını önler ve sorunsuz yerel geliştirmeyi destekler.
- Override dosyalarını kullanmak birden fazla ortamı destekler:
docker-compose.override.yml, canlı yenileme gibi yerel ayarlamalar yapmayı sağlar—üretim yapılandırmalarını değiştirmeden. Bu, geliştirme ve dağıtımı temiz bir şekilde ayrılmış tutar. - Sorun gidermeye, konteyner davranışını anlamakla başlamak gerekir: Günlükleri nasıl inceleyeceğinizi, çalışan servisleri nasıl kontrol edeceğinizi ve bağlantıyı test etmeyi bilmek, konteyner tabanlı kurulumlarda çoğu sorunu hızlı bir şekilde çözmenin anahtarıdır.
- Docker tabanlı bir kurulum iş akışınıza göre ölçeklenir: Bir kez oluşturulduğunda, aynı yapılandırma yerel, test veya üretim ortamlarını destekleyebilir ve gelecekteki Laravel projeleri için sağlam, tekrar kullanılabilir bir temel oluşturur.
Önkoşullar
- Sudo ayrıcalıklarına sahip kök olmayan bir kullanıcı olarak bir Ubuntu yerel makinesine veya geliştirme sunucusuna erişim. Eğer uzaktan bir sunucu kullanıyorsanız, etkin bir güvenlik duvarının kurulu olması tavsiye edilir. Bunları kurmak için lütfen Ubuntu için İlk Sunucu Kurulum Kılavuzumuza başvurun.
- Ubuntu'da Docker'ı Yükleme ve Kullanma adlı kılavuzun 1. ve 2. Adımlarını takip ederek sunucunuza Docker yüklendi.
- Ubuntu'da Docker Compose'u Kurma ve Kullanma Rehberinin 1. Adımını takip ederek sunucunuza Docker Compose yüklendi.
Adım 1 — Demo Uygulamayı Alma
Başlamak için, demo Laravel uygulamasını Github deposundan alacağız. İlgilendiğimiz tutorial-01 dalı, How To Install and Configure Laravel with Nginx on Ubuntu 22.04 (LEMP) rehberinde oluşturduğumuz temel Laravel uygulamasını içeriyor.
Bu eğitimle uyumlu uygulama kodunu almak için, tutorial-1.0.1 sürümünü ev dizininize indirerek:
cd ~
curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zipUygulama kodunu açmak için unzip komutuna ihtiyacımız olacak. Bu paketi daha önce yüklemediyseniz, şimdi şu şekilde yükleyebilirsiniz:
sudo apt update
sudo apt install unzipŞimdi, uygulamanın içeriğini açın ve daha kolay erişim için açılmış dizini yeniden adlandırın:
unzip travellist.zip
mv travellist-laravel-demo-tutorial-1.0.1 travellist-demotravellist-demo dizinine gidin:
cd travellist-demoBir sonraki adımda, uygulamayı kurmak için bir .env yapılandırma dosyası oluşturacağız.
Adım 2 — Uygulamanın .env Dosyasının Ayarlanması
Laravel yapılandırma dosyaları, uygulamanın kök dizini içinde yer alan config adlı bir dizinde bulunur. Ek olarak, ortam bağımlı yapılandırmayı ayarlamak için, örneğin kimlik bilgileri ve dağıtımlar arasında değişebilecek herhangi bir bilgi için, bir .env dosyası kullanılır. Bu dosya sürüm kontrolüne dahil edilmez.
Uyarı: Ortam yapılandırma dosyası, veritabanı kimlik bilgileri ve güvenlik anahtarları dahil olmak üzere sunucunuzla ilgili hassas bilgiler içerir. Bu nedenle, bu dosyayı asla kamuya açık şekilde paylaşmamalısınız.
.env dosyasında bulunan değerler, config dizininde yer alan normal yapılandırma dosyalarında belirlenen değerlere üstünlük sağlar. Yeni bir ortamda yapılan her kurulum, hangi ortamda çalıştığına bağlı olarak değişebilecek veritabanı bağlantı ayarları, hata ayıklama seçenekleri, uygulama URL'si gibi öğeleri tanımlamak için özel bir ortam dosyası gerektirir.
Şimdi, kurmakta olduğumuz geliştirme ortamı için yapılandırma seçeneklerini özelleştirmek amacıyla yeni bir .env dosyası oluşturacağız. Laravel, kendi .env dosyamızı oluşturmak için kopyalayabileceğimiz örnek bir .env dosyasıyla birlikte gelir:
cp .env.example .envBu dosyayı nano veya tercih ettiğiniz metin düzenleyici ile açın:
nano .envMevcut .env dosyası, travellist demo uygulamasından, 127.0.0.1 veritabanı sunucusunu kullanacak şekilde yerel bir MySQL veritabanı ayarlarını içeriyor. DB_HOST değişkenini, Docker ortamımızda oluşturacağımız veritabanı servisine işaret edecek şekilde güncellememiz gerekiyor. Bu rehberde, veritabanı servisimizi db olarak adlandıracağız. Listedeki DB_HOST değerini veritabanı servis adıyla değiştirin:
APP_NAME=Travellist
APP_ENV=dev
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password
...İsterseniz veritabanı adını, kullanıcı adını ve şifreyi de değiştirebilirsiniz. Bu değişkenler, servislerimizi yapılandırmak için docker-compose.yml dosyasını ayarlayacağımız bir sonraki adımda kullanılacaktır.
Düzenlemeyi bitirdiğinizde dosyayı kaydedin. nano kullandıysanız, bunu Ctrl+x tuşlarına basarak, ardından Y ve Enter ile onaylayarak yapabilirsiniz.
Adım 3 – Uygulamanın Dockerfile Dosyasını Ayarlamak
Her ne kadar hem MySQL hem de Nginx servislerimiz Docker Hub’dan alınan varsayılan imajlara dayansa da, uygulama konteyneri için yine de özel bir imaj oluşturmamız gerekiyor. Bunun için yeni bir Dockerfile oluşturacağız.
Bizim travellist imajımız, Docker Hub'daki php:7.4-fpm resmi PHP imajına dayanacak. Bu temel PHP-FPM ortamının üzerine, birkaç ek PHP modülü ve Composer bağımlılık yönetim aracını kuracağız.
Ayrıca yeni bir sistem kullanıcısı da oluşturacağız; bu, uygulamayı geliştirirken artisan ve composer komutlarını çalıştırmak için gereklidir. uid ayarı, konteyner içindeki kullanıcının Docker'ı çalıştırdığınız ana makinenizdeki sistem kullanıcısıyla aynı uid'ye sahip olmasını sağlar. Bu şekilde, bu komutlarla oluşturulan herhangi bir dosya, ana makinede doğru izinlerle çoğaltılır. Bu aynı zamanda, konteynerler içinde çalışan uygulamayı geliştirmek için ana makinede tercih ettiğiniz kod editörünü kullanabileceğiniz anlamına gelir.
Şu içeriğe sahip yeni bir Dockerfile oluştur:
nano DockerfileAşağıdaki içeriği Dockerfile'ınıza kopyalayın:
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# Set working directory
WORKDIR /var/www
USER $user
İşiniz bittiğinde dosyayı kaydetmeyi unutmayın.
Dockerfile’ımız, kullandığımız temel imajı tanımlayarak başlıyor: php:7.4-fpm.
Sistem paketlerini ve PHP eklentilerini kurduktan sonra, composer yürütülebilir dosyasını en güncel resmi imajından kendi uygulama imajımıza kopyalayarak Composer'ı kuruyoruz.
Yeni bir sistem kullanıcısı, Dockerfile'ın başında belirtilen user ve uid argümanları kullanılarak oluşturulur ve ayarlanır. Bu değerler, Docker Compose tarafından derleme sırasında enjekte edilecektir.
Son olarak, varsayılan çalışma dizinini /var/www olarak ayarlıyoruz ve yeni oluşturulan kullanıcıya geçiyoruz. Bu, uygulama konteynerinde composer ve artisan komutlarını çalıştırırken normal bir kullanıcı olarak bağlandığınızdan ve doğru dizinde bulunduğunuzdan emin olmanızı sağlar.
Adım 4 — Nginx Yapılandırmasını ve Veritabanı Yedek Dosyalarını Ayarlama
Docker Compose ile geliştirme ortamları oluştururken, bu hizmetleri kurmak veya başlatmak için yapılandırma veya başlangıç dosyalarını hizmet konteynerleriyle paylaşmak çoğu zaman gereklidir. Bu uygulama, uygulamayı geliştirirken ortamınızı ince ayar yapmak amacıyla yapılandırma dosyalarına değişiklik yapmayı kolaylaştırır.
Şimdi, servis konteynerlerimizi yapılandırmak ve başlatmak için kullanılacak dosyalarla bir klasör oluşturacağız.
Nginx'i kurmak için, uygulamanın nasıl sunulacağını yapılandıracak bir travellist.conf dosyasını paylaşacağız. Şu klasörü oluşturun: docker-compose/nginx
mkdir -p docker-compose/nginxO dizin içinde travellist.conf adlı yeni bir dosya açın:
nano docker-compose/nginx/travellist.confAşağıdaki Nginx yapılandırmasını o dosyaya kopyalayın:
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}Bu dosya, Nginx'in 80 numaralı portu dinlemesini ve varsayılan index sayfası olarak index.php'yi kullanmasını yapılandıracaktır. Belgelerin kök dizinini /var/www/public olarak ayarlayacak ve ardından Nginx'in *.php dosyalarını işlemek için 9000 portundaki app servisini kullanmasını yapılandıracaktır.
Düzenlemeyi bitirdiğinizde dosyayı kaydedin ve kapatın.
MySQL veritabanını kurmak için, konteyner başlatıldığında içe aktarılacak bir veritabanı dökümü paylaşacağız. Bu, o konteynerde kullanacağımız MySQL 8.0 imajı tarafından sağlanan bir özelliktir.
docker-compose klasörünün içinde MySQL başlatma dosyalarınız için yeni bir klasör oluşturun:
mkdir docker-compose/mysqlYeni bir .sql dosyası açın:
nano docker-compose/mysql/init_db.sqlAşağıdaki MySQL dökümü, Laravel on LEMP rehberimizde oluşturduğumuz veritabanına dayanmaktadır. Bu, places adında yeni bir tablo oluşturacaktır. Ardından tabloyu bir dizi örnek mekan ile dolduracaktır.
Dosyaya aşağıdaki kodu ekleyin:
DROP TABLE IF EXISTS `places`;
CREATE TABLE `places` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`visited` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);places tablosu üç alan içerir: id, name ve visited. visited alanı, gidilecek yerleri belirlemek için kullanılan bir bayraktır. Örnek yerleri değiştirmekten veya yenilerini eklemekten çekinmeyin. İşiniz bittiğinde dosyayı kaydedip kapatın.
Uygulamanın Dockerfile ve servis yapılandırma dosyalarını ayarlamayı bitirdik. Sonraki adımda, servislerimizi oluştururken bu dosyaları kullanmak için Docker Compose'u ayarlayacağız.
Adım 5 — Docker Compose ile Çoklu Konteyner Ortamı Oluşturma
Docker Compose, Docker üzerinde çalışan uygulamalar için çoklu konteyner ortamları oluşturmanıza olanak tanır. Tamamen özelleştirilebilir ortamları oluşturmak için servis tanımlarını kullanır ve bu ortamlar birden çok konteynerin ağları ve veri hacimlerini paylaşabilmesini sağlar. Bu, uygulama bileşenleri arasında sorunsuz bir entegrasyon sağlar.
Hizmet tanımlarımızı ayarlamak için, docker-compose.yml adında yeni bir dosya oluşturacağız. Genellikle bu dosya uygulama klasörünün kökünde bulunur ve konteynerleştirilmiş ortamınızı, konteynerlerinizi oluşturmak için kullanacağınız temel imajları ve hizmetlerinizin nasıl etkileşimde bulunacağını tanımlar.
docker-compose.yml dosyamızda üç farklı servisi tanımlayacağız: app, db ve nginx.
app servisi, daha önce oluşturduğumuz Dockerfile'a dayanarak travellist adlı bir imaj oluşturacaktır. Bu servis tarafından tanımlanan konteyner, PHP kodunu analiz etmek ve sonuçları ayrı bir konteynerda çalışacak olan nginx servisine göndermek için bir php-fpm sunucusu çalıştıracaktır. mysql servisi, MySQL 8.0 sunucusu çalıştıran bir konteyner tanımlar. Servislerimiz, travellist adında bir köprü ağı paylaşacaktır.
Uygulama dosyaları, hem app hem de nginx servislerinde bind mount kullanılarak senkronize edilecektir. Bind mountlar, host makine ile konteynerler arasında yüksek performanslı iki yönlü senkronizasyon sağladıkları için geliştirme ortamlarında faydalıdır.
Uygulama klasörünün kök dizininde yeni bir docker-compose.yml dosyası oluşturun:
nano docker-compose.ymlTipik bir docker-compose.yml dosyası, bir sürüm tanımıyla başlar, ardından tüm servislerin tanımlandığı bir services düğümü gelir. Paylaşılan ağlar genellikle dosyanın en alt kısmında tanımlanır.
Başlamak için, bu hazır kodu docker-compose.yml dosyanıza kopyalayın:
version: "3.9"
services:
networks:
travellist:
driver: bridgeŞimdi services düğümünü app, db ve nginx servislerini içerecek şekilde düzenleyeceğiz.
app Servisi
app servisi, travellist-app adında bir konteyner kuracaktır. Bu servis, docker-compose.yml dosyasının bulunduğu aynı yolda yer alan bir Dockerfile’a göre yeni bir Docker imajı oluşturur. Oluşturulan yeni imaj, travellist adıyla yerel olarak kaydedilecektir.
Uygulama olarak sunulan belge kökü nginx konteynerinde bulunsa da, Laravel Artisan aracıyla komut satırı görevlerini çalıştırabilmemiz için uygulama dosyalarına app konteynerinin içinde de bir yerde ihtiyacımız var.
Aşağıdaki servis tanımını docker-compose.yml dosyanızdaki services düğümünün altına kopyalayın:
app:
build:
args:
user: sammy
uid: 1000
context: ./
dockerfile: Dockerfile
image: travellist
container_name: travellist-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- travellistBu ayarlar şunları yapar:
build: Bu yapılandırma, Docker Compose'aappservisi için yerel bir görüntü oluşturmasını söyler; belirtilen yol (context) ve talimatlar için Dockerfile kullanılır.userveuidargümanları, oluşturma sırasında kullanıcı oluşturma komutlarını özelleştirmek için Dockerfile'a enjekte edilir.image: Oluşturulacak görüntü için kullanılacak isim.container_name: Bu servis için konteyner adını ayarlar.restart: Hizmet durdurulmadıkça her zaman yeniden başlat.working_dir: Bu servis için varsayılan dizini/var/wwwolarak ayarlar.volumes: Mevcut dizinin içeriğini konteyner içindeki/var/wwwdizinine senkronize edecek bir paylaşılan hacim oluşturur. Bunun sizin belge kökünüz olmadığını unutmayın, çünkü belge kökünüznginxkonteynerinde bulunacaktır.networks: Bu hizmetintravellistadlı bir ağı kullanacak şekilde ayarlanmasını sağlar.
db Servisi
db servisi, Docker Hub'dan önceden oluşturulmuş bir MySQL 8.0 imajını kullanır. Docker Compose, docker-compose.yml dosyasının bulunduğu aynı dizindeki .env değişken dosyalarını otomatik olarak yüklediği için, veritabanı ayarlarımızı daha önce oluşturduğumuz Laravel .env dosyasından alabiliriz.
app servisten hemen sonra services düğümünüzde aşağıdaki servis tanımını ekleyin:
db:
image: mysql:8.0
container_name: travellist-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- travellistBu ayarlar şunları yapar:
image: Bu kapsayıcı için kullanılacak Docker imajını tanımlar. Bu durumda, Docker Hub’dan MySQL 8.0 imajını kullanıyoruz.container_name: Bu servis için konteyner adını ayarlar:travellist-db.restart: Bu hizmetin her zaman yeniden başlatılmasını sağlar, aksi açıkça durdurulmadıkça.environment: Yeni konteynerde ortam değişkenlerini tanımlar. Laravel.envdosyasından alınan değerleri, belirtilen ortam değişkenlerine göre otomatik olarak yeni bir veritabanı ve kullanıcı oluşturacak olan MySQL servisimiz için kullanıyoruz.volumes: Uygulama veritabanını başlatmak için kullanılacak bir.sqlveritabanı dökümünü paylaşmak üzere bir hacim oluşturur. MySQL imajı, konteyner içindeki/docker-entrypoint-initdb.ddizinine yerleştirilen.sqldosyalarını otomatik olarak içe aktaracaktır.networks: Bu hizmetintravellistadlı bir ağı kullanacak şekilde ayarlanmasını sağlar.
nginx Servisi
nginx servisi, hafif bir Linux dağıtımı olan Alpine üzerine kurulmuş önceden oluşturulmuş bir Nginx imajını kullanır. travellist-nginx adında bir konteyner oluşturur ve ports tanımını kullanarak host sistemdeki 8000 portundan konteyner içindeki 80 portuna yönlendirme yapar.
db servisten hemen sonra services düğümünüzde aşağıdaki servis tanımını ekleyin:
nginx:
image: nginx:1.17-alpine
container_name: travellist-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d
networks:
- travellistBu ayarlar şunları yapar:
image: Bu konteyner için kullanılacak Docker imajını tanımlar. Bu durumda, Alpine Nginx 1.17 imajını kullanıyoruz.container_name: Bu servis için konteyner adını ayarlar: travellist-nginx.restart: Bu hizmeti her zaman yeniden başlatın, açıkça durdurulmadığı sürece.ports: Dış erişime, konteyner içinde 80 numaralı portta çalışan web sunucusuna8000portu üzerinden izin verecek bir port yönlendirmesi ayarlar.volumes: İki paylaşılan hacim (volume) oluşturur. Birincisi, mevcut dizindeki içerikleri konteyner içindeki/var/wwwdizinine senkronize eder. Bu sayede, uygulama dosyalarında yerel değişiklikler yaptığınızda, bu değişiklikler konteyner içindeki Nginx tarafından sunulan uygulamaya hızlı bir şekilde yansır. İkinci hacim isedocker-compose/nginx/travellist.confkonumundaki Nginx yapılandırma dosyamızın, konteynerin Nginx yapılandırma klasörüne kopyalanmasını sağlar.networks: Bu hizmetintravellistadlı bir ağı kullanacak şekilde ayarlanmasını sağlar.
Tamamlanan docker-compose.yml Dosyası
İşte tamamlanmış docker-compose.yml dosyamızın görünümü:
version: "3.9"
services:
app:
build:
args:
user: sammy
uid: 1000
context: ./
dockerfile: Dockerfile
image: travellist
container_name: travellist-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- travellist
db:
image: mysql:8.0
container_name: travellist-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- travellist
nginx:
image: nginx:1.17-alpine
container_name: travellist-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- travellist
networks:
travellist:
driver: bridgeİşi bitirdiğinizde dosyayı kaydettiğinizden emin olun.
Adım 6 — Uygulamayı Docker Compose ile Çalıştırma
Artık uygulama imajını oluşturmak ve kurulumumuzda belirttiğimiz servisleri çalıştırmak için docker compose komutlarını kullanacağız.
Aşağıdaki komutla app görüntüsünü oluşturun:
docker compose build appBu komutun tamamlanması birkaç dakika sürebilir. Benzer bir çıktı göreceksiniz:
Building app
Sending build context to Docker daemon 377.3kB
Step 1/11 : FROM php:7.4-fpm
---> 8c08d993542f
Step 2/11 : ARG user
---> e3ce3af04d87
Step 3/11 : ARG uid
---> 30cb921ef7df
Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev libxml2-dev zip unzip
. . .
---> b6dbc7a02e95
Step 5/11 : RUN apt-get clean && rm -rf /var/lib/apt/lists/*
---> 10ef9dde45ad
. . .
Step 6/11 : RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
. . .
---> 920e4f09ec75
Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
---> dbbcd44e44af
Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user
---> db98e899a69a
Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user
---> 5119e26ebfea
Step 10/11 : WORKDIR /var/www
---> 699c491611c0
Step 11/11 : USER $user
---> cf250fe8f1af
Successfully built cf250fe8f1af
Successfully tagged travellist:latestDerleme tamamlandığında, ortamı arka planda çalıştırabilirsiniz:
docker compose up -dCreating travellist-db ... done
Creating travellist-app ... done
Creating travellist-nginx ... doneBu, konteynerlerinizi arka planda çalıştıracaktır. Aktif servislerinizin durumu hakkında bilgi göstermek için şunu çalıştırın:
docker compose psBöyle bir çıktı göreceksiniz:
Name Command State Ports
-----------------------------------------------------------------------------------------------
travellist-app docker-php-entrypoint php-fpm Up 9000/tcp
travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
travellist-nginx nginx -g daemon off; Up 0.0.0.0:8000->80/tcp,:::8000->80/tcpOrtamınız artık çalışır durumda.
Artık her konteynerleştirilmiş servisin doğru şekilde yanıt verip vermediğini basit curl komutları kullanarak doğrulayabilirsiniz.
Nginx web servisini test etmek için:
curl -I http://localhost:8000Beklenen çıktı:
HTTP/1.1 200 OK Server: nginx/1.17.10 Content-Type: text/html; charset=UTF-8Bu, Nginx konteynerinin çalıştığını ve Laravel uygulamanızdan yanıtlar sağladığını doğrular.
PHP-FPM'i Nginx üzerinden test etmek için:
curl -s http://localhost:8000 | grep "Berlin"Uygulama düzgün çalışıyorsa, bu komut Berlin kelimesini içeren karşılama sayfasının HTML'sini döndürür.
Uygulamayı kurmayı bitirmek için hâlâ birkaç komut çalıştırmamız gerekiyor. Servis konteynerlerinde komutları çalıştırmak için docker compose exec komutunu kullanabilirsiniz. Örneğin, uygulama dizinindeki dosyalar hakkında detaylı bilgi göstermek için ls -l komutunu kullanabilirsiniz:
docker compose exec app ls -ltotal 256
-rw-r--r-- 1 sammy sammy 737 Apr 18 14:21 Dockerfile
-rw-r--r-- 1 sammy sammy 101 Jan 7 2020 README.md
drwxr-xr-x 6 sammy sammy 4096 Jan 7 2020 app
-rwxr-xr-x 1 sammy sammy 1686 Jan 7 2020 artisan
drwxr-xr-x 3 sammy sammy 4096 Jan 7 2020 bootstrap
-rw-r--r-- 1 sammy sammy 1501 Jan 7 2020 composer.json
-rw-r--r-- 1 sammy sammy 179071 Jan 7 2020 composer.lock
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 config
drwxr-xr-x 5 sammy sammy 4096 Jan 7 2020 database
drwxr-xr-x 4 sammy sammy 4096 Apr 18 14:22 docker-compose
-rw-r--r-- 1 sammy sammy 1017 Apr 18 14:29 docker-compose.yml
-rw-r--r-- 1 sammy sammy 1013 Jan 7 2020 package.json
-rw-r--r-- 1 sammy sammy 1405 Jan 7 2020 phpunit.xml
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 public
-rw-r--r-- 1 sammy sammy 273 Jan 7 2020 readme.md
drwxr-xr-x 6 sammy sammy 4096 Jan 7 2020 resources
drwxr-xr-x 2 sammy sammy 4096 Jan 7 2020 routes
-rw-r--r-- 1 sammy sammy 563 Jan 7 2020 server.php
drwxr-xr-x 5 sammy sammy 4096 Jan 7 2020 storage
drwxr-xr-x 4 sammy sammy 4096 Jan 7 2020 tests
-rw-r--r-- 1 sammy sammy 538 Jan 7 2020 webpack.mix.jsŞimdi uygulama bağımlılıklarını yüklemek için composer install komutunu çalıştıracağız:
docker compose exec app rm -rf vendor composer.lock
docker compose exec app composer installBöyle bir çıktı göreceksiniz:
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
. . .
Lock file operations: 89 installs, 0 updates, 0 removals
- Locking doctrine/inflector (2.0.4)
- Locking doctrine/instantiator (1.4.1)
- Locking doctrine/lexer (1.2.3)
- Locking dragonmantank/cron-expression (v2.3.1)
- Locking egulias/email-validator (2.1.25)
- Locking facade/flare-client-php (1.9.1)
- Locking facade/ignition (1.18.1)
- Locking facade/ignition-contracts (1.0.2)
- Locking fideloper/proxy (4.4.1)
- Locking filp/whoops (2.14.5)
. . .
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 89 installs, 0 updates, 0 removals
- Downloading doctrine/inflector (2.0.4)
- Downloading doctrine/lexer (1.2.3)
- Downloading dragonmantank/cron-expression (v2.3.1)
- Downloading symfony/polyfill-php80 (v1.25.0)
- Downloading symfony/polyfill-php72 (v1.25.0)
- Downloading symfony/polyfill-mbstring (v1.25.0)
- Downloading symfony/var-dumper (v4.4.39)
- Downloading symfony/deprecation-contracts (v2.5.1)
. . .
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.Uygulamayı test etmeden önce yapmamız gereken son şey, artisan Laravel komut satırı aracıyla benzersiz bir uygulama anahtarı oluşturmaktır. Bu anahtar, kullanıcı oturumlarını ve diğer hassas verileri şifrelemek için kullanılır:
docker compose exec app php artisan key:generateApplication key set successfully.Şimdi tarayıcınıza gidin ve sunucunuzun alan adını veya IP adresini 8000 numaralı port üzerinden erişin:
http://server_domain_or_IP:8000Not: Bu demoyu yerel bilgisayarınızda çalıştırıyorsanız, uygulamaya tarayıcınızdan erişmek için http://localhost:8000 adresini kullanın.
Böyle bir sayfa göreceksiniz:
Laravel uygulamasını bir tarayıcı kullanmadan, uygulama konteynerinin içinden de test edebilirsiniz:
docker compose exec app curl http://nginxHer şey doğru şekilde yapılandırılmışsa, Laravel’in varsayılan karşılama sayfasının HTML çıktısını görmelisiniz.
<html>
<head>
<title>Travel List</title>
</head>
<body>
<h1>My Travel Bucket List</h1>
<h2>Places I'd Like to Visit</h2>
<ul>
<li>Berlin</li>
<li>Budapest</li>
<li>Denver</li>
<li>Helsinki</li>
<li>Lisbon</li>
<li>Nairobi</li>
<li>Rio</li>
<li>Tokyo</li>
</ul>
<h2>Places I've Already Been To</h2>
<ul>
<li>Cincinnati</li>
<li>Moscow</li>
<li>Oslo</li>
</ul>
</body>
</html>Hizmetleriniz tarafından oluşturulan günlükleri kontrol etmek için logs komutunu kullanabilirsiniz:
docker compose logs nginxAttaching to travellist-nginx
. . .
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:49:16 +0000] "GET / HTTP/1.1" 200 627 "-" "curl/7.82.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"
travellist-nginx | 172.24.9.1 - - [18/Apr/2022:14:51:27 +0000] "GET /favicon.ico HTTP/1.1" 200 0 "http://localhost:8000/" "Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"Aşağıdaki curl komutunu da günlük girişlerini tetiklemek için kullanabilirsiniz:
curl http://localhost:8000Sonra tekrar çalıştır:
docker compose logs nginxArtık isteğiniz için eşleşen bir erişim günlük kaydını görmelisiniz.
Tüm hizmetlerin durumunu koruyarak Docker Compose ortamınızı duraklatmak istiyorsanız, şunu çalıştırın:
docker compose pausePausing travellist-db ... done
Pausing travellist-nginx ... done
Pausing travellist-app ... doneArdından hizmetlerinize şunlarla devam edebilirsiniz:
docker compose unpauseUnpausing travellist-app ... done
Unpausing travellist-nginx ... done
Unpausing travellist-db ... doneDocker Compose ortamınızı kapatmak ve tüm konteynerlerini, ağlarını ve hacimlerini kaldırmak için şunu çalıştırın:
docker compose downStopping travellist-nginx ... done
Stopping travellist-db ... done
Stopping travellist-app ... done
Removing travellist-nginx ... done
Removing travellist-db ... done
Removing travellist-app ... done
Removing network travellist-laravel-demo_travellistTüm Docker Compose komutlarının genel bir bakışı için lütfen Docker Compose komut satırı referansına bakın.
Laravel Dosya ve Dizin İzinlerini Düzeltme
Laravel'ı Docker konteynerleri içinde çalıştırırken, geliştiricilerin karşılaştığı en yaygın sorunlardan biri dosya ve dizin izinleriyle ilgilidir. Laravel, app konteyneri içindeki PHP-FPM sürecinin bazı dizinlere yazabilir olmasını gerektirir. Bu dizinler yazılabilir değilse, uygulama hataları kaydetmede, yapılandırma dosyalarını önbelleğe almada veya oturum verilerini doğru şekilde saklamada başarısız olabilir.
Şu tür mesajlarla karşılaşabilirsiniz:
The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission deniedveya
file_put_contents(/var/www/bootstrap/cache/config.php): Failed to open stream: Permission deniedBu hatalar, konteyner içinde PHP çalıştıran kullanıcının gerekli dizinlere yazma iznine sahip olmadığını gösterir.
Aşağıdaki adımlar, bu sorunları hem yerel hem de üretim ortamlarında nasıl teşhis edip düzelteceğinizi açıklar.
Yazılabilir Dizin İzinlerini Ayarla
Laravel, web sunucusu kullanıcısı tarafından yazılabilir iki dizin gerektirir:
/var/www/storage/var/www/bootstrap/cache
İzin hataları görüyorsanız, bunları konteynerin içinden sahiplik ve izinleri ayarlayarak düzeltebilirsiniz:
docker compose exec app chown -R sammy:sammy /var/www/storage /var/www/bootstrap/cache
docker compose exec app chmod -R 775 /var/www/storage /var/www/bootstrap/cacheDockerfile'ınız farklı bir kullanıcı adı kullanıyorsa (user yapı argümanı ile tanımlanmış), sammyyi o kullanıcı adıyla değiştirin.
Sahipliği aşağıdaki komutla doğrulayabilirsiniz:
docker compose exec app ls -ld /var/www/storage /var/www/bootstrap/cacheÇıktı, kullanıcının ve grubun konteyner içindeki PHP-FPM süreciyle eşleştiğini göstermelidir.
Bunun yerine izinleri ana makineden ayarlamak istiyorsanız, şunu çalıştırın:
sudo chown -R $(id -u):$(id -g) storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cacheBu, hem Laravel dizinlerinin konteyner hem de sizin ana kullanıcı tarafından yazılabilir olmasını sağlar.
Görüntü Oluşturma Sırasında Dizin Sahipliğini Ayarlama
Her yeniden derlemeden sonra izin sorunlarının tekrar etmesini önlemek için, Docker imajı oluşturma sürecinde dizin sahipliğini ayarlayabilirsiniz. Dockerfile dosyanızı açın ve kök olmayan kullanıcıya geçmeden önce sonlara doğru şu satırı ekleyin:
RUN chown -R $user:www-data /var/wwwBu komut, /var/www altındaki tüm dosya ve dizinlerin Dockerfile'ınızda belirttiğiniz kullanıcıya ait olmasını sağlar.
Daha hedeflenmiş ve güvenli bir yaklaşım için, Laravel'in yazması gereken dizinleri yalnızca ayarlayabilirsiniz:
RUN chown -R $user:www-data /var/www/storage /var/www/bootstrap/cacheBu değişikliği yaptıktan sonra, imajı yeniden oluşturun ve konteynerları yeniden başlatın:
docker compose build app
docker compose up -dKonteyner bir sonraki kez başladığında, gerekli izinlere zaten sahip olacak.
Ana Bilgisayar ve Konteyner Arasındaki Kullanıcı Kimliği Tutarlılığını Doğrula
Bind mount kullanırken, Docker dosyaları hostunuz ile konteyner arasında paylaşır. Eğer host kullanıcısının sayısal UID'si konteynerde tanımlanan UID'den farklıysa, dosya sahipliği çatışmaları meydana gelebilir. Bu, kullanıcı kimliklerinin makineler arasında değiştiği sistemlerde yaygındır.
UID değerlerini doğrulamak için şunu çalıştırın:
id -u $(whoami)
docker compose exec app id -uBu iki sayı eşleşmiyorsa, gerçek UID'nizi yapı sürecine geçirmek için docker-compose.yml dosyanızı güncelleyin:
build:
args:
user: sammy
uid: 1000Sonra görüntüyü yeniden oluşturun:
docker compose build app
docker compose up -dBu, konteyner kullanıcısının ana makine kullanıcınızla eşleşmesini sağlar ve bağlanmış dosyalarda izin uyuşmazlıklarını önler.
Composer Önbellek Dizin İzinlerini Düzelt
Composer, indirilen bağımlılıkları ve önbellek dosyalarını konteyner içindeki kullanıcının ev dizininde saklar (/home/sammy/.composer). Eğer bu dizin yazılabilir değilse, şu tür uyarılar görebilirsiniz:
Cannot create cache directory /home/sammy/.composer/cacheBunu, önbellek dizinini oluşturarak ve doğru sahipliği atayarak düzeltebilirsiniz:
docker compose exec app mkdir -p /home/sammy/.composer/cache
docker compose exec app chown -R sammy:sammy /home/sammy/.composerBu, Composer'ın bağımlılıkları ve önbellek dosyalarını izin hatası olmadan saklayabilmesini sağlar, bu da gelecekteki composer install çalıştırmalarını hızlandırır.
Üretim Ortamları için Önerilen Uygulamalar
Üretimde, izin yönetimi çalışma zamanında değil, görüntü oluşturulurken ele alınmalıdır. Bu, tutarlılığı ve güvenliği artırır.
Üretim için hazır bir yapılandırma için bu uygulamaları takip edin:
Uygulama kodu için bind mount kullanımından kaçının: Bunun yerine, uygulama dosyalarını derleme sırasında imajın içine kopyalayın. Bind mountlar yalnızca geliştirme için kullanılmalıdır.
Derleme sırasında izinleri ayarlayın: Doğru sahiplik ve erişim haklarını dağıtımdan önce sağlamak için Dockerfile dosyanıza
RUN chownvechmodkomutlarını ekleyin.En az ayrıcalıklı kullanıcıyı kullanın: PHP sürecinin root olmayan bir kullanıcı altında çalıştığından emin olun (mevcut ayar
$userbunu zaten yapıyor).Yazılabilir olmayan dizinlerde izinleri kısıtlayın: Çoğu uygulama dosyası yalnızca okunabilir olmalıdır. Bunu şu şekilde uygulayabilirsiniz:
chmod -R 755 /var/www chmod -R 775 /var/www/storage /var/www/bootstrap/cacheBu yapılandırma, Laravel'in sadece gerektiğinde yazmasını sağlarken diğer uygulama dosyalarının değiştirilmesini korur.
Bu adımları izleyerek, Laravel konteynerleriniz hem yerel hem de üretim ortamlarında kararlı ve öngörülebilir dosya izinlerine sahip olacaktır. Bu, tekrarlayan hataları azaltır ve Laravel'in verileri kaydetmesini, dosyaları önbelleğe almasını ve oturumları güvenilir şekilde yazmasını sağlar.
Yerel ve Üretim Ortamları için docker-compose.override.yml Dosyasını Anlamak
Docker Compose, çoklu konteyner uygulamalarını tek bir yapılandırma dosyası kullanarak tanımlamanıza olanak tanır. Çoğu durumda, bu yapılandırma docker-compose.yml adlı bir dosyada saklanır. Ancak, yerel geliştirme ve üretim gibi birden çok ortamı yönetmek genellikle ortama özgü ayarlamalar gerektirir. İşte bu noktada docker-compose.override.yml dosyası işe yarar.
Varsayılan olarak, Docker Compose otomatik olarak temel Compose dosyasıyla aynı dizinde docker-compose.override.yml adında bir dosya arar. Bulunduğunda, herhangi bir docker compose komutunu çalıştırdığınızda her iki dosyadaki yapılandırmaları birleştirir. Bu yaklaşım, geliştiricilerin temiz ve yeniden kullanılabilir bir temel yapılandırmayı korurken, yerel veya üretim kullanımı için kurulumun belirli yönlerini özelleştirmelerine olanak tanır.
docker-compose.override.yml Dosyasının Rolü
docker-compose.override.yml dosyası, temel Compose yapılandırmasının bir uzantısıdır. Sadece belirli bir ortama uygulanacak özellikleri değiştirir veya ekler ve ana docker-compose.yml dosyasında değişiklik yapılmasını gerektirmez. Override dosyası, geliştiricilerin kaynak kodunu monte etmeleri, hata ayıklama araçlarını etkinleştirmeleri veya test için ortam değişkenlerini değiştirmeleri gerektiren yerel geliştirme iş akışlarında özellikle kullanışlıdır.
docker compose up komutunu çalıştırdığınızda, Docker otomatik olarak docker-compose.yml ve docker-compose.override.yml dosyalarının içeriklerini birleştirir. Eğer bir servis, hacim veya yapılandırma her iki dosyada da tanımlanmışsa, override dosyasındaki değerler öncelik kazanır.
Farklı bir override dosyası kullanmak için, örneğin üretim için hazırlanmış bir dosya, dosyayı manuel olarak -f bayrağı ile belirtebilirsiniz:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dBu yaklaşım, tek bir tutarlı komut yapısını kullanırken farklı ortamlar için ayrı yapılandırmaları korumanıza olanak tanır.
Yerel Kalkınma için Yapılandırma
Yerel geliştirme ortamları genellikle sık değişiklikler, canlı kod yeniden yükleme ve ayrıntılı günlük kaydı gerektirir. docker-compose.override.yml dosyası, bu özellikleri diğer ortamları etkilemeden eklemeyi mümkün kılar.
Tipik bir yerel geçersiz kılma dosyası şunları içerebilir:
- Canlı kod güncellemeleri için bağlama noktaları
- Önceden oluşturulmuş görüntüler yerine yerel derleme yönergeleri
- Geliştirme özelinde ortam değişkenleri
- Hata ayıklama ve test hizmetleri
Örneğin:
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- ./src:/app
- ./logs:/app/logs
environment:
- DATABASE_URL=postgres://postgres:postgres@db:5432/app_db
- LOG_LEVEL=debug
ports:
- "8000:8000"
depends_on:
- db
db:
environment:
- POSTGRES_PASSWORD=postgresBu örnekte:
appservisi, yerel bir Dockerfile'dan (Dockerfile.dev) doğrudan oluşturulur, böylece değişiklikleri bir registry üzerinden imajları yeniden oluşturmadan test etmek kolay olur.- Kaynak kod, bind mount kullanılarak bağlanır, bu sayede konteyner yerel dosya değişikliklerini gerçek zamanlı olarak yansıtabilir.
- Geliştirme sırasında daha ayrıntılı çıktılar sağlamak için
LOG_LEVEL=debuggibi ortam değişkenleri ayarlanır. - Veritabanı, yerel testler için uygun olan basit kimlik bilgilerini kullanıyor ancak üretimde kullanılmamalıdır.
Bu yapılandırma, temel yapılandırmayı değiştirmeden daha hızlı ve esnek bir geliştirme ortamı sağlar.
Prodüksiyona Hazırlık
Üretim ortamları, istikrar, tekrarlanabilirlik ve güvenlik gerektirir. Konteynerler, yerel olarak oluşturulmak yerine önceden hazırlanmış imajlardan çalıştırılmalıdır ve hassas bilgiler güvenli bir şekilde yönetilmelidir. Yerel geliştirme için otomatik olarak uygulanan geçersiz kılma dosyasının aksine, üretim geçersiz kılmaları açıkça belirtilmelidir.
Bir üretim geçersiz kılma dosyası (docker-compose.prod.yml) genellikle yerel derleme adımlarını görüntü referanslarıyla değiştirmek, bağlama noktaları yerine adlandırılmış hacimler kullanmak ve kaynak sınırları ve ölçeklendirme gibi dağıtım ile ilgili özellikleri tanımlamak için tasarlanır.
Örnek:
version: "3.9"
services:
app:
image: registry.example.com/myapp:1.2.3
environment:
- DATABASE_URL=${DATABASE_URL}
- LOG_LEVEL=info
volumes:
- app-data:/var/lib/app
ports:
- "8000:8000"
restart: unless-stopped
deploy:
replicas: 3
resources:
limits:
cpus: "0.5"
memory: 512M
db:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
db_password:
external: true
volumes:
app-data:
db-data:Bu yapılandırmada:
appservisi, yerel olarak inşa etmek yerine bir kayıtta saklanan önceden oluşturulmuş bir imajı (myapp:1.2.3) referans alır.Bağlama noktaları, tutarlı ve izole veri depolamayı sağlamak için isimlendirilmiş hacimlerle değiştirilir.
Hassas kimlik bilgileri Docker sırları kullanılarak güvenli bir şekilde saklanır.
deploybölümü, yük altında daha iyi kararlılık için ölçeklendirme davranışını ve kaynak sınırlarını tanımlar.Yapılandırma, dağıtım sırasında açıkça uygulanmalıdır:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Bu yapı, üretim dağıtımlarının tutarlı, kontrollü olmasını ve yerel geliştirme öğelerinden arınmış olmasını sağlar.
Yerel ve Üretim Geçersiz Kılmalarını Karşılaştırma
| Yapılandırma Özelliği | Yerel (docker-compose.override.yml) | Üretim (docker-compose.prod.yml) |
|---|---|---|
| Otomatik olarak uygulandı | Evet | Hayır (kullanmak için -f gereklidir) |
| Kaynak kod yönetimi | Canlı güncellemeler için bağlama noktaları | Kayıttan önceden oluşturulmuş görüntüler |
| Çevre değişkenleri | Geliştirici odaklı değerler | Prodüksiyon güvenli değerler |
| Kayıt Tutma | Ayrıntılı (debug) | Kısa (info veya error) |
| Gizli bilgi yönetimi | Düz değerler veya .env | Docker sırları veya yönetilen sırlar |
| Ölçekleme | Tek konteyner | Birden çok kopya |
| Performans ayarlaması | Gerekli değil | Kaynak sınırları tanımlandı |
| Hata ayıklama araçları | Etkin | Engelli |
| Yeniden başlatma politikası | Manuel veya yok | |
Birden fazla Docker Compose dosyası kullanmak, ortam özelindeki yapılandırmaları temel kurulumdan ayırmanın temiz bir yolunu sağlar. Temel docker-compose.yml, ortak uygulama yapısını tanımlarken, docker-compose.override.yml yerel geliştirme için bunu ayarlar. Üretime dağıtırken, açık bir override dosyası tahmin edilebilir ve güvenli bir yapılandırma sağlar.
Bu desen, ekiplerin tutarlı bir iş akışını sürdürmesine olanak tanır. Geliştiriciler uygulamayı yerel olarak başlatmak için şunu kullanabilir:
docker compose upve üretime dağıtmak için kullan:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dHer iki ortam da aynı temel yapılandırmayı paylaşırken, kendi özel gereksinimlerine uygun bağımsız ayarları korur. Bu ayrım, bakım kolaylığını artırır, yapılandırma hatalarını azaltır ve yerel ile üretim ortamlarının uyumlu kalmasını sağlar.
Ortamınızı Sorun Giderme
Bu bölüm, uygulamanızı Docker Compose ile çalıştırırken karşılaşabileceğiniz yaygın sorunlar için sorun giderme adımlarını sağlar.
502 Bad Gateway (Nginx 502 yanıtları gösteriyor)
Belirtiler:
- Tarayıcı
http://localhost:8000adresine erişirken 502 Bad Gateway hatası gösteriyor. - Nginx loglarında
recv() failed (111: Connection refused)veyaconnect() failed (111: Connection refused) while connecting to upstreamgibi satırlar bulunur.
Muhtemel nedenler:
- PHP-FPM (yani
appservisi) çalışmıyor veya beklenen soket/port üzerinde dinlemiyor. - Nginx
fastcgi_passyanlış host/porta işaret ediyor. nginxileapparasında konteyner adı uyumsuzluğu veya ağ sorunları.appbaşlatılırken çöktü (örneğin, eksik eklentiler veya yapılandırma hataları nedeniyle).
Nasıl onaylanır:
Nginx günlüklerini inceleyin:
docker compose logs nginx | tail -n 100502mesajlarını veya üst akış bağlantı hatalarını arayın.appkonteyner durumunu ve günlüklerini kontrol edin:docker compose ps app docker compose logs app --tail=200appkonteyneri içinde PHP-FPM'in dinlediğini doğrulayın:docker compose exec app ss -ltnp | grep :9000 || docker compose exec app ss -lxp | grep php-fpmBeklenen: ya
9000portunda bir TCP dinleyicisi ya danginxtarafından kullanılan bir Unix soketi (bu compose ile daha az yaygın).Compose ağında
nginx'inapp'i çözümleyip erişebildiğini doğrulayın:docker compose exec nginx ping -c 2 app docker compose exec nginx wget -qO- --timeout=2 http://app:9000/ || trueEğer
pingbaşarısız olursa veyawgetzaman aşımına uğrarsa, ağda veya servis adında bir uyuşmazlık vardır.
Yaygın düzeltmeler:
PHP-FPM çalışmıyorsa, ölümcül PHP hataları veya başlatma hataları için
appgünlüklerini inceleyin. Temel hatayı düzeltin (genellikle eksik eklenti veya izin sorunu) ve yeniden başlatın:docker compose restart app docker compose logs app --tail=100Eğer Nginx yapılandırması farklı bir upstream kullanıyorsa (ör.
fastcgi_pass 127.0.0.1:9000;),docker-compose/nginx/travellist.confdosyasınıfastcgi_pass app:9000;olarak güncelleyin (compose servis adınızla eşleşecek şekilde) ve Nginx'i yeniden yükleyin:# After editing config in host docker compose exec nginx nginx -s reload docker compose logs nginx --tail=50Eğer PHP-FPM bir Unix soketi üzerinde dinliyorsa (örneğin,
/run/php/php7.4-fpm.sock) ama Nginx TCP bekliyorsa veya tam tersi durum varsa, Compose kurulumları için TCPapp:9000olarak standartlaştırın veya konteynerler arasında soketi doğru şekilde bağlayın (önerilen: çoklu konteyner Compose’da TCP kullanmak).
Eksik PHP uzantıları (Composer veya Artisan çalıştırılırken hatalar veya çalışma zamanı hataları)
Belirtiler:
- Composer veya Laravel komutları çalıştırılırken
Class "PDO" not found,ext-pdo is missingveyaCall to undefined function json_encodegibi mesajlar alırsınız. appgünlüklerinde tanımsız sınıflara veya işlevlere atıfta bulunan PHP hataları.
Nasıl onaylanır:
appkonteynerinin PHP modül listesini inceleyin:docker compose exec app php -m | sortİhtiyacınız olan uzantı isimlerini arayın (Laravel için tipik uzantılar:
pdo_mysql,mbstring,bcmath,openssl,tokenizer,xml,ctype,json,gd).Genellikle gerekli uzantıları belirten composer hata metnini kontrol edin:
docker compose exec app composer install
Düzeltmeler:
Dockerfile'ınıza eksik uzantıları ekleyin ve imajı yeniden oluşturun. Örnek (
pdo_mysqlvegdiçin):RUN apt-get update && apt-get install -y libpng-dev libxml2-dev \ && docker-php-ext-install pdo_mysql mbstring xml gdSonra yeniden oluşturun ve yeniden başlatın:
docker compose build app docker compose up -d app docker compose logs app --tail=100Eğer bir eklenti sistem kütüphanelerine ihtiyaç duyuyorsa (örneğin
gdiçinlibpng-devgerekliyse),docker-php-ext-installkomutundan önce ilgiliapt-get installsatırlarını ekleyin.Yerleşik olmayan bir PHP uzantısına ihtiyacınız varsa, PECL üzerinden yüklemeyi düşünün ve
php.inidosyasında etkinleştirin.
Veritabanı bağlantı hataları (Laravel MySQL'e bağlanamıyor)
Belirtiler:
- Laravel veritabanı bağlantı hatalarını gösterir (
SQLSTATE[HY000] [2002] Bağlantı reddedildiveyaKullanıcı için erişim reddedildi). - Göçler başarısız olur veya uygulama veri odaklı sayfalar için boş bir sayfa gösterir.
Nasıl onaylanır:
DB konteyner günlüklerini başlatma hataları için kontrol edin:
docker compose logs db --tail=200DB kapsayıcısının çalıştığını doğrulayın:
docker compose ps dbKimlik bilgileri ve sunucunun
.enviledocker-compose.ymlarasında tutarlı olduğunu doğrulayın. Laravel.envdosyasında,DB_HOSTcompose servis adı (db) olmalıdır,127.0.0.1veyalocalhostdeğil:DB_HOST=db DB_PORT=3306 DB_DATABASE=travellist DB_USERNAME=travellist_user DB_PASSWORD=passwordİçeriden
dbkonteyneri testi:docker compose exec db mysql -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SHOW DATABASES;"Veya, ağ bağlantısını doğrulamak için
appkonteynerinden test yapın:docker compose exec app sh -c 'which mysql >/dev/null 2>&1 || echo "no mysql client"; mysql -h db -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SELECT VERSION();"'
Yaygın nedenler ve çözümler:
.envdosyasında yanlış sunucu:DB_HOST=dbolarak güncelleyin, konteynerleri yeniden oluşturun veya ortam değişkenlerini yeniden yükleyin:docker compose down docker compose up -d docker compose exec app php artisan migrateUygulama başlarken veritabanı hazır değil: Uygulamanızda bir tekrar deneme mekanizması kullanın veya bir sağlık kontrolü ekleyip sıralamaya başlayın. Ayrıca manuel olarak da bekleyebilirsiniz:
docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping # expected: mysqld is aliveBaşlatma SQL'i başarısız:
./docker-compose/mysqlaltındaki dosyaları kontrol edin, bir sözdizimi veya izin hatası veritabanı başlatılmasını durdurabilir. İçe aktarma hataları için veritabanı loglarını inceleyin.İzinler/hatalı kimlik bilgileri: veritabanı ve kullanıcının mevcut olduğunu doğrulayın. Veritabanını yeniden oluşturun veya izinleri vermek için SQL çalıştırın.
Host düzeyinde port kullanımı: Eğer
curl telnet://localhost:3306komutunu denediyseniz vedbservisi bir host portu açmıyorsa, bu bağlantı tasarım gereği reddedilecektir. Testleri konteynerlerin içinden yapın veya yalnızca yerel hata ayıklama içindocker-compose.ymldosyasında portu açın (ports: - "3306:3306").
İzin ve dosya sistemi sorunları (depolama, önbellek, günlük dosyaları)
Belirtiler:
- Laravel, önbellek veya log yazmayla ilgili istisnalar fırlatır:
"/var/www/storage/logs/laravel.log" dosyası veya akışı açılamadı. - Kapsayıcı süreçleri tarafından oluşturulan dosyalar
roottarafından sahiplenilir ve ana bilgisayar kullanıcı tarafından yazılabilir değildir.
Nasıl onaylanır:
Ana makineden dosya izinlerini kontrol edin:
ls -l ls -l storage bootstrap/cache docker compose exec app id -u # user id inside containerKapsayıcı günlüklerini izin hataları için inceleyin.
Düzeltmeler:
Dockerfile'ın, ana bilgisayar kullanıcınızla eşleşen kullanıcıyı ve UID'yi ayarladığından emin olun (Dockerfile'ınız zaten
ARG uidile bir kullanıcı oluşturuyor).docker-compose.ymliçindeki build argümanlarındakiuid'nin ana bilgisayar UID'nizle eşleştiğini doğrulayın (genellikle1000).Sahipliği hosttan veya konteynerin içinden düzeltin:
docker compose exec app chown -R sammy:sammy /var/www/storage /var/www/bootstrap/cacheveya sunucudan:
sudo chown -R $(id -u):$(id -g) storage bootstrap/cacheGeliştirme sırasında bağlama montajları izin uyumsuzluklarına neden olabilir; konteynerleri başlattıktan sonra sahipliği ayarlamak için konteyner komutlarını çalıştırmayı tercih edin.
Composer veya satıcıyla ilgili hatalar
Belirtiler:
composer install,appiçinde başarısız olursa veyavendorklasörü eksikse sınıf bulunamaz.composerkapsayıcıda bellek tükenmesi bildiriyor.
Nasıl onaylanır:
appkonteynırı içinde composer çalıştırın ve çıktıyı yakalayın:docker compose exec app composer install --no-interaction --prefer-dist
Düzeltmeler:
Eğer
composerbellek limitlerine ulaşılırsa, daha fazla bellek verin veya composer çevresel değişkenini ayarlayın:docker compose exec app php -d memory_limit=-1 /usr/bin/composer installComposer çalıştırılabilir dosyasının mevcut olduğundan emin olun (Dockerfile'ınız composer'ı kopyalıyor). Eğer yoksa, composer katmanı ile imajı yeniden oluşturun.
Eğer
vendorbind mount overlay nedeniyle eksikse, bind mount'un imajda oluşturulanvendorklasörünü gizlemediğinden emin olun. En iyi uygulama, konteynerler çalıştıktan sonracomposer installkomutunu çalıştırmaktır, böylecevendorbağlanan klasörde oluşturulur; ya da üretim içinvendorklasörünü imaj oluşturma sırasında konteynere ekleyin.
Uygulama boş sayfa döndürüyor veya 500 hatası veriyor
Belirtiler:
- Tarayıcı boş bir yanıt veya HTTP 500 gösteriyor.
- Nginx günlükleri 200 gösteriyor ama sayfa boş;
appgünlükleri ölümcül hatalar gösteriyor.
Nasıl onaylanır:
Uygulama günlüklerini inceleyin:
docker compose exec app tail -n 200 storage/logs/laravel.log docker compose logs app --tail=200Ortamı kontrol edin:
.envdosyasındakiAPP_DEBUG=true, Laravel'in geliştirme sırasında ayrıntılı hata göstermesini sağlar (prodüksiyonda etkinleştirmeyin).
Düzeltmeler:
laravel.logdosyasında gösterilen temel hatayı düzeltin..envdosyasının var olduğundan veAPP_KEY'in ayarlandığından emin olun:docker compose exec app php artisan key:generateGöçleri çalıştır, önbelleği temizle:
docker compose exec app php artisan migrate --force docker compose exec app php artisan config:cache docker compose exec app php artisan route:cache docker compose exec app php artisan view:cache
Konteyner oluşturma hataları (docker compose build sırasında hatalar)
Belirtiler:
docker compose build, apt veya build adımı hatalarıyla başarısız oluyor.
Nasıl onaylanır:
Günlüklerle birlikte derlemeyi yeniden çalıştır:
docker compose build app
Düzeltmeler:
Başarısız olan adım çıktısını okuyun. Tipik sorunlar:
- Derleme ortamında Ağ/DNS: tekrar deneyin veya Docker'ın internete erişebildiğinden emin olun.
- Eksik paketler veya yanlış apt kaynağı: Yüklemeden önce
apt-get updateekleyin ve sonrasında apt listelerini temizleyin. - İmaj içine kopyalanan dosyalardaki izinler: doğru
COPYyollarını sağlayın.
Sağlam kurulumlar için örnek Dockerfile parçacığı:
RUN apt-get update && apt-get install -y --no-install-recommends \
libpng-dev libxml2-dev zip unzip \
&& docker-php-ext-install pdo_mysql mbstring xml gd \
&& apt-get clean && rm -rf /var/lib/apt/lists/*Konteynerler arasında ağ veya DNS sorunları
Belirtiler:
- Bir konteyner başka bir konteynere servis adıyla ulaşamaz (örneğin,
appdb:3306iledb'ye ulaşamaz). pingservis adıyla başarısız oluyor.
Nasıl onaylanır:
docker compose exec app ping -c 3 db
docker compose exec app getent hosts db
docker network inspect travellistDüzeltmeler:
Hizmetlerin
docker-compose.ymldosyasında aynı ağı paylaştığını doğrulayın (her ikisi detravellist'i referans göstermelidir).Eğer servis adlarını veya ağ adlarını değiştirdiyseniz,
DB_HOSTve Nginx upstreamlerini buna göre güncelleyin.Ağı yeniden oluştur (bu geçici konteynerleri yok eder, dikkatli olun):
docker compose down docker network prune # optional and destructive docker compose up -d
Faydalı tanı komutları
Bunları hedefli inceleme için çalıştırın:
Çalışan konteynerleri ve portları göster:
docker compose psBir hizmet için son kayıtlar:
docker compose logs -f --tail=200 nginxBir konteyner içinde bir shell çalıştırın:
docker compose exec app sh docker compose exec db bashKonteyner ortam değişkenlerini inceleyin:
docker compose exec app env | sort docker compose exec db env | grep MYSQLKonteyner işlem listesini kontrol et:
docker compose exec app ps aux docker compose exec app ss -ltnpMySQL sağlığını kontrol et:
docker compose exec db mysqladmin -u"${DB_USERNAME}" -p"${DB_PASSWORD}" ping
Hata ayıklama için ana bilgisayar portları ne zaman açılmalı
Varsayılan olarak bu kurulumdaki db servisi host portlarına bağlı değildir. Portları yalnızca yerel hata ayıklama için açın. MySQL'i geçici olarak host üzerinde açmak için docker-compose.yml dosyasında db altına ekleyin:
ports:
- "3306:3306"Sonra yeniden başlat:
docker compose up -d dbHata ayıklamadan sonra, veritabanını ağa açmamak için ports eşlemesini kaldırın.
SSS
1. Ana bilgisayarda Composer kurulması gerekiyor mu?
Hayır. Composer’ı tamamen uygulama konteyneri içinde çalıştırabilirsiniz; bu, bu Compose iş akışı için önerilen yaklaşımdır. Kılavuzdaki Dockerfile Composer’ı içeriyor, bu yüzden docker compose exec app composer install veya docker compose run --rm app composer require vendor/package gibi komutları çalıştırın. Composer’ı konteyner içinde çalıştırmak, doğru PHP sürümü ve eklentilerin kullanılmasını sağlar ve ana sistemde uyumsuz sahipliklere sahip vendor dosyalarının oluşmasını engeller.
2. Laravel göçlerini kapsayıcı içinden çalıştırabilir miyim?
Evet. Migration işlemlerini uygulama konteynerinden çalıştırın, böylece uygulamanızla aynı çalışma zamanı ve ağı kullanırlar: docker compose exec app php artisan migrate. Tek seferlik veya CI görevleri için docker compose run --rm app php artisan migrate --force komutunu kullanabilirsiniz. Migration'ları çalıştırmadan önce, veritabanı konteynerinin sağlıklı olduğundan ve bağlantıları kabul ettiğinden emin olun; örneğin docker compose exec db mysqladmin -u$ {DB_USERNAME} -p$ {DB_PASSWORD} ping komutuyla veya yanıt verene kadar tekrar deneyerek.
3. Ek PHP uzantılarını nasıl yüklerim?
Gerekli sistem paketlerini ve uzantı komutlarını Dockerfile'a ekleyin, ardından imajı yeniden oluşturun. Örneğin, bağımlılıkları yüklemek ve yaygın uzantıları derlemek için şunları kullanabilirsiniz:
RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev \
&& docker-php-ext-configure gd --with-jpeg \
&& docker-php-ext-install pdo_mysql mbstring gdBir PECL uzantısına ihtiyacınız varsa pecl install ve docker-php-ext-enable kullanın. Dockerfile’ı düzenledikten sonra değişiklikleri uygulamak için docker compose build app ve ardından docker compose up -d app komutlarını çalıştırın.
4. Nginx konteynerini HTTPS için nasıl açabilirim?
Nginx konfigürasyonunuza bir HTTPS sunucu bloğu ekleyin, sertifikanızı ve anahtarınızı konteynıra bağlayın ve docker-compose'ta 443 numaralı portu yayınlayın. İşte docker-compose.yml dosyasında minimal değişikliklerle bir örnek:
services:
nginx:
ports:
- "8000:80"
- "443:443"
volumes:
- ./docker-compose/nginx:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs:roDaha sonra /etc/nginx/certs/fullchain.pem ve /etc/nginx/certs/privkey.pem dosyalarını referans alan bir SSL sunucu bloğu ekleyin. Üretim ortamında, özel anahtarları uygulama katmanında saklamak yerine sertifikaları güvenli bir şekilde almak ve yenilemek için Traefik gibi bir ters proxy veya sertifika yöneticisi ya da harici bir yük dengeleyici kullanın.
5. Kod değişikliklerinden sonra Laravel'i nasıl yeniden oluşturabilirim?
Ne değiştiğine bağlı. Proje dizini için bind mount kullanıyorsanız, PHP, şablonlar, rotalar ve kontrollerde yapılan değişiklikler hemen yansır; gerekirse Laravel önbelleğini temizleyin, örneğin:
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear
docker compose exec app php artisan view:clearEğer composer bağımlılıklarını veya Dockerfile’ı (yeni eklentiler veya sistem paketleri) değiştirdiyseniz, yeniden yükleyin veya yeniden oluşturun: Bağımlılık değişiklikleri için docker compose exec app composer install, Dockerfile değişiklikleri için docker compose build app && docker compose up -d. PHP-FPM veya Nginx yapılandırmasını değiştirdiğinizde etkilenen servisi yeniden başlatın: docker compose restart app veya docker compose restart nginx.
Sonuç
Bu rehberde, altyapımızı bir YAML dosyasında tanımlamak için Docker Compose kullanarak üç konteynerli bir Docker ortamı kurduk.
Bu noktadan itibaren, Laravel uygulamanız üzerinde geliştirme ve test için yerel bir web sunucusu kurmanıza ve ayarlamanıza gerek duymadan çalışabilirsiniz. Ayrıca, kolayca çoğaltılabilen ve dağıtılabilen geçici bir ortamla çalışıyor olacaksınız; bu durum, uygulamanızı geliştirirken ve üretim ortamına geçerken faydalı olabilir.
Daha fazla Laravel eğitimi için, aşağıdaki makalelere göz atın:
- Laravel uygulamanızı Linux-Console.net üzerinde barındırın
- Ubuntu'da Nginx ile Laravel Nasıl Kurulur ve Yapılandırılır (LEMP Yığını)
- Laravel Eloquent API Kaynakları ile Modelleri JSON'a Dönüştürme Nasıl Yapılır
- Docker Compose ile Yeni Bir Laravel Uygulamasını Başlatma
Linux-Console.net Topluluğu ile öğrenme sürecine katıldığınız için teşekkürler.

