Bu örnek Nginx, MySQL ve PHP-FPM docker container (debian:stretch-slim) kullanarak Symfony uygulamasını geliştirme DEV ortamında çalıştırılabilir hale getirir ve sadece en basidinden gerekli olan modüller yüklüdür yani gereksinimlerinize göre ayarlama yapabilirsiniz. Tüm yapmanız gereken aşağıdaki docker klasörünü ve Symfony uygulamanızın içine kopyalamak ve symfony/docker klasörü içindeyken docker-compose up -d komutunu çalıştırmaktır. Bu kadar!


Timezone


Her ne kadar ayarlar kendi gereksinimlerinize bağlı olsa da, sunucular için en güvenli zaman dilimi DST (Günışığı Tasarrufu) bağımlı olanlardan ziyade UTC'dir. Aşağıdaki örnekte Europe/London olarak ayarlıyorum (GMT - bu bir DST'dir), ama isterseniz tüm bu satırları kaldırabilir veya yalnızca UTC ile değiştirebilirsiniz.


Yapı


$ tree -a
.
└── dev
├── docker-compose.yml
├── .env
├── mysql
│ ├── Dockerfile
│ └── mysqld.cnf
├── nginx
│ ├── app.conf
│ ├── Dockerfile
│ └── nginx.conf
└── php
├── Dockerfile
├── php.ini
└── www.conf

Dosyalar


.env


COMPOSE_PROJECT_NAME=inanzzz
REPOSITORY_NAME=dsa
IMAGE_TAG=latest

MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=dsa

docker-compose.yml


version: '3'

services:

dsa_mysql:
build:
context: ./mysql
image: '${COMPOSE_PROJECT_NAME}/${REPOSITORY_NAME}_mysql:${IMAGE_TAG}'
container_name: '${REPOSITORY_NAME}_mysql'
hostname: '${REPOSITORY_NAME}-mysql'
volumes:
- ./mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf:ro
- ../../var/log/docker/mysql:/var/log/mysql:consistent
environment:
MYSQL_DATABASE: '${MYSQL_DATABASE}'
MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD}'

dsa_php:
build:
context: ./php
image: '${COMPOSE_PROJECT_NAME}/${REPOSITORY_NAME}_php:${IMAGE_TAG}'
container_name: '${REPOSITORY_NAME}_php'
hostname: '${REPOSITORY_NAME}-php'
volumes:
- ../..:/app:consistent
- ./php/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
- ./php/php.ini:/usr/local/etc/php/conf.d/php.override.ini:ro
working_dir: /app

dsa_nginx:
build:
context: ./nginx
image: '${COMPOSE_PROJECT_NAME}/${REPOSITORY_NAME}_nginx:${IMAGE_TAG}'
container_name: '${REPOSITORY_NAME}_nginx'
hostname: '${REPOSITORY_NAME}-nginx'
ports:
- '8081:80'
volumes:
- ../..:/app:consistent
- ./nginx/app.conf:/etc/nginx/conf.d/default.conf:ro
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ../../var/log/docker/nginx:/var/log/nginx:consistent
depends_on:
- dsa_mysql
- dsa_php

docker/mysql/Dockerfile


# debian:stretch-slim
FROM mysql:5.7.24

# Timezone
RUN ln -snf /usr/share/zoneinfo/Europe/London /etc/localtime \
&& echo Europe/London > /etc/timezone
#

docker/mysql/mysqld.cnf


[mysqld]

pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
symbolic-links=0

character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci

explicit_defaults_for_timestamp=1

; LOGS
; General Query Log
general_log_file=/var/log/mysql/general_query.log
general_log=1
; Slow Query Logs
slow_query_log=1
long_query_time=1 #seconds
slow_query_log_file=/var/log/mysql/slow_query.log
log_queries_not_using_indexes=0
; Error Log
log_error=/var/log/mysql/error.log
[mysqld_safe]
log_error=/var/log/mysql/error.log

docker/nginx/Dockerfile


# debian:stretch-slim
FROM nginx:1.15.7

# Timezone
RUN ln -snf /usr/share/zoneinfo/Europe/London /etc/localtime \
&& echo Europe/London > /etc/timezone
#

docker/nginx/app.conf


server {
listen 80 default_server;

server_name localhost;

root /app/public;

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

location ~ ^/index\.php(/|$) {
fastcgi_pass dsa_php:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_hide_header X-Powered-By;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}

location ~ \.php$ {
return 404;
}

error_log /var/log/nginx/app_error.log;
access_log /var/log/nginx/app_access.log;
}

docker/nginx/nginx.conf


user nginx;

# 1 worker process per CPU core.
# Check max: $ grep processor /proc/cpuinfo | wc -l
worker_processes 2;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
# Tells worker processes how many people can be served simultaneously.
# worker_process (2) * worker_connections (2048) = 4096
# Check max: $ ulimit -n
worker_connections 2048;

# Connection processing method. The epoll is efficient method used on Linux 2.6+
use epoll;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

