├── .gitignore ├── doc ├── schema.png ├── schema.pptx └── custom.md ├── elk └── logstash │ ├── patterns │ ├── nginx.conf │ ├── symfony.conf │ └── default.conf │ └── logstash.conf ├── nginx ├── Dockerfile ├── nginx.conf └── symfony.conf ├── .travis.yml ├── LICENSE ├── docker-compose.yml ├── .env.dist ├── php7-fpm └── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /logs 2 | /.data 3 | .env 4 | /.idea -------------------------------------------------------------------------------- /doc/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjherraiz/docker-symfony-4/HEAD/doc/schema.png -------------------------------------------------------------------------------- /doc/schema.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjherraiz/docker-symfony-4/HEAD/doc/schema.pptx -------------------------------------------------------------------------------- /elk/logstash/patterns/nginx.conf: -------------------------------------------------------------------------------- 1 | NGINXACCESS %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{URIPATHPARAM:request}(?: HTTP/%{NUMBER:httpversion})?|-)" %{NUMBER:response} (?:%{NUMBER:bytes}|-) "(?:%{URI:referrer}|-)" %{QS:agent} %{NUMBER:request_time} %{NUMBER:upstream_response_time} %{NUMBER:gzip_ratio} (?:%{WORD:cache_hit}|-)%{GREEDYDATA} -------------------------------------------------------------------------------- /nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie 2 | 3 | MAINTAINER Maria Jose Herraiz 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | nginx 7 | 8 | ADD nginx.conf /etc/nginx/ 9 | ADD symfony.conf /etc/nginx/sites-available/ 10 | 11 | RUN ln -s /etc/nginx/sites-available/symfony.conf /etc/nginx/sites-enabled/symfony 12 | RUN rm /etc/nginx/sites-enabled/default 13 | 14 | RUN echo "upstream php-upstream { server php:9000; }" > /etc/nginx/conf.d/upstream.conf 15 | 16 | RUN usermod -u 1000 www-data 17 | 18 | CMD ["nginx"] 19 | 20 | EXPOSE 80 21 | EXPOSE 443 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | env: 4 | DOCKER_COMPOSE_VERSION: 1.8.1 5 | 6 | services: 7 | - docker 8 | 9 | before_install: 10 | - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose 11 | - chmod +x docker-compose 12 | - sudo mv docker-compose /usr/local/bin 13 | - docker-compose -v 14 | - docker -v 15 | # symfony application folder 16 | - mkdir symfony 17 | - cp .env.dist .env 18 | - cat docker-compose.yml 19 | 20 | script: 21 | - docker-compose build 22 | - docker-compose up -d 23 | - docker-compose ps 24 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes 4; 3 | pid /run/nginx.pid; 4 | 5 | events { 6 | worker_connections 2048; 7 | multi_accept on; 8 | use epoll; 9 | } 10 | 11 | http { 12 | server_tokens off; 13 | sendfile on; 14 | tcp_nopush on; 15 | tcp_nodelay on; 16 | keepalive_timeout 15; 17 | types_hash_max_size 2048; 18 | include /etc/nginx/mime.types; 19 | default_type application/octet-stream; 20 | access_log off; 21 | error_log off; 22 | gzip on; 23 | gzip_disable "msie6"; 24 | include /etc/nginx/conf.d/*.conf; 25 | include /etc/nginx/sites-enabled/*; 26 | open_file_cache max=100; 27 | } 28 | 29 | daemon off; 30 | -------------------------------------------------------------------------------- /elk/logstash/logstash.conf: -------------------------------------------------------------------------------- 1 | input { 2 | file { 3 | type => "nginx_access" 4 | path => "/var/log/nginx/symfony_access.log" 5 | start_position => beginning 6 | } 7 | file { 8 | type => "symfony_dev" 9 | path => "/var/www/symfony/var/log/dev.log" 10 | start_position => beginning 11 | } 12 | file { 13 | type => "symfony_prod" 14 | path => "/var/www/symfony/var/log/prod.log" 15 | start_position => beginning 16 | } 17 | } 18 | 19 | filter { 20 | if [type] == "nginx_access" { 21 | grok { 22 | patterns_dir => "./patterns" 23 | match => { "message" => "%{NGINXACCESS}"} 24 | } 25 | } 26 | else if [type] in ["symfony_dev", "symfony_prod"] { 27 | grok { 28 | patterns_dir => "./patterns" 29 | match => { "message" => "%{SYMFONY}"} 30 | } 31 | } 32 | } 33 | 34 | output { 35 | elasticsearch { 36 | host => "localhost" 37 | cluster => "logstash" 38 | } 39 | } -------------------------------------------------------------------------------- /nginx/symfony.conf: -------------------------------------------------------------------------------- 1 | server { 2 | server_name $VIRTUAL_HOST; 3 | root /var/www/symfony/public; 4 | 5 | location / { 6 | try_files $uri /index.php$is_args$args; 7 | } 8 | 9 | location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|eof|woff|ttf)$ { 10 | if (-f $request_filename) { 11 | expires 30d; 12 | access_log off; 13 | } 14 | } 15 | 16 | location ~ ^/index\.php(/|$) { 17 | fastcgi_pass php-upstream; 18 | fastcgi_split_path_info ^(.+\.php)(/.*)$; 19 | include fastcgi_params; 20 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 21 | fastcgi_param HTTPS off; 22 | } 23 | 24 | 25 | # return 404 for all other php files not matching the front controller 26 | # this prevents access to other php files you don't want to be accessible. 27 | location ~ \.php$ { 28 | return 404; 29 | } 30 | 31 | error_log /var/log/nginx/symfony_error.log; 32 | access_log /var/log/nginx/symfony_access.log; 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Maria Jose Herraiz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /doc/custom.md: -------------------------------------------------------------------------------- 1 | # How to customise this stack 2 | 3 | * [Add PHPMyAdmin](#Add-phpmyadmin) 4 | * [Add Redis](#Add-redis) 5 | 6 | ## Add PHPMyAdmin 7 | 8 | 1. Update docker-compose.yml file and add the following lines: 9 | 10 | ```yml 11 | service: 12 | # ... 13 | phpmyadmin: 14 | image: phpmyadmin/phpmyadmin 15 | ports: 16 | - "8080:80" 17 | ``` 18 | 19 | 2. Visit: [symfony.dev:8080](http://symfony.dev:8080) 20 | 21 | ## Add Redis 22 | 23 | 1. Update docker-compose.yml file and add the following lines: 24 | 25 | ```yml 26 | service: 27 | # ... 28 | redis: 29 | image: redis:alpine 30 | ports: 31 | - 6379:6379 32 | ``` 33 | 34 | 2. Adapt your Symfony configuration file 35 | 36 | ```yml 37 | # path/to/your/symfony-project/app/config/parameters.yml 38 | parameters: 39 | #... 40 | redis_host: redis 41 | ``` 42 | 43 | :question: Using [SncRedis](https://github.com/snc/SncRedisBundle)? 44 | Your Symfony config file should be like this: 45 | 46 | ```yml 47 | snc_redis: 48 | clients: 49 | default: 50 | type: predis 51 | alias: default 52 | dsn: redis://%redis_host% 53 | ``` 54 | 55 | Access to redis-cli with: 56 | 57 | ```bash 58 | # Redis commands 59 | $ docker-compose exec redis redis-cli 60 | ``` 61 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | db: 5 | image: mysql 6 | volumes: 7 | - "./.data/db:/var/lib/mysql" 8 | environment: 9 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} 10 | MYSQL_DATABASE: ${MYSQL_DATABASE} 11 | MYSQL_USER: ${MYSQL_USER} 12 | MYSQL_PASSWORD: ${MYSQL_PASSWORD} 13 | php: 14 | build: 15 | context: php7-fpm 16 | args: 17 | TIMEZONE: ${TIMEZONE} 18 | volumes: 19 | - ${SYMFONY_APP_PATH}:/var/www/symfony 20 | - ./logs/symfony:/var/www/symfony/var/log 21 | environment: 22 | APP_ENV: ${APP_ENV} 23 | APP_DEBUG: ${APP_DEBUG} 24 | APP_SECRET: ${APP_SECRET} 25 | DATABASE_URL: ${DATABASE_URL} 26 | MAILER_URL: ${MAILER_URL} 27 | links: 28 | - mailcatcher 29 | nginx: 30 | build: nginx 31 | ports: 32 | - 80:80 33 | volumes_from: 34 | - php 35 | volumes: 36 | - ./logs/nginx/:/var/log/nginx 37 | elk: 38 | image: willdurand/elk 39 | ports: 40 | - 81:80 41 | volumes: 42 | - ./elk/logstash:/etc/logstash 43 | - ./elk/logstash/patterns:/opt/logstash/patterns 44 | volumes_from: 45 | - php 46 | - nginx 47 | mailcatcher: 48 | image: yappabe/mailcatcher 49 | ports: 50 | - 1025:1025 51 | - 1080:1080 52 | -------------------------------------------------------------------------------- /.env.dist: -------------------------------------------------------------------------------- 1 | # Symfony application's path (absolute or relative) 2 | SYMFONY_APP_PATH=../path/to/symfony/folder 3 | VIRTUAL_HOST=symfony.localhost 4 | 5 | # MySQL 6 | MYSQL_ROOT_PASSWORD=root 7 | MYSQL_DATABASE=mydb 8 | MYSQL_USER=user 9 | MYSQL_PASSWORD=userpass 10 | 11 | # Timezone 12 | TIMEZONE=Europe/Paris 13 | 14 | # This file is a "template" of which env vars needs to be defined in your configuration or in an .env file 15 | # Set variables here that may be different on each deployment target of the app, e.g. development, staging, production. 16 | # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration 17 | 18 | ###> symfony/framework-bundle ### 19 | APP_ENV=dev 20 | APP_DEBUG=1 21 | APP_SECRET=67d829bf61dc5f87a73fd814e2c9f629 22 | ###< symfony/framework-bundle ### 23 | 24 | ###> doctrine/doctrine-bundle ### 25 | # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url 26 | # For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db" 27 | # Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls 28 | #DATABASE_URL=mysql://user:userpass@db:3306/mydb 29 | DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/blog.sqlite 30 | ###< doctrine/doctrine-bundle ### 31 | 32 | ###> symfony/swiftmailer-bundle ### 33 | # For Gmail as a transport, use: "gmail://username:password@localhost" 34 | # For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" 35 | # Delivery is disabled by default via "null://localhost" 36 | MAILER_URL=smtp://mailcatcher:1025 37 | ###< symfony/swiftmailer-bundle ### 38 | 39 | -------------------------------------------------------------------------------- /php7-fpm/Dockerfile: -------------------------------------------------------------------------------- 1 | # See https://github.com/docker-library/php/blob/master/7.1/fpm/Dockerfile 2 | FROM php:7.1-fpm 3 | ARG TIMEZONE 4 | 5 | MAINTAINER Maria Jose Herraiz 6 | 7 | RUN apt-get update && apt-get install -y \ 8 | openssl \ 9 | git \ 10 | unzip \ 11 | vim 12 | 13 | # Install Composer 14 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 15 | RUN composer --version 16 | 17 | # Set timezone 18 | RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone 19 | RUN printf '[PHP]\ndate.timezone = "%s"\n', ${TIMEZONE} > /usr/local/etc/php/conf.d/tzone.ini 20 | RUN "date" 21 | 22 | # Type docker-php-ext-install to see available extensions 23 | RUN docker-php-ext-install pdo pdo_mysql 24 | 25 | # Install Node 26 | RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - 27 | RUN apt-get install -y nodejs 28 | 29 | RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 30 | RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list 31 | RUN apt-get update && apt-get install yarn 32 | 33 | RUN yarn add webpack --dev 34 | 35 | # install xdebug 36 | RUN pecl install xdebug 37 | RUN docker-php-ext-enable xdebug 38 | RUN echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 39 | RUN echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 40 | RUN echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 41 | RUN echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 42 | RUN echo "xdebug.remote_connect_back=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 43 | RUN echo "xdebug.idekey=\"PHPSTORM\"" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 44 | RUN echo "xdebug.remote_port=9001" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 45 | 46 | RUN echo 'alias sf="php bin/console"' >> ~/.bashrc 47 | 48 | RUN mkdir -p /var/www/symfony/var/cache 49 | RUN mkdir -p /var/www/symfony/var/log 50 | 51 | WORKDIR /var/www/symfony 52 | 53 | RUN usermod -u 1000 www-data 54 | RUN chown -R www-data:www-data /var/www/symfony/var/cache 55 | RUN chown -R www-data:www-data /var/www/symfony/var/log 56 | -------------------------------------------------------------------------------- /elk/logstash/patterns/symfony.conf: -------------------------------------------------------------------------------- 1 | VERYGREEDYDATA (.|\n)* 2 | 3 | SYMFONY_EXCEPTION [^:]* 4 | 5 | SYMFONY_LOG_TYPE request|security|app|profiler|doctrine|event 6 | SYMFONY_LOG_LEVEL DEBUG|INFO|WARNING|ERROR|CRITICAL|ALERT 7 | SYMFONY_LOG %{SYMFONY_LOG_TYPE:log_type}\.%{SYMFONY_LOG_LEVEL:log_level} 8 | 9 | SYMFONY_PARAMETER "[^"]*":( )?"[^"]*" 10 | SYMFONY_PARAMETERS (%{SYMFONY_PARAMETER}(, )?)* 11 | SYMFONY_CONTEXT {.*} 12 | SYMFONY_REQUEST_METHOD GET|POST|PUT|DELETE|HEAD|OPTIONS|CONNECT 13 | SYMFONY_REQUEST_PARAMETERS {"url":"%{GREEDYDATA:request_url}","ip":"%{IP:request_ip}","http_method":"%{SYMFONY_REQUEST_METHOD:request_method}"} 14 | 15 | SYMFONY_REQUEST_INFO Matched route "%{GREEDYDATA:route}" \(parameters: %{SYMFONY_PARAMETERS:parameters}\) 16 | SYMFONY_REQUEST_UNCAUGHT_EXCEPTION %{SYMFONY_EXCEPTION:exception}: %{VERYGREEDYDATA:exception_message} \(uncaught exception\) at %{VERYGREEDYDATA:exception_file} line %{NUMBER:exception_file_line} 17 | SYMFONY_REQUEST_CRITICAL Exception thrown when handling an exception \(ErrorException: %{GREEDYDATA:exception_message} in %{GREEDYDATA:exception_file} line %{NUMBER:exception_file_line}\) 18 | SYMFONY_SECURITY_WARNING_USER_MISSING Username "%{GREEDYDATA:user}" could not be found. 19 | SYMFONY_SECURITY_INFO_USER_AUTHENTICATED User "%{GREEDYDATA:user}" has been authenticated successfully 20 | SYMFONY_SECURITY_INFO_AUTHENTICATION_FAILED Authentication request failed: %{GREEDYDATA:authentication_fail_reason} 21 | SYMFONY_SECURITY_DEBUG Username "%{GREEDYDATA:user}" was reloaded from user provider. 22 | SYMFONY_EVENT_DEBUG_NOTIFICATION Notified event "%{GREEDYDATA:event}" to listener "%{GREEDYDATA:listener}". 23 | SYMFONY_EVENT_DEBUG_PROPAGATION_STOP Listener "%{GREEDYDATA:listener}" stopped propagation of the event "%{GREEDYDATA:event}". 24 | SYMFONY_DOCTRINE_DEBUG (?<=doctrine.DEBUG: ).* 25 | 26 | SYMFONY_REQUEST %{SYMFONY_REQUEST_INFO}|%{SYMFONY_REQUEST_UNCAUGHT_EXCEPTION}|%{SYMFONY_REQUEST_CRITICAL} 27 | SYMFONY_SECURITY %{SYMFONY_SECURITY_WARNING_USER_MISSING}|%{SYMFONY_SECURITY_INFO_USER_AUTHENTICATED}|%{SYMFONY_SECURITY_DEBUG}|%{SYMFONY_SECURITY_INFO_AUTHENTICATION_FAILED} 28 | SYMFONY_EVENT %{SYMFONY_EVENT_DEBUG_NOTIFICATION}|%{SYMFONY_EVENT_DEBUG_PROPAGATION_STOP} 29 | SYMFONY_DOCTRINE %{SYMFONY_DOCTRINE_DEBUG:doctrine_sql_query} 30 | SYMFONY_VARIOUS_INFO Write SecurityContext in the session|Reloading user from user provider.|Read SecurityContext from the session|Populated SecurityContext with an anonymous Token|Access is denied (and user is neither anonymous, nor remember-me)|Unable to store the profiler information.|Remember-me cookie accepted. 31 | 32 | SYMFONY_LOG_MESSAGE %{SYMFONY_REQUEST}|%{SYMFONY_SECURITY}|%{SYMFONY_EVENT}|%{SYMFONY_DOCTRINE}|%{SYMFONY_VARIOUS_INFO:log_various_info}|%{VERYGREEDYDATA:log_unparsed_message} 33 | 34 | SYMFONY ^\[%{TIMESTAMP_ISO8601:date}\] %{SYMFONY_LOG}: %{SYMFONY_LOG_MESSAGE:log_message} (\[\]|%{SYMFONY_CONTEXT:log_context}) (\[\]|%{SYMFONY_REQUEST_PARAMETERS:log_request}) -------------------------------------------------------------------------------- /elk/logstash/patterns/default.conf: -------------------------------------------------------------------------------- 1 | USERNAME [a-zA-Z0-9._-]+ 2 | USER %{USERNAME} 3 | INT (?:[+-]?(?:[0-9]+)) 4 | BASE10NUM (?[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))) 5 | NUMBER (?:%{BASE10NUM}) 6 | BASE16NUM (?(?"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``)) 17 | UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12} 18 | # Networking 19 | MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC}) 20 | CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) 21 | WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) 22 | COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}) 23 | IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)? 24 | IPV4 (?/(?>[\w_%!$@:.,-]+|\\.)*)+ 33 | TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+)) 34 | WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+ 35 | URIPROTO [A-Za-z]+(\+[A-Za-z+]+)? 36 | URIHOST %{IPORHOST}(?::%{POSINT:port})? 37 | # uripath comes loosely from RFC1738, but mostly from what Firefox 38 | # doesn't turn into %XX 39 | URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*)+ 40 | #URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? 41 | URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]* 42 | URIPATHPARAM %{URIPATH}(?:%{URIPARAM})? 43 | URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})? 44 | # Months: January, Feb, 3, 03, 12, December 45 | MONTH \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b 46 | MONTHNUM (?:0?[1-9]|1[0-2]) 47 | MONTHNUM2 (?:0[1-9]|1[0-2]) 48 | MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]) 49 | # Days: Monday, Tue, Thu, etc... 50 | DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?) 51 | # Years? 52 | YEAR (?>\d\d){1,2} 53 | HOUR (?:2[0123]|[01]?[0-9]) 54 | MINUTE (?:[0-5][0-9]) 55 | # '60' is a leap second in most time standards and thus is valid. 56 | SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?) 57 | TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9]) 58 | # datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it) 59 | DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR} 60 | DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR} 61 | ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE})) 62 | ISO8601_SECOND (?:%{SECOND}|60) 63 | TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}? 64 | DATE %{DATE_US}|%{DATE_EU} 65 | DATESTAMP %{DATE}[- ]%{TIME} 66 | TZ (?:[PMCE][SD]T|UTC) 67 | DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ} 68 | DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE} 69 | DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR} 70 | DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND} 71 | # Syslog Dates: Month Day HH:MM:SS 72 | SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME} 73 | PROG (?:[\w._/%-]+) 74 | SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])? 75 | SYSLOGHOST %{IPORHOST} 76 | SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}> 77 | HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT} 78 | # Shortcuts 79 | QS %{QUOTEDSTRING} 80 | # Log formats 81 | SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}: 82 | COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) 83 | COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent} 84 | # Log Levels 85 | LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo|INFO|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Symfony 4 (PHP7-FPM - NGINX - MySQL - ELK) 2 | 3 | ![](doc/schema.png) 4 | 5 | Docker-symfony gives you everything you need for developing Symfony 4 application. This complete stack run with docker and [docker-compose (1.7 or higher)](https://docs.docker.com/compose/). 6 | 7 | ## Installation 8 | 9 | 1. Create a `.env` from the `.env.dist` file. Adapt it according to your symfony application 10 | 11 | ```bash 12 | cp .env.dist .env 13 | ``` 14 | 15 | 16 | 2. Build/run containers with (with and without detached mode) 17 | 18 | ```bash 19 | $ docker-compose build 20 | $ docker-compose up -d 21 | ``` 22 | 23 | 3. Update your system host file (add symfony.localhost) 24 | Remember that server name is define in .env file in this demo I use symfony.localhost please replace with your custom server name if you decide to use another one 25 | 26 | ```bash 27 | # UNIX only: get containers IP address and update host (replace IP according to your configuration) (on Windows, edit C:\Windows\System32\drivers\etc\hosts) 28 | $ sudo echo $(docker network inspect bridge | grep Gateway | grep -o -E '[0-9\.]+') "symfony.localhost" >> /etc/hosts 29 | ``` 30 | 31 | **Note:** For **OS X**, please take a look [here](https://docs.docker.com/docker-for-mac/networking/) and for **Windows** read [this](https://docs.docker.com/docker-for-windows/#/step-4-explore-the-application-and-run-examples) (4th step). 32 | 33 | 4. Prepare Symfony app 34 | 1. Update app/config/parameters.yml 35 | 36 | ```yml 37 | # path/to/your/symfony-project/app/config/parameters.yml 38 | parameters: 39 | database_host: db 40 | ``` 41 | 42 | 2. Composer install & create database 43 | 44 | ```bash 45 | $ docker-compose exec php bash 46 | $ composer install 47 | $ sf doctrine:database:create 48 | $ sf doctrine:schema:update --force 49 | # Only if you have `doctrine/doctrine-fixtures-bundle` installed 50 | $ sf doctrine:fixtures:load --no-interaction 51 | ``` 52 | 53 | 5. Enjoy :-) 54 | 55 | ## Usage 56 | 57 | Just run `docker-compose up -d`, then: 58 | 59 | * Symfony app: visit [symfony.localhost](http://symfony.localhost) 60 | * Symfony dev mode: set APP_ENV=dev and rebuild 61 | * Symfony test mode: set APP_ENV=test and rebuild 62 | * Symfony prod mode: set APP_ENV=prod and rebuild 63 | * Logs (Kibana): [symfony.localhost:81](http://symfony.localhost:81) 64 | * Logs (files location): logs/nginx and logs/symfony 65 | * Mailcatcher: visit [symfony.localhost:1080](http://symfony.localhost:1080) 66 | 67 | ## Customize 68 | 69 | If you want to add optionnals containers like Redis, PHPMyAdmin... take a look on [doc/custom.md](doc/custom.md). 70 | 71 | ## How it works? 72 | 73 | Have a look at the `docker-compose.yml` file, here are the `docker-compose` built images: 74 | 75 | * `db`: This is the MySQL database container, 76 | * `php`: This is the PHP-FPM container in which the application volume is mounted, 77 | * `nginx`: This is the Nginx webserver container in which application volume is mounted too, 78 | * `elk`: This is a ELK stack container which uses Logstash to collect logs, send them into Elasticsearch and visualize them with Kibana. 79 | * `mailcatcher`: This is a Mailcatcher container for email testing. 80 | 81 | This results in the following running containers: 82 | 83 | ```bash 84 | $ docker-compose ps 85 | Name Command State Ports 86 | -------------------------------------------------------------------------------------------------- 87 | dockersymfony_db_1 /entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp 88 | dockersymfony_elk_1 /usr/bin/supervisord -n -c ... Up 0.0.0.0:81->80/tcp 89 | dockersymfony_nginx_1 nginx Up 443/tcp, 0.0.0.0:80->80/tcp 90 | dockersymfony_php_1 php-fpm Up 0.0.0.0:9000->9000/tcp 91 | dockersymfony_mailcatcher_1 /run.sh Up 0.0.0.0:1025->1025/tcp, 0.0.0.0:1080->1080/tcp 92 | 93 | ``` 94 | 95 | ## Useful commands 96 | 97 | ```bash 98 | # bash commands 99 | $ docker-compose exec php bash 100 | 101 | # Composer (e.g. composer update) 102 | $ docker-compose exec php composer update 103 | 104 | # SF commands (Tips: there is an alias inside php container) 105 | $ docker-compose exec php php /var/www/symfony/bin/console cache:clear 106 | # Same command by using alias 107 | $ docker-compose exec php bash 108 | $ sf cache:clear 109 | 110 | # Retrieve an IP Address (here for the nginx container) 111 | $ docker inspect --format '{{ .NetworkSettings.Networks.dockersymfony_default.IPAddress }}' $(docker ps -f name=nginx -q) 112 | $ docker inspect $(docker ps -f name=nginx -q) | grep IPAddress 113 | 114 | # MySQL commands 115 | $ docker-compose exec db mysql -uroot -p"root" 116 | 117 | # Check CPU consumption 118 | $ docker stats $(docker inspect -f "{{ .Name }}" $(docker ps -q)) 119 | 120 | # Delete all containers 121 | $ docker rm $(docker ps -aq) 122 | 123 | # Delete all images 124 | $ docker rmi $(docker images -q) 125 | ``` 126 | 127 | ## Debug your app 128 | 129 | * How to config Xdebug? 130 | Xdebug is configured out of the box! 131 | Just config your IDE to connect port `9001` and id key `PHPSTORM` 132 | 133 | ## Credits 134 | This project at init was forked [from Maxence Poutord work](https://github.com/maxpou/docker-symfony) 135 | --------------------------------------------------------------------------------