01/06/2018 - DOCKER, SYMFONY, NGINX
Bu örnek Nginx, MySQL ve PHP-FPM docker container kullanarak Symfony uygulamasını çalıştırılabilir hale getirir. Tüm yapmanız gereken aşağıdaki dosyaları yaratmak ve Symfony uygulamanızı içine kopyalamaktır veya tam tersi. Bu işlemden sonra docker-compose komutu ile sistemi çalıştırabilirsiniz. Bu kadar!
Bu yazının en sonunda alternatif bir yapı sürümüne daha var ve bakmanızı tavsiye ederim.
$ tree -a
.
├── docker
│ ├── mysql
│ │ ├── Dockerfile
│ │ ├── init.sh
│ │ └── mysqld.cnf
│ ├── nginx
│ │ ├── default.conf
│ │ ├── Dockerfile
│ │ └── nginx.conf
│ └── php
│ ├── app.sh
│ ├── Dockerfile
│ ├── init.sh
│ ├── install.sh
│ ├── php.ini
│ └── www.conf
├── docker-compose.yml
├── public # You can remove this
│ └── index.php
├── .env
└── .env.dist # Create a .env file from this
###> symfony ###
APP_ENV=dev
APP_SECRET=secret
APP_DB_USER=user
APP_DB_PASS=pass
###< symfony ###
###> docker ###
MYSQL_ROOT_PASSWORD=root
###< docker ###
php
servisini aşağıda gösterildiği gibi tanımlamak, size uygulama içindeki diğer yapılandırma dosyalarını container içine kopyalamanıza yardımcı olur. Örneğin app/config
klasöründen bir dosya.
version: '3'
services:
mysql:
build:
context: ./docker/mysql
hostname: nginx
user: mysql
ports:
- 3306:3306
volumes:
- ./var/database:/var/lib/mysql:rw
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
APP_DB_USER: ${APP_DB_USER}
APP_DB_PASS: ${APP_DB_PASS}
php:
build:
context: ../symfony4-docker-platform
dockerfile: ./docker/php/Dockerfile
args:
APP_ENV: ${APP_ENV}
hostname: php
depends_on:
- mysql
ports:
- 9000:9000
volumes:
- .:/app:cached
working_dir: /app
environment:
APP_ENV: ${APP_ENV}
APP_SECRET: ${APP_SECRET}
APP_DB_USER: ${APP_DB_USER}
APP_DB_PASS: ${APP_DB_PASS}
nginx:
build:
context: ./docker/nginx
hostname: nginx
depends_on:
- mysql
- php
ports:
- 80:80
volumes:
- .:/app:cached
FROM mysql:5.7.22
COPY init.sh /docker-entrypoint-initdb.d
COPY mysqld.cnf /etc/mysql/mysql.conf.d
#!/bin/bash
printf "\n\033[0;44mPreparing the database\033[0m\n"
# Makes sure that the database is up before running database queries
echo "Checking if the database is up ..."
while ! mysqladmin ping -h"localhost" --silent; do
echo "Waiting for database to come up ..."
sleep 2
done
echo "Database is up ..."
# Create an application specific non-root user with all privileges
create="CREATE USER IF NOT EXISTS '${APP_DB_USER}'@'%' IDENTIFIED BY '${APP_DB_PASS}';"
grant="GRANT ALL PRIVILEGES ON *.* TO '${APP_DB_USER}'@'%' IDENTIFIED BY '${APP_DB_PASS}' WITH GRANT OPTION;"
mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "$create$grant"
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
symbolic-links = 0
character_set_server=utf8
collation_server=utf8_unicode_ci
explicit_defaults_for_timestamp = 1
FROM nginx:1.13.8
COPY default.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx
server {
listen 80 default_server;
server_name localhost; # OR app.com www.app.com
root /app/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass 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;
}
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;
}
FROM php:7.2-fpm
ARG APP_ENV
COPY ./docker/php/init.sh /tmp
RUN chmod +x /tmp/init.sh
RUN /tmp/init.sh
COPY ./docker/php/install.sh /tmp
RUN chmod +x /tmp/install.sh
RUN /tmp/install.sh
COPY ./docker/php/www.conf /usr/local/etc/php-fpm.d/www.conf.default
COPY ./docker/php/php.ini /usr/local/etc/php/conf.d
COPY ./docker/php/app.sh /
RUN chmod +x /app.sh
RUN /app.sh
ENV LANG en_GB.UTF-8
ENV LANGUAGE en_GB:en
ENV LC_ALL en_GB.UTF-8
RUN apt-get autoremove --purge \
&& apt-get -y clean \
&& rm -rf /var/lib/apt/lists/*
[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
[www]
user = www-data
group = www-data
listen = 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
#!/bin/bash
printf "\n\033[0;44mChecking the existence of 'APP_ENV' variable\033[0m\n"
if [[ -z "${APP_ENV}" ]]
then
printf "\033[0;31mVariable does not exist.\033[0m\n\n"
exit 1;
fi
printf "\033[0;32mVariable exists.\033[0m\n\n"
#!/bin/bash
printf "\n\033[0;44mInstalling system packages for the \"${APP_ENV}\" environment\033[0m\n"
apt-get update
apt-get install -y --no-install-recommends zip unzip nano tree locales
sed -i 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/g' /etc/locale.gen
ln -s /etc/locale.alias /usr/share/locale/locale.alias
locale-gen en_GB.UTF-8
ln -snf /usr/share/zoneinfo/Europe/London /etc/localtime
echo Europe/London > /etc/timezone
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
docker-php-ext-install opcache pdo_mysql
docker-php-ext-enable opcache
if [ "${APP_ENV}" == "dev" ] || [ "${APP_ENV}" == "test" ]
then
pecl install xdebug
docker-php-ext-enable xdebug
fi
#!/bin/bash
printf "\n\033[0;44mPreparing the application for the \"${APP_ENV}\" environment\033[0m\n"
if [ "${APP_ENV}" == "dev" ] || [ "${APP_ENV}" == "test" ]
then
echo "Run symfony commands for \"dev\" or \"test\" environments"
# composer install --no-interaction
else
echo "Run symfony commands for \"prod\" or \"stag\" environments"
# composer install --no-interaction --no-dev --optimize-autoloader
fi
echo "Run symfony commands for all environments"
# bin/console doctrine:migrations:migrate --no-interaction
# ...
printf "\n\033[0;44mBringing the \"${APP_ENV}\" environment up\033[0m\n"
$ docker-compose up -d --build
Önce IP adresini almak için aşağıdaki komutu çalıştırın.
$ echo $(docker network inspect {your-network-name-goes-here} | grep Gateway | grep -o -E '[0-9\.]+')
172.18.0.1
$ curl 172.18.0.1 # Or localhost
# You should get a nice response
.
├── app # Symfony application goes in here
│ └── public
│ └── index.php
├── docker
│ ├── mysql
│ │ ├── Dockerfile
│ │ ├── init.sh
│ │ └── mysqld.cnf
│ ├── nginx
│ │ ├── default.conf
│ │ ├── Dockerfile
│ │ └── nginx.conf
│ └── php
│ ├── Dockerfile
│ ├── init.sh
│ ├── install.sh
│ ├── php.ini
│ └── www.conf
├── .env
├── .env.dist # Create a .env file from this
└── docker-compose.yml
version: '3'
services:
mysql:
build:
context: ./docker/mysql
hostname: nginx
user: mysql
ports:
- 3306:3306
volumes:
- ./data/database:/var/lib/mysql:rw
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
APP_DB_USER: ${APP_DB_USER}
APP_DB_PASS: ${APP_DB_PASS}
php:
build:
context: ../api-doc
dockerfile: ./docker/php/Dockerfile
args:
APP_ENV: ${APP_ENV}
hostname: php
ports:
- 9000:9000
depends_on:
- mysql
volumes:
- ./app:/app:cached
working_dir: /app
environment:
APP_ENV: ${APP_ENV}
APP_DB_USER: ${APP_DB_USER}
APP_DB_PASS: ${APP_DB_PASS}
nginx:
build:
context: ./docker/nginx
hostname: nginx
ports:
- 80:80
depends_on:
- mysql
- php
volumes:
- ./app:/app:cached