# Used to reduce 502 and 504 HTTP errors.
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

# The sendfile allows transfer data from a file descriptor to another directly in kernel.
# Combination of sendfile and tcp_nopush ensures that the packets are full before being sent to the client.
# This reduces network overhead and speeds the way files are sent.
# The tcp_nodelay forces the socket to send the data.
sendfile on;
tcp_nopush on;
tcp_nodelay on;

# The client connection can stay open on the server up to given seconds.
keepalive_timeout 65;

# Hides Nginx server version in headers.
server_tokens off;

# Disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;

# Enables the Cross-site scripting (XSS) filter built into most recent web browsers.
# If user disables it on the browser level, this role re-enables it automatically on serve level.
add_header X-XSS-Protection '1; mode=block';

# Prevent the browser from rendering the page inside a frame/iframe to avoid clickjacking.
add_header X-Frame-Options DENY;

# Enable HSTS to prevent SSL stripping.
add_header Strict-Transport-Security 'max-age=31536000; includeSubdomains; preload';

# Prevent browser sending the referrer header when navigating from HTTPS to HTTP.
add_header 'Referrer-Policy' 'no-referrer-when-downgrade';

# Sets the maximum size of the types hash tables.
types_hash_max_size 2048;

# Compress files on the fly before transmitting.
# Compressed files are then decompressed by the browsers that support it.
gzip on;

include /etc/nginx/conf.d/*.conf;
}

docker/php/Dockerfile


# debian:stretch-slim
FROM php:7.2.13-fpm

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
locales \
git \
zip \
unzip \
&& pecl install xdebug

# PHP extensions
RUN docker-php-ext-install opcache pdo_mysql mysqli
RUN docker-php-ext-enable opcache xdebug
#

# Timezone
RUN ln -snf /usr/share/zoneinfo/Europe/London /etc/localtime \
&& echo Europe/London > /etc/timezone
#

# Language
RUN sed -i 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/g' /etc/locale.gen \
&& locale-gen en_GB.UTF-8

ENV LC_ALL en_GB.UTF-8
ENV LANG en_GB.UTF-8
ENV LANGUAGE en_GB:en
#

# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
#

# Composer parallel install plugin
RUN composer global require hirak/prestissimo
#

RUN apt-get autoremove --purge \
&& apt-get -y clean \
&& rm -rf /var/lib/apt/lists/*

CMD ["php-fpm", "--nodaemonize"]

docker/php/php.ini


[PHP]
date.timezone=Europe/London
log_errors=On
error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors=Off
max_execution_time=60
memory_limit=256M

[opcache]
; http://symfony.com/doc/current/performance.html
opcache.enable_cli=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
realpath_cache_size=4096K
realpath_cache_ttl=600

docker/php/www.conf


[global]
daemonize=no

[www]

user=www-data
group=www-data

listen=dsa_nginx:9000

; Dynamicaly chooses how the process manager will control the number of child processes.
pm=dynamic
; The maximum number of child processes to be created.
; This option sets the limit on the number of simultaneous requests that will be served.
; Availalbe RAM in MB / Average RAM used by php-fpm processes in MB=max_children
; 1500MB / 30MB=50 (minus a bit)
pm.max_children=40
; The number of child processes created on startup.
; min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers=2
; The desired minimum number of idle server processes.
pm.min_spare_servers=2
; The desired maximum number of idle server processes.
; 2 or 4 times of the CPU core
pm.max_spare_servers=4
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries.
pm.max_requests=500

Kurulum


$ docker-compose up -d --build

Test


Sadece curl http://localhost:8081 komutunu çalıştırın.


Loglar


Docker servis (Nginx, PHP-FPM and MySQL) loglarına Symfony uygulamasının var/log/docker klasöründen ulaşabilirsiniz.


Kurulum bilgisi


İmajlar


$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
inanzzz/dsa_php latest 6f0517c2fd66 17 minutes ago 469MB
inanzzz/dsa_nginx latest 84839a63faba About an hour ago 109MB
inanzzz/dsa_mysql latest 5752774a18bd About an hour ago 372MB
php 7.2.13-fpm 2bd622691e6e 5 days ago 371MB
nginx 1.15.7 568c4670fa80 2 weeks ago 109MB
mysql 5.7.24 ae6b78bedf88 4 weeks ago 372MB

Containerlar


$ docker ps
CONTAINER ID IMAGE COMMAND PORTS NAMES
dc072b8092c0 inanzzz/dsa_nginx:latest "nginx -g 'daemon of…" 0.0.0.0:8081->80/tcp dsa_nginx
0eeaad647c01 inanzzz/dsa_php:latest "docker-php-entrypoi…" 9000/tcp dsa_php
4ccfe75c4d3e inanzzz/dsa_mysql:latest "docker-entrypoint.s…" 3306/tcp, 33060/tcp dsa_mysql


$ docker network ls
NETWORK ID NAME DRIVER SCOPE
87542b88228e inanzzz_default bridge local