From e07ee7d07d8bd7f3091ac333fbd90b3b29a2153e Mon Sep 17 00:00:00 2001 From: Madson Jr Date: Wed, 18 Jul 2018 13:25:16 -0300 Subject: [PATCH 001/589] GraphViz support in workspace Issue #1003 --- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 2e6a7ea..22049d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -88,6 +88,7 @@ services: - INSTALL_PG_CLIENT=${WORKSPACE_INSTALL_PG_CLIENT} - INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE} - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} + - INSTALL_GRAPHVIZ=${WORKSPACE_INSTALL_GRAPHVIZ} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} diff --git a/env-example b/env-example index 25ebcb7..b0cb7dc 100644 --- a/env-example +++ b/env-example @@ -114,6 +114,7 @@ WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_LIBPNG=false +WORKSPACE_INSTALL_GRAPHVIZ=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.32 diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 4f1e464..6d25236 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -377,6 +377,17 @@ RUN if [ ${INSTALL_LIBPNG} = true ]; then \ apt install libpng16-16 \ ;fi +########################################################################### +# GraphViz extension +########################################################################### + +ARG INSTALL_GRAPHVIZ=false + +RUN if [ ${INSTALL_GRAPHVIZ} = true ]; then \ + apt-get update && \ + apt-get install -y graphviz \ +;fi + ########################################################################### # Drupal Console: ########################################################################### From 7aba9991f658d78eda59db04f67c3ff5d11bc4c1 Mon Sep 17 00:00:00 2001 From: Madson Jr Date: Wed, 18 Jul 2018 13:26:27 -0300 Subject: [PATCH 002/589] Conflict merge --- docker-compose.yml | 2 +- .../docker-entrypoint-initdb.d/createdb.sql.example | 12 ++++++------ nginx/sites/{default.conf => default.conf.example} | 0 workspace/Dockerfile | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename nginx/sites/{default.conf => default.conf.example} (100%) diff --git a/docker-compose.yml b/docker-compose.yml index d9566e8..8b2cbd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -685,7 +685,7 @@ services: networks: - frontend - backend - + ### Solr ################################################ solr: build: diff --git a/mysql/docker-entrypoint-initdb.d/createdb.sql.example b/mysql/docker-entrypoint-initdb.d/createdb.sql.example index 6420afb..dc48e59 100644 --- a/mysql/docker-entrypoint-initdb.d/createdb.sql.example +++ b/mysql/docker-entrypoint-initdb.d/createdb.sql.example @@ -16,13 +16,13 @@ # mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql # -#CREATE DATABASE IF NOT EXISTS `dev_db_1` COLLATE 'utf8_general_ci' ; -#GRANT ALL ON `dev_db_1`.* TO 'default'@'%' ; +CREATE DATABASE IF NOT EXISTS `finance_control` COLLATE 'utf8_general_ci' ; +GRANT ALL ON `finance_control`.* TO 'fincon'@'%' IDENTIFIED BY 'fincon'; -#CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ; -#GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ; +-- CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ; +-- GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ; -#CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ; -#GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ; +-- CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ; +-- GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ; FLUSH PRIVILEGES ; diff --git a/nginx/sites/default.conf b/nginx/sites/default.conf.example similarity index 100% rename from nginx/sites/default.conf rename to nginx/sites/default.conf.example diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 6d25236..36e4437 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -787,7 +787,7 @@ RUN if [ ${INSTALL_PG_CLIENT} = true ]; then \ USER root RUN apt-get update -yqq \ - && apt-get -yqq install nasm + && apt-get -yqq install nasm ########################################################################### # Dusk Dependencies: From d04fa78a75f614819faf873ee1dc94e97998ec56 Mon Sep 17 00:00:00 2001 From: Madson Jr Date: Wed, 18 Jul 2018 13:39:52 -0300 Subject: [PATCH 003/589] Removed invalid example file --- .../createdb.sql.example | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 mysql/docker-entrypoint-initdb.d/createdb.sql.example diff --git a/mysql/docker-entrypoint-initdb.d/createdb.sql.example b/mysql/docker-entrypoint-initdb.d/createdb.sql.example deleted file mode 100644 index dc48e59..0000000 --- a/mysql/docker-entrypoint-initdb.d/createdb.sql.example +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copy createdb.sql.example to createdb.sql -# then uncomment then set database name and username to create you need databases -# -# example: .env MYSQL_USER=appuser and need db name is myshop_db -# -# CREATE DATABASE IF NOT EXISTS `myshop_db` ; -# GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ; -# -# -# this sql script will auto run when the mysql container starts and the $DATA_PATH_HOST/mysql not found. -# -# if your $DATA_PATH_HOST/mysql exists and you do not want to delete it, you can run by manual execution: -# -# docker-compose exec mysql bash -# mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql -# - -CREATE DATABASE IF NOT EXISTS `finance_control` COLLATE 'utf8_general_ci' ; -GRANT ALL ON `finance_control`.* TO 'fincon'@'%' IDENTIFIED BY 'fincon'; - --- CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ; --- GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ; - --- CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ; --- GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ; - -FLUSH PRIVILEGES ; From e526e46e60beff6d2bf5ecb5395d8265f3994a36 Mon Sep 17 00:00:00 2001 From: Madson Jr Date: Fri, 20 Jul 2018 19:14:11 -0300 Subject: [PATCH 004/589] MySQL create DB example. --- .../createdb.sql.example | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 mysql/docker-entrypoint-initdb.d/createdb.sql.example diff --git a/mysql/docker-entrypoint-initdb.d/createdb.sql.example b/mysql/docker-entrypoint-initdb.d/createdb.sql.example new file mode 100644 index 0000000..6420afb --- /dev/null +++ b/mysql/docker-entrypoint-initdb.d/createdb.sql.example @@ -0,0 +1,28 @@ +# +# Copy createdb.sql.example to createdb.sql +# then uncomment then set database name and username to create you need databases +# +# example: .env MYSQL_USER=appuser and need db name is myshop_db +# +# CREATE DATABASE IF NOT EXISTS `myshop_db` ; +# GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ; +# +# +# this sql script will auto run when the mysql container starts and the $DATA_PATH_HOST/mysql not found. +# +# if your $DATA_PATH_HOST/mysql exists and you do not want to delete it, you can run by manual execution: +# +# docker-compose exec mysql bash +# mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql +# + +#CREATE DATABASE IF NOT EXISTS `dev_db_1` COLLATE 'utf8_general_ci' ; +#GRANT ALL ON `dev_db_1`.* TO 'default'@'%' ; + +#CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ; +#GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ; + +#CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ; +#GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ; + +FLUSH PRIVILEGES ; From 89051de67daba1825bad9dff8c9e31cf796131e1 Mon Sep 17 00:00:00 2001 From: Youri Westerman Date: Tue, 21 Aug 2018 12:41:34 +0700 Subject: [PATCH 005/589] This developer needed to turn back the clock in the PHP-FPM container, you will not believe what he did next! (#1675) * Added documentation for installing libfaketime in the php-fpm container * Enabled installing and using libfaketime system-wide inside the php-fpm container --- DOCUMENTATION/content/documentation/index.md | 23 ++++++++++++++++++++ docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 18 +++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 73e5990..9370110 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1499,10 +1499,33 @@ e) set it to `true` 3 - Set it to `true`
4 - Re-build the containers `docker-compose build php-fpm` +
+
+ +## Install libfaketime in the php-fpm container +Libfaketime allows you to control the date and time that is returned from the operating system. +It can be used by specifying a special string in the `PHP_FPM_FAKETIME` variable in the `.env` file. +For example: +`PHP_FPM_FAKETIME=-1d` +will set the clock back 1 day. See (https://github.com/wolfcw/libfaketime) for more information. + +1 - Open the `.env` file +
+2 - Search for the `PHP_FPM_INSTALL_FAKETIME` argument under the PHP-FPM container +
+3 - Set it to `true` +
+4 - Search for the `PHP_FPM_FAKETIME` argument under the PHP-FPM container +
+5 - Set it to the desired string +
+6 - Re-build the containers `docker-compose build php-fpm`
+ +
diff --git a/docker-compose.yml b/docker-compose.yml index e1a6f18..dd59584 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -144,6 +144,7 @@ services: - INSTALL_IMAGE_OPTIMIZERS=${PHP_FPM_INSTALL_IMAGE_OPTIMIZERS} - INSTALL_IMAGEMAGICK=${PHP_FPM_INSTALL_IMAGEMAGICK} - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} + - INSTALL_FAKETIME=${PHP_FPM_INSTALL_FAKETIME} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} @@ -154,6 +155,7 @@ services: environment: - PHP_IDE_CONFIG=${PHP_IDE_CONFIG} - DOCKER_HOST=tcp://docker-in-docker:2375 + - FAKETIME=${PHP_FPM_FAKETIME} depends_on: - workspace networks: diff --git a/env-example b/env-example index 15f55b8..bad6e1d 100644 --- a/env-example +++ b/env-example @@ -149,6 +149,8 @@ PHP_FPM_INSTALL_SWOOLE=false PHP_FPM_INSTALL_PG_CLIENT=false PHP_FPM_INSTALL_PCNTL=false PHP_FPM_INSTALL_CALENDAR=false +PHP_FPM_INSTALL_FAKETIME=false +PHP_FPM_FAKETIME=-0 ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 2fb86df..7158680 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -485,6 +485,18 @@ RUN if [ ${INSTALL_CALENDAR} = true ]; then \ docker-php-ext-install calendar \ ;fi +########################################################################### +# libfaketime: +########################################################################### + +USER root + +ARG INSTALL_FAKETIME=false + +RUN if [ ${INSTALL_FAKETIME} = true ]; then \ + apt-get install -y libfaketime \ +;fi + ########################################################################### # Check PHP version: ########################################################################### @@ -509,6 +521,12 @@ RUN apt-get clean && \ RUN usermod -u 1000 www-data +# Adding the faketime library to the preload file needs to be done last +# otherwise it will preload it for all commands that follow in this file +RUN if [ ${INSTALL_FAKETIME} = true ]; then \ + echo "/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1" > /etc/ld.so.preload \ +;fi + WORKDIR /var/www CMD ["php-fpm"] From b788a8bbfda5395ad7a42f5607c7d9a68ea3e837 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Tue, 21 Aug 2018 13:49:56 +0800 Subject: [PATCH 006/589] Add Web Based IDEs (#1705) Add Web Based IDEs: Theia, WebIDE, Codaid, IceCoder. --- docker-compose.yml | 56 +++++++++++++++++++++++++++++++++++++++++ env-example | 6 +++++ ide-codiad/Dockerfile | 5 ++++ ide-codiad/config.php | 43 +++++++++++++++++++++++++++++++ ide-icecoder/Dockerfile | 21 ++++++++++++++++ ide-theia/Dockerfile | 5 ++++ ide-webide/Dockerfile | 3 +++ 7 files changed, 139 insertions(+) create mode 100644 ide-codiad/Dockerfile create mode 100644 ide-codiad/config.php create mode 100644 ide-icecoder/Dockerfile create mode 100644 ide-theia/Dockerfile create mode 100644 ide-webide/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index dd59584..9541eb4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -891,3 +891,59 @@ services: networks: - backend +### IDE-THEIA ################################################ + ide-theia: + build: + context: ./ide-theia + volumes: + - ${APP_CODE_PATH_HOST}:/home/project + ports: + - "${IDE_THEIA_PORT}:3000" + networks: + - backend + +### IDE-WEBIDE ################################################ + ide-webide: + build: + context: ./ide-webide + volumes: + - ${DATA_PATH_HOST}/ide/webide/ide.db:/root/.coding-ide/ide.db + ports: + - "${IDE_WEBIDE_PORT}:8080" + networks: + - backend + +### IDE-CODIAD ################################################ + ide-codiad: + build: + context: ./ide-codiad + environment: + - APP_CODE_PATH_CONTAINER=${APP_CODE_PATH_CONTAINER} + - TZ=${WORKSPACE_TIMEZONE} + - PGID=1000 + - PUID=1000 + volumes: + - /etc/localtime:/etc/localtime:ro + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${DATA_PATH_HOST}/ide/codiad:/config + ports: + - "${IDE_CODIAD_PORT}:80" + networks: + - backend + +### IDE-ICECODER ################################################ + ide-icecoder: + build: + context: ./ide-icecoder + environment: + - DOCUMENT_ROOT=${APP_CODE_PATH_CONTAINER} + - TZ=${WORKSPACE_TIMEZONE} + - PGID=1000 + - PUID=1000 + volumes: + - /etc/localtime:/etc/localtime:ro + - ${APP_CODE_PATH_HOST}:/home/laradock/ICEcoder/dev + ports: + - "${IDE_ICECODER_PORT}:8080" + networks: + - backend diff --git a/env-example b/env-example index bad6e1d..0b72782 100644 --- a/env-example +++ b/env-example @@ -411,3 +411,9 @@ MONGO_WEBUI_INSTALL_MONGO=false METABASE_PORT=3030 METABASE_DB_FILE=metabase.db METABASE_JAVA_TIMEZONE=US/Pacific + +### IDE ############################################### +IDE_THEIA_PORT=987 +IDE_WEBIDE_PORT=984 +IDE_CODIAD_PORT=985 +IDE_ICECODER_PORT=986 diff --git a/ide-codiad/Dockerfile b/ide-codiad/Dockerfile new file mode 100644 index 0000000..583e75d --- /dev/null +++ b/ide-codiad/Dockerfile @@ -0,0 +1,5 @@ +FROM linuxserver/codiad + +LABEL maintainer="ahkui " + +COPY config.php /defaults/config.php diff --git a/ide-codiad/config.php b/ide-codiad/config.php new file mode 100644 index 0000000..acd4394 --- /dev/null +++ b/ide-codiad/config.php @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/ide-icecoder/Dockerfile b/ide-icecoder/Dockerfile new file mode 100644 index 0000000..a58ec67 --- /dev/null +++ b/ide-icecoder/Dockerfile @@ -0,0 +1,21 @@ +FROM php:alpine + +LABEL maintainer="ahkui " + +ARG PUID=1000 +ENV PUID ${PUID} +ARG PGID=1000 +ENV PGID ${PGID} + +RUN apk add --no-cache git + +RUN addgroup -g $PGID -S laradock && \ + adduser -u $PUID -S laradock -G laradock + +USER laradock + +RUN cd /home/laradock && git clone https://github.com/mattpass/ICEcoder.git + +WORKDIR /home/laradock/ICEcoder + +CMD ["php","-S","0.0.0.0:8080"] diff --git a/ide-theia/Dockerfile b/ide-theia/Dockerfile new file mode 100644 index 0000000..39f2c1b --- /dev/null +++ b/ide-theia/Dockerfile @@ -0,0 +1,5 @@ +FROM theiaide/theia + +LABEL maintainer="ahkui " + +RUN echo 'fs.inotify.max_user_watches=524288' >> /etc/sysctl.conf \ No newline at end of file diff --git a/ide-webide/Dockerfile b/ide-webide/Dockerfile new file mode 100644 index 0000000..257b50a --- /dev/null +++ b/ide-webide/Dockerfile @@ -0,0 +1,3 @@ +FROM webide/webide + +LABEL maintainer="ahkui " From aa84dd861636e191463fe009267a8365e0100cfe Mon Sep 17 00:00:00 2001 From: vladyslavstartsev Date: Tue, 21 Aug 2018 14:01:12 +0300 Subject: [PATCH 007/589] added ext-gmp to workspace container (#1762) --- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 9541eb4..aa7badf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,6 +52,7 @@ services: - INSTALL_XDEBUG=${WORKSPACE_INSTALL_XDEBUG} - INSTALL_PHPDBG=${WORKSPACE_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} + - INSTALL_GMP=${WORKSPACE_INSTALL_GMP} - INSTALL_SOAP=${WORKSPACE_INSTALL_SOAP} - INSTALL_LDAP=${WORKSPACE_INSTALL_LDAP} - INSTALL_IMAP=${WORKSPACE_INSTALL_IMAP} diff --git a/env-example b/env-example index 0b72782..6378c0b 100644 --- a/env-example +++ b/env-example @@ -89,6 +89,7 @@ WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_XDEBUG=false WORKSPACE_INSTALL_PHPDBG=false WORKSPACE_INSTALL_LDAP=false +WORKSPACE_INSTALL_GMP=false WORKSPACE_INSTALL_SOAP=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 2a639f1..0030d95 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -180,6 +180,20 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ USER root +ARG INSTALL_GMP=false +ARG PHP_VERSION=${PHP_VERSION} + +RUN if [ ${INSTALL_GMP} = true ]; then \ + # Install the PHP SOAP extension + apt-get -y install php${PHP_VERSION}-gmp \ +;fi + +########################################################################### +# SOAP: +########################################################################### + +USER root + ARG INSTALL_SOAP=false RUN if [ ${INSTALL_SOAP} = true ]; then \ From 947a791ad2feb8e42f49325d9ca3f06db3451420 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Sun, 26 Aug 2018 16:02:55 +0800 Subject: [PATCH 008/589] Auto reload caddy and add basicauth example (#1706) * add live reload and basicauth --- caddy/Dockerfile | 8 +++++--- caddy/{ => caddy}/Caddyfile | 5 +++++ caddy/caddy/authlist.conf | 1 + docker-compose.yml | 2 +- env-example | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) rename caddy/{ => caddy}/Caddyfile (93%) create mode 100644 caddy/caddy/authlist.conf diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 5603e3a..06dc490 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -6,12 +6,14 @@ ARG plugins="cors" ## ARG plugins="cors cgi cloudflare azure linode" - RUN caddyplug install ${plugins} - + +RUN apk add --no-cache inotify-tools \ + && echo -e "#!/bin/sh\nwhile inotifywait -e modify /etc/caddy; do\n\tpkill caddy\ndone " >> /start.sh \ + && chmod +x /start.sh EXPOSE 80 443 2015 WORKDIR /var/www/public -CMD ["/usr/bin/caddy", "-conf", "/etc/Caddyfile","-agree"] +CMD ["sh","-c","/start.sh & /usr/bin/caddy -conf /etc/caddy/Caddyfile -agree"] diff --git a/caddy/Caddyfile b/caddy/caddy/Caddyfile similarity index 93% rename from caddy/Caddyfile rename to caddy/caddy/Caddyfile index b563fb1..1848d34 100644 --- a/caddy/Caddyfile +++ b/caddy/caddy/Caddyfile @@ -44,3 +44,8 @@ laradock2.demo:80 { #proxy domain.com #cors } + +laradock3.demo:80 { + import authlist.conf + root /var/www/public +} \ No newline at end of file diff --git a/caddy/caddy/authlist.conf b/caddy/caddy/authlist.conf new file mode 100644 index 0000000..651bf55 --- /dev/null +++ b/caddy/caddy/authlist.conf @@ -0,0 +1 @@ +basicauth / laradock laradock diff --git a/docker-compose.yml b/docker-compose.yml index aa7badf..920f57d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -471,7 +471,7 @@ services: build: ./caddy volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - - ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile + - ${CADDY_CONFIG_PATH}:/etc/caddy - ${CADDY_HOST_LOG_PATH}:/var/log/caddy - ${DATA_PATH_HOST}:/root/.caddy ports: diff --git a/env-example b/env-example index 6378c0b..c851395 100644 --- a/env-example +++ b/env-example @@ -355,7 +355,7 @@ MONGODB_PORT=27017 CADDY_HOST_HTTP_PORT=80 CADDY_HOST_HTTPS_PORT=443 CADDY_HOST_LOG_PATH=./logs/caddy -CADDY_CUSTOM_CADDYFILE=./caddy/Caddyfile +CADDY_CONFIG_PATH=./caddy/caddy ### LARAVEL ECHO SERVER ################################### From 39469e1404172d2d833b9eb9f0fb4665624815df Mon Sep 17 00:00:00 2001 From: vladyslavstartsev Date: Tue, 28 Aug 2018 09:16:25 +0300 Subject: [PATCH 009/589] added ssh2 to workspace and php-fpm (#1756) --- docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 17 +++++++++++++++++ workspace/Dockerfile | 13 +++++++++++++ 4 files changed, 34 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 920f57d..61f261b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,6 +52,7 @@ services: - INSTALL_XDEBUG=${WORKSPACE_INSTALL_XDEBUG} - INSTALL_PHPDBG=${WORKSPACE_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} + - INSTALL_SSH2=${WORKSPACE_INSTALL_SSH2} - INSTALL_GMP=${WORKSPACE_INSTALL_GMP} - INSTALL_SOAP=${WORKSPACE_INSTALL_SOAP} - INSTALL_LDAP=${WORKSPACE_INSTALL_LDAP} @@ -120,6 +121,7 @@ services: - INSTALL_XDEBUG=${PHP_FPM_INSTALL_XDEBUG} - INSTALL_PHPDBG=${PHP_FPM_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} + - INSTALL_SSH2=${PHP_FPM_INSTALL_SSH2} - INSTALL_SOAP=${PHP_FPM_INSTALL_SOAP} - INSTALL_IMAP=${PHP_FPM_INSTALL_IMAP} - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} diff --git a/env-example b/env-example index c851395..6089cdc 100644 --- a/env-example +++ b/env-example @@ -88,6 +88,7 @@ WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_XDEBUG=false WORKSPACE_INSTALL_PHPDBG=false +WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false WORKSPACE_INSTALL_GMP=false WORKSPACE_INSTALL_SOAP=false @@ -139,6 +140,7 @@ PHP_FPM_INSTALL_IMAP=false PHP_FPM_INSTALL_MONGO=false PHP_FPM_INSTALL_AMQP=false PHP_FPM_INSTALL_MSSQL=false +PHP_FPM_INSTALL_SSH2=false PHP_FPM_INSTALL_SOAP=false PHP_FPM_INSTALL_GMP=false PHP_FPM_INSTALL_EXIF=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 7158680..e1b4c45 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -50,6 +50,23 @@ RUN apt-get update -yqq && \ # - INSTALL_ZIP_ARCHIVE=true # +########################################################################### +# SSH2: +########################################################################### + +ARG INSTALL_SSH2=false + +RUN if [ ${INSTALL_SSH2} = true ]; then \ + # Install the ssh2 extension + apt-get -y install libssh2-1-dev && \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl install -a ssh2-0.13; \ + else \ + pecl install -a ssh2-1.1.2; \ + fi && \ + docker-php-ext-enable ssh2 \ +;fi + ########################################################################### # SOAP: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 0030d95..37f1fb1 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -174,6 +174,19 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ drush core-status \ ;fi +########################################################################### +# SSH2: +########################################################################### + +USER root + +ARG INSTALL_SSH2=false + +RUN if [ ${INSTALL_SSH2} = true ]; then \ + # Install the PHP SSH2 extension + apt-get -y install libssh2-1-dev php${LARADOCK_PHP_VERSION}-ssh2 \ +;fi + ########################################################################### # SOAP: ########################################################################### From 2e2cb6df227aef83285e627bada59320606674da Mon Sep 17 00:00:00 2001 From: Tatamo Date: Fri, 31 Aug 2018 21:19:52 +0900 Subject: [PATCH 010/589] Enable `docker-compose exec workspace npm` (and yarn, etc.) (#1743) * fix node PATH to enable docker-compose exec workspace npm * add PATH for yarn to enable docker-compose exec workspace yarn --- workspace/Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 37f1fb1..dd22fef 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -448,6 +448,7 @@ RUN if [ ${INSTALL_NODE} = true ]; then \ && if [ ${INSTALL_NPM_VUE_CLI} = true ]; then \ npm install -g @vue/cli \ ;fi \ + && ln -s `npm bin --global` /home/laradock/.node-bin \ ;fi # Wouldn't execute when added to the RUN statement in the above block @@ -468,7 +469,7 @@ RUN if [ ${INSTALL_NODE} = true ]; then \ ;fi # Add PATH for node -ENV PATH $PATH:$NVM_DIR/versions/node/v${NODE_VERSION}/bin +ENV PATH $PATH:/home/laradock/.node-bin RUN if [ ${NPM_REGISTRY} ]; then \ . ~/.bashrc && npm config set registry ${NPM_REGISTRY} \ @@ -504,6 +505,9 @@ RUN if [ ${INSTALL_YARN} = true ]; then \ echo 'export PATH="$YARN_DIR/bin:$PATH"' >> ~/.bashrc \ ;fi +# Add PATH for YARN +ENV PATH $PATH:/home/laradock/.yarn/bin + ########################################################################### # PHP Aerospike: ########################################################################### From 902198ab05cd5e6f90c2f9bdd389ca2266a30f30 Mon Sep 17 00:00:00 2001 From: tadaken3 Date: Sat, 8 Sep 2018 20:42:58 +0900 Subject: [PATCH 011/589] fix application path (#1781) * fix application path In the "env.sample" , "APP_CODE_PATH_HOST" was written. I fixed Documentation. --- DOCUMENTATION/content/getting-started/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index bca083e..a067fa3 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -81,10 +81,10 @@ We'll need to do step 1 of the [Usage](#Usage) section now to make this happen. cp env-example .env ``` -At the top, change the `APPLICATION` variable to your project path. +At the top, change the `APP_CODE_PATH_HOST` variable to your project path. ``` -APPLICATION=../project-z/ +APP_CODE_PATH_HOST=../project-z/ ``` Make sure to replace `project-z` with your project folder name. From 00df369e9655a28a3178f8f3bc569be00adda5be Mon Sep 17 00:00:00 2001 From: ganlei <769323213@qq.com> Date: Sat, 8 Sep 2018 21:31:05 +0800 Subject: [PATCH 012/589] =?UTF-8?q?Add=20IonCube=20Loader=20=EF=BC=88zend?= =?UTF-8?q?=5Fextension=EF=BC=89=20(#1763)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DOCUMENTATION/content/documentation/index.md | 22 ++++++++++++++++++++ docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 15 +++++++++++++ workspace/Dockerfile | 15 +++++++++++++ 5 files changed, 56 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 9370110..b3e2294 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -353,6 +353,28 @@ Note: If `.php-fpm/xdebug` doesn't execute and gives `Permission Denied` error t +
+ +## Install ionCube Loader + +1 - First install `ionCube Loader` in the Workspace and the PHP-FPM Containers: +
+a) open the `.env` file +
+b) search for the `WORKSPACE_INSTALL_IONCUBE` argument under the Workspace Container +
+c) set it to `true` +
+d) search for the `PHP_FPM_INSTALL_IONCUBE` argument under the PHP-FPM Container +
+e) set it to `true` + +2 - Re-build the containers `docker-compose build workspace php-fpm` + +Always download the latest version of [Loaders for ionCube ](http://www.ioncube.com/loaders.php). + + +
diff --git a/docker-compose.yml b/docker-compose.yml index 61f261b..a944795 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -90,6 +90,7 @@ services: - INSTALL_PG_CLIENT=${WORKSPACE_INSTALL_PG_CLIENT} - INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE} - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} + - INSTALL_IONCUBE=${WORKSPACE_INSTALL_IONCUBE} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} @@ -148,6 +149,7 @@ services: - INSTALL_IMAGEMAGICK=${PHP_FPM_INSTALL_IMAGEMAGICK} - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} - INSTALL_FAKETIME=${PHP_FPM_INSTALL_FAKETIME} + - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} diff --git a/env-example b/env-example index 6089cdc..1e5b475 100644 --- a/env-example +++ b/env-example @@ -116,6 +116,7 @@ WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_LIBPNG=false +WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.32 @@ -153,6 +154,7 @@ PHP_FPM_INSTALL_PG_CLIENT=false PHP_FPM_INSTALL_PCNTL=false PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false +PHP_FPM_INSTALL_IONCUBE=false PHP_FPM_FAKETIME=-0 ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index e1b4c45..dd7f0d1 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -342,6 +342,21 @@ RUN if [ ${INSTALL_AEROSPIKE} = true ]; then \ && docker-php-ext-enable aerospike \ ;fi +########################################################################### +# IonCube Loader: +########################################################################### + +ARG INSTALL_IONCUBE=false + +RUN if [ ${INSTALL_IONCUBE} = true ]; then \ + # Install the php ioncube loader + curl -L -o /tmp/ioncube_loaders_lin_x86-64.tar.gz https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz \ + && tar zxpf /tmp/ioncube_loaders_lin_x86-64.tar.gz -C /tmp \ + && mv /tmp/ioncube/ioncube_loader_lin_${LARADOCK_PHP_VERSION}.so $(php -r "echo ini_get('extension_dir');")/ioncube_loader.so \ + && printf "zend_extension=ioncube_loader.so\n" > $PHP_INI_DIR/conf.d/0ioncube.ini \ + && rm -rf /tmp/ioncube* \ +;fi + ########################################################################### # Opcache: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index dd22fef..2ce9078 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -397,6 +397,21 @@ RUN if [ ${INSTALL_LIBPNG} = true ]; then \ apt install libpng16-16 \ ;fi +########################################################################### +# IonCube Loader +########################################################################### + +ARG INSTALL_IONCUBE=false + +RUN if [ ${INSTALL_IONCUBE} = true ]; then \ + # Install the php ioncube loader + curl -L -o /tmp/ioncube_loaders_lin_x86-64.tar.gz https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz \ + && tar zxpf /tmp/ioncube_loaders_lin_x86-64.tar.gz -C /tmp \ + && mv /tmp/ioncube/ioncube_loader_lin_${LARADOCK_PHP_VERSION}.so $(php -r "echo ini_get('extension_dir');")/ioncube_loader.so \ + && echo "zend_extension=ioncube_loader.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/0ioncube.ini \ + && rm -rf /tmp/ioncube* \ +;fi + ########################################################################### # Drupal Console: ########################################################################### From 876935452ec75fb19f75fef386234dc38e7c78de Mon Sep 17 00:00:00 2001 From: ThunderbirdsX3 Date: Sat, 8 Sep 2018 20:31:58 +0700 Subject: [PATCH 013/589] Add .gitignore to php-worker (#1780) * Add .gitignore * Change file to example. --- php-worker/supervisord.d/.gitignore | 1 + .../{laravel-worker.conf => laravel-worker.conf.example} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 php-worker/supervisord.d/.gitignore rename php-worker/supervisord.d/{laravel-worker.conf => laravel-worker.conf.example} (89%) diff --git a/php-worker/supervisord.d/.gitignore b/php-worker/supervisord.d/.gitignore new file mode 100644 index 0000000..fee9217 --- /dev/null +++ b/php-worker/supervisord.d/.gitignore @@ -0,0 +1 @@ +*.conf diff --git a/php-worker/supervisord.d/laravel-worker.conf b/php-worker/supervisord.d/laravel-worker.conf.example similarity index 89% rename from php-worker/supervisord.d/laravel-worker.conf rename to php-worker/supervisord.d/laravel-worker.conf.example index cce9e92..06156bc 100644 --- a/php-worker/supervisord.d/laravel-worker.conf +++ b/php-worker/supervisord.d/laravel-worker.conf.example @@ -4,4 +4,4 @@ command=php /var/www/artisan queue:work --sleep=3 --tries=3 --daemon autostart=true autorestart=true numprocs=8 -redirect_stderr=true \ No newline at end of file +redirect_stderr=true From aaef73c84da9a62ba4e47586cd33a6fd14258472 Mon Sep 17 00:00:00 2001 From: Vladislav Otchenashev Date: Sat, 15 Sep 2018 16:16:37 +0300 Subject: [PATCH 014/589] fix typo (#1797) --- mysql/docker-entrypoint-initdb.d/createdb.sql.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql/docker-entrypoint-initdb.d/createdb.sql.example b/mysql/docker-entrypoint-initdb.d/createdb.sql.example index 6420afb..417ec10 100644 --- a/mysql/docker-entrypoint-initdb.d/createdb.sql.example +++ b/mysql/docker-entrypoint-initdb.d/createdb.sql.example @@ -2,7 +2,7 @@ # Copy createdb.sql.example to createdb.sql # then uncomment then set database name and username to create you need databases # -# example: .env MYSQL_USER=appuser and need db name is myshop_db +# example: .env MYSQL_USER=appuser and needed db name is myshop_db # # CREATE DATABASE IF NOT EXISTS `myshop_db` ; # GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ; From 20c85904c58942b7043ff7b7978a0310c497079d Mon Sep 17 00:00:00 2001 From: Null Date: Sat, 15 Sep 2018 16:19:24 +0300 Subject: [PATCH 015/589] Package has been deprecated (#1796) workspace npm bower --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index 1e5b475..b181080 100644 --- a/env-example +++ b/env-example @@ -81,7 +81,7 @@ WORKSPACE_NPM_REGISTRY= WORKSPACE_INSTALL_YARN=true WORKSPACE_YARN_VERSION=latest WORKSPACE_INSTALL_NPM_GULP=true -WORKSPACE_INSTALL_NPM_BOWER=true +WORKSPACE_INSTALL_NPM_BOWER=false WORKSPACE_INSTALL_NPM_VUE_CLI=true WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false From 86a4108ef40847efa8f09ed2244e65134812a790 Mon Sep 17 00:00:00 2001 From: semenikhin Date: Sat, 15 Sep 2018 18:20:22 +0500 Subject: [PATCH 016/589] fix comment (#1790) GMP --- workspace/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 2ce9078..7ea6b1f 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -188,7 +188,7 @@ RUN if [ ${INSTALL_SSH2} = true ]; then \ ;fi ########################################################################### -# SOAP: +# GMP: ########################################################################### USER root @@ -197,7 +197,7 @@ ARG INSTALL_GMP=false ARG PHP_VERSION=${PHP_VERSION} RUN if [ ${INSTALL_GMP} = true ]; then \ - # Install the PHP SOAP extension + # Install the PHP GMP extension apt-get -y install php${PHP_VERSION}-gmp \ ;fi From 0bbfb2d228eaa3bde199d70175aac429e6a09bb4 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Sat, 15 Sep 2018 21:22:44 +0800 Subject: [PATCH 017/589] Update caddy Dockerfile (#1788) * Change base image --- caddy/Dockerfile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 06dc490..c987b7e 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -1,7 +1,15 @@ -FROM zuohuadong/caddy:alpine +FROM golang:alpine LABEL maintainer="Huadong Zuo " +RUN apk add --no-cache \ + openssh \ + git \ + build-base && \ + go get github.com/abiosoft/caddyplug/caddyplug \ + && caddyplug install-caddy \ + apk del build-base + ARG plugins="cors" ## ARG plugins="cors cgi cloudflare azure linode" @@ -12,7 +20,7 @@ RUN apk add --no-cache inotify-tools \ && echo -e "#!/bin/sh\nwhile inotifywait -e modify /etc/caddy; do\n\tpkill caddy\ndone " >> /start.sh \ && chmod +x /start.sh -EXPOSE 80 443 2015 +EXPOSE 80 443 WORKDIR /var/www/public From 46588204375429f96c513b8e17f5e32de6dc8457 Mon Sep 17 00:00:00 2001 From: Diego Vieira Date: Sat, 15 Sep 2018 14:40:13 +0100 Subject: [PATCH 018/589] Update baseurl to https (#1791) Closes #1751 --- DOCUMENTATION/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCUMENTATION/config.toml b/DOCUMENTATION/config.toml index 74e4fa0..91fd072 100644 --- a/DOCUMENTATION/config.toml +++ b/DOCUMENTATION/config.toml @@ -1,4 +1,4 @@ -baseurl = "http://laradock.io/" +baseurl = "https://laradock.io/" languageCode = "en-us" publishDir = "../docs" title = "Laradock" From e101e4d5b2d6f548dfffbdad01c267d2f9d5a126 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Sun, 16 Sep 2018 17:44:18 +0800 Subject: [PATCH 019/589] Add mail services(mailu) (#1775) * add mail service --- DOCUMENTATION/content/documentation/index.md | 22 +++ DOCUMENTATION/content/introduction/index.md | 2 +- docker-compose.yml | 164 +++++++++++++++++++ env-example | 61 +++++++ 4 files changed, 248 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index b3e2294..c3668d1 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -565,6 +565,28 @@ docker-compose up -d php-worker +
+ +## Use Mailu + +1 - You need register a domain. + +2 - Required RECAPTCHA for signup email [HERE](https://www.google.com/recaptcha/admin) + +2 - modify following environment variable in `.env` file + +``` +MAILU_RECAPTCHA_PUBLIC_KEY= +MAILU_RECAPTCHA_PRIVATE_KEY= +MAILU_DOMAIN=laradock.io +MAILU_HOSTNAMES=mail.laradock.io +``` + +2 - Open your browser and visit `http://YOUR_DOMAIN`. + + + +
## Use NetData diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index a8ccf26..4e15223 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -97,7 +97,7 @@ Beanstalkd - RabbitMQ - PHP Worker - **Queueing Management:** Beanstalkd Console - RabbitMQ Console - **Random Tools:** -HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Grafana - Gitlab - Mailhog - MailDev - Minio - Varnish - Swoole - NetData - Portainer - Laravel Echo... +Mailu - HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Grafana - Gitlab - Mailhog - MailDev - Minio - Varnish - Swoole - NetData - Portainer - Laravel Echo... Laradock introduces the **Workspace** Image, as a development environment. It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of Containers and tools you may choose. diff --git a/docker-compose.yml b/docker-compose.yml index a944795..990506c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -952,3 +952,167 @@ services: - "${IDE_ICECODER_PORT}:8080" networks: - backend + + +### MAILU ################################################ + mailu: + image: mailu/admin:${MAILU_VERSION} + volumes: + - "${DATA_PATH_HOST}/mailu/data:/data" + - "${DATA_PATH_HOST}/mailu/dkim:/dkim" + - "${DATA_PATH_HOST}/mailu/webmail:/webmail" + - /var/run/docker.sock:/var/run/docker.sock:ro + depends_on: + - mailu-front + - mailu-imap + - mailu-smtp + - mailu-antispam + - mailu-antivirus + - mailu-webdav + - mailu-admin + - mailu-webmail + - mailu-fetchmail + command: ["sh", "-c", "echo ${MAILU_INIT_ADMIN_USERNAME}@${MAILU_DOMAIN} ${MAILU_INIT_ADMIN_PASSWORD} ;python manage.py advertise ; python manage.py db upgrade ; python manage.py admin ${MAILU_INIT_ADMIN_USERNAME} ${MAILU_DOMAIN} ${MAILU_INIT_ADMIN_PASSWORD} || true;sed -i -- \"s/= Off/= On/g\" /webmail/_data_/_default_/configs/config.ini || true;if grep -Fq \"registration_link_url\" /webmail/_data_/_default_/configs/config.ini;then echo Already set!;else echo \"\" >> /webmail/_data_/_default_/configs/config.ini; echo \"[login]\" >> /webmail/_data_/_default_/configs/config.ini;echo \"registration_link_url = '${MAILU_WEBSITE}${MAILU_WEB_ADMIN}/ui/user/signup'\" >> /webmail/_data_/_default_/configs/config.ini;fi"] + networks: + - backend + mailu-front: + image: mailu/nginx:${MAILU_VERSION} + environment: + - ADMIN=${MAILU_ADMIN} + - WEB_ADMIN=${MAILU_WEB_ADMIN} + - WEB_WEBMAIL=${MAILU_WEB_WEBMAIL} + - WEBDAV=${MAILU_WEBDAV} + - HOSTNAMES=${MAILU_HOSTNAMES} + - TLS_FLAVOR=${MAILU_TLS_FLAVOR} + - MESSAGE_SIZE_LIMIT=${MAILU_MESSAGE_SIZE_LIMIT} + ports: + - "${MAILU_HTTP_PORT}:80" + - "${MAILU_HTTPS_PORT}:443" + - "110:110" + - "143:143" + - "993:993" + - "995:995" + - "25:25" + - "465:465" + - "587:587" + volumes: + - "${DATA_PATH_HOST}/mailu/certs:/certs" + networks: + backend: + aliases: + - front + mailu-imap: + image: mailu/dovecot:${MAILU_VERSION} + environment: + - DOMAIN=${MAILU_DOMAIN} + - HOSTNAMES=${MAILU_HOSTNAMES} + - POSTMASTER=${MAILU_POSTMASTER} + - WEBMAIL=${MAILU_WEBMAIL} + - RECIPIENT_DELIMITER=${MAILU_RECIPIENT_DELIMITER} + volumes: + - "${DATA_PATH_HOST}/mailu/data:/data" + - "${DATA_PATH_HOST}/mailu/mail:/mail" + - "${DATA_PATH_HOST}/mailu/overrides:/overrides" + depends_on: + - mailu-front + networks: + backend: + aliases: + - imap + mailu-smtp: + image: mailu/postfix:${MAILU_VERSION} + environment: + - DOMAIN=${MAILU_DOMAIN} + - HOSTNAMES=${MAILU_HOSTNAMES} + - RELAYHOST=${MAILU_RELAYHOST} + - RELAYNETS=${MAILU_RELAYNETS} + - RECIPIENT_DELIMITER=${MAILU_RECIPIENT_DELIMITER} + - MESSAGE_SIZE_LIMIT=${MAILU_MESSAGE_SIZE_LIMIT} + volumes: + - "${DATA_PATH_HOST}/mailu/data:/data" + - "${DATA_PATH_HOST}/mailu/overrides:/overrides" + depends_on: + - mailu-front + networks: + backend: + aliases: + - smtp + mailu-antispam: + image: mailu/rspamd:${MAILU_VERSION} + volumes: + - "${DATA_PATH_HOST}/mailu/filter:/var/lib/rspamd" + - "${DATA_PATH_HOST}/mailu/dkim:/dkim" + - "${DATA_PATH_HOST}/mailu/overrides/rspamd:/etc/rspamd/override.d" + depends_on: + - mailu-front + networks: + backend: + aliases: + - antispam + mailu-antivirus: + image: mailu/clamav:${MAILU_VERSION} + volumes: + - "${DATA_PATH_HOST}/mailu/filter:/data" + networks: + backend: + aliases: + - antivirus + mailu-webdav: + image: mailu/${MAILU_WEBDAV}:${MAILU_VERSION} + volumes: + - "${DATA_PATH_HOST}/mailu/dav:/data" + networks: + backend: + aliases: + - webdav + mailu-admin: + image: mailu/admin:${MAILU_VERSION} + environment: + - DOMAIN=${MAILU_DOMAIN} + - HOSTNAMES=${MAILU_HOSTNAMES} + - POSTMASTER=${MAILU_POSTMASTER} + - SECRET_KEY=${MAILU_SECRET_KEY} + - AUTH_RATELIMIT=${MAILU_AUTH_RATELIMIT} + - TLS_FLAVOR=${MAILU_TLS_FLAVOR} + - DISABLE_STATISTICS=${MAILU_DISABLE_STATISTICS} + - DMARC_RUA=${MAILU_DMARC_RUA} + - DMARC_RUF=${MAILU_DMARC_RUF} + - WELCOME=${MAILU_WELCOME} + - WELCOME_SUBJECT=${MAILU_WELCOME_SUBJECT} + - WELCOME_BODY=${MAILU_WELCOME_BODY} + - WEB_ADMIN=${MAILU_WEB_ADMIN} + - WEB_WEBMAIL=${MAILU_WEB_WEBMAIL} + - WEBSITE=${MAILU_WEBSITE} + - WEBMAIL=${MAILU_WEBMAIL} + - SITENAME=${MAILU_SITENAME} + - PASSWORD_SCHEME=${MAILU_PASSWORD_SCHEME} + - RECAPTCHA_PUBLIC_KEY=${MAILU_RECAPTCHA_PUBLIC_KEY} + - RECAPTCHA_PRIVATE_KEY=${MAILU_RECAPTCHA_PRIVATE_KEY} + volumes: + - "${DATA_PATH_HOST}/mailu/data:/data" + - "${DATA_PATH_HOST}/mailu/dkim:/dkim" + - /var/run/docker.sock:/var/run/docker.sock:ro + depends_on: + - redis + networks: + backend: + aliases: + - admin + mailu-webmail: + image: "mailu/${MAILU_WEBMAIL}:${MAILU_VERSION}" + volumes: + - "${DATA_PATH_HOST}/mailu/webmail:/data" + networks: + backend: + aliases: + - webmail + mailu-fetchmail: + image: mailu/fetchmail:${MAILU_VERSION} + environment: + - FETCHMAIL_DELAY=${MAILU_FETCHMAIL_DELAY} + volumes: + - "${DATA_PATH_HOST}/mailu/data:/data" + networks: + backend: + aliases: + - fetchmail diff --git a/env-example b/env-example index b181080..aa16e5f 100644 --- a/env-example +++ b/env-example @@ -422,3 +422,64 @@ IDE_THEIA_PORT=987 IDE_WEBIDE_PORT=984 IDE_CODIAD_PORT=985 IDE_ICECODER_PORT=986 + +### MAILU ############################################### +MAILU_VERSION=latest +MAILU_RECAPTCHA_PUBLIC_KEY= +MAILU_RECAPTCHA_PRIVATE_KEY= +# Main mail domain +MAILU_HTTP_PORT=6080 +MAILU_HTTPS_PORT=60443 +MAILU_DOMAIN=example.com +MAILU_INIT_ADMIN_USERNAME=laradock +MAILU_INIT_ADMIN_PASSWORD=laradock +# Hostnames for this server, separated with comas +MAILU_HOSTNAMES=mail.example.com,alternative.example.com,yetanother.example.com +# Postmaster local part (will append the main mail domain) +MAILU_POSTMASTER=admin +# Set to a randomly generated 16 bytes string +MAILU_SECRET_KEY=ChangeMeChangeMe +# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail) +MAILU_TLS_FLAVOR=cert +# Authentication rate limit (per source IP address) +MAILU_AUTH_RATELIMIT=10/minute;1000/hour +# Opt-out of statistics, replace with "True" to opt out +MAILU_DISABLE_STATISTICS=False +# Message size limit in bytes +# Default: accept messages up to 50MB +MAILU_MESSAGE_SIZE_LIMIT=50000000 +# Will relay all outgoing mails if configured +MAILU_RELAYHOST= +# Networks granted relay permissions, make sure that you include your Docker +# internal network (default to 172.17.0.0/16) +MAILU_RELAYNETS=172.16.0.0/12 +# Fetchmail delay +MAILU_FETCHMAIL_DELAY=600 +# Recipient delimiter, character used to delimiter localpart from custom address part +# e.g. localpart+custom@domain;tld +MAILU_RECIPIENT_DELIMITER=+ +# DMARC rua and ruf email +MAILU_DMARC_RUA=admin +MAILU_DMARC_RUF=admin +# Weclome email, enable and set a topic and body if you wish to send welcome +# emails to all users. +MAILU_WELCOME=True +MAILU_WELCOME_SUBJECT=Welcome to your new email account +MAILU_WELCOME_BODY=Welcome to your new email account, if you can read this, then it is configured properly! +# Path to the admin interface if enabled +MAILU_WEB_ADMIN=/admin +# Path to the webmail if enabled +MAILU_WEB_WEBMAIL=/webmail +# Website name +MAILU_SITENAME=Example Mail +# Linked Website URL +MAILU_WEBSITE=http://mail.example.com +# Default password scheme used for newly created accounts and changed passwords +# (value: SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT) +MAILU_PASSWORD_SCHEME=SHA512-CRYPT +# Expose the admin interface (value: true, false) +MAILU_ADMIN=true +# Choose which webmail to run if any (values: roundcube, rainloop, none) +MAILU_WEBMAIL=rainloop +# Dav server implementation (value: radicale, none) +MAILU_WEBDAV=radicale From 70c1be4168c11bff16e80c016b24d3935935cebf Mon Sep 17 00:00:00 2001 From: Alex Mayer Date: Sun, 16 Sep 2018 05:58:26 -0400 Subject: [PATCH 020/589] Point ea Alias To Correct File (#1698) --- workspace/aliases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 29fc22d..2c415ab 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -50,7 +50,7 @@ alias cla="clear && ls -l" alias cll="clear && ls -la" alias cls="clear && ls" alias code="cd /var/www" -alias ea="vi ~/aliases" +alias ea="vi ~/aliases.sh" # Always enable colored `grep` output # Note: `GREP_OPTIONS="--color=auto"` is deprecated, hence the alias usage. From 61576c0b1b88f574f8393ff652c2cff524a46b91 Mon Sep 17 00:00:00 2001 From: Null Date: Sun, 16 Sep 2018 13:00:46 +0300 Subject: [PATCH 021/589] Change to stable CLI interface (#1793) workspace apt command --- workspace/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 7ea6b1f..b87fab2 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -393,8 +393,8 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ ARG INSTALL_LIBPNG=false RUN if [ ${INSTALL_LIBPNG} = true ]; then \ - apt update && \ - apt install libpng16-16 \ + apt-get update && \ + apt-get install libpng16-16 \ ;fi ########################################################################### From 6a3b3fac2de9fc44f56fa58f5349378238990fbf Mon Sep 17 00:00:00 2001 From: Peter Mein Date: Sun, 16 Sep 2018 14:21:13 +0200 Subject: [PATCH 022/589] Added support for Thumbor (#1373) --- DOCUMENTATION/content/documentation/index.md | 21 ++++ docker-compose.yml | 116 +++++++++++++++++++ env-example | 116 +++++++++++++++++++ thumbor/Dockerfile | 5 + 4 files changed, 258 insertions(+) create mode 100644 thumbor/Dockerfile diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index c3668d1..78dadf8 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1043,6 +1043,27 @@ docker-compose up -d minio +
+ +## Use Thumbor + +Thumbor is a smart imaging service. It enables on-demand crop, resizing and flipping of images. ([Thumbor](https://github.com/thumbor/thumbor)) + +1 - Configure Thumbor: + - Checkout all the options under the thumbor settings + + +2 - Run the Thumbor Container (`minio`) with the `docker-compose up` command. Example: + +```bash +docker-compose up -d thumbor +``` + +3 - Navigate to an example image on `http://localhost:8000/unsafe/300x300/i.imgur.com/bvjzPct.jpg` + +For more documentation on Thumbor visit the [Thumbor documenation](http://thumbor.readthedocs.io/en/latest/index.html) page + +
## Use AWS diff --git a/docker-compose.yml b/docker-compose.yml index 990506c..cb5056e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -707,6 +707,122 @@ services: networks: - backend +### Thumbor ######################################### + thumbor: + build: ./thumbor + volumes: + - ${DATA_SAVE_PATH}/thumbor/data:/data + - ${DATA_SAVE_PATH}/thumbor/data:/logs + ports: + - "${THUMBOR_PORT}:8000" + environment: + - THUMBOR_LOG_FORMAT=${THUMBOR_LOG_FORMAT} + - THUMBOR_LOG_DATE_FORMAT=${THUMBOR_LOG_DATE_FORMAT} + - MAX_WIDTH=${MAX_WIDTH} + - MAX_HEIGHT=${MAX_HEIGHT} + - MIN_WIDTH=${MIN_WIDTH} + - MIN_HEIGHT=${MIN_HEIGHT} + - ALLOWED_SOURCES=${ALLOWED_SOURCES} + - QUALITY=${QUALITY} + - WEBP_QUALITY=${WEBP_QUALITY} + - PNG_COMPRESSION_LEVEL=${PNG_COMPRESSION_LEVEL} + - AUTO_WEBP=${AUTO_WEBP} + - MAX_AGE=${MAX_AGE} + - MAX_AGE_TEMP_IMAGE=${MAX_AGE_TEMP_IMAGE} + - RESPECT_ORIENTATION=${RESPECT_ORIENTATION} + - IGNORE_SMART_ERRORS=${IGNORE_SMART_ERRORS} + - PRESERVE_EXIF_INFO=${PRESERVE_EXIF_INFO} + - ALLOW_ANIMATED_GIFS=${ALLOW_ANIMATED_GIFS} + - USE_GIFSICLE_ENGINE=${USE_GIFSICLE_ENGINE} + - USE_BLACKLIST=${USE_BLACKLIST} + - LOADER=${LOADER} + - STORAGE=${STORAGE} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - RESULT_STORAGE=${RESULT_STORAGE} + - ENGINE=${ENGINE} + - SECURITY_KEY=${SECURITY_KEY} + - ALLOW_UNSAFE_URL=${ALLOW_UNSAFE_URL} + - ALLOW_OLD_URLS=${ALLOW_OLD_URLS} + - FILE_LOADER_ROOT_PATH=${FILE_LOADER_ROOT_PATH} + - HTTP_LOADER_CONNECT_TIMEOUT=${HTTP_LOADER_CONNECT_TIMEOUT} + - HTTP_LOADER_REQUEST_TIMEOUT=${HTTP_LOADER_REQUEST_TIMEOUT} + - HTTP_LOADER_FOLLOW_REDIRECTS=${HTTP_LOADER_FOLLOW_REDIRECTS} + - HTTP_LOADER_MAX_REDIRECTS=${HTTP_LOADER_MAX_REDIRECTS} + - HTTP_LOADER_FORWARD_USER_AGENT=${HTTP_LOADER_FORWARD_USER_AGENT} + - HTTP_LOADER_DEFAULT_USER_AGENT=${HTTP_LOADER_DEFAULT_USER_AGENT} + - HTTP_LOADER_PROXY_HOST=${HTTP_LOADER_PROXY_HOST} + - HTTP_LOADER_PROXY_PORT=${HTTP_LOADER_PROXY_PORT} + - HTTP_LOADER_PROXY_USERNAME=${HTTP_LOADER_PROXY_USERNAME} + - HTTP_LOADER_PROXY_PASSWORD=${HTTP_LOADER_PROXY_PASSWORD} + - HTTP_LOADER_CA_CERTS=${HTTP_LOADER_CA_CERTS} + - HTTP_LOADER_VALIDATE_CERTS=${HTTP_LOADER_VALIDATE_CERTS} + - HTTP_LOADER_CLIENT_KEY=${HTTP_LOADER_CLIENT_KEY} + - HTTP_LOADER_CLIENT_CERT=${HTTP_LOADER_CLIENT_CERT} + - HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT=${HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT} + - STORAGE_EXPIRATION_SECONDS=${STORAGE_EXPIRATION_SECONDS} + - STORES_CRYPTO_KEY_FOR_EACH_IMAGE=${STORES_CRYPTO_KEY_FOR_EACH_IMAGE} + - FILE_STORAGE_ROOT_PATH=${FILE_STORAGE_ROOT_PATH} + - UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE} + - UPLOAD_ENABLED=${UPLOAD_ENABLED} + - UPLOAD_PHOTO_STORAGE=${UPLOAD_PHOTO_STORAGE} + - UPLOAD_DELETE_ALLOWED=${UPLOAD_DELETE_ALLOWED} + - UPLOAD_PUT_ALLOWED=${UPLOAD_PUT_ALLOWED} + - UPLOAD_DEFAULT_FILENAME=${UPLOAD_DEFAULT_FILENAME} + - MONGO_STORAGE_SERVER_HOST=${MONGO_STORAGE_SERVER_HOST} + - MONGO_STORAGE_SERVER_PORT=${MONGO_STORAGE_SERVER_PORT} + - MONGO_STORAGE_SERVER_DB=${MONGO_STORAGE_SERVER_DB} + - MONGO_STORAGE_SERVER_COLLECTION=${MONGO_STORAGE_SERVER_COLLECTION} + - REDIS_STORAGE_SERVER_HOST=${REDIS_STORAGE_SERVER_HOST} + - REDIS_STORAGE_SERVER_PORT=${REDIS_STORAGE_SERVER_PORT} + - REDIS_STORAGE_SERVER_DB=${REDIS_STORAGE_SERVER_DB} + - REDIS_STORAGE_SERVER_PASSWORD=${REDIS_STORAGE_SERVER_PASSWORD} + - REDIS_RESULT_STORAGE_SERVER_HOST=${REDIS_RESULT_STORAGE_SERVER_HOST} + - REDIS_RESULT_STORAGE_SERVER_PORT=${REDIS_RESULT_STORAGE_SERVER_PORT} + - REDIS_RESULT_STORAGE_SERVER_DB=${REDIS_RESULT_STORAGE_SERVER_DB} + - REDIS_RESULT_STORAGE_SERVER_PASSWORD=${REDIS_RESULT_STORAGE_SERVER_PASSWORD} + - MEMCACHE_STORAGE_SERVERS=${MEMCACHE_STORAGE_SERVERS} + - MIXED_STORAGE_FILE_STORAGE=${MIXED_STORAGE_FILE_STORAGE} + - MIXED_STORAGE_CRYPTO_STORAGE=${MIXED_STORAGE_CRYPTO_STORAGE} + - MIXED_STORAGE_DETECTOR_STORAGE=${MIXED_STORAGE_DETECTOR_STORAGE} + - META_CALLBACK_NAME=${META_CALLBACK_NAME} + - DETECTORS=${DETECTORS} + - FACE_DETECTOR_CASCADE_FILE=${FACE_DETECTOR_CASCADE_FILE} + - OPTIMIZERS=${OPTIMIZERS} + - JPEGTRAN_PATH=${JPEGTRAN_PATH} + - PROGRESSIVE_JPEG=${PROGRESSIVE_JPEG} + - RESULT_STORAGE_EXPIRATION_SECONDS=${RESULT_STORAGE_EXPIRATION_SECONDS} + - RESULT_STORAGE_FILE_STORAGE_ROOT_PATH=${RESULT_STORAGE_FILE_STORAGE_ROOT_PATH} + - RESULT_STORAGE_STORES_UNSAFE=${RESULT_STORAGE_STORES_UNSAFE} + - REDIS_QUEUE_SERVER_HOST=${REDIS_QUEUE_SERVER_HOST} + - REDIS_QUEUE_SERVER_PORT=${REDIS_QUEUE_SERVER_PORT} + - REDIS_QUEUE_SERVER_DB=${REDIS_QUEUE_SERVER_DB} + - REDIS_QUEUE_SERVER_PASSWORD=${REDIS_QUEUE_SERVER_PASSWORD} + - SQS_QUEUE_KEY_ID=${SQS_QUEUE_KEY_ID} + - SQS_QUEUE_KEY_SECRET=${SQS_QUEUE_KEY_SECRET} + - SQS_QUEUE_REGION=${SQS_QUEUE_REGION} + - USE_CUSTOM_ERROR_HANDLING=${USE_CUSTOM_ERROR_HANDLING} + - ERROR_HANDLER_MODULE=${ERROR_HANDLER_MODULE} + - ERROR_FILE_LOGGER=${ERROR_FILE_LOGGER} + - ERROR_FILE_NAME_USE_CONTEXT=${ERROR_FILE_NAME_USE_CONTEXT} + - SENTRY_DSN_URL=${SENTRY_DSN_URL} + - TC_AWS_REGION=${TC_AWS_REGION} + - TC_AWS_ENDPOINT=${TC_AWS_ENDPOINT} + - TC_AWS_STORAGE_BUCKET=${TC_AWS_STORAGE_BUCKET} + - TC_AWS_STORAGE_ROOT_PATH=${TC_AWS_STORAGE_ROOT_PATH} + - TC_AWS_LOADER_BUCKET=${TC_AWS_LOADER_BUCKET} + - TC_AWS_LOADER_ROOT_PATH=${TC_AWS_LOADER_ROOT_PATH} + - TC_AWS_RESULT_STORAGE_BUCKET=${TC_AWS_RESULT_STORAGE_BUCKET} + - TC_AWS_RESULT_STORAGE_ROOT_PATH=${TC_AWS_RESULT_STORAGE_ROOT_PATH} + - TC_AWS_STORAGE_SSE=${TC_AWS_STORAGE_SSE} + - TC_AWS_STORAGE_RRS=${TC_AWS_STORAGE_RRS} + - TC_AWS_ENABLE_HTTP_LOADER=${TC_AWS_ENABLE_HTTP_LOADER} + - TC_AWS_ALLOWED_BUCKETS=${TC_AWS_ALLOWED_BUCKETS} + - TC_AWS_STORE_METADATA=${TC_AWS_STORE_METADATA} + networks: + - frontend + - backend + ### AWS EB-CLI ################################################ aws: build: diff --git a/env-example b/env-example index aa16e5f..89929d3 100644 --- a/env-example +++ b/env-example @@ -365,6 +365,122 @@ CADDY_CONFIG_PATH=./caddy/caddy LARAVEL_ECHO_SERVER_PORT=6001 +### DOCKER-SYNC ######################################################################################################## + +# osx: 'native_osx' (default) +# windows: 'unison' +# linux: docker-sync not required + +DOCKER_SYNC_STRATEGY=native_osx + +### THUMBOR ############################################################################################################ + +THUMBOR_PORT=8000 +THUMBOR_LOG_FORMAT="%(asctime)s %(name)s:%(levelname)s %(message)s" +THUMBOR_LOG_DATE_FORMAT="%Y-%m-%d %H:%M:%S" +MAX_WIDTH=0 +MAX_HEIGHT=0 +MIN_WIDTH=1 +MIN_HEIGHT=1 +ALLOWED_SOURCES=[] +QUALITY=80 +WEBP_QUALITY=None +PNG_COMPRESSION_LEVEL=6 +AUTO_WEBP=False +MAX_AGE=86400 +MAX_AGE_TEMP_IMAGE=0 +RESPECT_ORIENTATION=False +IGNORE_SMART_ERRORS=False +PRESERVE_EXIF_INFO=False +ALLOW_ANIMATED_GIFS=True +USE_GIFSICLE_ENGINE=False +USE_BLACKLIST=False +LOADER=thumbor.loaders.http_loader +STORAGE=thumbor.storages.file_storage +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +RESULT_STORAGE=thumbor.result_storages.file_storage +ENGINE=thumbor.engines.pil +SECURITY_KEY="MY_SECURE_KEY" +ALLOW_UNSAFE_URL=True +ALLOW_OLD_URLS=True +FILE_LOADER_ROOT_PATH=/data/loader +HTTP_LOADER_CONNECT_TIMEOUT=5 +HTTP_LOADER_REQUEST_TIMEOUT=20 +HTTP_LOADER_FOLLOW_REDIRECTS=True +HTTP_LOADER_MAX_REDIRECTS=5 +HTTP_LOADER_FORWARD_USER_AGENT=False +HTTP_LOADER_DEFAULT_USER_AGENT="Thumbor/5.2.1" +HTTP_LOADER_PROXY_HOST=None +HTTP_LOADER_PROXY_PORT=None +HTTP_LOADER_PROXY_USERNAME=None +HTTP_LOADER_PROXY_PASSWORD=None +HTTP_LOADER_CA_CERTS=None +HTTP_LOADER_VALIDATE_CERTS=True +HTTP_LOADER_CLIENT_KEY=None +HTTP_LOADER_CLIENT_CERT=None +HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT=False +STORAGE_EXPIRATION_SECONDS=2592000 +STORES_CRYPTO_KEY_FOR_EACH_IMAGE=False +FILE_STORAGE_ROOT_PATH=/data/storage +UPLOAD_MAX_SIZE=0 +UPLOAD_ENABLED=False +UPLOAD_PHOTO_STORAGE=thumbor.storages.file_storage +UPLOAD_DELETE_ALLOWED=False +UPLOAD_PUT_ALLOWED=False +UPLOAD_DEFAULT_FILENAME=image +MONGO_STORAGE_SERVER_HOST=mongo +MONGO_STORAGE_SERVER_PORT=27017 +MONGO_STORAGE_SERVER_DB=thumbor +MONGO_STORAGE_SERVER_COLLECTION=images +REDIS_STORAGE_SERVER_HOST=redis +REDIS_STORAGE_SERVER_PORT=6379 +REDIS_STORAGE_SERVER_DB=0 +REDIS_STORAGE_SERVER_PASSWORD=None +REDIS_RESULT_STORAGE_SERVER_HOST=redis +REDIS_RESULT_STORAGE_SERVER_PORT=6379 +REDIS_RESULT_STORAGE_SERVER_DB=0 +REDIS_RESULT_STORAGE_SERVER_PASSWORD=None +MEMCACHE_STORAGE_SERVERS=["localhost:11211",] +MIXED_STORAGE_FILE_STORAGE=thumbor.storages.no_storage +MIXED_STORAGE_CRYPTO_STORAGE=thumbor.storages.no_storage +MIXED_STORAGE_DETECTOR_STORAGE=thumbor.storages.no_storage +META_CALLBACK_NAME=None +DETECTORS=[] +FACE_DETECTOR_CASCADE_FILE=haarcascade_frontalface_alt.xml +OPTIMIZERS=[] +JPEGTRAN_PATH=/usr/bin/jpegtran +PROGRESSIVE_JPEG=True +FILTERS=["thumbor.filters.brightness", "thumbor.filters.contrast", "thumbor.filters.rgb", "thumbor.filters.round_corner", "thumbor.filters.quality", "thumbor.filters.noise", "thumbor.filters.watermark", "thumbor.filters.equalize", "thumbor.filters.fill", "thumbor.filters.sharpen", "thumbor.filters.strip_icc", "thumbor.filters.frame", "thumbor.filters.grayscale", "thumbor.filters.rotate", "thumbor.filters.format", "thumbor.filters.max_bytes", "thumbor.filters.convolution", "thumbor.filters.blur", "thumbor.filters.extract_focal", "thumbor.filters.no_upscale"] +RESULT_STORAGE_EXPIRATION_SECONDS=0 +RESULT_STORAGE_FILE_STORAGE_ROOT_PATH=/data/result_storage +RESULT_STORAGE_STORES_UNSAFE=False +REDIS_QUEUE_SERVER_HOST=redis +REDIS_QUEUE_SERVER_PORT=6379 +REDIS_QUEUE_SERVER_DB="0" +REDIS_QUEUE_SERVER_PASSWORD=None +SQS_QUEUE_KEY_ID=None +SQS_QUEUE_KEY_SECRET=None +SQS_QUEUE_REGION=us-east-1 +USE_CUSTOM_ERROR_HANDLING=False +ERROR_HANDLER_MODULE=thumbor.error_handlers.sentry +ERROR_FILE_LOGGER=None +ERROR_FILE_NAME_USE_CONTEXT="False" +SENTRY_DSN_URL= +TC_AWS_REGION=eu-west-1 +TC_AWS_ENDPOINT=None +TC_AWS_STORAGE_BUCKET= +TC_AWS_STORAGE_ROOT_PATH= +TC_AWS_LOADER_BUCKET= +TC_AWS_LOADER_ROOT_PATH= +TC_AWS_RESULT_STORAGE_BUCKET= +TC_AWS_RESULT_STORAGE_ROOT_PATH= +TC_AWS_STORAGE_SSE=False +TC_AWS_STORAGE_RRS=False +TC_AWS_ENABLE_HTTP_LOADER=False +TC_AWS_ALLOWED_BUCKETS=False +TC_AWS_STORE_METADATA=False + ### SOLR ################################################## SOLR_VERSION=5.5 diff --git a/thumbor/Dockerfile b/thumbor/Dockerfile new file mode 100644 index 0000000..ee36c2e --- /dev/null +++ b/thumbor/Dockerfile @@ -0,0 +1,5 @@ +FROM apsl/thumbor + +CMD ["thumbor"] + +EXPOSE 8000 From d5d90738634ce0f6c7179d0edcb2732fe52efd55 Mon Sep 17 00:00:00 2001 From: ganl <769323213@qq.com> Date: Mon, 17 Sep 2018 22:07:07 +0800 Subject: [PATCH 023/589] Fix `CHANGE_SOURCE` argument always false for nginx's Dockerfile (#1786) --- DOCUMENTATION/content/documentation/index.md | 2 +- docker-compose.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 78dadf8..17e05e1 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1886,7 +1886,7 @@ This error sometimes happens because your Laravel application isn't running on t ## I get stuck when building nginx on `fetch http://mirrors.aliyun.com/alpine/v3.5/main/x86_64/APKINDEX.tar.gz` -As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-293296687), removing the line `RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories` from `nginx/Dockerfile` solves the problem. +As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-419652646), Already fixed,just set `CHANGE_SOURCE` to false. ## Custom composer repo packagist url and npm registry url diff --git a/docker-compose.yml b/docker-compose.yml index cb5056e..2e5fc7b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -193,6 +193,7 @@ services: args: - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER} - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} + - CHANGE_SOURCE=${CHANGE_SOURCE} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ${NGINX_HOST_LOG_PATH}:/var/log/nginx From 784aab20433db48b6ceb7fd06fa45b920db784c6 Mon Sep 17 00:00:00 2001 From: Null Date: Mon, 17 Sep 2018 17:11:30 +0300 Subject: [PATCH 024/589] Update NVM installer (#1794) --- workspace/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index b87fab2..1863615 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -446,7 +446,8 @@ ENV NVM_DIR /home/laradock/.nvm RUN if [ ${INSTALL_NODE} = true ]; then \ # Install nvm (A Node Version Manager) - curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash \ + mkdir -p $NVM_DIR && \ + curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash \ && . $NVM_DIR/nvm.sh \ && nvm install ${NODE_VERSION} \ && nvm use ${NODE_VERSION} \ From 919cde3a762eb43d9ce2d4ff1f04ead8039577a8 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Mon, 17 Sep 2018 22:28:12 +0800 Subject: [PATCH 025/589] update thumbor volume var name. (#1801) --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2e5fc7b..062b84e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -712,8 +712,8 @@ services: thumbor: build: ./thumbor volumes: - - ${DATA_SAVE_PATH}/thumbor/data:/data - - ${DATA_SAVE_PATH}/thumbor/data:/logs + - ${DATA_PATH_HOST}/thumbor/data:/data + - ${DATA_PATH_HOST}/thumbor/data:/logs ports: - "${THUMBOR_PORT}:8000" environment: From 436df887c9c606f83aa85516e8fd0e9ced7f5e32 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Tue, 18 Sep 2018 11:15:59 +0800 Subject: [PATCH 026/589] Add docker registry (#1770) * add docker registry and docker registry web ui --- docker-compose.yml | 29 +++++++++++++++++++++++++++++ docker-registry/Dockerfile | 3 +++ docker-web-ui/Dockerfile | 3 +++ env-example | 11 +++++++++++ 4 files changed, 46 insertions(+) create mode 100644 docker-registry/Dockerfile create mode 100644 docker-web-ui/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 062b84e..ea3e325 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1070,6 +1070,35 @@ services: networks: - backend +### DOCKER-REGISTRY ################################################ + docker-registry: + build: + context: ./docker-registry + volumes: + - /etc/localtime:/etc/localtime:ro + - ${DATA_PATH_HOST}/docker-registry:/var/lib/registry + ports: + - "${DOCKER_REGISTRY_PORT}:5000" + networks: + - backend + +### DOCKER-WEB-UI ################################################ + docker-web-ui: + build: + context: ./docker-web-ui + environment: + - TZ=${WORKSPACE_TIMEZONE} + - ENV_DOCKER_REGISTRY_HOST=${DOCKER_WEBUI_REGISTRY_HOST} + - ENV_DOCKER_REGISTRY_PORT=${DOCKER_WEBUI_REGISTRY_PORT} + - ENV_DOCKER_REGISTRY_USE_SSL=${DOCKER_REGISTRY_USE_SSL} + - ENV_MODE_BROWSE_ONLY=${DOCKER_REGISTRY_BROWSE_ONLY} + volumes: + - /etc/localtime:/etc/localtime:ro + ports: + - "${DOCKER_WEBUI_PORT}:80" + networks: + - frontend + - backend ### MAILU ################################################ mailu: diff --git a/docker-registry/Dockerfile b/docker-registry/Dockerfile new file mode 100644 index 0000000..daa7c57 --- /dev/null +++ b/docker-registry/Dockerfile @@ -0,0 +1,3 @@ +FROM registry:2 + +LABEL maintainer="ahkui " diff --git a/docker-web-ui/Dockerfile b/docker-web-ui/Dockerfile new file mode 100644 index 0000000..48e01bc --- /dev/null +++ b/docker-web-ui/Dockerfile @@ -0,0 +1,3 @@ +FROM konradkleine/docker-registry-frontend:v2 + +LABEL maintainer="ahkui " diff --git a/env-example b/env-example index 89929d3..b4a7733 100644 --- a/env-example +++ b/env-example @@ -539,6 +539,17 @@ IDE_WEBIDE_PORT=984 IDE_CODIAD_PORT=985 IDE_ICECODER_PORT=986 +### DOCKERREGISTRY ############################################### +DOCKER_REGISTRY_PORT=5000 + +### DOCKERWEBUI ############################################### +DOCKER_WEBUI_REGISTRY_HOST=docker-registry +DOCKER_WEBUI_REGISTRY_PORT=5000 +# if have use https proxy please set to 1 +DOCKER_REGISTRY_USE_SSL=0 +DOCKER_REGISTRY_BROWSE_ONLY=false +DOCKER_WEBUI_PORT=8754 + ### MAILU ############################################### MAILU_VERSION=latest MAILU_RECAPTCHA_PUBLIC_KEY= From db02fe7570c50615e18dd7371cc5d8ed443bab4f Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Tue, 18 Sep 2018 21:44:36 +0800 Subject: [PATCH 027/589] Fix Travis CI build failed (#1803) php-fpm: Unable to locate package libfaketime --- php-fpm/Dockerfile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index dd7f0d1..e9172dd 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -67,6 +67,18 @@ RUN if [ ${INSTALL_SSH2} = true ]; then \ docker-php-ext-enable ssh2 \ ;fi +########################################################################### +# libfaketime: +########################################################################### + +USER root + +ARG INSTALL_FAKETIME=false + +RUN if [ ${INSTALL_FAKETIME} = true ]; then \ + apt-get install -y libfaketime \ +;fi + ########################################################################### # SOAP: ########################################################################### @@ -517,18 +529,6 @@ RUN if [ ${INSTALL_CALENDAR} = true ]; then \ docker-php-ext-install calendar \ ;fi -########################################################################### -# libfaketime: -########################################################################### - -USER root - -ARG INSTALL_FAKETIME=false - -RUN if [ ${INSTALL_FAKETIME} = true ]; then \ - apt-get install -y libfaketime \ -;fi - ########################################################################### # Check PHP version: ########################################################################### From 9cfe5c61565a77b4da40817f3e1d45e18ef5920d Mon Sep 17 00:00:00 2001 From: Frank Yuan Date: Sat, 22 Sep 2018 15:45:41 +0800 Subject: [PATCH 028/589] add phalcon ext (#1806) * add phalcon ext --- DOCUMENTATION/content/introduction/index.md | 2 +- docker-compose.yml | 4 ++++ env-example | 7 +++++++ php-fpm/Dockerfile | 19 +++++++++++++++++++ workspace/Dockerfile | 19 +++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 4e15223..6544270 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -97,7 +97,7 @@ Beanstalkd - RabbitMQ - PHP Worker - **Queueing Management:** Beanstalkd Console - RabbitMQ Console - **Random Tools:** -Mailu - HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Grafana - Gitlab - Mailhog - MailDev - Minio - Varnish - Swoole - NetData - Portainer - Laravel Echo... +Mailu - HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Grafana - Gitlab - Mailhog - MailDev - Minio - Varnish - Swoole - NetData - Portainer - Laravel Echo - Phalcon... Laradock introduces the **Workspace** Image, as a development environment. It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of Containers and tools you may choose. diff --git a/docker-compose.yml b/docker-compose.yml index ea3e325..91e62b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,6 +48,7 @@ services: context: ./workspace args: - LARADOCK_PHP_VERSION=${PHP_VERSION} + - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_SUBVERSION=${WORKSPACE_INSTALL_SUBVERSION} - INSTALL_XDEBUG=${WORKSPACE_INSTALL_XDEBUG} - INSTALL_PHPDBG=${WORKSPACE_INSTALL_PHPDBG} @@ -88,6 +89,7 @@ services: - INSTALL_TERRAFORM=${WORKSPACE_INSTALL_TERRAFORM} - INSTALL_DUSK_DEPS=${WORKSPACE_INSTALL_DUSK_DEPS} - INSTALL_PG_CLIENT=${WORKSPACE_INSTALL_PG_CLIENT} + - INSTALL_PHALCON=${WORKSPACE_INSTALL_PHALCON} - INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE} - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} - INSTALL_IONCUBE=${WORKSPACE_INSTALL_IONCUBE} @@ -119,6 +121,7 @@ services: context: ./php-fpm args: - LARADOCK_PHP_VERSION=${PHP_VERSION} + - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_XDEBUG=${PHP_FPM_INSTALL_XDEBUG} - INSTALL_PHPDBG=${PHP_FPM_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} @@ -144,6 +147,7 @@ services: - INSTALL_INTL=${PHP_FPM_INSTALL_INTL} - INSTALL_GHOSTSCRIPT=${PHP_FPM_INSTALL_GHOSTSCRIPT} - INSTALL_LDAP=${PHP_FPM_INSTALL_LDAP} + - INSTALL_PHALCON=${PHP_FPM_INSTALL_PHALCON} - INSTALL_SWOOLE=${PHP_FPM_INSTALL_SWOOLE} - INSTALL_IMAGE_OPTIMIZERS=${PHP_FPM_INSTALL_IMAGE_OPTIMIZERS} - INSTALL_IMAGEMAGICK=${PHP_FPM_INSTALL_IMAGEMAGICK} diff --git a/env-example b/env-example index b4a7733..da60341 100644 --- a/env-example +++ b/env-example @@ -37,6 +37,11 @@ COMPOSE_PROJECT_NAME=laradock # Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 7.2 - 7.1 - 7.0 - 5.6 PHP_VERSION=7.2 +### Phalcon Version ########################################### + +# Select a Phalcon version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 3.4.0+ +PHALCON_VERSION=3.4.1 + ### PHP Interpreter ####################################### # Select the PHP Interpreter. Accepted values: hhvm - php-fpm @@ -114,6 +119,7 @@ WORKSPACE_INSTALL_IMAGEMAGICK=false WORKSPACE_INSTALL_TERRAFORM=false WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false +WORKSPACE_INSTALL_PHALCON=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false @@ -149,6 +155,7 @@ PHP_FPM_INSTALL_AEROSPIKE=false PHP_FPM_INSTALL_PGSQL=false PHP_FPM_INSTALL_GHOSTSCRIPT=false PHP_FPM_INSTALL_LDAP=false +PHP_FPM_INSTALL_PHALCON=false PHP_FPM_INSTALL_SWOOLE=false PHP_FPM_INSTALL_PG_CLIENT=false PHP_FPM_INSTALL_PCNTL=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index e9172dd..760ffd7 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -529,6 +529,25 @@ RUN if [ ${INSTALL_CALENDAR} = true ]; then \ docker-php-ext-install calendar \ ;fi +########################################################################### +# Phalcon: +########################################################################### + +ARG INSTALL_PHALCON=false +ARG LARADOCK_PHALCON_VERSION +ENV LARADOCK_PHALCON_VERSION ${LARADOCK_PHALCON_VERSION} + +RUN if [ $INSTALL_PHALCON = true ]; then \ + apt-get update && apt-get install -y unzip libpcre3-dev gcc make re2c \ + && curl -L -o /tmp/cphalcon.zip https://github.com/phalcon/cphalcon/archive/v${LARADOCK_PHALCON_VERSION}.zip \ + && unzip -d /tmp/ /tmp/cphalcon.zip \ + && cd /tmp/cphalcon-${LARADOCK_PHALCON_VERSION}/build \ + && ./install \ + && echo "extension=phalcon.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini \ + && ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-phalcon.ini \ + && rm -rf /tmp/cphalcon* \ +;fi + ########################################################################### # Check PHP version: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 1863615..9899308 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -844,6 +844,25 @@ RUN if [ ${INSTALL_DUSK_DEPS} = true ]; then \ && rm chromedriver_linux64.zip \ ;fi +########################################################################### +# Phalcon: +########################################################################### + +ARG INSTALL_PHALCON=false +ARG LARADOCK_PHALCON_VERSION +ENV LARADOCK_PHALCON_VERSION ${LARADOCK_PHALCON_VERSION} + +RUN if [ $INSTALL_PHALCON = true ]; then \ + apt-get update && apt-get install -y unzip libpcre3-dev gcc make re2c \ + && curl -L -o /tmp/cphalcon.zip https://github.com/phalcon/cphalcon/archive/v${LARADOCK_PHALCON_VERSION}.zip \ + && unzip -d /tmp/ /tmp/cphalcon.zip \ + && cd /tmp/cphalcon-${LARADOCK_PHALCON_VERSION}/build \ + && ./install \ + && echo "extension=phalcon.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini \ + && ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-phalcon.ini \ + && rm -rf /tmp/cphalcon* \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From c88683161384c9c47c78c153060997ca232a7f02 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Sat, 27 Oct 2018 15:38:40 +0200 Subject: [PATCH 029/589] integrate seedanddew --- .../hugo-material-docs/layouts/index.html | 27 ++++++++++--------- .../layouts/partials/head.html | 21 +++++++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html b/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html index f76e458..5ee52d1 100644 --- a/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html +++ b/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html @@ -25,18 +25,21 @@
- - - - - - - + +
+ + + + + + + +
{{ range where .Site.Pages "Type" "index" }}

{{ .Title }} {{ if .IsDraft }} (Draft){{ end }}

diff --git a/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/head.html b/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/head.html index 0953395..ea23eb8 100644 --- a/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/head.html +++ b/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/head.html @@ -70,6 +70,27 @@ {{ end }} + + {{ with .RSSLink }} From 538b6aa0cd484c475c5c537a763e4e1fe330fcae Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Sat, 27 Oct 2018 16:04:16 +0200 Subject: [PATCH 030/589] fix home page logo link --- .github/README.md | 2 +- .github/home-page-images/laradock-logo.jpg | Bin 0 -> 293572 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .github/home-page-images/laradock-logo.jpg diff --git a/.github/README.md b/.github/README.md index 948ec93..2de4462 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,5 +1,5 @@

- Laradock Logo + Laradock Logo

A Docker PHP development environment that facilitates running PHP Apps on Docker

diff --git a/.github/home-page-images/laradock-logo.jpg b/.github/home-page-images/laradock-logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d6af558747e731b8c6f686f816da781759f7148 GIT binary patch literal 293572 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

pUQ;CoV&f7Eer50Q#~A>vb# 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

{ECP+MvmroBRP`ed-u* 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 KZ*%gELg`j*puSt})Ddr6%r+Noni2?`v<%ps!{D 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 literal 0 HcmV?d00001 From 876336bc1a8f873b4c8e34b5867f581c74f6ec95 Mon Sep 17 00:00:00 2001 From: Adriel Kloppenburg Date: Wed, 14 Nov 2018 00:44:43 +1300 Subject: [PATCH 031/589] Fixed typo (#1358) --- DOCUMENTATION/content/getting-started/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index a067fa3..8262ead 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -161,7 +161,7 @@ We recommend using a Docker version which is newer than 1.13. cp env-example .env ``` -You can edit the `.env` file to choose which software you want to be installed in your environment. You can always refer to the `docker-compose.yml` file to see how those variables have been used. +You can edit the `.env` file to choose which software's you want to be installed in your environment. You can always refer to the `docker-compose.yml` file to see how those variables are being used. Depending on the host's operating system you may need to change the value given to `COMPOSE_FILE`. When you are running Laradock on Mac OS the correct file separator to use is `:`. When running Laradock from a Windows environment multiple files must be separated with `;`. From 1dac382827c392f33a18aa59ff13ab4865277416 Mon Sep 17 00:00:00 2001 From: Abdelrahman Omran Date: Tue, 13 Nov 2018 16:30:41 +0400 Subject: [PATCH 032/589] Drop the useless PHP tokenizer extension install step (#1650) It is bundled and enabled by default in the PHP language already, and adding this step raises a warning: warning: tokenizer (tokenizer.so) is already loaded! Also if this option disabled, it's still installed as part of the language anyway! --- docker-compose.yml | 1 - env-example | 1 - php-fpm/Dockerfile | 9 --------- 3 files changed, 11 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 91e62b7..2f9ff02 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -143,7 +143,6 @@ services: - INSTALL_MYSQLI=${PHP_FPM_INSTALL_MYSQLI} - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_PG_CLIENT=${PHP_FPM_INSTALL_PG_CLIENT} - - INSTALL_TOKENIZER=${PHP_FPM_INSTALL_TOKENIZER} - INSTALL_INTL=${PHP_FPM_INSTALL_INTL} - INSTALL_GHOSTSCRIPT=${PHP_FPM_INSTALL_GHOSTSCRIPT} - INSTALL_LDAP=${PHP_FPM_INSTALL_LDAP} diff --git a/env-example b/env-example index da60341..e975f78 100644 --- a/env-example +++ b/env-example @@ -134,7 +134,6 @@ WORKSPACE_SSH_PORT=2222 PHP_FPM_INSTALL_ZIP_ARCHIVE=true PHP_FPM_INSTALL_BCMATH=true PHP_FPM_INSTALL_MYSQLI=true -PHP_FPM_INSTALL_TOKENIZER=true PHP_FPM_INSTALL_INTL=true PHP_FPM_INSTALL_IMAGEMAGICK=true PHP_FPM_INSTALL_OPCACHE=true diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 760ffd7..427214e 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -392,15 +392,6 @@ RUN if [ ${INSTALL_MYSQLI} = true ]; then \ docker-php-ext-install mysqli \ ;fi -########################################################################### -# Tokenizer Modifications: -########################################################################### - -ARG INSTALL_TOKENIZER=false - -RUN if [ ${INSTALL_TOKENIZER} = true ]; then \ - docker-php-ext-install tokenizer \ -;fi ########################################################################### # Human Language and Character Encoding Support: From 7219b3543aed519914508f3e2f62e35be5b35bf4 Mon Sep 17 00:00:00 2001 From: Vladyslav Shchepotin Date: Tue, 13 Nov 2018 14:44:51 +0200 Subject: [PATCH 033/589] Nginx: added OpenSSL for local development (#1527) * feature(nginx): add OpenSSL --- docker-compose.yml | 1 + env-example | 1 + nginx/Dockerfile | 4 +++- nginx/sites/app.conf.example | 6 ++++++ nginx/sites/default.conf | 6 ++++++ nginx/sites/laravel.conf.example | 6 ++++++ nginx/sites/symfony.conf.example | 6 ++++++ nginx/ssl/.gitkeep | 0 nginx/startup.sh | 9 +++++++++ 9 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 nginx/ssl/.gitkeep create mode 100644 nginx/startup.sh diff --git a/docker-compose.yml b/docker-compose.yml index 2f9ff02..1c88b9e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -201,6 +201,7 @@ services: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ${NGINX_HOST_LOG_PATH}:/var/log/nginx - ${NGINX_SITES_PATH}:/etc/nginx/sites-available + - ${NGINX_SSL_PATH}:/etc/nginx/ssl ports: - "${NGINX_HOST_HTTP_PORT}:80" - "${NGINX_HOST_HTTPS_PORT}:443" diff --git a/env-example b/env-example index e975f78..e33fea4 100644 --- a/env-example +++ b/env-example @@ -176,6 +176,7 @@ NGINX_HOST_LOG_PATH=./logs/nginx/ NGINX_SITES_PATH=./nginx/sites/ NGINX_PHP_UPSTREAM_CONTAINER=php-fpm NGINX_PHP_UPSTREAM_PORT=9000 +NGINX_SSL_PATH=./nginx/ssl/ ### APACHE ################################################ diff --git a/nginx/Dockerfile b/nginx/Dockerfile index 7af74fc..c648130 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -14,6 +14,7 @@ RUN if [ ${CHANGE_SOURCE} = true ]; then \ RUN apk update \ && apk upgrade \ + && apk add --no-cache openssl \ && apk add --no-cache bash \ && adduser -D -H -u 1000 -s /bin/bash www-data @@ -24,6 +25,7 @@ ARG PHP_UPSTREAM_PORT=9000 RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \ && rm /etc/nginx/conf.d/default.conf -CMD ["nginx"] +ADD ./startup.sh /opt/startup.sh +CMD ["/bin/bash", "/opt/startup.sh"] EXPOSE 80 443 diff --git a/nginx/sites/app.conf.example b/nginx/sites/app.conf.example index d8f29eb..a0f8357 100644 --- a/nginx/sites/app.conf.example +++ b/nginx/sites/app.conf.example @@ -3,6 +3,12 @@ server { listen 80; listen [::]:80; + # For https + # listen 443 ssl; + # listen [::]:443 ssl ipv6only=on; + # ssl_certificate /etc/nginx/ssl/default.crt; + # ssl_certificate_key /etc/nginx/ssl/default.key; + server_name app.test; root /var/www/app; index index.php index.html index.htm; diff --git a/nginx/sites/default.conf b/nginx/sites/default.conf index 3d1a10e..e02bb83 100644 --- a/nginx/sites/default.conf +++ b/nginx/sites/default.conf @@ -3,6 +3,12 @@ server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; + # For https + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server ipv6only=on; + # ssl_certificate /etc/nginx/ssl/default.crt; + # ssl_certificate_key /etc/nginx/ssl/default.key; + server_name localhost; root /var/www/public; index index.php index.html index.htm; diff --git a/nginx/sites/laravel.conf.example b/nginx/sites/laravel.conf.example index 40cd842..c30bf8a 100644 --- a/nginx/sites/laravel.conf.example +++ b/nginx/sites/laravel.conf.example @@ -3,6 +3,12 @@ server { listen 80; listen [::]:80; + # For https + # listen 443 ssl; + # listen [::]:443 ssl ipv6only=on; + # ssl_certificate /etc/nginx/ssl/default.crt; + # ssl_certificate_key /etc/nginx/ssl/default.key; + server_name laravel.test; root /var/www/laravel/public; index index.php index.html index.htm; diff --git a/nginx/sites/symfony.conf.example b/nginx/sites/symfony.conf.example index acb0aad..2834d74 100644 --- a/nginx/sites/symfony.conf.example +++ b/nginx/sites/symfony.conf.example @@ -3,6 +3,12 @@ server { listen 80; listen [::]:80; + # For https + # listen 443 ssl; + # listen [::]:443 ssl ipv6only=on; + # ssl_certificate /etc/nginx/ssl/default.crt; + # ssl_certificate_key /etc/nginx/ssl/default.key; + server_name symfony.test; root /var/www/projects/symfony/web; index index.php index.html index.htm; diff --git a/nginx/ssl/.gitkeep b/nginx/ssl/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/nginx/startup.sh b/nginx/startup.sh new file mode 100644 index 0000000..069d141 --- /dev/null +++ b/nginx/startup.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ ! -f /etc/nginx/ssl/default.crt ]; then + openssl genrsa -out "/etc/nginx/ssl/default.key" 2048 + openssl req -new -key "/etc/nginx/ssl/default.key" -out "/etc/nginx/ssl/default.csr" -subj "/CN=default/O=default/C=UK" + openssl x509 -req -days 365 -in "/etc/nginx/ssl/default.csr" -signkey "/etc/nginx/ssl/default.key" -out "/etc/nginx/ssl/default.crt" +fi + +nginx From 549094d7d20ee7552b6069ec48255fea624c3c3b Mon Sep 17 00:00:00 2001 From: Xiaolong Yang Date: Tue, 13 Nov 2018 20:47:52 +0800 Subject: [PATCH 034/589] Update Doc '.php-fpm' to './php-fpm' (#1848) --- DOCUMENTATION/content/guides/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index 05c72a7..03f0b96 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -418,7 +418,7 @@ laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222- ## Enable xDebug on php-fpm -In a host terminal sitting in the laradock folder, run: `.php-fpm/xdebug status` +In a host terminal sitting in the laradock folder, run: `./php-fpm/xdebug status` You should see something like the following: ``` @@ -430,7 +430,7 @@ Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Xdebug v2.4.1, Copyright (c) 2002-2016, by Derick Rethans ``` -Other commands include `.php-fpm/xdebug start | stop`. +Other commands include `./php-fpm/xdebug start | stop`. If you have enabled `xdebug=true` in `docker-compose.yml/php-fpm`, `xdebug` will already be running when `php-fpm` is started and listening for debug info on port 9000. @@ -516,9 +516,9 @@ If you have enabled `xdebug=true` in `docker-compose.yml/php-fpm`, `xdebug` will ### Debug WebSite - In case xDebug is disabled, from the `laradock` folder run: -`.php-fpm/xdebug start`. +`./php-fpm/xdebug start`. - To switch xdebug off, run: -`.php-fpm/xdebug stop` +`./php-fpm/xdebug stop` - Start Remote Debugging - ![DebugRemoteOn](/images/photos/PHPStorm/DebugRemoteOn.png) From 0ffea858d60d21f596c1b0ebf29bb6b6c3d555cf Mon Sep 17 00:00:00 2001 From: Null Date: Tue, 13 Nov 2018 14:51:26 +0200 Subject: [PATCH 035/589] Remove duplicate key (#1808) --- env-example | 8 -------- 1 file changed, 8 deletions(-) diff --git a/env-example b/env-example index e33fea4..00554ce 100644 --- a/env-example +++ b/env-example @@ -372,14 +372,6 @@ CADDY_CONFIG_PATH=./caddy/caddy LARAVEL_ECHO_SERVER_PORT=6001 -### DOCKER-SYNC ######################################################################################################## - -# osx: 'native_osx' (default) -# windows: 'unison' -# linux: docker-sync not required - -DOCKER_SYNC_STRATEGY=native_osx - ### THUMBOR ############################################################################################################ THUMBOR_PORT=8000 From c1e8e955a1b3041e2266f3a7307b3f1d88ed3375 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 13 Nov 2018 17:54:02 +0500 Subject: [PATCH 036/589] Fix typo in seed alias (#1843) --- workspace/aliases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 2c415ab..6cb1357 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -68,7 +68,7 @@ alias fresh="php artisan migrate:fresh" alias migrate="php artisan migrate" alias refresh="php artisan migrate:refresh" alias rollback="php artisan migrate:rollback" -alias seed="php artisan:seed" +alias seed="php artisan db:seed" alias serve="php artisan serve --quiet &" alias phpunit="./vendor/bin/phpunit" From 0af2115658b635a4eddcb38d4b9ab1e7ef096c97 Mon Sep 17 00:00:00 2001 From: vladyslavstartsev Date: Tue, 13 Nov 2018 14:55:15 +0200 Subject: [PATCH 037/589] added SOAP ext to php-worker (#1817) --- DOCUMENTATION/content/documentation/index.md | 1 + docker-compose.yml | 1 + env-example | 1 + php-worker/Dockerfile | 6 ++++++ 4 files changed, 9 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 17e05e1..7e24cf9 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -545,6 +545,7 @@ b) add a new service container by simply copy-paste this section below PHP-FPM c args: - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL} #Optionally install PGSQL PHP drivers - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} #Optionally install BCMath php package + - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} #Optionally install Soap php package volumes_from: - applications depends_on: diff --git a/docker-compose.yml b/docker-compose.yml index 1c88b9e..52dd3bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -179,6 +179,7 @@ services: - PHP_VERSION=${PHP_VERSION} - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL} - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} + - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./php-worker/supervisord.d:/etc/supervisord.d diff --git a/env-example b/env-example index 00554ce..286f9b2 100644 --- a/env-example +++ b/env-example @@ -167,6 +167,7 @@ PHP_FPM_FAKETIME=-0 PHP_WORKER_INSTALL_PGSQL=false PHP_WORKER_INSTALL_BCMATH=false +PHP_WORKER_INSTALL_SOAP=false ### NGINX ################################################# diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index d7c677d..50a5190 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -25,6 +25,12 @@ RUN apk --update add wget \ RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached +#Install SOAP package: +ARG INSTALL_SOAP=false +RUN if [ ${INSTALL_SOAP} = true ]; then \ + docker-php-ext-install soap \ +;fi + #Install BCMath package: ARG INSTALL_BCMATH=false RUN if [ ${INSTALL_BCMATH} = true ]; then \ From cf46b87a01c08f561727f2d4cdbe3513103d54a1 Mon Sep 17 00:00:00 2001 From: "Rex.Chien" Date: Tue, 13 Nov 2018 20:58:00 +0800 Subject: [PATCH 038/589] add mssql support for solr (#1829) --- docker-compose.yml | 1 + env-example | 1 + solr/Dockerfile | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 52dd3bb..34e172d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -706,6 +706,7 @@ services: args: - SOLR_VERSION=${SOLR_VERSION} - SOLR_DATAIMPORTHANDLER_MYSQL=${SOLR_DATAIMPORTHANDLER_MYSQL} + - SOLR_DATAIMPORTHANDLER_MSSQL=${SOLR_DATAIMPORTHANDLER_MSSQL} volumes: - ${DATA_PATH_HOST}/solr:/opt/solr/server/solr/mycores ports: diff --git a/env-example b/env-example index 286f9b2..c8e0cbc 100644 --- a/env-example +++ b/env-example @@ -486,6 +486,7 @@ TC_AWS_STORE_METADATA=False SOLR_VERSION=5.5 SOLR_PORT=8983 SOLR_DATAIMPORTHANDLER_MYSQL=false +SOLR_DATAIMPORTHANDLER_MSSQL=false ### GITLAB ############################################### GITLAB_HOST_HTTP_PORT=8989 diff --git a/solr/Dockerfile b/solr/Dockerfile index ba604a3..c133a6a 100644 --- a/solr/Dockerfile +++ b/solr/Dockerfile @@ -12,3 +12,13 @@ RUN if [ ${SOLR_DATAIMPORTHANDLER_MYSQL} = true ]; then \ && rm /tmp/mysql_connector.tar.gz \ ;fi +ARG SOLR_DATAIMPORTHANDLER_MSSQL=false +ENV SOLR_DATAIMPORTHANDLER_MSSQL ${SOLR_DATAIMPORTHANDLER_MSSQL} + +# download mssql connector for dataimporthandler +RUN if [ ${SOLR_DATAIMPORTHANDLER_MSSQL} = true ]; then \ + curl -L -o /tmp/mssql-jdbc-7.0.0.jre8.jar "https://github.com/Microsoft/mssql-jdbc/releases/download/v7.0.0/mssql-jdbc-7.0.0.jre8.jar" \ + && mkdir /opt/solr/contrib/dataimporthandler/lib \ + && mv /tmp/mssql-jdbc-7.0.0.jre8.jar "/opt/solr/contrib/dataimporthandler/lib/mssql-jdbc-7.0.0.jre8.jar" \ +;fi + From ca9d244396485f63d3f387860ab095c5e5866b2e Mon Sep 17 00:00:00 2001 From: Jon Date: Tue, 13 Nov 2018 13:31:05 +0000 Subject: [PATCH 039/589] Add default pgadmin credentials to docsls allow log in (#1864) --- DOCUMENTATION/content/documentation/index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 7e24cf9..5f54af3 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -866,6 +866,12 @@ docker-compose up -d postgres pgadmin 2 - Open your browser and visit the localhost on port **5050**: `http://localhost:5050` +3 - At login page use default credentials: + +Username : pgadmin4@pgadmin.org + +Password : admin + From 0ed5487ed7204aff6897db8de14e1e79469280fd Mon Sep 17 00:00:00 2001 From: Tolga Boztuna Date: Tue, 13 Nov 2018 16:35:19 +0300 Subject: [PATCH 040/589] fix typo in env-example (#1834) --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index c8e0cbc..f9fea34 100644 --- a/env-example +++ b/env-example @@ -589,7 +589,7 @@ MAILU_RECIPIENT_DELIMITER=+ # DMARC rua and ruf email MAILU_DMARC_RUA=admin MAILU_DMARC_RUF=admin -# Weclome email, enable and set a topic and body if you wish to send welcome +# Welcome email, enable and set a topic and body if you wish to send welcome # emails to all users. MAILU_WELCOME=True MAILU_WELCOME_SUBJECT=Welcome to your new email account From 441146b325a17b5e551db1436a496fa456ba215e Mon Sep 17 00:00:00 2001 From: fangke2688 Date: Wed, 21 Nov 2018 12:37:17 +0800 Subject: [PATCH 041/589] Change text error (#1882) Change text error --- DOCUMENTATION/content/documentation/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 5f54af3..4e926a5 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1239,7 +1239,7 @@ ssh -o PasswordAuthentication=no \ laradock@localhost ``` -To login as root, replace laradock@locahost with root@localhost. +To login as root, replace laradock@localhost with root@localhost. From 1519c8003646c76b3309cef29126f17f2c798341 Mon Sep 17 00:00:00 2001 From: Brice Date: Thu, 22 Nov 2018 11:05:44 +1100 Subject: [PATCH 042/589] Enable calling node commands (npm, bower, etc) from the host with 'docker-compose exec' (#1481) --- workspace/Dockerfile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 9899308..5070e40 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -487,6 +487,20 @@ RUN if [ ${INSTALL_NODE} = true ]; then \ # Add PATH for node ENV PATH $PATH:/home/laradock/.node-bin +# Make it so the node modules can be executed with 'docker-compose exec' +# We'll create symbolic links into '/usr/local/bin'. +RUN if [ ${INSTALL_NODE} = true ]; then \ + find $NVM_DIR -type f -name node -exec ln -s {} /usr/local/bin/node \; && \ + NODE_MODS_DIR="$NVM_DIR/versions/node/$(node -v)/lib/node_modules" && \ + ln -s $NODE_MODS_DIR/bower/bin/bower /usr/local/bin/bower && \ + ln -s $NODE_MODS_DIR/gulp/bin/gulp.js /usr/local/bin/gulp && \ + ln -s $NODE_MODS_DIR/npm/bin/npm-cli.js /usr/local/bin/npm && \ + ln -s $NODE_MODS_DIR/npm/bin/npx-cli.js /usr/local/bin/npx && \ + ln -s $NODE_MODS_DIR/vue-cli/bin/vue /usr/local/bin/vue && \ + ln -s $NODE_MODS_DIR/vue-cli/bin/vue-init /usr/local/bin/vue-init && \ + ln -s $NODE_MODS_DIR/vue-cli/bin/vue-list /usr/local/bin/vue-list \ +;fi + RUN if [ ${NPM_REGISTRY} ]; then \ . ~/.bashrc && npm config set registry ${NPM_REGISTRY} \ ;fi From a1af01b137b825336457888f078ec03270decdc5 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Thu, 22 Nov 2018 08:07:54 +0800 Subject: [PATCH 043/589] update workspace dockerfile (#1759) fix workspace user laradock laravel command not found --- workspace/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 5070e40..04d3811 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -610,7 +610,7 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ # Laravel Installer: ########################################################################### -USER root +USER laradock ARG COMPOSER_REPO_PACKAGIST ENV COMPOSER_REPO_PACKAGIST ${COMPOSER_REPO_PACKAGIST} From afdf2661bdedbedbd5a50bb43e6d61e8c4376c1e Mon Sep 17 00:00:00 2001 From: j1yak <32684143+j1yak@users.noreply.github.com> Date: Thu, 22 Nov 2018 01:09:48 +0100 Subject: [PATCH 044/589] fix certbot (#1666) --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 34e172d..8fa6c52 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -575,7 +575,7 @@ services: context: ./certbot volumes: - ./data/certbot/certs/:/var/certs - - ./certbot/letsencrypt/:${APP_CODE_PATH_CONTAINER}/letsencrypt + - ./certbot/letsencrypt/:/var/www/letsencrypt environment: - CN="fake.domain.com" - EMAIL="fake.email@gmail.com" From 156d124db01b28dd425c28bbadb4d523b6e887bb Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Thu, 22 Nov 2018 07:10:09 +0700 Subject: [PATCH 045/589] default user for workspace is laradock, so that owner of log file when running php artisan command doesn't change (#1875) --- workspace/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 04d3811..c82a48a 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -889,12 +889,12 @@ RUN php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." #-------------------------------------------------------------------------- # -USER root - # Clean up RUN apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ rm /var/log/lastlog /var/log/faillog +USER laradock + # Set default work directory WORKDIR /var/www From d7765a7b10736d90aa475b6eb74251a3490396bf Mon Sep 17 00:00:00 2001 From: vlauciani Date: Thu, 22 Nov 2018 01:10:33 +0100 Subject: [PATCH 046/589] Update docker-compose.yml to add 'dind' to 'Workspace' (#1869) Add 'docker-in-docker' links end 'DOCKER_HOST' environment to 'workspace'. --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 8fa6c52..fa8fe65 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,9 +111,12 @@ services: tty: true environment: - PHP_IDE_CONFIG=${PHP_IDE_CONFIG} + - DOCKER_HOST=tcp://docker-in-docker:2375 networks: - frontend - backend + links: + - docker-in-docker ### PHP-FPM ############################################## php-fpm: From 796b46cf5a01028dc76a9818c7b2d440790aa7d6 Mon Sep 17 00:00:00 2001 From: Michael Radionov <14803637+michaelradionov@users.noreply.github.com> Date: Thu, 22 Nov 2018 05:12:52 +0500 Subject: [PATCH 047/589] PHP YAML extension (#1798) --- DOCUMENTATION/content/documentation/index.md | 15 +++++++++++++++ docker-compose.yml | 1 + env-example | 1 + php-fpm/Dockerfile | 14 ++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 4e926a5..4a7041c 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1599,6 +1599,21 @@ will set the clock back 1 day. See (https://github.com/wolfcw/libfaketime) for m + +
+ +## Install YAML PHP extension in the php-fpm container +YAML PHP extension allows you to easily parse and create YAML structured data. I like YAML because it's well readable for humans. See http://php.net/manual/en/ref.yaml.php and http://yaml.org/ for more info. + +1 - Open the `.env` file +
+2 - Search for the `INSTALL_YAML` argument under the PHP-FPM container +
+3 - Set it to `true` +
+4 - Re-build the container `docker-compose build php-fpm`
+ +
## PHPStorm Debugging Guide diff --git a/docker-compose.yml b/docker-compose.yml index fa8fe65..8369370 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -156,6 +156,7 @@ services: - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} - INSTALL_FAKETIME=${PHP_FPM_INSTALL_FAKETIME} - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} + - INSTALL_YAML=${INSTALL_YAML} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} diff --git a/env-example b/env-example index f9fea34..a0d5706 100644 --- a/env-example +++ b/env-example @@ -162,6 +162,7 @@ PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false PHP_FPM_INSTALL_IONCUBE=false PHP_FPM_FAKETIME=-0 +INSTALL_YAML=false ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 427214e..3bd250d 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -539,6 +539,20 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && rm -rf /tmp/cphalcon* \ ;fi +########################################################################### +# YAML: +########################################################################### + +USER root + +ARG INSTALL_YAML=false + +RUN if [ ${INSTALL_YAML} = true ]; then \ + apt-get install libyaml-dev -y ; \ + pecl install yaml ; \ + docker-php-ext-enable yaml \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From 5c41a4f3e9539fe479b62471b14e00d9ebc1d31d Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Thu, 22 Nov 2018 11:44:28 +0800 Subject: [PATCH 048/589] Update Install YAML PHP extension title (#1887) miss change title --- DOCUMENTATION/content/documentation/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 4a7041c..be4f380 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1601,7 +1601,7 @@ will set the clock back 1 day. See (https://github.com/wolfcw/libfaketime) for m
- + ## Install YAML PHP extension in the php-fpm container YAML PHP extension allows you to easily parse and create YAML structured data. I like YAML because it's well readable for humans. See http://php.net/manual/en/ref.yaml.php and http://yaml.org/ for more info. From cc81e57206226ca3706b172a3a93bb2b54a3888d Mon Sep 17 00:00:00 2001 From: Michael Radionov <14803637+michaelradionov@users.noreply.github.com> Date: Thu, 22 Nov 2018 19:24:50 +0500 Subject: [PATCH 049/589] FIX PHP YAML extension #1798 (#1888) * FIX PHP YAML extension #1798 * changed parameter name --- DOCUMENTATION/content/documentation/index.md | 2 +- docker-compose.yml | 2 +- env-example | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index be4f380..80e787c 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1607,7 +1607,7 @@ YAML PHP extension allows you to easily parse and create YAML structured data. I 1 - Open the `.env` file
-2 - Search for the `INSTALL_YAML` argument under the PHP-FPM container +2 - Search for the `PHP_FPM_INSTALL_YAML` argument under the PHP-FPM container
3 - Set it to `true`
diff --git a/docker-compose.yml b/docker-compose.yml index 8369370..60e9b26 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -156,7 +156,7 @@ services: - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} - INSTALL_FAKETIME=${PHP_FPM_INSTALL_FAKETIME} - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} - - INSTALL_YAML=${INSTALL_YAML} + - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} diff --git a/env-example b/env-example index a0d5706..67f874f 100644 --- a/env-example +++ b/env-example @@ -162,7 +162,7 @@ PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false PHP_FPM_INSTALL_IONCUBE=false PHP_FPM_FAKETIME=-0 -INSTALL_YAML=false +PHP_FPM_INSTALL_YAML=false ### PHP_WORKER ############################################ From 4480962922a05a43de83f3959f1a1dad4f0d0dfd Mon Sep 17 00:00:00 2001 From: Thijs Kuilman Date: Thu, 22 Nov 2018 15:25:39 +0100 Subject: [PATCH 050/589] Updated Chrome Driver to latest stable version (2.32 to 2.42) in env-example (#1813) --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index 67f874f..f0f874b 100644 --- a/env-example +++ b/env-example @@ -125,7 +125,7 @@ WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 -WORKSPACE_CHROME_DRIVER_VERSION=2.32 +WORKSPACE_CHROME_DRIVER_VERSION=2.42 WORKSPACE_TIMEZONE=UTC WORKSPACE_SSH_PORT=2222 From 22032974c95ddadde18ad90c2fdc346d4b632360 Mon Sep 17 00:00:00 2001 From: Walter Franchetti Date: Fri, 23 Nov 2018 13:47:26 +0100 Subject: [PATCH 051/589] laravel-horizon (#1854) --- docker-compose.yml | 18 +++ laravel-horizon/Dockerfile | 107 ++++++++++++++++++ laravel-horizon/supervisord.conf | 10 ++ laravel-horizon/supervisord.d/.gitignore | 1 + .../laravel-horizon.conf.example | 6 + 5 files changed, 142 insertions(+) create mode 100644 laravel-horizon/Dockerfile create mode 100644 laravel-horizon/supervisord.conf create mode 100644 laravel-horizon/supervisord.d/.gitignore create mode 100644 laravel-horizon/supervisord.d/laravel-horizon.conf.example diff --git a/docker-compose.yml b/docker-compose.yml index 60e9b26..5547092 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -193,6 +193,24 @@ services: - "dockerhost:${DOCKER_HOST_IP}" networks: - backend +### Laravel Horizon ############################################ + laravel-horizon: + build: + context: ./laravel-horizon + args: + - PHP_VERSION=${PHP_VERSION} + - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} + - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} + - INSTALL_MEMCACHED=${PHP_FPM_INSTALL_MEMCACHED} + volumes: + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ./laravel-horizon/supervisord.d:/etc/supervisord.d + depends_on: + - workspace + extra_hosts: + - "dockerhost:${DOCKER_HOST_IP}" + networks: + - backend ### NGINX Server ######################################### nginx: diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile new file mode 100644 index 0000000..35a6955 --- /dev/null +++ b/laravel-horizon/Dockerfile @@ -0,0 +1,107 @@ +# +#-------------------------------------------------------------------------- +# Image Setup +#-------------------------------------------------------------------------- +# + +ARG PHP_VERSION=${PHP_VERSION} +FROM php:${PHP_VERSION}-alpine + +LABEL maintainer="Mahmoud Zalt " + +RUN apk --update add wget \ + curl \ + git \ + build-base \ + libmemcached-dev \ + libmcrypt-dev \ + libxml2-dev \ + zlib-dev \ + autoconf \ + cyrus-sasl-dev \ + libgsasl-dev \ + supervisor + +RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl +RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached + +#Install BCMath package: +ARG INSTALL_BCMATH=false +RUN if [ ${INSTALL_BCMATH} = true ]; then \ + docker-php-ext-install bcmath \ + ;fi + +# Install PostgreSQL drivers: +ARG INSTALL_PGSQL=false +RUN if [ ${INSTALL_PGSQL} = true ]; then \ + apk --update add postgresql-dev \ + && docker-php-ext-install pdo_pgsql \ + ;fi + +########################################################################### +# PHP Memcached: +########################################################################### + +ARG INSTALL_MEMCACHED=false + +RUN if [ ${INSTALL_MEMCACHED} = true ]; then \ + # Install the php memcached extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/2.2.0.tar.gz"; \ + else \ + curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/php7.tar.gz"; \ + fi \ + && mkdir -p memcached \ + && tar -C memcached -zxvf /tmp/memcached.tar.gz --strip 1 \ + && ( \ + cd memcached \ + && phpize \ + && ./configure \ + && make -j$(nproc) \ + && make install \ + ) \ + && rm -r memcached \ + && rm /tmp/memcached.tar.gz \ + && docker-php-ext-enable memcached \ + ;fi + +RUN rm /var/cache/apk/* \ + && mkdir -p /var/www + +# +#-------------------------------------------------------------------------- +# Optional Supervisord Configuration +#-------------------------------------------------------------------------- +# +# Modify the ./supervisor.conf file to match your App's requirements. +# Make sure you rebuild your container with every change. +# + +COPY supervisord.conf /etc/supervisord.conf + +ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"] + +# +#-------------------------------------------------------------------------- +# Optional Software's Installation +#-------------------------------------------------------------------------- +# +# If you need to modify this image, feel free to do it right here. +# +# -- Your awesome modifications go here -- # + +# +#-------------------------------------------------------------------------- +# Check PHP version +#-------------------------------------------------------------------------- +# + +RUN php -v | head -n 1 | grep -q "PHP ${PHP_VERSION}." + +# +#-------------------------------------------------------------------------- +# Final Touch +#-------------------------------------------------------------------------- +# + +WORKDIR /etc/supervisor/conf.d/ diff --git a/laravel-horizon/supervisord.conf b/laravel-horizon/supervisord.conf new file mode 100644 index 0000000..203f014 --- /dev/null +++ b/laravel-horizon/supervisord.conf @@ -0,0 +1,10 @@ +[supervisord] +nodaemon=true +[supervisorctl] +[inet_http_server] +port = 127.0.0.1:9001 +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[include] +files = supervisord.d/*.conf \ No newline at end of file diff --git a/laravel-horizon/supervisord.d/.gitignore b/laravel-horizon/supervisord.d/.gitignore new file mode 100644 index 0000000..fee9217 --- /dev/null +++ b/laravel-horizon/supervisord.d/.gitignore @@ -0,0 +1 @@ +*.conf diff --git a/laravel-horizon/supervisord.d/laravel-horizon.conf.example b/laravel-horizon/supervisord.d/laravel-horizon.conf.example new file mode 100644 index 0000000..245dccd --- /dev/null +++ b/laravel-horizon/supervisord.d/laravel-horizon.conf.example @@ -0,0 +1,6 @@ +[program:laravel-horizon] +process_name=%(program_name)s_%(process_num)02d +command=php /var/www/artisan horizon +autostart=true +autorestart=true +redirect_stderr=true From fa7d3c239cf646612991c76f64de7f40f95a8a1c Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Tue, 27 Nov 2018 15:57:36 +0700 Subject: [PATCH 052/589] Fix Permission denied (#1893) * Revert "default user for workspace is laradock, so that owner of log file when running php artisan command doesn't change (#1875)" This reverts commit 156d124db01b28dd425c28bbadb4d523b6e887bb. * update document to inform user should add --user=laradock when exec into workspace, update sync.sh bash to exec into workspace with user laradock --- DOCUMENTATION/content/documentation/index.md | 2 +- sync.sh | 4 ++-- workspace/Dockerfile | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 80e787c..38337d8 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -508,7 +508,7 @@ docker-compose ps docker-compose exec workspace bash ``` -Add `--user=laradock` (example `docker-compose exec --user=laradock workspace bash`) to have files created as your host's user. +Note: Should add `--user=laradock` (example `docker-compose exec --user=laradock workspace bash`) to have files created as your host's user to prevent issue owner of log file will be changed to root then laravel website cannot write on log file if using rotated log and new log file not existed 4 - Run anything you want :) diff --git a/sync.sh b/sync.sh index 237d55a..95f415f 100755 --- a/sync.sh +++ b/sync.sh @@ -41,7 +41,7 @@ display_options () { print_style " install" "info"; printf "\t\t Installs docker-sync gem on the host machine.\n" print_style " up [services]" "success"; printf "\t Starts docker-sync and runs docker compose.\n" print_style " down" "success"; printf "\t\t\t Stops containers and docker-sync.\n" - print_style " bash" "success"; printf "\t\t\t Opens bash on the workspace.\n" + print_style " bash" "success"; printf "\t\t\t Opens bash on the workspace with user laradock.\n" print_style " sync" "info"; printf "\t\t\t Manually triggers the synchronization of files.\n" print_style " clean" "danger"; printf "\t\t Removes all files from docker-sync.\n" } @@ -69,7 +69,7 @@ elif [ "$1" == "down" ]; then docker-sync stop elif [ "$1" == "bash" ]; then - docker-compose exec workspace bash + docker-compose exec --user=laradock workspace bash elif [ "$1" == "install" ]; then print_style "Installing docker-sync\n" "info" diff --git a/workspace/Dockerfile b/workspace/Dockerfile index c82a48a..04d3811 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -889,12 +889,12 @@ RUN php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." #-------------------------------------------------------------------------- # +USER root + # Clean up RUN apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ rm /var/log/lastlog /var/log/faillog -USER laradock - # Set default work directory WORKDIR /var/www From 2689638d7d388d5c9ab0d099ddcead1c802d1f8c Mon Sep 17 00:00:00 2001 From: "Mike P. Sinn" Date: Tue, 27 Nov 2018 02:59:14 -0600 Subject: [PATCH 053/589] MySQL Client in Workspace (#1892) --- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 5547092..b7cbd30 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -93,6 +93,7 @@ services: - INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE} - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} - INSTALL_IONCUBE=${WORKSPACE_INSTALL_IONCUBE} + - INSTALL_MYSQL_CLIENT=${WORKSPACE_INSTALL_MYSQL_CLIENT} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} diff --git a/env-example b/env-example index f0f874b..7df991b 100644 --- a/env-example +++ b/env-example @@ -123,6 +123,7 @@ WORKSPACE_INSTALL_PHALCON=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false +WORKSPACE_INSTALL_MYSQL_CLIENT=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 04d3811..8e65a2d 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -877,6 +877,19 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && rm -rf /tmp/cphalcon* \ ;fi +########################################################################### +# MySQL Client: +########################################################################### + +USER root + +ARG INSTALL_MYSQL_CLIENT=false + +RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From d8c36ab86007f04293d380bcf8325cb70c76fdd0 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Tue, 27 Nov 2018 16:00:03 +0700 Subject: [PATCH 054/589] add zip extension support for PHP in php-worker (#1894) --- docker-compose.yml | 1 + env-example | 1 + php-worker/Dockerfile | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index b7cbd30..0c3ff89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,6 +185,7 @@ services: - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL} - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} + - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./php-worker/supervisord.d:/etc/supervisord.d diff --git a/env-example b/env-example index 7df991b..b9866d6 100644 --- a/env-example +++ b/env-example @@ -170,6 +170,7 @@ PHP_FPM_INSTALL_YAML=false PHP_WORKER_INSTALL_PGSQL=false PHP_WORKER_INSTALL_BCMATH=false PHP_WORKER_INSTALL_SOAP=false +PHP_WORKER_INSTALL_ZIP_ARCHIVE=false ### NGINX ################################################# diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 50a5190..555e59f 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -44,6 +44,15 @@ RUN if [ ${INSTALL_PGSQL} = true ]; then \ && docker-php-ext-install pdo_pgsql \ ;fi +# Install ZipArchive: +ARG INSTALL_ZIP_ARCHIVE=false +RUN if [ ${INSTALL_ZIP_ARCHIVE} = true ]; then \ + apk --update add libzip-dev && \ + docker-php-ext-configure zip --with-libzip && \ + # Install the zip extension + docker-php-ext-install zip \ +;fi + RUN rm /var/cache/apk/* \ && mkdir -p /var/www From ee89ff96d5d2441bd65e227aeea82462a2eefdb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=89=9F=E5=8B=87?= Date: Tue, 4 Dec 2018 00:52:59 +0800 Subject: [PATCH 055/589] [U] ignore self-signed certificate --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 890c25c..4235e77 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /.project .docker-sync /jenkins/jenkins_home +/nginx/ssl/ From 2de32fe97fb5edd36a0de199b8504bcd3877818c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=89=9F=E5=8B=87?= Date: Tue, 4 Dec 2018 01:35:21 +0800 Subject: [PATCH 056/589] [F] fix latest version for mysql8.0.13 --- mysql/my.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql/my.cnf b/mysql/my.cnf index e03ccf8..399eaac 100644 --- a/mysql/my.cnf +++ b/mysql/my.cnf @@ -7,4 +7,4 @@ [mysqld] sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" -character-set-server=utf8 +character-set-server=utf8mb4 From 28e82813c4bbc84547cfac1c91e21342dfeed588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=89=9F=E5=8B=87?= Date: Tue, 4 Dec 2018 01:57:37 +0800 Subject: [PATCH 057/589] [F] fix mysql cann't start when version is 8.* --- docker-compose.yml | 1 + mysql/my.cnf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0c3ff89..2965a67 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -303,6 +303,7 @@ services: context: ./mysql args: - MYSQL_VERSION=${MYSQL_VERSION} + command: "--innodb_use_native_aio=0" environment: - MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_USER=${MYSQL_USER} diff --git a/mysql/my.cnf b/mysql/my.cnf index 399eaac..68578ef 100644 --- a/mysql/my.cnf +++ b/mysql/my.cnf @@ -6,5 +6,5 @@ [mysql] [mysqld] -sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" +sql-mode="STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" character-set-server=utf8mb4 From d03ead34a2714dd582a08da96e2a641ed80a2464 Mon Sep 17 00:00:00 2001 From: Vladyslav Shchepotin Date: Tue, 8 Jan 2019 09:24:32 +0200 Subject: [PATCH 058/589] Nginx for Windows (#1879) * feature(nginx): add OpenSSL * feature(nginx): add volume to store the certificates * feature(nginx): add option installation OpenSSL * feature(nginx): autogenerate certificates * chore(nginx): add new line at end of file * fix(nginx): fix run nginx on Windows * fix(gitignore): end of file --- .gitignore | 3 +++ nginx/Dockerfile | 1 + 2 files changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 890c25c..9888e50 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ /.project .docker-sync /jenkins/jenkins_home +/nginx/ssl/*.crt +/nginx/ssl/*.key +/nginx/ssl/*.csr diff --git a/nginx/Dockerfile b/nginx/Dockerfile index c648130..12c456d 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -26,6 +26,7 @@ RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREA && rm /etc/nginx/conf.d/default.conf ADD ./startup.sh /opt/startup.sh +RUN sed -i 's/\r//g' /opt/startup.sh CMD ["/bin/bash", "/opt/startup.sh"] EXPOSE 80 443 From 35ffd02b443dd671201421bb0b9827791156be94 Mon Sep 17 00:00:00 2001 From: Hyduan Date: Tue, 8 Jan 2019 15:29:04 +0800 Subject: [PATCH 059/589] Add ZooKeeper Component (#1899) --- docker-compose.yml | 11 +++++++++++ env-example | 4 ++++ zookeeper/Dockerfile | 10 ++++++++++ 3 files changed, 25 insertions(+) create mode 100644 zookeeper/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 0c3ff89..09bb188 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -437,6 +437,17 @@ services: networks: - backend +### ZooKeeper ######################################### + zookeeper: + build: ./zookeeper + volumes: + - ${DATA_PATH_HOST}/zookeeper/data:/data + - ${DATA_PATH_HOST}/zookeeper/datalog:/datalog + ports: + - "${ZOOKEEPER_PORT}:2181" + networks: + - backend + ### Aerospike ########################################## aerospike: build: ./aerospike diff --git a/env-example b/env-example index b9866d6..af6e1a9 100644 --- a/env-example +++ b/env-example @@ -207,6 +207,10 @@ MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d REDIS_PORT=6379 +### ZooKeeper ############################################# + +ZOOKEEPER_PORT=2181 + ### Percona ############################################### PERCONA_DATABASE=homestead diff --git a/zookeeper/Dockerfile b/zookeeper/Dockerfile new file mode 100644 index 0000000..8d5723d --- /dev/null +++ b/zookeeper/Dockerfile @@ -0,0 +1,10 @@ +FROM zookeeper:latest + +LABEL maintainer="Hyduan " + +VOLUME /data +VOLUME /datalog + +EXPOSE 2181 + +CMD ["zookeeper"] From e6d866b8a62370467b7b8c974d4e8b59aa569c8b Mon Sep 17 00:00:00 2001 From: Spyros Sakellaropoulos Date: Tue, 8 Jan 2019 09:30:12 +0200 Subject: [PATCH 060/589] Added APCU installation option (#1831) --- docker-compose.yml | 1 + env-example | 1 + php-fpm/Dockerfile | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 09bb188..ba0a365 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -157,6 +157,7 @@ services: - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} - INSTALL_FAKETIME=${PHP_FPM_INSTALL_FAKETIME} - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} + - INSTALL_APCU=${PHP_FPM_INSTALL_APCU} - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini diff --git a/env-example b/env-example index af6e1a9..44fdcb9 100644 --- a/env-example +++ b/env-example @@ -163,6 +163,7 @@ PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false PHP_FPM_INSTALL_IONCUBE=false PHP_FPM_FAKETIME=-0 +PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 3bd250d..0a3e57a 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -539,6 +539,16 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && rm -rf /tmp/cphalcon* \ ;fi +########################################################################### +# APCU: +########################################################################### + +ARG INSTALL_APCU=false + +RUN if [ ${INSTALL_APCU} = true ]; then \ + pecl install apcu && \ + docker-php-ext-enable apcu \ + ########################################################################### # YAML: ########################################################################### From a1bda23cd91538db5c0386b597c6f07c92c179d0 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Tue, 8 Jan 2019 14:30:53 +0700 Subject: [PATCH 061/589] add new conf example file to run laravel scheduler in php-worker (#1930) --- DOCUMENTATION/content/documentation/index.md | 53 +++++++++++-------- .../laravel-scheduler.conf.example | 8 +++ 2 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 php-worker/supervisord.d/laravel-scheduler.conf.example diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 38337d8..725d4ae 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -532,29 +532,8 @@ phpunit ## Run Laravel Queue Worker -1 - First add `php-worker` container. It will be similar as like PHP-FPM Container. -
-a) open the `docker-compose.yml` file -
-b) add a new service container by simply copy-paste this section below PHP-FPM container +1 - Create supervisor configuration file (for ex., named `laravel-worker.conf`) for Laravel Queue Worker in `php-worker/supervisord.d/` by simply copy from `laravel-worker.conf.example` -```yaml - php-worker: - build: - context: ./php-worker - args: - - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL} #Optionally install PGSQL PHP drivers - - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} #Optionally install BCMath php package - - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} #Optionally install Soap php package - volumes_from: - - applications - depends_on: - - workspace - extra_hosts: - - "dockerhost:${DOCKER_HOST_IP}" - networks: - - backend -``` 2 - Start everything up ```bash @@ -566,6 +545,34 @@ docker-compose up -d php-worker +
+ +## Run Laravel Scheduler + +Laradock provides 2 ways to run Laravel Scheduler +1 - Using cron in workspace container. Most of the time, when you start Laradock, it'll automatically start workspace container with cron inside, along with setting to run `schedule:run` command every minute. + +2 - Using Supervisord in php-worker to run `schedule:run`. This way is suggested when you don't want to start workspace in production environment. +
+a) Comment out cron setting in workspace container, file `workspace/crontab/laradock` + +```bash +# * * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1 +``` +
+b) Create supervisor configuration file (for ex., named `laravel-scheduler.conf`) for Laravel Scheduler in `php-worker/supervisord.d/` by simply copy from `laravel-scheduler.conf.example` +
+c) Start php-worker container + +```bash +docker-compose up -d php-worker +``` + + + + + +
## Use Mailu @@ -1198,7 +1205,7 @@ We also recommend [setting the timezone in Laravel](http://www.camroncade.com/ma You can add your cron jobs to `workspace/crontab/root` after the `php artisan` line. ``` -* * * * * php /var/www/artisan schedule:run >> /dev/null 2>&1 +* * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1 # Custom cron * * * * * root echo "Every Minute" > /var/log/cron.log 2>&1 diff --git a/php-worker/supervisord.d/laravel-scheduler.conf.example b/php-worker/supervisord.d/laravel-scheduler.conf.example new file mode 100644 index 0000000..0e83f87 --- /dev/null +++ b/php-worker/supervisord.d/laravel-scheduler.conf.example @@ -0,0 +1,8 @@ +[program:laravel-scheduler] +process_name=%(program_name)s_%(process_num)02d +command=/bin/sh -c "while [ true ]; do (php /var/www/artisan schedule:run --verbose --no-interaction &); sleep 60; done" +autostart=true +autorestart=true +numprocs=1 +user=laradock +redirect_stderr=true From 3e771dbcfcefeec94d610a178076b3855b021cfc Mon Sep 17 00:00:00 2001 From: Tomonso Ejang <15569410+tomonsoejang@users.noreply.github.com> Date: Tue, 8 Jan 2019 13:01:21 +0530 Subject: [PATCH 062/589] Typo in PHP_VERSION for PHP gmp extension (#1933) --- workspace/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 8e65a2d..1d8b476 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -194,11 +194,11 @@ RUN if [ ${INSTALL_SSH2} = true ]; then \ USER root ARG INSTALL_GMP=false -ARG PHP_VERSION=${PHP_VERSION} +ARG PHP_VERSION=${LARADOCK_PHP_VERSION} RUN if [ ${INSTALL_GMP} = true ]; then \ # Install the PHP GMP extension - apt-get -y install php${PHP_VERSION}-gmp \ + apt-get -y install php${LARADOCK_PHP_VERSION}-gmp \ ;fi ########################################################################### From 30c8afafa2494fcc93d7083184d348c5bb4da61b Mon Sep 17 00:00:00 2001 From: Luis Coutinho Date: Tue, 8 Jan 2019 07:33:40 +0000 Subject: [PATCH 063/589] Add mosquitto broker (#1914) * Add mosquitto broker * Add documetation to mosquitto --- DOCUMENTATION/content/documentation/index.md | 24 + docker-compose.yml | 14 + env-example | 4 + mosquitto/Dockerfile | 5 + mosquitto/mosquitto.conf | 838 +++++++++++++++++++ 5 files changed, 885 insertions(+) create mode 100644 mosquitto/Dockerfile create mode 100644 mosquitto/mosquitto.conf diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 725d4ae..743d11e 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1121,6 +1121,30 @@ docker-compose up -d grafana +
+ +## Use Mosquitto (MQTT Broker) + +1 - Configure Mosquitto: Change Port using `MOSQUITTO_PORT` if you wish to. Default is port 9001. + +2 - Run the Mosquitto Container (`mosquitto`) with the `docker-compose up`command: + +```bash +docker-compose up -d mosquitto +``` + +3 - Open your command line and use a MQTT Client (Eg. https://github.com/mqttjs/MQTT.js) to subscribe a topic and publish a message. + +4 - Subscribe: `mqtt sub -t 'test' -h localhost -p 9001 -C 'ws' -v` + +5 - Publish: `mqtt pub -t 'test' -h localhost -p 9001 -C 'ws' -m 'Hello!'` + + + + + + +
diff --git a/docker-compose.yml b/docker-compose.yml index ba0a365..b36d449 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,8 @@ volumes: driver: ${VOLUMES_DRIVER} elasticsearch: driver: ${VOLUMES_DRIVER} + mosquitto: + driver: ${VOLUMES_DRIVER} services: @@ -1304,3 +1306,15 @@ services: backend: aliases: - fetchmail + +### MOSQUITTO Broker ######################################### + mosquitto: + build: + context: ./mosquitto + volumes: + - ${DATA_PATH_HOST}/mosquitto/data:/mosquitto/data + ports: + - "${MOSQUITTO_PORT}:9001" + networks: + - frontend + - backend diff --git a/env-example b/env-example index 44fdcb9..9304054 100644 --- a/env-example +++ b/env-example @@ -619,3 +619,7 @@ MAILU_ADMIN=true MAILU_WEBMAIL=rainloop # Dav server implementation (value: radicale, none) MAILU_WEBDAV=radicale + +### MOSQUITTO ################################################# + +MOSQUITTO_PORT=9001 diff --git a/mosquitto/Dockerfile b/mosquitto/Dockerfile new file mode 100644 index 0000000..7fb0e73 --- /dev/null +++ b/mosquitto/Dockerfile @@ -0,0 +1,5 @@ +FROM eclipse-mosquitto:latest + +LABEL maintainer="Luis Coutinho " + +COPY mosquitto.conf /mosquitto/config/ diff --git a/mosquitto/mosquitto.conf b/mosquitto/mosquitto.conf new file mode 100644 index 0000000..03e80f2 --- /dev/null +++ b/mosquitto/mosquitto.conf @@ -0,0 +1,838 @@ +# Config file for mosquitto +# +# See mosquitto.conf(5) for more information. +# +# Default values are shown, uncomment to change. +# +# Use the # character to indicate a comment, but only if it is the +# very first character on the line. + +# ================================================================= +# General configuration +# ================================================================= + +# Time in seconds to wait before resending an outgoing QoS=1 or +# QoS=2 message. +#retry_interval 20 + +# Time in seconds between updates of the $SYS tree. +# Set to 0 to disable the publishing of the $SYS tree. +#sys_interval 10 + +# Time in seconds between cleaning the internal message store of +# unreferenced messages. Lower values will result in lower memory +# usage but more processor time, higher values will have the +# opposite effect. +# Setting a value of 0 means the unreferenced messages will be +# disposed of as quickly as possible. +#store_clean_interval 10 + +# Write process id to a file. Default is a blank string which means +# a pid file shouldn't be written. +# This should be set to /var/run/mosquitto.pid if mosquitto is +# being run automatically on boot with an init script and +# start-stop-daemon or similar. +#pid_file + +# When run as root, drop privileges to this user and its primary +# group. +# Leave blank to stay as root, but this is not recommended. +# If run as a non-root user, this setting has no effect. +# Note that on Windows this has no effect and so mosquitto should +# be started by the user you wish it to run as. +#user mosquitto + +# The maximum number of QoS 1 and 2 messages currently inflight per +# client. +# This includes messages that are partway through handshakes and +# those that are being retried. Defaults to 20. Set to 0 for no +# maximum. Setting to 1 will guarantee in-order delivery of QoS 1 +# and 2 messages. +#max_inflight_messages 20 + +# The maximum number of QoS 1 and 2 messages to hold in a queue +# above those that are currently in-flight. Defaults to 100. Set +# to 0 for no maximum (not recommended). +# See also queue_qos0_messages. +#max_queued_messages 100 + +# Set to true to queue messages with QoS 0 when a persistent client is +# disconnected. These messages are included in the limit imposed by +# max_queued_messages. +# Defaults to false. +# This is a non-standard option for the MQTT v3.1 spec but is allowed in +# v3.1.1. +#queue_qos0_messages false + +# This option sets the maximum publish payload size that the broker will allow. +# Received messages that exceed this size will not be accepted by the broker. +# The default value is 0, which means that all valid MQTT messages are +# accepted. MQTT imposes a maximum payload size of 268435455 bytes. +#message_size_limit 0 + +# This option controls whether a client is allowed to connect with a zero +# length client id or not. This option only affects clients using MQTT v3.1.1 +# and later. If set to false, clients connecting with a zero length client id +# are disconnected. If set to true, clients will be allocated a client id by +# the broker. This means it is only useful for clients with clean session set +# to true. +#allow_zero_length_clientid true + +# If allow_zero_length_clientid is true, this option allows you to set a prefix +# to automatically generated client ids to aid visibility in logs. +#auto_id_prefix + +# This option allows persistent clients (those with clean session set to false) +# to be removed if they do not reconnect within a certain time frame. +# +# This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1. +# +# Badly designed clients may set clean session to false whilst using a randomly +# generated client id. This leads to persistent clients that will never +# reconnect. This option allows these clients to be removed. +# +# The expiration period should be an integer followed by one of h d w m y for +# hour, day, week, month and year respectively. For example +# +# persistent_client_expiration 2m +# persistent_client_expiration 14d +# persistent_client_expiration 1y +# +# The default if not set is to never expire persistent clients. +#persistent_client_expiration + +# If a client is subscribed to multiple subscriptions that overlap, e.g. foo/# +# and foo/+/baz , then MQTT expects that when the broker receives a message on +# a topic that matches both subscriptions, such as foo/bar/baz, then the client +# should only receive the message once. +# Mosquitto keeps track of which clients a message has been sent to in order to +# meet this requirement. The allow_duplicate_messages option allows this +# behaviour to be disabled, which may be useful if you have a large number of +# clients subscribed to the same set of topics and are very concerned about +# minimising memory usage. +# It can be safely set to true if you know in advance that your clients will +# never have overlapping subscriptions, otherwise your clients must be able to +# correctly deal with duplicate messages even when then have QoS=2. +#allow_duplicate_messages false + +# The MQTT specification requires that the QoS of a message delivered to a +# subscriber is never upgraded to match the QoS of the subscription. Enabling +# this option changes this behaviour. If upgrade_outgoing_qos is set true, +# messages sent to a subscriber will always match the QoS of its subscription. +# This is a non-standard option explicitly disallowed by the spec. +#upgrade_outgoing_qos false + +# ================================================================= +# Default listener +# ================================================================= + +# IP address/hostname to bind the default listener to. If not +# given, the default listener will not be bound to a specific +# address and so will be accessible to all network interfaces. +# bind_address ip-address/host name +#bind_address + +# Port to use for the default listener. +port 9001 + +# The maximum number of client connections to allow. This is +# a per listener setting. +# Default is -1, which means unlimited connections. +# Note that other process limits mean that unlimited connections +# are not really possible. Typically the default maximum number of +# connections possible is around 1024. +#max_connections -1 + +# Choose the protocol to use when listening. +# This can be either mqtt or websockets. +# Websockets support is currently disabled by default at compile time. +# Certificate based TLS may be used with websockets, except that +# only the cafile, certfile, keyfile and ciphers options are supported. +protocol websockets + +# When a listener is using the websockets protocol, it is possible to serve +# http data as well. Set http_dir to a directory which contains the files you +# wish to serve. If this option is not specified, then no normal http +# connections will be possible. +#http_dir + +# Set use_username_as_clientid to true to replace the clientid that a client +# connected with with its username. This allows authentication to be tied to +# the clientid, which means that it is possible to prevent one client +# disconnecting another by using the same clientid. +# If a client connects with no username it will be disconnected as not +# authorised when this option is set to true. +# Do not use in conjunction with clientid_prefixes. +# See also use_identity_as_username. +#use_username_as_clientid + +# ----------------------------------------------------------------- +# Certificate based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable SSL/TLS support for +# this listener. Note that the recommended port for MQTT over TLS +# is 8883, but this must be set manually. +# +# See also the mosquitto-tls man page. + +# At least one of cafile or capath must be defined. They both +# define methods of accessing the PEM encoded Certificate +# Authority certificates that have signed your server certificate +# and that you wish to trust. +# cafile defines the path to a file containing the CA certificates. +# capath defines a directory that will be searched for files +# containing the CA certificates. For capath to work correctly, the +# certificate files must have ".crt" as the file ending and you must run +# "c_rehash " each time you add/remove a certificate. +#cafile +#capath + +# Path to the PEM encoded server certificate. +#certfile + +# Path to the PEM encoded keyfile. +#keyfile + +# This option defines the version of the TLS protocol to use for this listener. +# The default value allows v1.2, v1.1 and v1.0, if they are all supported by +# the version of openssl that the broker was compiled against. For openssl >= +# 1.0.1 the valid values are tlsv1.2 tlsv1.1 and tlsv1. For openssl < 1.0.1 the +# valid values are tlsv1. +#tls_version + +# By default a TLS enabled listener will operate in a similar fashion to a +# https enabled web server, in that the server has a certificate signed by a CA +# and the client will verify that it is a trusted certificate. The overall aim +# is encryption of the network traffic. By setting require_certificate to true, +# the client must provide a valid certificate in order for the network +# connection to proceed. This allows access to the broker to be controlled +# outside of the mechanisms provided by MQTT. +#require_certificate false + +# If require_certificate is true, you may set use_identity_as_username to true +# to use the CN value from the client certificate as a username. If this is +# true, the password_file option will not be used for this listener. +#use_identity_as_username false + +# If you have require_certificate set to true, you can create a certificate +# revocation list file to revoke access to particular client certificates. If +# you have done this, use crlfile to point to the PEM encoded revocation file. +#crlfile + +# If you wish to control which encryption ciphers are used, use the ciphers +# option. The list of available ciphers can be optained using the "openssl +# ciphers" command and should be provided in the same format as the output of +# that command. +# If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH +#ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH + +# ----------------------------------------------------------------- +# Pre-shared-key based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable PSK based SSL/TLS support for +# this listener. Note that the recommended port for MQTT over TLS is 8883, but +# this must be set manually. +# +# See also the mosquitto-tls man page and the "Certificate based SSL/TLS +# support" section. Only one of certificate or PSK encryption support can be +# enabled for any listener. + +# The psk_hint option enables pre-shared-key support for this listener and also +# acts as an identifier for this listener. The hint is sent to clients and may +# be used locally to aid authentication. The hint is a free form string that +# doesn't have much meaning in itself, so feel free to be creative. +# If this option is provided, see psk_file to define the pre-shared keys to be +# used or create a security plugin to handle them. +#psk_hint + +# Set use_identity_as_username to have the psk identity sent by the client used +# as its username. Authentication will be carried out using the PSK rather than +# the MQTT username/password and so password_file will not be used for this +# listener. +#use_identity_as_username false + +# When using PSK, the encryption ciphers used will be chosen from the list of +# available PSK ciphers. If you want to control which ciphers are available, +# use the "ciphers" option. The list of available ciphers can be optained +# using the "openssl ciphers" command and should be provided in the same format +# as the output of that command. +#ciphers + +# ================================================================= +# Extra listeners +# ================================================================= + +# Listen on a port/ip address combination. By using this variable +# multiple times, mosquitto can listen on more than one port. If +# this variable is used and neither bind_address nor port given, +# then the default listener will not be started. +# The port number to listen on must be given. Optionally, an ip +# address or host name may be supplied as a second argument. In +# this case, mosquitto will attempt to bind the listener to that +# address and so restrict access to the associated network and +# interface. By default, mosquitto will listen on all interfaces. +# Note that for a websockets listener it is not possible to bind to a host +# name. +# listener port-number [ip address/host name] +#listener + +# The maximum number of client connections to allow. This is +# a per listener setting. +# Default is -1, which means unlimited connections. +# Note that other process limits mean that unlimited connections +# are not really possible. Typically the default maximum number of +# connections possible is around 1024. +#max_connections -1 + +# The listener can be restricted to operating within a topic hierarchy using +# the mount_point option. This is achieved be prefixing the mount_point string +# to all topics for any clients connected to this listener. This prefixing only +# happens internally to the broker; the client will not see the prefix. +#mount_point + +# Choose the protocol to use when listening. +# This can be either mqtt or websockets. +# Certificate based TLS may be used with websockets, except that only the +# cafile, certfile, keyfile and ciphers options are supported. +#protocol mqtt + +# When a listener is using the websockets protocol, it is possible to serve +# http data as well. Set http_dir to a directory which contains the files you +# wish to serve. If this option is not specified, then no normal http +# connections will be possible. +#http_dir + +# Set use_username_as_clientid to true to replace the clientid that a client +# connected with with its username. This allows authentication to be tied to +# the clientid, which means that it is possible to prevent one client +# disconnecting another by using the same clientid. +# If a client connects with no username it will be disconnected as not +# authorised when this option is set to true. +# Do not use in conjunction with clientid_prefixes. +# See also use_identity_as_username. +#use_username_as_clientid + +# ----------------------------------------------------------------- +# Certificate based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable certificate based SSL/TLS support +# for this listener. Note that the recommended port for MQTT over TLS is 8883, +# but this must be set manually. +# +# See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS +# support" section. Only one of certificate or PSK encryption support can be +# enabled for any listener. + +# At least one of cafile or capath must be defined to enable certificate based +# TLS encryption. They both define methods of accessing the PEM encoded +# Certificate Authority certificates that have signed your server certificate +# and that you wish to trust. +# cafile defines the path to a file containing the CA certificates. +# capath defines a directory that will be searched for files +# containing the CA certificates. For capath to work correctly, the +# certificate files must have ".crt" as the file ending and you must run +# "c_rehash " each time you add/remove a certificate. +#cafile +#capath + +# Path to the PEM encoded server certificate. +#certfile + +# Path to the PEM encoded keyfile. +#keyfile + +# By default an TLS enabled listener will operate in a similar fashion to a +# https enabled web server, in that the server has a certificate signed by a CA +# and the client will verify that it is a trusted certificate. The overall aim +# is encryption of the network traffic. By setting require_certificate to true, +# the client must provide a valid certificate in order for the network +# connection to proceed. This allows access to the broker to be controlled +# outside of the mechanisms provided by MQTT. +#require_certificate false + +# If require_certificate is true, you may set use_identity_as_username to true +# to use the CN value from the client certificate as a username. If this is +# true, the password_file option will not be used for this listener. +#use_identity_as_username false + +# If you have require_certificate set to true, you can create a certificate +# revocation list file to revoke access to particular client certificates. If +# you have done this, use crlfile to point to the PEM encoded revocation file. +#crlfile + +# If you wish to control which encryption ciphers are used, use the ciphers +# option. The list of available ciphers can be optained using the "openssl +# ciphers" command and should be provided in the same format as the output of +# that command. +#ciphers + +# ----------------------------------------------------------------- +# Pre-shared-key based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable PSK based SSL/TLS support for +# this listener. Note that the recommended port for MQTT over TLS is 8883, but +# this must be set manually. +# +# See also the mosquitto-tls man page and the "Certificate based SSL/TLS +# support" section. Only one of certificate or PSK encryption support can be +# enabled for any listener. + +# The psk_hint option enables pre-shared-key support for this listener and also +# acts as an identifier for this listener. The hint is sent to clients and may +# be used locally to aid authentication. The hint is a free form string that +# doesn't have much meaning in itself, so feel free to be creative. +# If this option is provided, see psk_file to define the pre-shared keys to be +# used or create a security plugin to handle them. +#psk_hint + +# Set use_identity_as_username to have the psk identity sent by the client used +# as its username. Authentication will be carried out using the PSK rather than +# the MQTT username/password and so password_file will not be used for this +# listener. +#use_identity_as_username false + +# When using PSK, the encryption ciphers used will be chosen from the list of +# available PSK ciphers. If you want to control which ciphers are available, +# use the "ciphers" option. The list of available ciphers can be optained +# using the "openssl ciphers" command and should be provided in the same format +# as the output of that command. +#ciphers + +# ================================================================= +# Persistence +# ================================================================= + +# If persistence is enabled, save the in-memory database to disk +# every autosave_interval seconds. If set to 0, the persistence +# database will only be written when mosquitto exits. See also +# autosave_on_changes. +# Note that writing of the persistence database can be forced by +# sending mosquitto a SIGUSR1 signal. +#autosave_interval 1800 + +# If true, mosquitto will count the number of subscription changes, retained +# messages received and queued messages and if the total exceeds +# autosave_interval then the in-memory database will be saved to disk. +# If false, mosquitto will save the in-memory database to disk by treating +# autosave_interval as a time in seconds. +#autosave_on_changes false + +# Save persistent message data to disk (true/false). +# This saves information about all messages, including +# subscriptions, currently in-flight messages and retained +# messages. +# retained_persistence is a synonym for this option. +persistence true + +# The filename to use for the persistent database, not including +# the path. +#persistence_file mosquitto.db + +# Location for persistent database. Must include trailing / +# Default is an empty string (current directory). +# Set to e.g. /var/lib/mosquitto/ if running as a proper service on Linux or +# similar. +persistence_location /mosquitto/data/ + +# ================================================================= +# Logging +# ================================================================= + +# Places to log to. Use multiple log_dest lines for multiple +# logging destinations. +# Possible destinations are: stdout stderr syslog topic file +# +# stdout and stderr log to the console on the named output. +# +# syslog uses the userspace syslog facility which usually ends up +# in /var/log/messages or similar. +# +# topic logs to the broker topic '$SYS/broker/log/', +# where severity is one of D, E, W, N, I, M which are debug, error, +# warning, notice, information and message. Message type severity is used by +# the subscribe/unsubscribe log_types and publishes log messages to +# $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe. +# +# The file destination requires an additional parameter which is the file to be +# logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be +# closed and reopened when the broker receives a HUP signal. Only a single file +# destination may be configured. +# +# Note that if the broker is running as a Windows service it will default to +# "log_dest none" and neither stdout nor stderr logging is available. +# Use "log_dest none" if you wish to disable logging. +log_dest file /mosquitto/log/mosquitto.log + +# If using syslog logging (not on Windows), messages will be logged to the +# "daemon" facility by default. Use the log_facility option to choose which of +# local0 to local7 to log to instead. The option value should be an integer +# value, e.g. "log_facility 5" to use local5. +#log_facility + +# Types of messages to log. Use multiple log_type lines for logging +# multiple types of messages. +# Possible types are: debug, error, warning, notice, information, +# none, subscribe, unsubscribe, websockets, all. +# Note that debug type messages are for decoding the incoming/outgoing +# network packets. They are not logged in "topics". +log_type error +log_type warning +log_type notice +log_type information +log_type all + +# Change the websockets logging level. This is a global option, it is not +# possible to set per listener. This is an integer that is interpreted by +# libwebsockets as a bit mask for its lws_log_levels enum. See the +# libwebsockets documentation for more details. "log_type websockets" must also +# be enabled. +#websockets_log_level 0 + +# If set to true, client connection and disconnection messages will be included +# in the log. +#connection_messages true + +# If set to true, add a timestamp value to each log message. +#log_timestamp true + +# ================================================================= +# Security +# ================================================================= + +# If set, only clients that have a matching prefix on their +# clientid will be allowed to connect to the broker. By default, +# all clients may connect. +# For example, setting "secure-" here would mean a client "secure- +# client" could connect but another with clientid "mqtt" couldn't. +#clientid_prefixes + +# Boolean value that determines whether clients that connect +# without providing a username are allowed to connect. If set to +# false then a password file should be created (see the +# password_file option) to control authenticated client access. +# Defaults to true. +#allow_anonymous true + +# In addition to the clientid_prefixes, allow_anonymous and TLS +# authentication options, username based authentication is also +# possible. The default support is described in "Default +# authentication and topic access control" below. The auth_plugin +# allows another authentication method to be used. +# Specify the path to the loadable plugin and see the +# "Authentication and topic access plugin options" section below. +#auth_plugin + +# If auth_plugin_deny_special_chars is true, the default, then before an ACL +# check is made, the username/client id of the client needing the check is +# searched for the presence of either a '+' or '#' character. If either of +# these characters is found in either the username or client id, then the ACL +# check is denied before it is sent to the plugin.o +# +# This check prevents the case where a malicious user could circumvent an ACL +# check by using one of these characters as their username or client id. This +# is the same issue as was reported with mosquitto itself as CVE-2017-7650. +# +# If you are entirely sure that the plugin you are using is not vulnerable to +# this attack (i.e. if you never use usernames or client ids in topics) then +# you can disable this extra check and have all ACL checks delivered to your +# plugin by setting auth_plugin_deny_special_chars to false. +#auth_plugin_deny_special_chars true + +# ----------------------------------------------------------------- +# Default authentication and topic access control +# ----------------------------------------------------------------- + +# Control access to the broker using a password file. This file can be +# generated using the mosquitto_passwd utility. If TLS support is not compiled +# into mosquitto (it is recommended that TLS support should be included) then +# plain text passwords are used, in which case the file should be a text file +# with lines in the format: +# username:password +# The password (and colon) may be omitted if desired, although this +# offers very little in the way of security. +# +# See the TLS client require_certificate and use_identity_as_username options +# for alternative authentication options. +#password_file + +# Access may also be controlled using a pre-shared-key file. This requires +# TLS-PSK support and a listener configured to use it. The file should be text +# lines in the format: +# identity:key +# The key should be in hexadecimal format without a leading "0x". +#psk_file + +# Control access to topics on the broker using an access control list +# file. If this parameter is defined then only the topics listed will +# have access. +# If the first character of a line of the ACL file is a # it is treated as a +# comment. +# Topic access is added with lines of the format: +# +# topic [read|write|readwrite] +# +# The access type is controlled using "read", "write" or "readwrite". This +# parameter is optional (unless contains a space character) - if not +# given then the access is read/write. can contain the + or # +# wildcards as in subscriptions. +# +# The first set of topics are applied to anonymous clients, assuming +# allow_anonymous is true. User specific topic ACLs are added after a +# user line as follows: +# +# user +# +# The username referred to here is the same as in password_file. It is +# not the clientid. +# +# +# If is also possible to define ACLs based on pattern substitution within the +# topic. The patterns available for substition are: +# +# %c to match the client id of the client +# %u to match the username of the client +# +# The substitution pattern must be the only text for that level of hierarchy. +# +# The form is the same as for the topic keyword, but using pattern as the +# keyword. +# Pattern ACLs apply to all users even if the "user" keyword has previously +# been given. +# +# If using bridges with usernames and ACLs, connection messages can be allowed +# with the following pattern: +# pattern write $SYS/broker/connection/%c/state +# +# pattern [read|write|readwrite] +# +# Example: +# +# pattern write sensor/%u/data +# +#acl_file + +# ----------------------------------------------------------------- +# Authentication and topic access plugin options +# ----------------------------------------------------------------- + +# If the auth_plugin option above is used, define options to pass to the +# plugin here as described by the plugin instructions. All options named +# using the format auth_opt_* will be passed to the plugin, for example: +# +# auth_opt_db_host +# auth_opt_db_port +# auth_opt_db_username +# auth_opt_db_password + + +# ================================================================= +# Bridges +# ================================================================= + +# A bridge is a way of connecting multiple MQTT brokers together. +# Create a new bridge using the "connection" option as described below. Set +# options for the bridges using the remaining parameters. You must specify the +# address and at least one topic to subscribe to. +# Each connection must have a unique name. +# The address line may have multiple host address and ports specified. See +# below in the round_robin description for more details on bridge behaviour if +# multiple addresses are used. +# The direction that the topic will be shared can be chosen by +# specifying out, in or both, where the default value is out. +# The QoS level of the bridged communication can be specified with the next +# topic option. The default QoS level is 0, to change the QoS the topic +# direction must also be given. +# The local and remote prefix options allow a topic to be remapped when it is +# bridged to/from the remote broker. This provides the ability to place a topic +# tree in an appropriate location. +# For more details see the mosquitto.conf man page. +# Multiple topics can be specified per connection, but be careful +# not to create any loops. +# If you are using bridges with cleansession set to false (the default), then +# you may get unexpected behaviour from incoming topics if you change what +# topics you are subscribing to. This is because the remote broker keeps the +# subscription for the old topic. If you have this problem, connect your bridge +# with cleansession set to true, then reconnect with cleansession set to false +# as normal. +#connection +#address [:] [[:]] +#topic [[[out | in | both] qos-level] local-prefix remote-prefix] + +# Set the version of the MQTT protocol to use with for this bridge. Can be one +# of mqttv31 or mqttv311. Defaults to mqttv31. +#bridge_protocol_version mqttv31 + +# If a bridge has topics that have "out" direction, the default behaviour is to +# send an unsubscribe request to the remote broker on that topic. This means +# that changing a topic direction from "in" to "out" will not keep receiving +# incoming messages. Sending these unsubscribe requests is not always +# desirable, setting bridge_attempt_unsubscribe to false will disable sending +# the unsubscribe request. +#bridge_attempt_unsubscribe true + +# If the bridge has more than one address given in the address/addresses +# configuration, the round_robin option defines the behaviour of the bridge on +# a failure of the bridge connection. If round_robin is false, the default +# value, then the first address is treated as the main bridge connection. If +# the connection fails, the other secondary addresses will be attempted in +# turn. Whilst connected to a secondary bridge, the bridge will periodically +# attempt to reconnect to the main bridge until successful. +# If round_robin is true, then all addresses are treated as equals. If a +# connection fails, the next address will be tried and if successful will +# remain connected until it fails +#round_robin false + +# Set the client id to use on the remote end of this bridge connection. If not +# defined, this defaults to 'name.hostname' where name is the connection name +# and hostname is the hostname of this computer. +# This replaces the old "clientid" option to avoid confusion. "clientid" +# remains valid for the time being. +#remote_clientid + +# Set the clientid to use on the local broker. If not defined, this defaults to +# 'local.'. If you are bridging a broker to itself, it is important +# that local_clientid and clientid do not match. +#local_clientid + +# Set the clean session variable for this bridge. +# When set to true, when the bridge disconnects for any reason, all +# messages and subscriptions will be cleaned up on the remote +# broker. Note that with cleansession set to true, there may be a +# significant amount of retained messages sent when the bridge +# reconnects after losing its connection. +# When set to false, the subscriptions and messages are kept on the +# remote broker, and delivered when the bridge reconnects. +#cleansession false + +# If set to true, publish notification messages to the local and remote brokers +# giving information about the state of the bridge connection. Retained +# messages are published to the topic $SYS/broker/connection//state +# unless the notification_topic option is used. +# If the message is 1 then the connection is active, or 0 if the connection has +# failed. +#notifications true + +# Choose the topic on which notification messages for this bridge are +# published. If not set, messages are published on the topic +# $SYS/broker/connection//state +#notification_topic + +# Set the keepalive interval for this bridge connection, in +# seconds. +#keepalive_interval 60 + +# Set the start type of the bridge. This controls how the bridge starts and +# can be one of three types: automatic, lazy and once. Note that RSMB provides +# a fourth start type "manual" which isn't currently supported by mosquitto. +# +# "automatic" is the default start type and means that the bridge connection +# will be started automatically when the broker starts and also restarted +# after a short delay (30 seconds) if the connection fails. +# +# Bridges using the "lazy" start type will be started automatically when the +# number of queued messages exceeds the number set with the "threshold" +# parameter. It will be stopped automatically after the time set by the +# "idle_timeout" parameter. Use this start type if you wish the connection to +# only be active when it is needed. +# +# A bridge using the "once" start type will be started automatically when the +# broker starts but will not be restarted if the connection fails. +#start_type automatic + +# Set the amount of time a bridge using the automatic start type will wait +# until attempting to reconnect. Defaults to 30 seconds. +#restart_timeout 30 + +# Set the amount of time a bridge using the lazy start type must be idle before +# it will be stopped. Defaults to 60 seconds. +#idle_timeout 60 + +# Set the number of messages that need to be queued for a bridge with lazy +# start type to be restarted. Defaults to 10 messages. +# Must be less than max_queued_messages. +#threshold 10 + +# If try_private is set to true, the bridge will attempt to indicate to the +# remote broker that it is a bridge not an ordinary client. If successful, this +# means that loop detection will be more effective and that retained messages +# will be propagated correctly. Not all brokers support this feature so it may +# be necessary to set try_private to false if your bridge does not connect +# properly. +#try_private true + +# Set the username to use when connecting to a broker that requires +# authentication. +# This replaces the old "username" option to avoid confusion. "username" +# remains valid for the time being. +#remote_username + +# Set the password to use when connecting to a broker that requires +# authentication. This option is only used if remote_username is also set. +# This replaces the old "password" option to avoid confusion. "password" +# remains valid for the time being. +#remote_password + +# ----------------------------------------------------------------- +# Certificate based SSL/TLS support +# ----------------------------------------------------------------- +# Either bridge_cafile or bridge_capath must be defined to enable TLS support +# for this bridge. +# bridge_cafile defines the path to a file containing the +# Certificate Authority certificates that have signed the remote broker +# certificate. +# bridge_capath defines a directory that will be searched for files containing +# the CA certificates. For bridge_capath to work correctly, the certificate +# files must have ".crt" as the file ending and you must run "c_rehash " each time you add/remove a certificate. +#bridge_cafile +#bridge_capath + +# Path to the PEM encoded client certificate, if required by the remote broker. +#bridge_certfile + +# Path to the PEM encoded client private key, if required by the remote broker. +#bridge_keyfile + +# When using certificate based encryption, bridge_insecure disables +# verification of the server hostname in the server certificate. This can be +# useful when testing initial server configurations, but makes it possible for +# a malicious third party to impersonate your server through DNS spoofing, for +# example. Use this option in testing only. If you need to resort to using this +# option in a production environment, your setup is at fault and there is no +# point using encryption. +#bridge_insecure false + +# ----------------------------------------------------------------- +# PSK based SSL/TLS support +# ----------------------------------------------------------------- +# Pre-shared-key encryption provides an alternative to certificate based +# encryption. A bridge can be configured to use PSK with the bridge_identity +# and bridge_psk options. These are the client PSK identity, and pre-shared-key +# in hexadecimal format with no "0x". Only one of certificate and PSK based +# encryption can be used on one +# bridge at once. +#bridge_identity +#bridge_psk + + +# ================================================================= +# External config files +# ================================================================= + +# External configuration files may be included by using the +# include_dir option. This defines a directory that will be searched +# for config files. All files that end in '.conf' will be loaded as +# a configuration file. It is best to have this as the last option +# in the main file. This option will only be processed from the main +# configuration file. The directory specified must not contain the +# main configuration file. +#include_dir + +# ================================================================= +# rsmb options - unlikely to ever be supported +# ================================================================= + +#ffdc_output +#max_log_entries +#trace_level +#trace_output From 163eb1f73ad4c7e6790b27623b67222ee5e48661 Mon Sep 17 00:00:00 2001 From: Atef Ben Ali Date: Tue, 8 Jan 2019 08:34:18 +0100 Subject: [PATCH 064/589] add more `git` aliases (#1922) --- workspace/aliases.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 6cb1357..033deda 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -107,6 +107,12 @@ alias gd="git --no-pager diff" alias git-revert="git reset --hard && git clean -df" alias gs="git status" alias whoops="git reset --hard && git clean -df" +alias glog="git log --oneline --decorate --graph" +alias gsh="git show" +alias grb="git rebase -i" +alias gbr="git branch" +alias gc="git commit" +alias gck="git checkout" # Create a new directory and enter it function mkd() { From e07c128063b812368e9a866e24a51523b34d37a5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 8 Jan 2019 12:35:22 +0500 Subject: [PATCH 065/589] Install socket extension for php-fpm (#1923) In some case for pushing into queue you need use constant from sockets extension --- php-fpm/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 0a3e57a..6f89041 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -224,7 +224,9 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ apt-get install librabbitmq-dev -y && \ # Install the amqp extension pecl install amqp && \ - docker-php-ext-enable amqp \ + docker-php-ext-enable amqp && \ + # Install the sockets extension + docker-php-ext-install sockets \ ;fi ########################################################################### From bbff18c6314e72b7ac8fc60d84b6ad641ac2577e Mon Sep 17 00:00:00 2001 From: Lucas Caponi da Silva Date: Tue, 8 Jan 2019 05:36:20 -0200 Subject: [PATCH 066/589] [ Fixing Permission Error ] (#1842) - Inside container, we can't change /etc files without root permissions --- ide-theia/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ide-theia/Dockerfile b/ide-theia/Dockerfile index 39f2c1b..6d42bb4 100644 --- a/ide-theia/Dockerfile +++ b/ide-theia/Dockerfile @@ -2,4 +2,6 @@ FROM theiaide/theia LABEL maintainer="ahkui " -RUN echo 'fs.inotify.max_user_watches=524288' >> /etc/sysctl.conf \ No newline at end of file +USER root + +RUN echo 'fs.inotify.max_user_watches=524288' >> /etc/sysctl.conf From ce7a29c66282e5f8060406ce7ff1827470495808 Mon Sep 17 00:00:00 2001 From: Masahiro Ienaga Date: Wed, 9 Jan 2019 22:22:42 +0900 Subject: [PATCH 067/589] modify syntax error (#1942) Syntax error in shell when installing APCU. Because Fixed shell syntax. fix #1943, #1940. --- php-fpm/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 6f89041..0592525 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -550,6 +550,7 @@ ARG INSTALL_APCU=false RUN if [ ${INSTALL_APCU} = true ]; then \ pecl install apcu && \ docker-php-ext-enable apcu \ +;fi ########################################################################### # YAML: From f44a8e0ca0e6c1b9451e3424d75072155c59bc62 Mon Sep 17 00:00:00 2001 From: andreypaa Date: Wed, 9 Jan 2019 16:31:18 +0300 Subject: [PATCH 068/589] Update to fresh version Adminer 4.x (#1900) --- adminer/Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/adminer/Dockerfile b/adminer/Dockerfile index fb66a3e..1cf4d3d 100644 --- a/adminer/Dockerfile +++ b/adminer/Dockerfile @@ -1,7 +1,4 @@ -FROM adminer:4.3.0 - -# Version 4.3.1 contains PostgreSQL login errors. See docs. -# See https://sourceforge.net/p/adminer/bugs-and-features/548/ +FROM adminer:4 LABEL maintainer="Patrick Artounian " From 7c4f6dd7a9c9cecb7ed1cc9acdd92d6e76e654d3 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Wed, 9 Jan 2019 22:53:48 +0700 Subject: [PATCH 069/589] add gitignore for nginx/ssl folder, prevent keeping cert files in git (#1929) --- nginx/ssl/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 nginx/ssl/.gitignore diff --git a/nginx/ssl/.gitignore b/nginx/ssl/.gitignore new file mode 100644 index 0000000..f98d0ee --- /dev/null +++ b/nginx/ssl/.gitignore @@ -0,0 +1,3 @@ +*.crt +*.csr +*.key From 03ff791e1744afd0df4273f9632b0a2d691d2178 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Wed, 9 Jan 2019 22:54:32 +0700 Subject: [PATCH 070/589] php-worker: add laradock user (#1928) --- docker-compose.yml | 2 ++ env-example | 2 ++ php-worker/Dockerfile | 9 +++++++++ php-worker/supervisord.d/laravel-worker.conf.example | 1 + 4 files changed, 14 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index b36d449..f042c27 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,8 @@ services: - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} + - PUID=${PHP_WORKER_PUID} + - PGID=${PHP_WORKER_PGID} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./php-worker/supervisord.d:/etc/supervisord.d diff --git a/env-example b/env-example index 9304054..5767720 100644 --- a/env-example +++ b/env-example @@ -172,6 +172,8 @@ PHP_WORKER_INSTALL_PGSQL=false PHP_WORKER_INSTALL_BCMATH=false PHP_WORKER_INSTALL_SOAP=false PHP_WORKER_INSTALL_ZIP_ARCHIVE=false +PHP_WORKER_PUID=1000 +PHP_WORKER_PGID=1000 ### NGINX ################################################# diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 555e59f..fadfb80 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -25,6 +25,15 @@ RUN apk --update add wget \ RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached +# Add a non-root user: +ARG PUID=1000 +ENV PUID ${PUID} +ARG PGID=1000 +ENV PGID ${PGID} + +RUN addgroup -g ${PGID} laradock && \ + adduser -D -G laradock -u ${PUID} laradock + #Install SOAP package: ARG INSTALL_SOAP=false RUN if [ ${INSTALL_SOAP} = true ]; then \ diff --git a/php-worker/supervisord.d/laravel-worker.conf.example b/php-worker/supervisord.d/laravel-worker.conf.example index 06156bc..0640118 100644 --- a/php-worker/supervisord.d/laravel-worker.conf.example +++ b/php-worker/supervisord.d/laravel-worker.conf.example @@ -4,4 +4,5 @@ command=php /var/www/artisan queue:work --sleep=3 --tries=3 --daemon autostart=true autorestart=true numprocs=8 +user=laradock redirect_stderr=true From 04f071555cbff3c24736fde9e3e08befd2758731 Mon Sep 17 00:00:00 2001 From: Frank Yuan Date: Thu, 10 Jan 2019 10:56:30 +0800 Subject: [PATCH 071/589] fixed php-fpm install phalcon ext bug (#1811) * add phalcon ext * fixed phalcon install * update index.md * php-worker install phalcon ext --- docker-compose.yml | 2 ++ env-example | 1 + php-fpm/Dockerfile | 5 +++-- php-fpm/phalcon.ini | 1 + php-worker/Dockerfile | 15 +++++++++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 php-fpm/phalcon.ini diff --git a/docker-compose.yml b/docker-compose.yml index f042c27..df11146 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,8 +185,10 @@ services: context: ./php-worker args: - PHP_VERSION=${PHP_VERSION} + - PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL} - INSTALL_BCMATH=${PHP_WORKER_INSTALL_BCMATH} + - INSTALL_PHALCON=${PHP_WORKER_INSTALL_PHALCON} - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} - PUID=${PHP_WORKER_PUID} diff --git a/env-example b/env-example index 5767720..e67eabb 100644 --- a/env-example +++ b/env-example @@ -170,6 +170,7 @@ PHP_FPM_INSTALL_YAML=false PHP_WORKER_INSTALL_PGSQL=false PHP_WORKER_INSTALL_BCMATH=false +PHP_WORKER_INSTALL_PHALCON=false PHP_WORKER_INSTALL_SOAP=false PHP_WORKER_INSTALL_ZIP_ARCHIVE=false PHP_WORKER_PUID=1000 diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 0592525..641d0ea 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -536,11 +536,12 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && unzip -d /tmp/ /tmp/cphalcon.zip \ && cd /tmp/cphalcon-${LARADOCK_PHALCON_VERSION}/build \ && ./install \ - && echo "extension=phalcon.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini \ - && ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/phalcon.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-phalcon.ini \ && rm -rf /tmp/cphalcon* \ ;fi +# Copy phalcon configration +COPY ./phalcon.ini /usr/local/etc/php/conf.d/phalcon.ini + ########################################################################### # APCU: ########################################################################### diff --git a/php-fpm/phalcon.ini b/php-fpm/phalcon.ini new file mode 100644 index 0000000..24b58ba --- /dev/null +++ b/php-fpm/phalcon.ini @@ -0,0 +1 @@ +extension=phalcon.so \ No newline at end of file diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index fadfb80..590159b 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -16,6 +16,7 @@ RUN apk --update add wget \ libmemcached-dev \ libmcrypt-dev \ libxml2-dev \ + pcre-dev \ zlib-dev \ autoconf \ cyrus-sasl-dev \ @@ -65,6 +66,20 @@ RUN if [ ${INSTALL_ZIP_ARCHIVE} = true ]; then \ RUN rm /var/cache/apk/* \ && mkdir -p /var/www +# Install Phalcon ext +ARG INSTALL_PHALCON=false +ARG PHALCON_VERSION +ENV PHALCON_VERSION ${PHALCON_VERSION} + +RUN if [ $INSTALL_PHALCON = true ]; then \ + apk --update add unzip gcc make re2c bash\ + && curl -L -o /tmp/cphalcon.zip https://github.com/phalcon/cphalcon/archive/v${PHALCON_VERSION}.zip \ + && unzip -d /tmp/ /tmp/cphalcon.zip \ + && cd /tmp/cphalcon-${PHALCON_VERSION}/build \ + && ./install \ + && rm -rf /tmp/cphalcon* \ +;fi + # #-------------------------------------------------------------------------- # Optional Supervisord Configuration From acac6eb229188e4ebf6205d9b8c2b1ec02ec5688 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Thu, 10 Jan 2019 21:50:59 +0800 Subject: [PATCH 072/589] fix PHP Warning: PHP Startup: Unable to load dynamic library 'phalcon.so' (#1947) when install APCu and no install Phalcon. --- php-fpm/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 641d0ea..aa3b58a 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -530,18 +530,19 @@ ARG INSTALL_PHALCON=false ARG LARADOCK_PHALCON_VERSION ENV LARADOCK_PHALCON_VERSION ${LARADOCK_PHALCON_VERSION} +# Copy phalcon configration +COPY ./phalcon.ini /usr/local/etc/php/conf.d/phalcon.ini.disable + RUN if [ $INSTALL_PHALCON = true ]; then \ apt-get update && apt-get install -y unzip libpcre3-dev gcc make re2c \ && curl -L -o /tmp/cphalcon.zip https://github.com/phalcon/cphalcon/archive/v${LARADOCK_PHALCON_VERSION}.zip \ && unzip -d /tmp/ /tmp/cphalcon.zip \ && cd /tmp/cphalcon-${LARADOCK_PHALCON_VERSION}/build \ && ./install \ + && mv /usr/local/etc/php/conf.d/phalcon.ini.disable /usr/local/etc/php/conf.d/phalcon.ini \ && rm -rf /tmp/cphalcon* \ ;fi -# Copy phalcon configration -COPY ./phalcon.ini /usr/local/etc/php/conf.d/phalcon.ini - ########################################################################### # APCU: ########################################################################### From 36c78369d58b650792db06980e5989edfb482596 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Thu, 10 Jan 2019 23:23:51 +0800 Subject: [PATCH 073/589] fix aerospike build fail (#1948) --- env-example | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/env-example b/env-example index e67eabb..3d6cdf3 100644 --- a/env-example +++ b/env-example @@ -358,10 +358,8 @@ AEROSPIKE_FABRIC_PORT=3001 AEROSPIKE_HEARTBEAT_PORT=3002 AEROSPIKE_INFO_PORT=3003 -## Temp solution, this should be in the dockerfile -# for all versions "https://github.com/aerospike/aerospike-client-php/archive/master.tar.gz" -# for php 7.2 (using this branch until the support for 7.2 on master) "https://github.com/aerospike/aerospike-client-php/archive/7.2.0-release-candidate.tar.gz" -AEROSPIKE_PHP_REPOSITORY=https://github.com/aerospike/aerospike-client-php/archive/7.2.0-release-candidate.tar.gz +# for all versions +AEROSPIKE_PHP_REPOSITORY=https://github.com/aerospike/aerospike-client-php/archive/master.tar.gz # for php 5.6 # AEROSPIKE_PHP_REPOSITORY=https://github.com/aerospike/aerospike-client-php5/archive/3.4.15.tar.gz From 53e82293138a74215d1e8b005de6f4fde9c9fd76 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Fri, 11 Jan 2019 17:52:12 +0700 Subject: [PATCH 074/589] using Alpine for Beanstalkd and RabbitMQ, list all ports exposed for RabbitMQ (#1950) --- beanstalkd/Dockerfile | 15 +++------------ rabbitmq/Dockerfile | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/beanstalkd/Dockerfile b/beanstalkd/Dockerfile index b95a351..967fac7 100644 --- a/beanstalkd/Dockerfile +++ b/beanstalkd/Dockerfile @@ -1,16 +1,7 @@ -FROM phusion/baseimage:latest - +FROM alpine LABEL maintainer="Mahmoud Zalt " -ENV DEBIAN_FRONTEND noninteractive -ENV PATH /usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - -RUN apt-get update -RUN apt-get install -y beanstalkd -RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -VOLUME /var/lib/beanstalkd/data +RUN apk add --no-cache beanstalkd EXPOSE 11300 - -CMD ["/usr/bin/beanstalkd"] +ENTRYPOINT ["/usr/bin/beanstalkd"] diff --git a/rabbitmq/Dockerfile b/rabbitmq/Dockerfile index d79b4ed..1e232d4 100644 --- a/rabbitmq/Dockerfile +++ b/rabbitmq/Dockerfile @@ -1,7 +1,7 @@ -FROM rabbitmq +FROM rabbitmq:alpine LABEL maintainer="Mahmoud Zalt " RUN rabbitmq-plugins enable --offline rabbitmq_management -EXPOSE 15671 15672 +EXPOSE 4369 5671 5672 15671 15672 25672 From 913abc54f9edde865a1d6de8a03b38098593ebfb Mon Sep 17 00:00:00 2001 From: huadong zuo Date: Sun, 13 Jan 2019 23:03:24 +0800 Subject: [PATCH 075/589] chore(pgadmin) use alpine (#1936) --- pgadmin/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pgadmin/Dockerfile b/pgadmin/Dockerfile index c507b58..f0ec44b 100644 --- a/pgadmin/Dockerfile +++ b/pgadmin/Dockerfile @@ -1,4 +1,4 @@ -FROM fenglc/pgadmin4 +FROM fenglc/pgadmin4:alpine LABEL maintainer="Huadong Zuo " From 3ad37405c6cd91304a0e286dcc2d75f8931beffa Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 24 Jan 2019 20:25:08 +0300 Subject: [PATCH 076/589] Chmod --- mariadb/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mariadb/Dockerfile b/mariadb/Dockerfile index 0dcb948..1929726 100644 --- a/mariadb/Dockerfile +++ b/mariadb/Dockerfile @@ -4,6 +4,8 @@ LABEL maintainer="Mahmoud Zalt " COPY my.cnf /etc/mysql/conf.d/my.cnf +RUN chmod -R 644 /etc/mysql/conf.d/my.cnf + CMD ["mysqld"] EXPOSE 3306 From b1e346383b136ad9f426e3a7b1180b3c5598a59a Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Sat, 9 Feb 2019 15:33:06 +0700 Subject: [PATCH 077/589] fix php-fpm AMQP build for 5.6, 7.0 and 7.1 (#1965) --- php-fpm/Dockerfile | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index aa3b58a..f9825f3 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -221,7 +221,16 @@ RUN if [ ${INSTALL_MONGO} = true ]; then \ ARG INSTALL_AMQP=false RUN if [ ${INSTALL_AMQP} = true ]; then \ - apt-get install librabbitmq-dev -y && \ + # download and install manually, to make sure it's compatible with ampq installed by pecl later + # install cmake first + apt-get update && apt-get -y install cmake && \ + curl -L -o /tmp/rabbitmq-c.tar.gz https://github.com/alanxz/rabbitmq-c/archive/master.tar.gz && \ + mkdir -p rabbitmq-c && \ + tar -C rabbitmq-c -zxvf /tmp/rabbitmq-c.tar.gz --strip 1 && \ + cd rabbitmq-c/ && \ + mkdir _build && cd _build/ && \ + cmake .. && \ + cmake --build . --target install && \ # Install the amqp extension pecl install amqp && \ docker-php-ext-enable amqp && \ @@ -550,7 +559,11 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ ARG INSTALL_APCU=false RUN if [ ${INSTALL_APCU} = true ]; then \ - pecl install apcu && \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl install -a apcu-4.0.11; \ + else \ + pecl install apcu; \ + fi && \ docker-php-ext-enable apcu \ ;fi @@ -564,7 +577,11 @@ ARG INSTALL_YAML=false RUN if [ ${INSTALL_YAML} = true ]; then \ apt-get install libyaml-dev -y ; \ - pecl install yaml ; \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl install -a yaml-1.3.2; \ + else \ + pecl install yaml; \ + fi && \ docker-php-ext-enable yaml \ ;fi From d5647295ca5b5c627b06d7384335d83c698290fd Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Sat, 9 Feb 2019 15:34:34 +0700 Subject: [PATCH 078/589] add MYSQL_CLIENT and AMQP for php-worker (#1949) --- docker-compose.yml | 2 ++ env-example | 2 ++ php-worker/Dockerfile | 20 ++++++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index df11146..bcc2763 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -191,6 +191,8 @@ services: - INSTALL_PHALCON=${PHP_WORKER_INSTALL_PHALCON} - INSTALL_SOAP=${PHP_WORKER_INSTALL_SOAP} - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} + - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} + - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: diff --git a/env-example b/env-example index 3d6cdf3..ca17871 100644 --- a/env-example +++ b/env-example @@ -173,6 +173,8 @@ PHP_WORKER_INSTALL_BCMATH=false PHP_WORKER_INSTALL_PHALCON=false PHP_WORKER_INSTALL_SOAP=false PHP_WORKER_INSTALL_ZIP_ARCHIVE=false +PHP_WORKER_INSTALL_MYSQL_CLIENT=false +PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 590159b..25bcf83 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -63,8 +63,21 @@ RUN if [ ${INSTALL_ZIP_ARCHIVE} = true ]; then \ docker-php-ext-install zip \ ;fi -RUN rm /var/cache/apk/* \ - && mkdir -p /var/www +# Install MySQL Client: +ARG INSTALL_MYSQL_CLIENT=false +RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ + apk --update add mysql-client \ +;fi + +# Install AMQP: +ARG INSTALL_AMQP=false + +RUN if [ ${INSTALL_AMQP} = true ]; then \ + apk --update add rabbitmq-c rabbitmq-c-dev && \ + pecl install amqp && \ + docker-php-ext-enable amqp && \ + docker-php-ext-install sockets \ +;fi # Install Phalcon ext ARG INSTALL_PHALCON=false @@ -80,6 +93,9 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && rm -rf /tmp/cphalcon* \ ;fi +RUN rm /var/cache/apk/* \ + && mkdir -p /var/www + # #-------------------------------------------------------------------------- # Optional Supervisord Configuration From 7430a34dd5516e9ca707c1d37effdcddc140ebe8 Mon Sep 17 00:00:00 2001 From: Andrew Siegman Date: Sat, 9 Feb 2019 02:40:14 -0600 Subject: [PATCH 079/589] Add logstash support (#1852) * add logstash support --- .gitignore | 4 ++++ docker-compose.yml | 40 ++++++++++++++++++++++++++---------- logstash/Dockerfile | 10 +++++++++ logstash/config/logstash.yml | 5 +++++ logstash/pipeline/.gitkeep | 0 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 logstash/Dockerfile create mode 100644 logstash/config/logstash.yml create mode 100644 logstash/pipeline/.gitkeep diff --git a/.gitignore b/.gitignore index 9888e50..affb5c6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ /.project .docker-sync /jenkins/jenkins_home + +/logstash/pipeline/*.conf +/logstash/config/pipelines.yml + /nginx/ssl/*.crt /nginx/ssl/*.key /nginx/ssl/*.csr diff --git a/docker-compose.yml b/docker-compose.yml index bcc2763..7ed9f9f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -602,6 +602,24 @@ services: - frontend - backend +### Logstash ############################################## + logstash: + build: ./logstash + volumes: + - './logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml' + - './logstash/pipeline:/usr/share/logstash/pipeline' + ports: + - '5001:5001' + environment: + LS_JAVA_OPTS: '-Xmx1g -Xms1g' + env_file: + - .env + networks: + - frontend + - backend + depends_on: + - elasticsearch + ### Kibana ############################################## kibana: build: ./kibana @@ -742,7 +760,7 @@ services: networks: - frontend - backend - + ### Solr ################################################ solr: build: @@ -904,15 +922,15 @@ services: context: ./gitlab environment: GITLAB_OMNIBUS_CONFIG: | - external_url '${GITLAB_DOMAIN_NAME}' - redis['enable'] = false - nginx['listen_https'] = false - nginx['listen_port'] = 80 - postgresql['enable'] = false - gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] - gitlab_rails['redis_host'] = 'redis' + external_url '${GITLAB_DOMAIN_NAME}' + redis['enable'] = false + nginx['listen_https'] = false + nginx['listen_port'] = 80 + postgresql['enable'] = false + gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] + gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_database'] = 8 - gitlab_rails['db_host'] = 'postgres' + gitlab_rails['db_host'] = 'postgres' gitlab_rails['db_username'] = 'laradock_gitlab' gitlab_rails['db_password'] = 'laradock_gitlab' gitlab_rails['db_database'] = 'laradock_gitlab' @@ -939,7 +957,7 @@ services: - ${DATA_PATH_HOST}/gitlab/runner:/etc/gitlab-runner - /var/run/docker.sock:/var/run/docker.sock:rw restart: always - + ### JupyterHub ######################################### jupyterhub: build: @@ -1050,7 +1068,7 @@ services: - backend depends_on: - mongo - + ### Metabase ################################################# metabase: image: metabase/metabase:latest diff --git a/logstash/Dockerfile b/logstash/Dockerfile new file mode 100644 index 0000000..a8c5452 --- /dev/null +++ b/logstash/Dockerfile @@ -0,0 +1,10 @@ +FROM docker.elastic.co/logstash/logstash:6.4.2 + +USER root +RUN rm -f /usr/share/logstash/pipeline/logstash.conf +RUN curl -L -o /usr/share/logstash/lib/mysql-connector-java-5.1.47.jar https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar +ADD ./pipeline/ /usr/share/logstash/pipeline/ +ADD ./config/ /usr/share/logstash/config/ + +RUN logstash-plugin install logstash-input-jdbc + diff --git a/logstash/config/logstash.yml b/logstash/config/logstash.yml new file mode 100644 index 0000000..c344717 --- /dev/null +++ b/logstash/config/logstash.yml @@ -0,0 +1,5 @@ +http.host: "0.0.0.0" + +xpack.monitoring.enabled: false +config.reload.automatic: true +path.config: "/usr/share/logstash/pipeline" diff --git a/logstash/pipeline/.gitkeep b/logstash/pipeline/.gitkeep new file mode 100644 index 0000000..e69de29 From d27f4368eec570d0a6a12136cb8476fbc1cb343a Mon Sep 17 00:00:00 2001 From: Slava Razum Date: Sat, 9 Feb 2019 11:06:26 +0200 Subject: [PATCH 080/589] Run bash when login by `laradock` via ssh (#1541) --- workspace/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 1d8b476..16d07c0 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -41,7 +41,7 @@ RUN apt-get update -yqq && \ pecl channel-update pecl.php.net && \ groupadd -g ${PGID} laradock && \ useradd -u ${PUID} -g laradock -m laradock -G docker_env && \ - usermod -p "*" laradock + usermod -p "*" laradock -s /bin/bash # #-------------------------------------------------------------------------- From eb0c94131388f659fa014d533386e6081a8c9583 Mon Sep 17 00:00:00 2001 From: Luis Coutinho Date: Sat, 9 Feb 2019 11:25:21 +0000 Subject: [PATCH 081/589] Add traefik (#1916) * Add mosquitto broker * Add documetation to mosquitto * Add traefik --- DOCUMENTATION/content/documentation/index.md | 82 +++++++++++++++++++- docker-compose.yml | 18 +++++ env-example | 7 ++ traefik/Dockerfile | 7 ++ traefik/acme.json | 0 traefik/traefik.toml | 23 ++++++ 6 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 traefik/Dockerfile create mode 100644 traefik/acme.json create mode 100644 traefik/traefik.toml diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 743d11e..089e4ec 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1121,6 +1121,87 @@ docker-compose up -d grafana +
+ +## Use Traefik + +To use Traefik you need to do some changes in `traefik/trafik.toml` and `docker-compose.yml`. + +1 - Open `traefik.toml` and change the `e-mail` property in `acme` section. + +2 - Change your domain in `acme.domains`. For example: `main = "example.org"` + +2.1 - If you have subdomains, you must add them to `sans` property in `acme.domains` section. + +```bash +[[acme.domais]] + main = "example.org" + sans = ["monitor.example.org", "pma.example.org"] +``` + +3 - If you need to add basic authentication (https://docs.traefik.io/configuration/entrypoints/#basic-authentication), you just need to add the following text after `[entryPoints.https.tls]`: + +```bash +[entryPoints.https.auth.basic] + users = ["user:password"] +``` + +4 - You need to change the `docker-compose.yml` file to match the Traefik needs. If you want to use Traefik, you must not expose the ports of each container to the internet, but specify some labels. + +4.1 For example, let's try with NGINX. You must have: + +```bash +nginx: + build: + context: ./nginx + args: + - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER} + - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} + - CHANGE_SOURCE=${CHANGE_SOURCE} + volumes: + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${NGINX_HOST_LOG_PATH}:/var/log/nginx + - ${NGINX_SITES_PATH}:/etc/nginx/sites-available + depends_on: + - php-fpm + networks: + - frontend + - backend + labels: + - traefik.backend=nginx + - traefik.frontend.rule=Host:example.org + - traefik.port=80 +``` + +instead of + +```bash +nginx: + build: + context: ./nginx + args: + - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER} + - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} + - CHANGE_SOURCE=${CHANGE_SOURCE} + volumes: + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${NGINX_HOST_LOG_PATH}:/var/log/nginx + - ${NGINX_SITES_PATH}:/etc/nginx/sites-available + - ${NGINX_SSL_PATH}:/etc/nginx/ssl + ports: + - "${NGINX_HOST_HTTP_PORT}:80" + - "${NGINX_HOST_HTTPS_PORT}:443" + depends_on: + - php-fpm + networks: + - frontend + - backend +``` + + + + +
## Use Mosquitto (MQTT Broker) @@ -1144,7 +1225,6 @@ docker-compose up -d mosquitto -
diff --git a/docker-compose.yml b/docker-compose.yml index 7ed9f9f..693ed2e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1331,6 +1331,24 @@ services: aliases: - fetchmail +### TRAEFIK ######################################### + traefik: + build: + context: ./traefik + command: --docker + volumes: + - /var/run/docker.sock:/var/run/docker.sock + ports: + - "${TRAEFIK_HOST_HTTP_PORT}:80" + - "${TRAEFIK_HOST_HTTPS_PORT}:443" + networks: + - frontend + - backend + labels: + - traefik.backend=traefik + - traefik.frontend.rule=Host:monitor.localhost + - traefik.port=8080 + ### MOSQUITTO Broker ######################################### mosquitto: build: diff --git a/env-example b/env-example index ca17871..d4f127f 100644 --- a/env-example +++ b/env-example @@ -623,6 +623,13 @@ MAILU_WEBMAIL=rainloop # Dav server implementation (value: radicale, none) MAILU_WEBDAV=radicale + +### TRAEFIK ################################################# + +TRAEFIK_HOST_HTTP_PORT=80 +TRAEFIK_HOST_HTTPS_PORT=443 + + ### MOSQUITTO ################################################# MOSQUITTO_PORT=9001 diff --git a/traefik/Dockerfile b/traefik/Dockerfile new file mode 100644 index 0000000..73825fd --- /dev/null +++ b/traefik/Dockerfile @@ -0,0 +1,7 @@ +FROM traefik:1.7.5-alpine + +LABEL maintainer="Luis Coutinho " + +COPY traefik.toml acme.json / + +RUN chmod 600 /acme.json diff --git a/traefik/acme.json b/traefik/acme.json new file mode 100644 index 0000000..e69de29 diff --git a/traefik/traefik.toml b/traefik/traefik.toml new file mode 100644 index 0000000..5875b94 --- /dev/null +++ b/traefik/traefik.toml @@ -0,0 +1,23 @@ +defaultEntryPoints = ["http", "https"] + +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +[web] +address = ":8080" +[acme] +email = "email@example.org" +storage = "acme.json" +entryPoint = "https" +onHostRule = true + [acme.httpChallenge] + entryPoint = "http" + +[[acme.domais]] + main = "localhost" From e0dc683d3f9b11fc10563fa9229d19124c75ab1f Mon Sep 17 00:00:00 2001 From: Atef Ben Ali Date: Sat, 9 Feb 2019 12:25:50 +0100 Subject: [PATCH 082/589] Add `gloga` alias (#1970) This add `git log --oneline --decorate --graph --all` command alias. --- workspace/aliases.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 033deda..ec845ab 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -108,6 +108,7 @@ alias git-revert="git reset --hard && git clean -df" alias gs="git status" alias whoops="git reset --hard && git clean -df" alias glog="git log --oneline --decorate --graph" +alias gloga="git log --oneline --decorate --graph --all" alias gsh="git show" alias grb="git rebase -i" alias gbr="git branch" From 99f7e65c9992b0ee9141776e991e87408c9896c9 Mon Sep 17 00:00:00 2001 From: Miguel Ortiz Date: Sat, 9 Feb 2019 06:26:50 -0500 Subject: [PATCH 083/589] Backup Rethikdb (#1937) - You requiere run python-pip for backing up your data --- DOCUMENTATION/content/documentation/index.md | 3 ++- rethinkdb/Dockerfile | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 089e4ec..0e11cf7 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1018,8 +1018,9 @@ docker-compose up -d rethinkdb - set the `DB_DATABASE` to `database`. +#### Additional Notes - +- You may do backing up of your data using the next reference: [backing up your data](https://www.rethinkdb.com/docs/backup/).
diff --git a/rethinkdb/Dockerfile b/rethinkdb/Dockerfile index f7db9a1..f905769 100644 --- a/rethinkdb/Dockerfile +++ b/rethinkdb/Dockerfile @@ -4,6 +4,13 @@ LABEL maintainer="Cristian Mello " VOLUME /data/rethinkdb_data +#Necessary for the backup rethinkdb +RUN apt-get -y update \ + && apt-get -y upgrade \ + && apt-get -y install python-pip \ + && pip install rethinkdb \ + && rm -rf /var/lib/apt/lists/* + RUN cp /etc/rethinkdb/default.conf.sample /etc/rethinkdb/instances.d/instance1.conf CMD ["rethinkdb", "--bind", "all"] From 9e4dfa2a0c926d0ad62f730b811884c437eb8e52 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 9 Feb 2019 19:28:29 +0800 Subject: [PATCH 084/589] fix caddy failed download (#1977) * fix caddy failed download * RUN command inline --- caddy/Dockerfile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index c987b7e..1f2ed64 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -5,8 +5,11 @@ LABEL maintainer="Huadong Zuo " RUN apk add --no-cache \ openssh \ git \ - build-base && \ - go get github.com/abiosoft/caddyplug/caddyplug \ + build-base \ + && mkdir -p $GOPATH/src/golang.org/x/ \ + && cd $GOPATH/src/golang.org/x/ \ + && git clone https://github.com/golang/sys.git sys \ + && go get github.com/abiosoft/caddyplug/caddyplug \ && caddyplug install-caddy \ apk del build-base From a09144f02b4cce07ed17750b5411a3e97524c3c7 Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Sat, 9 Feb 2019 18:29:25 +0700 Subject: [PATCH 085/589] persistent RabbitMQ (#1956) --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 693ed2e..35dc0bc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -505,6 +505,9 @@ services: environment: - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} + hostname: laradock-rabbitmq + volumes: + - ${DATA_PATH_HOST}/rabbitmq:/var/lib/rabbitmq depends_on: - php-fpm networks: From f6c5aa1801d95e37a357dfa3243ddf7135854e3e Mon Sep 17 00:00:00 2001 From: Lan Phan Date: Sat, 9 Feb 2019 18:29:51 +0700 Subject: [PATCH 086/589] fix build Solr, failed in https://travis-ci.org/laradock/laradock/jobs/479960032 (#1957) --- solr/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/Dockerfile b/solr/Dockerfile index c133a6a..ca5baff 100644 --- a/solr/Dockerfile +++ b/solr/Dockerfile @@ -18,7 +18,7 @@ ENV SOLR_DATAIMPORTHANDLER_MSSQL ${SOLR_DATAIMPORTHANDLER_MSSQL} # download mssql connector for dataimporthandler RUN if [ ${SOLR_DATAIMPORTHANDLER_MSSQL} = true ]; then \ curl -L -o /tmp/mssql-jdbc-7.0.0.jre8.jar "https://github.com/Microsoft/mssql-jdbc/releases/download/v7.0.0/mssql-jdbc-7.0.0.jre8.jar" \ - && mkdir /opt/solr/contrib/dataimporthandler/lib \ + && mkdir -p /opt/solr/contrib/dataimporthandler/lib \ && mv /tmp/mssql-jdbc-7.0.0.jre8.jar "/opt/solr/contrib/dataimporthandler/lib/mssql-jdbc-7.0.0.jre8.jar" \ ;fi From 5edf3f398b90333ad2b3f0e72698051aefd235c6 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Sat, 9 Feb 2019 19:37:11 +0800 Subject: [PATCH 087/589] Update document and fix some container bug (#1785) --- docker-compose.yml | 52 ++++++++++++------- env-example | 15 +++++- ide-theia/Dockerfile | 2 + jupyterhub/Dockerfile | 1 + jupyterhub/jupyterhub_config.py | 9 +++- .../init_gitlab_db.sh | 15 +++--- .../init_jupyterhub_db.sh | 15 +++--- redis-webui/Dockerfile | 3 ++ 8 files changed, 77 insertions(+), 35 deletions(-) create mode 100644 redis-webui/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 35dc0bc..99c3650 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -386,6 +386,14 @@ services: - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - GITLAB_POSTGRES_INIT=${GITLAB_POSTGRES_INIT} + - GITLAB_POSTGRES_USER=${GITLAB_POSTGRES_USER} + - GITLAB_POSTGRES_PASSWORD=${GITLAB_POSTGRES_PASSWORD} + - GITLAB_POSTGRES_DB=${GITLAB_POSTGRES_DB} + - JUPYTERHUB_POSTGRES_INIT=${JUPYTERHUB_POSTGRES_INIT} + - JUPYTERHUB_POSTGRES_USER=${JUPYTERHUB_POSTGRES_USER} + - JUPYTERHUB_POSTGRES_PASSWORD=${JUPYTERHUB_POSTGRES_PASSWORD} + - JUPYTERHUB_POSTGRES_DB=${JUPYTERHUB_POSTGRES_DB} networks: - backend @@ -925,18 +933,19 @@ services: context: ./gitlab environment: GITLAB_OMNIBUS_CONFIG: | - external_url '${GITLAB_DOMAIN_NAME}' - redis['enable'] = false - nginx['listen_https'] = false - nginx['listen_port'] = 80 - postgresql['enable'] = false - gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] - gitlab_rails['redis_host'] = 'redis' + external_url '${GITLAB_DOMAIN_NAME}' + redis['enable'] = false + nginx['listen_https'] = false + nginx['listen_port'] = 80 + nginx['custom_gitlab_server_config'] = "set_real_ip_from 172.0.0.0/8;\nreal_ip_header X-Real-IP;\nreal_ip_recursive on;" + postgresql['enable'] = false + gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] + gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_database'] = 8 - gitlab_rails['db_host'] = 'postgres' - gitlab_rails['db_username'] = 'laradock_gitlab' - gitlab_rails['db_password'] = 'laradock_gitlab' - gitlab_rails['db_database'] = 'laradock_gitlab' + gitlab_rails['db_host'] = '${GITLAB_POSTGRES_HOST}' + gitlab_rails['db_username'] = '${GITLAB_POSTGRES_USER}' + gitlab_rails['db_password'] = '${GITLAB_POSTGRES_PASSWORD}' + gitlab_rails['db_database'] = '${GITLAB_POSTGRES_DB}' gitlab_rails['initial_root_password'] = '${GITLAB_ROOT_PASSWORD}' gitlab_rails['gitlab_shell_ssh_port'] = ${GITLAB_HOST_SSH_PORT} volumes: @@ -955,12 +964,15 @@ services: gitlab-runner: image: gitlab/gitlab-runner:latest environment: - - CI_SERVER_URL=${GITLAB_DOMAIN_NAME} + - CI_SERVER_URL=${GITLAB_CI_SERVER_URL} + - REGISTRATION_TOKEN=${GITLAB_RUNNER_REGISTRATION_TOKEN} + - RUNNER_NAME=${COMPOSE_PROJECT_NAME}-runner + - REGISTER_NON_INTERACTIVE=${GITLAB_REGISTER_NON_INTERACTIVE} + - RUNNER_EXECUTOR=shell volumes: - ${DATA_PATH_HOST}/gitlab/runner:/etc/gitlab-runner - /var/run/docker.sock:/var/run/docker.sock:rw - restart: always - + ### JupyterHub ######################################### jupyterhub: build: @@ -968,7 +980,6 @@ services: depends_on: - postgres - jupyterhub-user - restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock:rw - ${DATA_PATH_HOST}/jupyterhub/:/data @@ -989,7 +1000,8 @@ services: - JUPYTERHUB_OAUTH_CALLBACK_URL=${JUPYTERHUB_OAUTH_CALLBACK_URL} - JUPYTERHUB_OAUTH_CLIENT_ID=${JUPYTERHUB_OAUTH_CLIENT_ID} - JUPYTERHUB_OAUTH_CLIENT_SECRET=${JUPYTERHUB_OAUTH_CLIENT_SECRET} - - JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE=${JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE} + - JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE=${COMPOSE_PROJECT_NAME}_jupyterhub-user + - JUPYTERHUB_ENABLE_NVIDIA=${JUPYTERHUB_ENABLE_NVIDIA} jupyterhub-user: build: context: ./jupyterhub @@ -1039,9 +1051,10 @@ services: networks: - backend -### PHPRedisAdmin ################################################ - phpredisadmin: - image: erikdubbelboer/phpredisadmin:latest +### REDISWEBUI ################################################ + redis-webui: + build: + context: ./redis-webui environment: - ADMIN_USER=${REDIS_WEBUI_USERNAME} - ADMIN_PASS=${REDIS_WEBUI_PASSWORD} @@ -1058,7 +1071,6 @@ services: mongo-webui: build: context: ./mongo-webui - restart: always environment: - ROOT_URL=${MONGO_WEBUI_ROOT_URL} - MONGO_URL=${MONGO_WEBUI_MONGO_URL} diff --git a/env-example b/env-example index d4f127f..e2bd86e 100644 --- a/env-example +++ b/env-example @@ -500,14 +500,25 @@ SOLR_DATAIMPORTHANDLER_MYSQL=false SOLR_DATAIMPORTHANDLER_MSSQL=false ### GITLAB ############################################### +GITLAB_POSTGRES_INIT=true GITLAB_HOST_HTTP_PORT=8989 GITLAB_HOST_HTTPS_PORT=9898 GITLAB_HOST_SSH_PORT=2289 GITLAB_DOMAIN_NAME=http://localhost GITLAB_ROOT_PASSWORD=laradock GITLAB_HOST_LOG_PATH=./logs/gitlab +GITLAB_POSTGRES_HOST=postgres +GITLAB_POSTGRES_USER=laradock_gitlab +GITLAB_POSTGRES_PASSWORD=laradock_gitlab +GITLAB_POSTGRES_DB=laradock_gitlab + +### GITLAB-RUNNER ############################################### +GITLAB_CI_SERVER_URL=http://localhost:8989 +GITLAB_RUNNER_REGISTRATION_TOKEN= +GITLAB_REGISTER_NON_INTERACTIVE=true ### JUPYTERHUB ############################################### +JUPYTERHUB_POSTGRES_INIT=true JUPYTERHUB_POSTGRES_HOST=postgres JUPYTERHUB_POSTGRES_USER=laradock_jupyterhub JUPYTERHUB_POSTGRES_PASSWORD=laradock_jupyterhub @@ -516,10 +527,10 @@ JUPYTERHUB_PORT=9991 JUPYTERHUB_OAUTH_CALLBACK_URL=http://laradock:9991/hub/oauth_callback JUPYTERHUB_OAUTH_CLIENT_ID={GITHUB_CLIENT_ID} JUPYTERHUB_OAUTH_CLIENT_SECRET={GITHUB_CLIENT_SECRET} -JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE=laradock_jupyterhub-user JUPYTERHUB_CUSTOM_CONFIG=./jupyterhub/jupyterhub_config.py JUPYTERHUB_USER_DATA=/jupyterhub JUPYTERHUB_USER_LIST=./jupyterhub/userlist +JUPYTERHUB_ENABLE_NVIDIA=false ### IPYTHON ################################################## LARADOCK_IPYTHON_CONTROLLER_IP=127.0.0.1 @@ -527,7 +538,7 @@ LARADOCK_IPYTHON_CONTROLLER_IP=127.0.0.1 ### NETDATA ############################################### NETDATA_PORT=19999 -### PHPREDISADMIN ######################################### +### REDISWEBUI ######################################### REDIS_WEBUI_USERNAME=laradock REDIS_WEBUI_PASSWORD=laradock REDIS_WEBUI_CONNECT_HOST=redis diff --git a/ide-theia/Dockerfile b/ide-theia/Dockerfile index 6d42bb4..9824b6a 100644 --- a/ide-theia/Dockerfile +++ b/ide-theia/Dockerfile @@ -5,3 +5,5 @@ LABEL maintainer="ahkui " USER root RUN echo 'fs.inotify.max_user_watches=524288' >> /etc/sysctl.conf + +USER theia diff --git a/jupyterhub/Dockerfile b/jupyterhub/Dockerfile index 2016f77..ddea0be 100644 --- a/jupyterhub/Dockerfile +++ b/jupyterhub/Dockerfile @@ -10,6 +10,7 @@ ENV JUPYTERHUB_OAUTH_CALLBACK_URL ${JUPYTERHUB_OAUTH_CALLBACK_URL} ENV JUPYTERHUB_OAUTH_CLIENT_ID ${JUPYTERHUB_OAUTH_CLIENT_ID} ENV JUPYTERHUB_OAUTH_CLIENT_SECRET ${JUPYTERHUB_OAUTH_CLIENT_SECRET} ENV JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE ${JUPYTERHUB_LOCAL_NOTEBOOK_IMAGE} +ENV JUPYTERHUB_ENABLE_NVIDIA ${JUPYTERHUB_ENABLE_NVIDIA} RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - diff --git a/jupyterhub/jupyterhub_config.py b/jupyterhub/jupyterhub_config.py index 612296c..e8da1b8 100644 --- a/jupyterhub/jupyterhub_config.py +++ b/jupyterhub/jupyterhub_config.py @@ -6,6 +6,9 @@ import os c = get_config() +# create system users that don't exist yet +c.LocalAuthenticator.create_system_users = True + def create_dir_hook(spawner): username = spawner.user.name # get the username volume_path = os.path.join('/user-data', username) @@ -45,8 +48,12 @@ network_name = os.environ.get('JUPYTERHUB_NETWORK_NAME','laradock_backend') c.DockerSpawner.use_internal_ip = True c.DockerSpawner.network_name = network_name +enable_nvidia = os.environ.get('JUPYTERHUB_ENABLE_NVIDIA','false') # Pass the network name as argument to spawned containers -c.DockerSpawner.extra_host_config = { 'network_mode': network_name, 'runtime': 'nvidia' } +c.DockerSpawner.extra_host_config = { 'network_mode': network_name } +if 'true' == enable_nvidia: + c.DockerSpawner.extra_host_config = { 'network_mode': network_name, 'runtime': 'nvidia' } + pass # c.DockerSpawner.extra_host_config = { 'network_mode': network_name, "devices":["/dev/nvidiactl","/dev/nvidia-uvm","/dev/nvidia0"] } # Explicitly set notebook directory because we'll be mounting a host volume to # it. Most jupyter/docker-stacks *-notebook images run the Notebook server as diff --git a/postgres/docker-entrypoint-initdb.d/init_gitlab_db.sh b/postgres/docker-entrypoint-initdb.d/init_gitlab_db.sh index d9d7738..4f4267d 100644 --- a/postgres/docker-entrypoint-initdb.d/init_gitlab_db.sh +++ b/postgres/docker-entrypoint-initdb.d/init_gitlab_db.sh @@ -33,9 +33,12 @@ # EOSQL # ### default database and user for gitlab ############################################## -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER laradock_gitlab WITH PASSWORD 'laradock_gitlab'; - CREATE DATABASE laradock_gitlab; - GRANT ALL PRIVILEGES ON DATABASE laradock_gitlab TO laradock_gitlab; - ALTER ROLE laradock_gitlab CREATEROLE SUPERUSER; -EOSQL +if [ "$GITLAB_POSTGRES_INIT" == 'true' ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER $GITLAB_POSTGRES_USER WITH PASSWORD '$GITLAB_POSTGRES_PASSWORD'; + CREATE DATABASE $GITLAB_POSTGRES_DB; + GRANT ALL PRIVILEGES ON DATABASE $GITLAB_POSTGRES_DB TO $GITLAB_POSTGRES_USER; + ALTER ROLE $GITLAB_POSTGRES_USER CREATEROLE SUPERUSER; + EOSQL + echo +fi \ No newline at end of file diff --git a/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh b/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh index 6f3d44c..787fabc 100644 --- a/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh +++ b/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh @@ -33,9 +33,12 @@ # EOSQL # ### default database and user for jupyterhub ############################################## -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER laradock_jupyterhub WITH PASSWORD 'laradock_jupyterhub'; - CREATE DATABASE laradock_jupyterhub; - GRANT ALL PRIVILEGES ON DATABASE laradock_jupyterhub TO laradock_jupyterhub; - ALTER ROLE laradock_jupyterhub CREATEROLE SUPERUSER; -EOSQL +if [ $JUPYTERHUB_POSTGRES_INIT == 'true' ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER $JUPYTERHUB_POSTGRES_USER WITH PASSWORD '$JUPYTERHUB_POSTGRES_PASSWORD'; + CREATE DATABASE $JUPYTERHUB_POSTGRES_DB; + GRANT ALL PRIVILEGES ON DATABASE $JUPYTERHUB_POSTGRES_DB TO $JUPYTERHUB_POSTGRES_USER; + ALTER ROLE $JUPYTERHUB_POSTGRES_USER CREATEROLE SUPERUSER; + EOSQL + echo +fi diff --git a/redis-webui/Dockerfile b/redis-webui/Dockerfile new file mode 100644 index 0000000..fb026ac --- /dev/null +++ b/redis-webui/Dockerfile @@ -0,0 +1,3 @@ +FROM erikdubbelboer/phpredisadmin + +LABEL maintainer="ahkui " From c7aa535598f7098ab23d741a5baf069f988bb69f Mon Sep 17 00:00:00 2001 From: Dmitry Ossipov Date: Sat, 9 Feb 2019 18:48:28 +0700 Subject: [PATCH 088/589] Added WP-CLI support to workspace (#1748) * Added WP-CLI support * Updated documentation for WP-CLI --- DOCUMENTATION/content/introduction/index.md | 2 +- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 15 +++++++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 6544270..97eb705 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -103,7 +103,7 @@ Laradock introduces the **Workspace** Image, as a development environment. It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of Containers and tools you may choose. **Workspace Image Tools** -PHP CLI - Composer - Git - Linuxbrew - Node - V8JS - Gulp - SQLite - xDebug - Envoy - Deployer - Vim - Yarn - SOAP - Drush... +PHP CLI - Composer - Git - Linuxbrew - Node - V8JS - Gulp - SQLite - xDebug - Envoy - Deployer - Vim - Yarn - SOAP - Drush - WP-CLI... You can choose, which tools to install in your workspace container and other containers, from the `.env` file. diff --git a/docker-compose.yml b/docker-compose.yml index 99c3650..bac93ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,6 +71,7 @@ services: - INSTALL_NPM_BOWER=${WORKSPACE_INSTALL_NPM_BOWER} - INSTALL_NPM_VUE_CLI=${WORKSPACE_INSTALL_NPM_VUE_CLI} - INSTALL_DRUSH=${WORKSPACE_INSTALL_DRUSH} + - INSTALL_WP_CLI=${WORKSPACE_INSTALL_WP_CLI} - INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE} - INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE} - AEROSPIKE_PHP_REPOSITORY=${AEROSPIKE_PHP_REPOSITORY} diff --git a/env-example b/env-example index e2bd86e..d9a9216 100644 --- a/env-example +++ b/env-example @@ -104,6 +104,7 @@ WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 WORKSPACE_INSTALL_DRUPAL_CONSOLE=false +WORKSPACE_INSTALL_WP_CLI=false WORKSPACE_INSTALL_AEROSPIKE=false WORKSPACE_INSTALL_V8JS=false WORKSPACE_INSTALL_LARAVEL_ENVOY=false diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 16d07c0..e1af865 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -174,6 +174,21 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ drush core-status \ ;fi +########################################################################### +# WP CLI: +########################################################################### + +# The command line interface for WordPress + +USER root + +ARG INSTALL_WP_CLI=false + +RUN if [ ${INSTALL_WP_CLI} = true ]; then \ + curl -fsSL -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar | bash && \ + chmod +x /usr/local/bin/wp \ +;fi + ########################################################################### # SSH2: ########################################################################### From 1d420a2507630d462cd8b8125b9226b805e36a74 Mon Sep 17 00:00:00 2001 From: hawkup Date: Sat, 9 Feb 2019 18:57:11 +0700 Subject: [PATCH 089/589] Separate variable flag container path out from APP_CODE_PATH_CONTAINER (#1591) Because Container cannot volume when use APP_CODE_PATH_CONTAINER (with flag) concat with path name, e.g. /var/www:nocache/letencrypt This will fix 1540. --- DOCUMENTATION/content/documentation/index.md | 2 +- docker-compose.yml | 16 ++++++++-------- env-example | 7 +++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 0e11cf7..7795184 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1832,7 +1832,7 @@ Laradock comes with `sync.sh`, an optional bash script, that automates installin DOCKER_SYNC_STRATEGY=native_osx ``` -3) set `APP_CODE_PATH_CONTAINER=/var/www` to `APP_CODE_PATH_CONTAINER=/var/www:nocopy` in the .env file +3) set `APP_CODE_CONTAINER_FLAG` to `APP_CODE_CONTAINER_FLAG=:nocopy` in the .env file 4) Install the docker-sync gem on the host-machine: ```bash diff --git a/docker-compose.yml b/docker-compose.yml index bac93ac..7c6bf3a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: - BLACKFIRE_CLIENT_ID=${BLACKFIRE_CLIENT_ID} - BLACKFIRE_CLIENT_TOKEN=${BLACKFIRE_CLIENT_TOKEN} volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} extra_hosts: - "dockerhost:${DOCKER_HOST_IP}" ports: @@ -164,7 +164,7 @@ services: - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} expose: - "9000" extra_hosts: @@ -197,7 +197,7 @@ services: - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} - ./php-worker/supervisord.d:/etc/supervisord.d depends_on: - workspace @@ -233,7 +233,7 @@ services: - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} - CHANGE_SOURCE=${CHANGE_SOURCE} volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} - ${NGINX_HOST_LOG_PATH}:/var/log/nginx - ${NGINX_SITES_PATH}:/etc/nginx/sites-available - ${NGINX_SSL_PATH}:/etc/nginx/ssl @@ -267,7 +267,7 @@ services: - PHP_UPSTREAM_TIMEOUT=${APACHE_PHP_UPSTREAM_TIMEOUT} - DOCUMENT_ROOT=${APACHE_DOCUMENT_ROOT} volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 - ${APACHE_SITES_PATH}:/etc/apache2/sites-available ports: @@ -283,7 +283,7 @@ services: hhvm: build: ./hhvm volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} expose: - "9000" depends_on: @@ -536,7 +536,7 @@ services: caddy: build: ./caddy volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} - ${CADDY_CONFIG_PATH}:/etc/caddy - ${CADDY_HOST_LOG_PATH}:/var/log/caddy - ${DATA_PATH_HOST}:/root/.caddy @@ -909,7 +909,7 @@ services: build: context: ./aws volumes: - - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} + - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} depends_on: - workspace tty: true diff --git a/env-example b/env-example index d9a9216..e3cdca0 100644 --- a/env-example +++ b/env-example @@ -7,8 +7,11 @@ # Point to the path of your applications code on your host APP_CODE_PATH_HOST=../ -# Point to where the `APP_CODE_PATH_HOST` should be in the container. You may add flags to the path `:cached`, `:delegated`. When using Docker Sync add `:nocopy` -APP_CODE_PATH_CONTAINER=/var/www:cached +# Point to where the `APP_CODE_PATH_HOST` should be in the container +APP_CODE_PATH_CONTAINER=/var/www + +# You may add flags to the path `:cached`, `:delegated`. When using Docker Sync add `:nocopy` +APP_CODE_CONTAINER_FLAG=:cached # Choose storage path on your machine. For all storage systems DATA_PATH_HOST=~/.laradock/data From 53ca88714c4c5672bd6ddfc4970cb48c02337447 Mon Sep 17 00:00:00 2001 From: Alex Mayer Date: Sat, 9 Feb 2019 06:58:12 -0500 Subject: [PATCH 090/589] Map cll And cla Aliases To Correct Commands (#1696) --- workspace/aliases.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index ec845ab..0bf5073 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -46,8 +46,8 @@ alias h="history" alias j="jobs" alias e='exit' alias c="clear" -alias cla="clear && ls -l" -alias cll="clear && ls -la" +alias cla="clear && ls -la" +alias cll="clear && ls -l" alias cls="clear && ls" alias code="cd /var/www" alias ea="vi ~/aliases.sh" From fc3355a9cc906e74111d44a476322ddf7da5d0b6 Mon Sep 17 00:00:00 2001 From: Jesus Galvan <2798097+jsgv@users.noreply.github.com> Date: Sat, 9 Feb 2019 19:07:37 +0700 Subject: [PATCH 091/589] Add CouchDB (#1974) * Add CouchDB --- couchdb/Dockerfile | 3 +++ docker-compose.yml | 11 +++++++++++ env-example | 4 ++++ 3 files changed, 18 insertions(+) create mode 100644 couchdb/Dockerfile diff --git a/couchdb/Dockerfile b/couchdb/Dockerfile new file mode 100644 index 0000000..b1154bc --- /dev/null +++ b/couchdb/Dockerfile @@ -0,0 +1,3 @@ +FROM couchdb + +EXPOSE 5984 diff --git a/docker-compose.yml b/docker-compose.yml index 7c6bf3a..edba1ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1376,3 +1376,14 @@ services: networks: - frontend - backend + +### COUCHDB ################################################### + couchdb: + build: + context: ./couchdb + volumes: + - ${DATA_PATH_HOST}/couchdb/data:/opt/couchdb/data + ports: + - "${COUCHDB_PORT}:5984" + networks: + - backend diff --git a/env-example b/env-example index e3cdca0..641f71f 100644 --- a/env-example +++ b/env-example @@ -648,3 +648,7 @@ TRAEFIK_HOST_HTTPS_PORT=443 ### MOSQUITTO ################################################# MOSQUITTO_PORT=9001 + +### COUCHDB ################################################### + +COUCHDB_PORT=5984 From 931f99ed0f3db50b94455d4c00907b247ae0492e Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Tue, 12 Feb 2019 18:37:38 +0800 Subject: [PATCH 092/589] workspace redis extension use apt install. (#1990) --- workspace/Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index e1af865..518e333 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -374,10 +374,7 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ ARG INSTALL_PHPREDIS=false RUN if [ ${INSTALL_PHPREDIS} = true ]; then \ - # Install Php Redis extension - printf "\n" | pecl -q install -o -f redis && \ - echo "extension=redis.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/redis.ini && \ - phpenmod redis \ + apt-get install -yqq php-redis \ ;fi ########################################################################### From e0d7229e95b58af4905add4686f698cd367f38ca Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Tue, 12 Feb 2019 21:24:06 +0800 Subject: [PATCH 093/589] fix adminer INSTALL_MSSQL build fail. (#1991) 1. adminer:4 now use php 7.3, but extension sqlsrv and pdo_sqlsrv not support. 2. add pdo_dblib to support mssql. --- adminer/Dockerfile | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/adminer/Dockerfile b/adminer/Dockerfile index 1cf4d3d..cb39977 100644 --- a/adminer/Dockerfile +++ b/adminer/Dockerfile @@ -13,11 +13,15 @@ ARG INSTALL_MSSQL=false ENV INSTALL_MSSQL ${INSTALL_MSSQL} RUN if [ ${INSTALL_MSSQL} = true ]; then \ set -xe \ - && apk --update add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc unixodbc-dev \ - && pecl channel-update pecl.php.net \ - && pecl install pdo_sqlsrv-4.1.8preview sqlsrv-4.1.8preview \ - && echo "extension=sqlsrv.so" > /usr/local/etc/php/conf.d/20-sqlsrv.ini \ - && echo "extension=pdo_sqlsrv.so" > /usr/local/etc/php/conf.d/20-pdo_sqlsrv.ini \ + # && apk --update add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc unixodbc-dev \ + # && pecl channel-update pecl.php.net \ + # && pecl install pdo_sqlsrv-4.1.8preview sqlsrv-4.1.8preview \ + # && echo "extension=sqlsrv.so" > /usr/local/etc/php/conf.d/20-sqlsrv.ini \ + # && echo "extension=pdo_sqlsrv.so" > /usr/local/etc/php/conf.d/20-pdo_sqlsrv.ini \ + && apk --update add --no-cache freetds unixodbc \ + && apk --update add --no-cache --virtual .build-deps $PHPIZE_DEPS freetds-dev unixodbc-dev \ + && docker-php-ext-install pdo_dblib \ + && apk del .build-deps \ ;fi USER adminer From 1286b7ef065a8d4736523e0e43be054eda231f76 Mon Sep 17 00:00:00 2001 From: Ion Jaureguialzo Sarasola Date: Thu, 14 Feb 2019 14:52:40 +0100 Subject: [PATCH 094/589] Support for additional locales in PHP-FPM (#1976) --- DOCUMENTATION/content/documentation/index.md | 13 +++++++++++++ docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 16 ++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 7795184..af7f195 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1300,6 +1300,19 @@ We also recommend [setting the timezone in Laravel](http://www.camroncade.com/ma +
+ +## Add locales to PHP-FPM + +To add locales to the container: + +1 - Open the `.env` file and set `PHP_FPM_INSTALL_ADDITIONAL_LOCALES` to `true`. + +2 - Add locale codes to `PHP_FPM_ADDITIONAL_LOCALES`. + +3 - Re-build your PHP-FPM Container `docker-compose build php-fpm`. + +4 - Check enabled locales with `docker-compose exec php-fpm locale -a` diff --git a/docker-compose.yml b/docker-compose.yml index edba1ed..e9fb4c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -162,6 +162,8 @@ services: - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} - INSTALL_APCU=${PHP_FPM_INSTALL_APCU} - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} + - INSTALL_ADDITIONAL_LOCALES=${PHP_FPM_INSTALL_ADDITIONAL_LOCALES} + - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} diff --git a/env-example b/env-example index 641f71f..5cb9254 100644 --- a/env-example +++ b/env-example @@ -169,6 +169,8 @@ PHP_FPM_INSTALL_IONCUBE=false PHP_FPM_FAKETIME=-0 PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false +PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false +PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index f9825f3..1e8800f 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -585,6 +585,22 @@ RUN if [ ${INSTALL_YAML} = true ]; then \ docker-php-ext-enable yaml \ ;fi +########################################################################### +# Install additional locales: +########################################################################### + +ARG INSTALL_ADDITIONAL_LOCALES=false +ARG ADDITIONAL_LOCALES + +RUN if [ ${INSTALL_ADDITIONAL_LOCALES} = true ]; then \ + apt-get install -y locales \ + && echo '' >> /usr/share/locale/locale.alias \ + && temp="${ADDITIONAL_LOCALES%\"}" \ + && temp="${temp#\"}" \ + && for i in ${temp}; do sed -i "/$i/s/^#//g" /etc/locale.gen; done \ + && locale-gen \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From 739e8d34483d405964372d9acd2cc4b3f4f16f03 Mon Sep 17 00:00:00 2001 From: ashutosh chaudhary <216.ashutosh@gmail.com> Date: Thu, 14 Feb 2019 19:26:59 +0530 Subject: [PATCH 095/589] Fixed docker command permission denied error while building (#1822) --- jenkins/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jenkins/Dockerfile b/jenkins/Dockerfile index cb12f4b..df66c42 100644 --- a/jenkins/Dockerfile +++ b/jenkins/Dockerfile @@ -108,3 +108,7 @@ COPY install-plugins.sh /usr/local/bin/install-plugins.sh #RUN chmod 644 /var/jenkins_home/.ssh/id_rsa.pub ## ssh-keyscan -H github.com >> ~/.ssh/known_hosts ## ssh-keyscan -H bitbucket.org >> ~/.ssh/known_hosts + +# Fix docker permission denied error +USER root +RUN usermod -aG docker jenkins From ee2db98c616b7d5fc96582f4305b9898325b51ee Mon Sep 17 00:00:00 2001 From: scappuccino <32836223+scappuccino@users.noreply.github.com> Date: Sat, 16 Feb 2019 16:03:42 +0100 Subject: [PATCH 096/589] xsl support added (feature for magento 2) (#1995) * Update php-fpm Dockerfile * Update workspace Dockerfile * Update env-example --- env-example | 2 ++ php-fpm/Dockerfile | 12 ++++++++++++ workspace/Dockerfile | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/env-example b/env-example index 5cb9254..f869137 100644 --- a/env-example +++ b/env-example @@ -100,6 +100,7 @@ WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false WORKSPACE_INSTALL_GMP=false WORKSPACE_INSTALL_SOAP=false +WORKSPACE_INSTALL_XSL=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false @@ -153,6 +154,7 @@ PHP_FPM_INSTALL_AMQP=false PHP_FPM_INSTALL_MSSQL=false PHP_FPM_INSTALL_SSH2=false PHP_FPM_INSTALL_SOAP=false +PHP_FPM_INSTALL_XSL=false PHP_FPM_INSTALL_GMP=false PHP_FPM_INSTALL_EXIF=false PHP_FPM_INSTALL_AEROSPIKE=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 1e8800f..87b7d3a 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -92,6 +92,18 @@ RUN if [ ${INSTALL_SOAP} = true ]; then \ docker-php-ext-install soap \ ;fi +########################################################################### +# XSL: +########################################################################### + +ARG INSTALL_XSL=false + +RUN if [ ${INSTALL_XSL} = true ]; then \ + # Install the xsl extension + apt-get -y install libxslt-dev && \ + docker-php-ext-install xsl \ +;fi + ########################################################################### # pgsql ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 518e333..d465493 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -229,6 +229,20 @@ RUN if [ ${INSTALL_SOAP} = true ]; then \ apt-get -y install libxml2-dev php${LARADOCK_PHP_VERSION}-soap \ ;fi +########################################################################### +# XSL: +########################################################################### + +USER root + +ARG INSTALL_XSL=false + +RUN if [ ${INSTALL_XSL} = true ]; then \ + # Install the PHP XSL extension + apt-get -y install libxslt-dev php${LARADOCK_PHP_VERSION}-xsl \ +;fi + + ########################################################################### # LDAP: ########################################################################### From 1282c413fdadcab69a1ad1b9a8c6bed40ac8bf41 Mon Sep 17 00:00:00 2001 From: vladyslavstartsev Date: Sat, 16 Feb 2019 17:32:03 +0200 Subject: [PATCH 097/589] added zip to php-fpm workspace container (so there is no composer warning) (#1903) --- docker-compose.yml | 1 - env-example | 1 - php-fpm/Dockerfile | 23 +++++++++-------------- workspace/Dockerfile | 7 +++++++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e9fb4c5..25cc19a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -138,7 +138,6 @@ services: - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} - INSTALL_MSSQL=${PHP_FPM_INSTALL_MSSQL} - - INSTALL_ZIP_ARCHIVE=${PHP_FPM_INSTALL_ZIP_ARCHIVE} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_GMP=${PHP_FPM_INSTALL_GMP} - INSTALL_PHPREDIS=${PHP_FPM_INSTALL_PHPREDIS} diff --git a/env-example b/env-example index f869137..bf45663 100644 --- a/env-example +++ b/env-example @@ -137,7 +137,6 @@ WORKSPACE_SSH_PORT=2222 ### PHP_FPM ############################################### -PHP_FPM_INSTALL_ZIP_ARCHIVE=true PHP_FPM_INSTALL_BCMATH=true PHP_FPM_INSTALL_MYSQLI=true PHP_FPM_INSTALL_INTL=true diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 87b7d3a..74804c0 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -38,6 +38,14 @@ RUN apt-get update -yqq && \ # to add more Software's or remove existing one, you need to edit the # base image (https://github.com/Laradock/php-fpm). # +# next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 +USER root + +RUN apt-get install libzip-dev zip unzip -y && \ + docker-php-ext-configure zip --with-libzip && \ + # Install the zip extension + docker-php-ext-install zip \ + # #-------------------------------------------------------------------------- @@ -47,7 +55,7 @@ RUN apt-get update -yqq && \ # Optional Software's will only be installed if you set them to `true` # in the `docker-compose.yml` before the build. # Example: -# - INSTALL_ZIP_ARCHIVE=true +# - INSTALL_SOAP=true # ########################################################################### @@ -250,19 +258,6 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ docker-php-ext-install sockets \ ;fi -########################################################################### -# ZipArchive: -########################################################################### - -ARG INSTALL_ZIP_ARCHIVE=false - -RUN if [ ${INSTALL_ZIP_ARCHIVE} = true ]; then \ - apt-get install libzip-dev -y && \ - docker-php-ext-configure zip --with-libzip && \ - # Install the zip extension - docker-php-ext-install zip \ -;fi - ########################################################################### # pcntl ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index d465493..2d9ee44 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -53,6 +53,13 @@ RUN apt-get update -yqq && \ # to add more Software's or remove existing one, you need to edit the # base image (https://github.com/Laradock/workspace). # +# next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 +USER root + +RUN apt-get install libzip-dev zip unzip -y && \ + docker-php-ext-configure zip --with-libzip && \ + # Install the zip extension + docker-php-ext-install zip \ # #-------------------------------------------------------------------------- From 14ee775e39a5a156c83a20e30fa9e81fd7f19445 Mon Sep 17 00:00:00 2001 From: hareku Date: Sun, 17 Feb 2019 00:38:18 +0900 Subject: [PATCH 098/589] add: redis-cluster (#1981) --- DOCUMENTATION/content/documentation/index.md | 38 ++++++++++++++++++++ docker-compose.yml | 8 +++++ env-example | 4 +++ redis-cluster/Dockerfile | 3 ++ 4 files changed, 53 insertions(+) create mode 100644 redis-cluster/Dockerfile diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index af7f195..e07b8b3 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -708,6 +708,44 @@ composer require predis/predis:^1.0 +
+ +## Use Redis Cluster + +1 - First make sure you run the Redis-Cluster Container (`redis-cluster`) with the `docker-compose up` command. + +```bash +docker-compose up -d redis-cluster +``` + +2 - Open your Laravel's `config/database.php` and set the redis cluster configuration. Below is example configuration with phpredis. + +Read the [Laravel official documentation](https://laravel.com/docs/5.7/redis#configuration) for more details. + +```php +'redis' => [ + 'client' => 'phpredis', + 'options' => [ + 'cluster' => 'redis', + ], + 'clusters' => [ + 'default' => [ + [ + 'host' => 'redis-cluster', + 'password' => null, + 'port' => 7000, + 'database' => 0, + ], + ], + ], +], +``` + + + + + +
## Use Mongo diff --git a/docker-compose.yml b/docker-compose.yml index 25cc19a..78dc206 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -456,6 +456,14 @@ services: networks: - backend +### Redis Cluster ########################################## + redis-cluster: + build: ./redis-cluster + ports: + - "${REDIS_CLUSTER_PORT_RANGE}:7000-7005" + networks: + - backend + ### ZooKeeper ######################################### zookeeper: build: ./zookeeper diff --git a/env-example b/env-example index bf45663..1164af1 100644 --- a/env-example +++ b/env-example @@ -220,6 +220,10 @@ MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d REDIS_PORT=6379 +### REDIS CLUSTER ######################################### + +REDIS_CLUSTER_PORT_RANGE=7000-7005 + ### ZooKeeper ############################################# ZOOKEEPER_PORT=2181 diff --git a/redis-cluster/Dockerfile b/redis-cluster/Dockerfile new file mode 100644 index 0000000..d610fc4 --- /dev/null +++ b/redis-cluster/Dockerfile @@ -0,0 +1,3 @@ +FROM grokzen/redis-cluster:latest + +LABEL maintainer="hareku " From 61ac73e806b250b478b8c0feab9fb7995a5bc97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yunier=20L=C3=B3pez=20Mart=C3=ADnez?= Date: Sat, 16 Feb 2019 11:08:33 -0500 Subject: [PATCH 099/589] Added WORKSPACE_INSTALL_NPM_ANGULAR_CLI option to install Angular CLI to Workspace (#1857) --- DOCUMENTATION/content/documentation/index.md | 16 ++++++++++++++++ docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index e07b8b3..5a5f2b3 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1651,6 +1651,22 @@ To install NPM VUE CLI in the Workspace container +
+ +## Install NPM ANGULAR CLI + +To install NPM ANGULAR CLI in the Workspace container + +1 - Open the `.env` file + +2 - Search for the `WORKSPACE_INSTALL_NPM_ANGULAR_CLI` argument under the Workspace Container and set it to `true` + +3 - Re-build the container `docker-compose build workspace` + + + + +
diff --git a/docker-compose.yml b/docker-compose.yml index 78dc206..45ddf33 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -70,6 +70,7 @@ services: - INSTALL_NPM_GULP=${WORKSPACE_INSTALL_NPM_GULP} - INSTALL_NPM_BOWER=${WORKSPACE_INSTALL_NPM_BOWER} - INSTALL_NPM_VUE_CLI=${WORKSPACE_INSTALL_NPM_VUE_CLI} + - INSTALL_NPM_ANGULAR_CLI=${WORKSPACE_INSTALL_NPM_ANGULAR_CLI} - INSTALL_DRUSH=${WORKSPACE_INSTALL_DRUSH} - INSTALL_WP_CLI=${WORKSPACE_INSTALL_WP_CLI} - INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE} diff --git a/env-example b/env-example index 1164af1..d8eacb0 100644 --- a/env-example +++ b/env-example @@ -91,6 +91,7 @@ WORKSPACE_YARN_VERSION=latest WORKSPACE_INSTALL_NPM_GULP=true WORKSPACE_INSTALL_NPM_BOWER=false WORKSPACE_INSTALL_NPM_VUE_CLI=true +WORKSPACE_INSTALL_NPM_ANGULAR_CLI=false WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 2d9ee44..20dc8e0 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -473,6 +473,7 @@ ARG INSTALL_NODE=false ARG INSTALL_NPM_GULP=false ARG INSTALL_NPM_BOWER=false ARG INSTALL_NPM_VUE_CLI=false +ARG INSTALL_NPM_ANGULAR_CLI=false ARG NPM_REGISTRY ENV NPM_REGISTRY ${NPM_REGISTRY} ENV NVM_DIR /home/laradock/.nvm @@ -497,6 +498,9 @@ RUN if [ ${INSTALL_NODE} = true ]; then \ && if [ ${INSTALL_NPM_VUE_CLI} = true ]; then \ npm install -g @vue/cli \ ;fi \ + && if [ ${INSTALL_NPM_ANGULAR_CLI} = true ]; then \ + npm install -g @angular/cli \ + ;fi \ && ln -s `npm bin --global` /home/laradock/.node-bin \ ;fi From 27af2bca8c9527414779f62a1ad98209aefd90a9 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Sun, 17 Feb 2019 01:19:20 +0800 Subject: [PATCH 100/589] fix install zip fail (#1998) --- php-fpm/Dockerfile | 3 +-- workspace/Dockerfile | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 74804c0..6fd6fea 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -44,8 +44,7 @@ USER root RUN apt-get install libzip-dev zip unzip -y && \ docker-php-ext-configure zip --with-libzip && \ # Install the zip extension - docker-php-ext-install zip \ - + docker-php-ext-install zip # #-------------------------------------------------------------------------- diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 20dc8e0..d0ebdc3 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -56,10 +56,9 @@ RUN apt-get update -yqq && \ # next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 USER root -RUN apt-get install libzip-dev zip unzip -y && \ - docker-php-ext-configure zip --with-libzip && \ +RUN apt-get install -y libzip-dev zip unzip \ # Install the zip extension - docker-php-ext-install zip \ + php${LARADOCK_PHP_VERSION}-zip # #-------------------------------------------------------------------------- From b0edaf93a1459a5313c0a958bd44464ce42dad50 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 22 Feb 2019 17:46:25 +0800 Subject: [PATCH 101/589] reorganizaion aerospike extension install (#2008) --- docker-compose.yml | 2 -- env-example | 5 ----- php-fpm/Dockerfile | 15 +++++++-------- travis-build.sh | 4 ---- workspace/Dockerfile | 19 +++++++++++-------- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 45ddf33..e28ac75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -75,7 +75,6 @@ services: - INSTALL_WP_CLI=${WORKSPACE_INSTALL_WP_CLI} - INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE} - INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE} - - AEROSPIKE_PHP_REPOSITORY=${AEROSPIKE_PHP_REPOSITORY} - INSTALL_V8JS=${WORKSPACE_INSTALL_V8JS} - COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL} - COMPOSER_REPO_PACKAGIST=${WORKSPACE_COMPOSER_REPO_PACKAGIST} @@ -146,7 +145,6 @@ services: - INSTALL_OPCACHE=${PHP_FPM_INSTALL_OPCACHE} - INSTALL_EXIF=${PHP_FPM_INSTALL_EXIF} - INSTALL_AEROSPIKE=${PHP_FPM_INSTALL_AEROSPIKE} - - AEROSPIKE_PHP_REPOSITORY=${AEROSPIKE_PHP_REPOSITORY} - INSTALL_MYSQLI=${PHP_FPM_INSTALL_MYSQLI} - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_PG_CLIENT=${PHP_FPM_INSTALL_PG_CLIENT} diff --git a/env-example b/env-example index d8eacb0..8623623 100644 --- a/env-example +++ b/env-example @@ -372,11 +372,6 @@ AEROSPIKE_FABRIC_PORT=3001 AEROSPIKE_HEARTBEAT_PORT=3002 AEROSPIKE_INFO_PORT=3003 -# for all versions -AEROSPIKE_PHP_REPOSITORY=https://github.com/aerospike/aerospike-client-php/archive/master.tar.gz -# for php 5.6 -# AEROSPIKE_PHP_REPOSITORY=https://github.com/aerospike/aerospike-client-php5/archive/3.4.15.tar.gz - ### RETHINKDB ############################################# RETHINKDB_PORT=8090 diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 6fd6fea..a6bfb51 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -24,7 +24,7 @@ ARG LARADOCK_PHP_VERSION ENV DEBIAN_FRONTEND noninteractive # always run apt update when start and after add new source list, then clean up at end. -RUN apt-get update -yqq && \ +RUN set -xe && apt-get update -yqq && \ apt-get install -y apt-utils && \ pecl channel-update pecl.php.net @@ -338,30 +338,29 @@ RUN if [ ${INSTALL_EXIF} = true ]; then \ USER root ARG INSTALL_AEROSPIKE=false -ARG AEROSPIKE_PHP_REPOSITORY -RUN if [ ${INSTALL_AEROSPIKE} = true ]; then \ +RUN set -xe && if [ ${INSTALL_AEROSPIKE} = true ]; then \ # Fix dependencies for PHPUnit within aerospike extension apt-get -y install sudo wget && \ # Install the php aerospike extension if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ curl -L -o /tmp/aerospike-client-php.tar.gz https://github.com/aerospike/aerospike-client-php5/archive/master.tar.gz; \ else \ - curl -L -o /tmp/aerospike-client-php.tar.gz ${AEROSPIKE_PHP_REPOSITORY}; \ + curl -L -o /tmp/aerospike-client-php.tar.gz https://github.com/aerospike/aerospike-client-php/archive/master.tar.gz; \ fi \ - && mkdir -p aerospike-client-php \ - && tar -C aerospike-client-php -zxvf /tmp/aerospike-client-php.tar.gz --strip 1 \ + && mkdir -p /tmp/aerospike-client-php \ + && tar -C /tmp/aerospike-client-php -zxvf /tmp/aerospike-client-php.tar.gz --strip 1 \ && \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ ( \ - cd aerospike-client-php/src/aerospike \ + cd /tmp/aerospike-client-php/src/aerospike \ && phpize \ && ./build.sh \ && make install \ ) \ else \ ( \ - cd aerospike-client-php/src \ + cd /tmp/aerospike-client-php/src \ && phpize \ && ./build.sh \ && make install \ diff --git a/travis-build.sh b/travis-build.sh index eeee67b..d6aec97 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -15,10 +15,6 @@ if [ -n "${PHP_VERSION}" ]; then sed -i -- "s/PHP_VERSION=.*/PHP_VERSION=${PHP_VERSION}/g" .env sed -i -- 's/=false/=true/g' .env sed -i -- 's/PHPDBG=true/PHPDBG=false/g' .env - if [ "${PHP_VERSION}" == "5.6" ]; then - sed -i -- 's/^AEROSPIKE_PHP_REPOSITORY=/##AEROSPIKE_PHP_REPOSITORY=/g' .env - sed -i -- 's/^# AEROSPIKE_PHP_REPOSITORY=/AEROSPIKE_PHP_REPOSITORY=/g' .env - fi cat .env docker-compose build ${BUILD_SERVICE} docker images diff --git a/workspace/Dockerfile b/workspace/Dockerfile index d0ebdc3..67c3677 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -37,7 +37,7 @@ ARG PGID=1000 ENV PGID ${PGID} # always run apt update when start and after add new source list, then clean up at end. -RUN apt-get update -yqq && \ +RUN set -xe && apt-get update -yqq && \ pecl channel-update pecl.php.net && \ groupadd -g ${PGID} laradock && \ useradd -u ${PUID} -g laradock -m laradock -G docker_env && \ @@ -581,26 +581,29 @@ ENV PATH $PATH:/home/laradock/.yarn/bin USER root ARG INSTALL_AEROSPIKE=false -ARG AEROSPIKE_PHP_REPOSITORY -RUN if [ ${INSTALL_AEROSPIKE} = true ]; then \ +RUN set -xe && if [ ${INSTALL_AEROSPIKE} = true ]; then \ # Fix dependencies for PHPUnit within aerospike extension apt-get -y install sudo wget && \ # Install the php aerospike extension - curl -L -o /tmp/aerospike-client-php.tar.gz ${AEROSPIKE_PHP_REPOSITORY} \ - && mkdir -p aerospike-client-php \ - && tar -C aerospike-client-php -zxvf /tmp/aerospike-client-php.tar.gz --strip 1 \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + curl -L -o /tmp/aerospike-client-php.tar.gz https://github.com/aerospike/aerospike-client-php5/archive/master.tar.gz; \ + else \ + curl -L -o /tmp/aerospike-client-php.tar.gz https://github.com/aerospike/aerospike-client-php/archive/master.tar.gz; \ + fi \ + && mkdir -p /tmp/aerospike-client-php \ + && tar -C /tmp/aerospike-client-php -zxvf /tmp/aerospike-client-php.tar.gz --strip 1 \ && \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ ( \ - cd aerospike-client-php/src/aerospike \ + cd /tmp/aerospike-client-php/src/aerospike \ && phpize \ && ./build.sh \ && make install \ ) \ else \ ( \ - cd aerospike-client-php/src \ + cd /tmp/aerospike-client-php/src \ && phpize \ && ./build.sh \ && make install \ From 2deb9bf1cb575927e185aa497b4a234110dabe94 Mon Sep 17 00:00:00 2001 From: Yu Li Date: Fri, 22 Feb 2019 18:30:05 +0800 Subject: [PATCH 102/589] php-fpm install mysql-client (#2005) --- docker-compose.yml | 19 ++++++++++--------- env-example | 1 + php-fpm/Dockerfile | 13 +++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e28ac75..2fff5b6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -161,6 +161,7 @@ services: - INSTALL_APCU=${PHP_FPM_INSTALL_APCU} - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} - INSTALL_ADDITIONAL_LOCALES=${PHP_FPM_INSTALL_ADDITIONAL_LOCALES} + - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini @@ -942,16 +943,16 @@ services: context: ./gitlab environment: GITLAB_OMNIBUS_CONFIG: | - external_url '${GITLAB_DOMAIN_NAME}' - redis['enable'] = false - nginx['listen_https'] = false - nginx['listen_port'] = 80 + external_url '${GITLAB_DOMAIN_NAME}' + redis['enable'] = false + nginx['listen_https'] = false + nginx['listen_port'] = 80 nginx['custom_gitlab_server_config'] = "set_real_ip_from 172.0.0.0/8;\nreal_ip_header X-Real-IP;\nreal_ip_recursive on;" - postgresql['enable'] = false - gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] - gitlab_rails['redis_host'] = 'redis' + postgresql['enable'] = false + gitlab_rails['trusted_proxies'] = ['caddy','nginx','apache2'] + gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_database'] = 8 - gitlab_rails['db_host'] = '${GITLAB_POSTGRES_HOST}' + gitlab_rails['db_host'] = '${GITLAB_POSTGRES_HOST}' gitlab_rails['db_username'] = '${GITLAB_POSTGRES_USER}' gitlab_rails['db_password'] = '${GITLAB_POSTGRES_PASSWORD}' gitlab_rails['db_database'] = '${GITLAB_POSTGRES_DB}' @@ -981,7 +982,7 @@ services: volumes: - ${DATA_PATH_HOST}/gitlab/runner:/etc/gitlab-runner - /var/run/docker.sock:/var/run/docker.sock:rw - + ### JupyterHub ######################################### jupyterhub: build: diff --git a/env-example b/env-example index 8623623..70b3570 100644 --- a/env-example +++ b/env-example @@ -172,6 +172,7 @@ PHP_FPM_FAKETIME=-0 PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false +PHP_FPM_INSTALL_MYSQL_CLIENT=false PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" ### PHP_WORKER ############################################ diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index a6bfb51..22c3a30 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -606,6 +606,19 @@ RUN if [ ${INSTALL_ADDITIONAL_LOCALES} = true ]; then \ && locale-gen \ ;fi +########################################################################### +# MySQL Client: +########################################################################### + +USER root + +ARG INSTALL_MYSQL_CLIENT=false + +RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From 176d4e8033cacada690c0632b6314495e40ef6aa Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 22 Feb 2019 23:45:21 +0800 Subject: [PATCH 103/589] php 7.0 php-fpm and workspace PECL install sqlsrv pdo_sqlsrv specify 5.3.0 version. (#2010) --- php-fpm/Dockerfile | 6 +++++- workspace/Dockerfile | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 22c3a30..be2ab84 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -477,7 +477,11 @@ RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ && ln -sfn /etc/locale.alias /usr/share/locale/locale.alias \ && locale-gen \ # Install pdo_sqlsrv and sqlsrv from PECL. Replace pdo_sqlsrv-4.1.8preview with preferred version. - && pecl install pdo_sqlsrv sqlsrv \ + && if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \ + pecl install pdo_sqlsrv-5.3.0 sqlsrv-5.3.0 \ + ;else \ + pecl install pdo_sqlsrv sqlsrv \ + ;fi \ && docker-php-ext-enable pdo_sqlsrv sqlsrv \ && php -m | grep -q 'pdo_sqlsrv' \ && php -m | grep -q 'sqlsrv' \ diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 67c3677..feccf6a 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -746,7 +746,11 @@ RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ ln -sfn /opt/mssql-tools/bin/bcp /usr/bin/bcp && \ echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ locale-gen && \ - pecl install sqlsrv pdo_sqlsrv && \ + if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \ + pecl install sqlsrv-5.3.0 pdo_sqlsrv-5.3.0 \ + ;else \ + pecl install sqlsrv pdo_sqlsrv \ + ;fi && \ echo "extension=sqlsrv.so" > /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-sqlsrv.ini && \ echo "extension=pdo_sqlsrv.so" > /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-pdo_sqlsrv.ini \ && php -m | grep -q 'sqlsrv' \ From 1ec9244f7f0e6edad13f22b7adea0062425529c2 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Sat, 23 Feb 2019 00:52:14 +0800 Subject: [PATCH 104/589] Fix workspace php56 build fail (#2012) * check swoole extenstion after install. * php 5.6 install swoole-2.0.11 downgrade version to 2.0.10 avoid segmentation fault. --- php-fpm/Dockerfile | 3 ++- workspace/Dockerfile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index be2ab84..78a819a 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -206,7 +206,7 @@ ARG INSTALL_SWOOLE=false RUN if [ ${INSTALL_SWOOLE} = true ]; then \ # Install Php Swoole Extension if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ - pecl install swoole-2.0.11; \ + pecl install swoole-2.0.10; \ else \ if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \ pecl install swoole-2.2.0; \ @@ -215,6 +215,7 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ fi \ fi && \ docker-php-ext-enable swoole \ + && php -m | grep -q 'swoole' \ ;fi ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index feccf6a..f09be7b 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -406,7 +406,7 @@ ARG INSTALL_SWOOLE=false RUN if [ ${INSTALL_SWOOLE} = true ]; then \ # Install Php Swoole Extension if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ - pecl -q install swoole-2.0.11; \ + pecl -q install swoole-2.0.10; \ else \ if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \ pecl install swoole-2.2.0; \ @@ -416,6 +416,7 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ fi && \ echo "extension=swoole.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/swoole.ini && \ ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/swoole.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-swoole.ini \ + && php -m | grep -q 'swoole' \ ;fi ########################################################################### From f7dff0f72f54ac826d3ac65cc1e8701a1486e92d Mon Sep 17 00:00:00 2001 From: Panagiotis Koursaris Date: Sat, 23 Feb 2019 06:19:34 +0200 Subject: [PATCH 105/589] update version of elastic and kibana (#1996) --- elasticsearch/Dockerfile | 2 +- kibana/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elasticsearch/Dockerfile b/elasticsearch/Dockerfile index c82bd0c..d3ff4f4 100644 --- a/elasticsearch/Dockerfile +++ b/elasticsearch/Dockerfile @@ -1,3 +1,3 @@ -FROM docker.elastic.co/elasticsearch/elasticsearch:6.2.3 +FROM docker.elastic.co/elasticsearch/elasticsearch:6.6.0 EXPOSE 9200 9300 diff --git a/kibana/Dockerfile b/kibana/Dockerfile index b97bc19..badfd80 100644 --- a/kibana/Dockerfile +++ b/kibana/Dockerfile @@ -1,3 +1,3 @@ -FROM docker.elastic.co/kibana/kibana:6.2.3 +FROM docker.elastic.co/kibana/kibana:6.6.0 EXPOSE 5601 From cde20c3ced28fb92225cf5fd7f04fb2fbec90edb Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Sat, 23 Feb 2019 12:24:58 +0800 Subject: [PATCH 106/589] Fix workspace php56 install V8JS build fail (#2013) * Add check swoole extenstion after install. * Fix php 5.6 install swoole-2.0.11 get segmentation fault. * Fix php 5.6 install v8js build fail. --- workspace/Dockerfile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index f09be7b..11676ff 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -624,13 +624,17 @@ USER root ARG INSTALL_V8JS=false -RUN if [ ${INSTALL_V8JS} = true ]; then \ - # Install the php V8JS extension +RUN set -xe && if [ ${INSTALL_V8JS} = true ]; then \ add-apt-repository -y ppa:pinepain/libv8-archived \ && apt-get update -yqq \ - && apt-get install -y php${LARADOCK_PHP_VERSION}-xml php${LARADOCK_PHP_VERSION}-dev php-pear libv8-5.4 \ - && pecl install v8js \ + && apt-get install -y libv8-5.4 && \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl install v8js-0.6.4; \ + else \ + pecl install v8js; \ + fi \ && echo "extension=v8js.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ + && php -m | grep -q 'v8js' \ ;fi ########################################################################### From 61d7b18922006d582ae68ca0cdf5e202e5bcf08d Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Sat, 23 Feb 2019 16:46:46 +0800 Subject: [PATCH 107/589] Optimize php-fpm and workspace Dockerfile. (#2015) --- php-fpm/Dockerfile | 52 ++++++++++++++++---------------- workspace/Dockerfile | 71 +++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 62 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 78a819a..0d4f7cd 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -24,27 +24,27 @@ ARG LARADOCK_PHP_VERSION ENV DEBIAN_FRONTEND noninteractive # always run apt update when start and after add new source list, then clean up at end. -RUN set -xe && apt-get update -yqq && \ - apt-get install -y apt-utils && \ - pecl channel-update pecl.php.net - -# -#-------------------------------------------------------------------------- -# Mandatory Software's Installation -#-------------------------------------------------------------------------- -# -# Mandatory Software's such as ("mcrypt", "pdo_mysql", "libssl-dev", ....) -# are installed on the base image 'laradock/php-fpm' image. If you want -# to add more Software's or remove existing one, you need to edit the -# base image (https://github.com/Laradock/php-fpm). -# -# next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 -USER root - -RUN apt-get install libzip-dev zip unzip -y && \ - docker-php-ext-configure zip --with-libzip && \ - # Install the zip extension - docker-php-ext-install zip +RUN set -xe; \ + apt-get update -yqq && \ + pecl channel-update pecl.php.net && \ + apt-get install -yqq \ + apt-utils \ + # + #-------------------------------------------------------------------------- + # Mandatory Software's Installation + #-------------------------------------------------------------------------- + # + # Mandatory Software's such as ("mcrypt", "pdo_mysql", "libssl-dev", ....) + # are installed on the base image 'laradock/php-fpm' image. If you want + # to add more Software's or remove existing one, you need to edit the + # base image (https://github.com/Laradock/php-fpm). + # + # next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 + libzip-dev zip unzip && \ + docker-php-ext-configure zip --with-libzip && \ + # Install the zip extension + docker-php-ext-install zip && \ + php -m | grep -q 'zip' # #-------------------------------------------------------------------------- @@ -340,7 +340,8 @@ USER root ARG INSTALL_AEROSPIKE=false -RUN set -xe && if [ ${INSTALL_AEROSPIKE} = true ]; then \ +RUN set -xe; \ + if [ ${INSTALL_AEROSPIKE} = true ]; then \ # Fix dependencies for PHPUnit within aerospike extension apt-get -y install sudo wget && \ # Install the php aerospike extension @@ -455,7 +456,8 @@ RUN if [ ${INSTALL_LDAP} = true ]; then \ ARG INSTALL_MSSQL=false -RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ +RUN set -eux; \ + if [ ${INSTALL_MSSQL} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ apt-get -y install freetds-dev libsybdb5 \ && ln -s /usr/lib/x86_64-linux-gnu/libsybdb.so /usr/lib/libsybdb.so \ @@ -487,7 +489,7 @@ RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ && php -m | grep -q 'pdo_sqlsrv' \ && php -m | grep -q 'sqlsrv' \ ;fi \ -;fi + ;fi ########################################################################### # Image optimizers: @@ -628,7 +630,7 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ # Check PHP version: ########################################################################### -RUN php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." +RUN set -xe; php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." # #-------------------------------------------------------------------------- diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 11676ff..9c16f17 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -37,28 +37,31 @@ ARG PGID=1000 ENV PGID ${PGID} # always run apt update when start and after add new source list, then clean up at end. -RUN set -xe && apt-get update -yqq && \ +RUN set -xe; \ + apt-get update -yqq && \ pecl channel-update pecl.php.net && \ groupadd -g ${PGID} laradock && \ useradd -u ${PUID} -g laradock -m laradock -G docker_env && \ - usermod -p "*" laradock -s /bin/bash - -# -#-------------------------------------------------------------------------- -# Mandatory Software's Installation -#-------------------------------------------------------------------------- -# -# Mandatory Software's such as ("php-cli", "git", "vim", ....) are -# installed on the base image 'laradock/workspace' image. If you want -# to add more Software's or remove existing one, you need to edit the -# base image (https://github.com/Laradock/workspace). -# -# next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 -USER root - -RUN apt-get install -y libzip-dev zip unzip \ - # Install the zip extension - php${LARADOCK_PHP_VERSION}-zip + usermod -p "*" laradock -s /bin/bash && \ + apt-get install -yqq \ + apt-utils \ + # + #-------------------------------------------------------------------------- + # Mandatory Software's Installation + #-------------------------------------------------------------------------- + # + # Mandatory Software's such as ("php-cli", "git", "vim", ....) are + # installed on the base image 'laradock/workspace' image. If you want + # to add more Software's or remove existing one, you need to edit the + # base image (https://github.com/Laradock/workspace). + # + # next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 + libzip-dev zip unzip \ + # Install the zip extension + php${LARADOCK_PHP_VERSION}-zip \ + # nasm + nasm && \ + php -m | grep -q 'zip' # #-------------------------------------------------------------------------- @@ -96,14 +99,14 @@ RUN sed -i 's/\r//' /root/aliases.sh && \ echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source ~/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc USER laradock RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source ~/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc ########################################################################### # Composer: @@ -583,7 +586,8 @@ USER root ARG INSTALL_AEROSPIKE=false -RUN set -xe && if [ ${INSTALL_AEROSPIKE} = true ]; then \ +RUN set -xe; \ + if [ ${INSTALL_AEROSPIKE} = true ]; then \ # Fix dependencies for PHPUnit within aerospike extension apt-get -y install sudo wget && \ # Install the php aerospike extension @@ -614,7 +618,7 @@ RUN set -xe && if [ ${INSTALL_AEROSPIKE} = true ]; then \ && echo 'extension=aerospike.so' >> /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/aerospike.ini \ && echo 'aerospike.udf.lua_system_path=/usr/local/aerospike/lua' >> /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/aerospike.ini \ && echo 'aerospike.udf.lua_user_path=/usr/local/aerospike/usr-lua' >> /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/aerospike.ini \ -;fi + ;fi ########################################################################### # PHP V8JS: @@ -624,7 +628,8 @@ USER root ARG INSTALL_V8JS=false -RUN set -xe && if [ ${INSTALL_V8JS} = true ]; then \ +RUN set -xe; \ + if [ ${INSTALL_V8JS} = true ]; then \ add-apt-repository -y ppa:pinepain/libv8-archived \ && apt-get update -yqq \ && apt-get install -y libv8-5.4 && \ @@ -635,7 +640,7 @@ RUN set -xe && if [ ${INSTALL_V8JS} = true ]; then \ fi \ && echo "extension=v8js.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ && php -m | grep -q 'v8js' \ -;fi + ;fi ########################################################################### # Laravel Envoy: @@ -733,7 +738,8 @@ RUN if [ ${INSTALL_LINUXBREW} = true ]; then \ ARG INSTALL_MSSQL=false -RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ +RUN set -eux; \ + if [ ${INSTALL_MSSQL} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ apt-get -y install php5.6-sybase freetds-bin freetds-common libsybdb5 \ && php -m | grep -q 'mssql' \ @@ -761,7 +767,7 @@ RUN set -eux; if [ ${INSTALL_MSSQL} = true ]; then \ && php -m | grep -q 'sqlsrv' \ && php -m | grep -q 'pdo_sqlsrv' \ ;fi \ -;fi + ;fi ########################################################################### # Minio: @@ -871,15 +877,6 @@ RUN if [ ${INSTALL_PG_CLIENT} = true ]; then \ && apt-get -y install postgresql-client-10 \ ;fi -########################################################################### -# nasm -########################################################################### - -USER root - -RUN apt-get update -yqq \ - && apt-get -yqq install nasm - ########################################################################### # Dusk Dependencies: ########################################################################### @@ -942,7 +939,7 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ # Check PHP version: ########################################################################### -RUN php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." +RUN set -xe; php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}." # #-------------------------------------------------------------------------- From 8f6923531fa39fc2c76fc187fd3273ddd3527984 Mon Sep 17 00:00:00 2001 From: salvo-github <36646452+salvo-github@users.noreply.github.com> Date: Tue, 26 Feb 2019 14:14:32 +0100 Subject: [PATCH 108/589] added variable for xsl (#2016) --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 2fff5b6..005a95b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,6 +58,7 @@ services: - INSTALL_SSH2=${WORKSPACE_INSTALL_SSH2} - INSTALL_GMP=${WORKSPACE_INSTALL_GMP} - INSTALL_SOAP=${WORKSPACE_INSTALL_SOAP} + - INSTALL_XSL=${WORKSPACE_INSTALL_XSL} - INSTALL_LDAP=${WORKSPACE_INSTALL_LDAP} - INSTALL_IMAP=${WORKSPACE_INSTALL_IMAP} - INSTALL_MONGO=${WORKSPACE_INSTALL_MONGO} @@ -134,6 +135,7 @@ services: - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} - INSTALL_SSH2=${PHP_FPM_INSTALL_SSH2} - INSTALL_SOAP=${PHP_FPM_INSTALL_SOAP} + - INSTALL_XSL=${PHP_FPM_INSTALL_XSL} - INSTALL_IMAP=${PHP_FPM_INSTALL_IMAP} - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} From cf6a9ba2c9e8df7e55371454079f66bb2d0d028c Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 1 Mar 2019 11:02:13 +0800 Subject: [PATCH 109/589] php-fpm and workspace replace base image (#2025) * php-fpm and workspace replace base image * Aerospike PHP 5.6.40 Debian 9.6 is not supported, travis-ci build by pass. --- php-fpm/Dockerfile | 3 ++- travis-build.sh | 5 +++++ workspace/Dockerfile | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 0d4f7cd..4cabe57 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -14,7 +14,8 @@ ARG LARADOCK_PHP_VERSION -FROM laradock/php-fpm:2.2-${LARADOCK_PHP_VERSION} +# FROM laradock/php-fpm:2.2-${LARADOCK_PHP_VERSION} +FROM letsdockerize/laradock-php-fpm:2.3-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " diff --git a/travis-build.sh b/travis-build.sh index d6aec97..2270683 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -15,6 +15,11 @@ if [ -n "${PHP_VERSION}" ]; then sed -i -- "s/PHP_VERSION=.*/PHP_VERSION=${PHP_VERSION}/g" .env sed -i -- 's/=false/=true/g' .env sed -i -- 's/PHPDBG=true/PHPDBG=false/g' .env + if [ "${PHP_VERSION}" == "5.6" ]; then + # Aerospike C Client SDK 4.0.7, Debian 9.6 is not supported + # https://github.com/aerospike/aerospike-client-php5/issues/145 + sed -i -- 's/PHP_FPM_INSTALL_AEROSPIKE=true/PHP_FPM_INSTALL_AEROSPIKE=false/g' .env + fi cat .env docker-compose build ${BUILD_SERVICE} docker images diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 9c16f17..5cb8619 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -14,7 +14,8 @@ ARG LARADOCK_PHP_VERSION -FROM laradock/workspace:2.2-${LARADOCK_PHP_VERSION} +# FROM laradock/workspace:2.2-${LARADOCK_PHP_VERSION} +FROM letsdockerize/laradock-workspace:2.3-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " From 2d7b780e56682a2296f1015d6263c91c1d28b991 Mon Sep 17 00:00:00 2001 From: salvo-github <36646452+salvo-github@users.noreply.github.com> Date: Fri, 1 Mar 2019 04:04:03 +0100 Subject: [PATCH 110/589] Auth file for magento 2 installation (#2022) --- DOCUMENTATION/content/documentation/index.md | 17 +++++++++++++++++ docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 12 ++++++++++++ workspace/auth.json | 8 ++++++++ 5 files changed, 39 insertions(+) create mode 100644 workspace/auth.json diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 5a5f2b3..1fa6ff6 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1543,6 +1543,23 @@ Enabling Global Composer Install during the build for the container allows you t +
+ +## Magento 2 authentication credential (composer install) + +1 - Open the `.env` file + +2 - Search for the `WORKSPACE_COMPOSER_AUTH` argument under the Workspace Container and set it to `true` + +3 - Now add your credentials to `workspace/auth.json` + +4 - Re-build the Workspace Container `docker-compose build workspace` + + + + + +
## Install Prestissimo diff --git a/docker-compose.yml b/docker-compose.yml index 005a95b..e7aff2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -78,6 +78,7 @@ services: - INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE} - INSTALL_V8JS=${WORKSPACE_INSTALL_V8JS} - COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL} + - COMPOSER_AUTH=${WORKSPACE_COMPOSER_AUTH} - COMPOSER_REPO_PACKAGIST=${WORKSPACE_COMPOSER_REPO_PACKAGIST} - INSTALL_WORKSPACE_SSH=${WORKSPACE_INSTALL_WORKSPACE_SSH} - INSTALL_LARAVEL_ENVOY=${WORKSPACE_INSTALL_LARAVEL_ENVOY} diff --git a/env-example b/env-example index 70b3570..e944f1a 100644 --- a/env-example +++ b/env-example @@ -82,6 +82,7 @@ DOCKER_SYNC_STRATEGY=native_osx ### WORKSPACE ############################################# WORKSPACE_COMPOSER_GLOBAL_INSTALL=true +WORKSPACE_COMPOSER_AUTH=false WORKSPACE_COMPOSER_REPO_PACKAGIST= WORKSPACE_INSTALL_NODE=true WORKSPACE_NODE_VERSION=node diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 5cb8619..501c487 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -118,6 +118,9 @@ USER root # Add the composer.json COPY ./composer.json /home/laradock/.composer/composer.json +# Add the auth.json for magento 2 credentials +COPY ./auth.json /home/laradock/.composer/auth.json + # Make sure that ~/.composer belongs to laradock RUN chown -R laradock:laradock /home/laradock/.composer @@ -132,6 +135,15 @@ RUN if [ ${COMPOSER_GLOBAL_INSTALL} = true ]; then \ composer global install \ ;fi +# Check if auth file is disabled +ARG COMPOSER_AUTH=false +ENV COMPOSER_AUTH ${COMPOSER_AUTH} + +RUN if [ ${COMPOSER_AUTH} = false ]; then \ + # remove the file + rm /home/laradock/.composer/auth.json +;fi + ARG COMPOSER_REPO_PACKAGIST ENV COMPOSER_REPO_PACKAGIST ${COMPOSER_REPO_PACKAGIST} diff --git a/workspace/auth.json b/workspace/auth.json new file mode 100644 index 0000000..03cde45 --- /dev/null +++ b/workspace/auth.json @@ -0,0 +1,8 @@ +{ + "http-basic": { + "repo.magento.com": { + "username": "", + "password": "" + } + } +} From d964e2898c67f126250c286d510ed4482bc84b56 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 1 Mar 2019 12:04:32 +0800 Subject: [PATCH 111/589] fix Dockerfile parse error line #2022 --- workspace/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 501c487..17a4886 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -141,7 +141,7 @@ ENV COMPOSER_AUTH ${COMPOSER_AUTH} RUN if [ ${COMPOSER_AUTH} = false ]; then \ # remove the file - rm /home/laradock/.composer/auth.json + rm /home/laradock/.composer/auth.json \ ;fi ARG COMPOSER_REPO_PACKAGIST From d404555cf5f7685693fd542c8affbcd7efdc1059 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 1 Mar 2019 12:16:08 +0800 Subject: [PATCH 112/589] fix ipython-controller build fail (#2027) --- .travis.yml | 1 + ipython/Dockerfile.controller | 4 ++-- ipython/Dockerfile.engine | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53e43ce..12ad650 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ env: - PHP_VERSION=NA BUILD_SERVICE="adminer phpmyadmin pgadmin" - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy" - PHP_VERSION=NA BUILD_SERVICE="kibana grafana laravel-echo-server" + - PHP_VERSION=NA BUILD_SERVICE="ipython-controller" # - PHP_VERSION=NA BUILD_SERVICE="aws" # Installing a newer Docker version diff --git a/ipython/Dockerfile.controller b/ipython/Dockerfile.controller index 3acb62d..d325c6f 100644 --- a/ipython/Dockerfile.controller +++ b/ipython/Dockerfile.controller @@ -4,7 +4,7 @@ LABEL maintainer="ahkui " USER root -RUN apk add --no-cache build-base +RUN apk add --no-cache build-base zeromq-dev RUN python -m pip --quiet --no-cache-dir install \ ipyparallel @@ -14,4 +14,4 @@ RUN ipython profile create --parallel --profile=default COPY ipcontroller-client.json /root/.ipython/profile_default/security/ipcontroller-client.json COPY ipcontroller-engine.json /root/.ipython/profile_default/security/ipcontroller-engine.json -CMD ["sh","-c","ipcontroller --ip=* --reuse"] \ No newline at end of file +CMD ["sh","-c","ipcontroller --ip=* --reuse"] diff --git a/ipython/Dockerfile.engine b/ipython/Dockerfile.engine index 5f709b6..b0ff3fc 100644 --- a/ipython/Dockerfile.engine +++ b/ipython/Dockerfile.engine @@ -4,7 +4,7 @@ LABEL maintainer="ahkui " USER root -RUN apk add --no-cache build-base +RUN apk add --no-cache build-base zeromq-dev RUN python -m pip --quiet --no-cache-dir install \ ipyparallel \ From f18eb9728bc13b15c972e9ff33beebef404add40 Mon Sep 17 00:00:00 2001 From: Arif Waram Date: Fri, 1 Mar 2019 14:48:23 +0700 Subject: [PATCH 113/589] add an official redis stable config file (#1911) for more convenience start with default settings. ref. from http://download.redis.io/redis-stable/redis.conf --- redis/redis.conf | 1377 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1377 insertions(+) create mode 100644 redis/redis.conf diff --git a/redis/redis.conf b/redis/redis.conf new file mode 100644 index 0000000..eb03c58 --- /dev/null +++ b/redis/redis.conf @@ -0,0 +1,1377 @@ +# Redis configuration file example. +# +# Note that in order to read the configuration file, Redis must be +# started with the file path as first argument: +# +# ./redis-server /path/to/redis.conf + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include /path/to/local.conf +# include /path/to/other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule /path/to/my_module.so +# loadmodule /path/to/other_module.so + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 127.0.0.1 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +pidfile /var/run/redis_6379.pid + +# Specify the server verbosity level. +# This can be one of: +# debug (a lot of information, useful for development/testing) +# verbose (many rarely useful info, but not a mess like the debug level) +# notice (moderately verbose, what you want in production probably) +# warning (only very important / critical messages are logged) +loglevel notice + +# Specify the log file name. Also the empty string can be used to force +# Redis to log on the standard output. Note that if you use standard +# output for logging but daemonize, logs will be sent to /dev/null +logfile "" + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no + +# Specify the syslog identity. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" + +save 900 1 +save 300 10 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# ------------------------------------------------------- +# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY +# ------------------------------------------------------- +# +# New replicas and reconnecting replicas that are not able to continue the replication +# process just receiving differences, need to do what is called a "full +# synchronization". An RDB file is transmitted from the master to the replicas. +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child producing +# the RDB file finishes its work. With diskless replication instead once +# the transfer starts, new replicas arriving will be queued and a new transfer +# will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple replicas +# will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the server +# waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# Replicas send PINGs to server in a predefined interval. It's possible to change +# this interval with the repl_ping_replica_period option. The default value is 10 +# seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a replica +# wants to reconnect again, often a full resync is not needed, but a partial +# resync is enough, just passing the portion of data the replica missed while +# disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO output. +# It is used by Redis Sentinel in order to select a replica to promote into a +# master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel will +# pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +################################## SECURITY ################################### + +# Require clients to issue AUTH before processing any other +# commands. This might be useful in environments in which you do not trust +# others with access to the host running redis-server. +# +# This should stay commented out for backward compatibility and because most +# people do not need auth (e.g. they run their own servers). +# +# Warning: since Redis is pretty fast an outside user can try up to +# 150k passwords per second against a good box. This means that you should +# use a very strong password otherwise it will be very easy to break. +# +# requirepass foobared + +# Command renaming. +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select among five behaviors: +# +# volatile-lru -> Evict using approximated LRU among the keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU among the keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key among the ones with an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica to have +# a different memory setting, and you are sure all the writes performed to the +# replica are idempotent, then you may change this default (but be sure to understand +# what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory and so +# forth). So make sure you monitor your replicas and make sure they have enough +# memory to never hit a real out-of-memory condition before the master hits +# the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives: + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### +# +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however +# in order to mark it as "mature" we need to wait for a non trivial percentage +# of users to deploy it in production. +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes + +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# A Alias for g$lshzxe, so that the "AKE" string means all the events. +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used as +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +########################### ACTIVE DEFRAGMENTATION ####################### +# +# WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested +# even in production and manually tested by multiple engineers for some +# time. +# +# What is active defragmentation? +# ------------------------------- +# +# Active (online) defragmentation allows a Redis server to compact the +# spaces left between small allocations and deallocations of data in memory, +# thus allowing to reclaim back memory. +# +# Fragmentation is a natural process that happens with every allocator (but +# less so with Jemalloc, fortunately) and certain workloads. Normally a server +# restart is needed in order to lower the fragmentation, or at least to flush +# away all the data and create it again. However thanks to this feature +# implemented by Oran Agra for Redis 4.0 this process can happen at runtime +# in an "hot" way, while the server is running. +# +# Basically when the fragmentation is over a certain level (see the +# configuration options below) Redis will start to create new copies of the +# values in contiguous memory regions by exploiting certain specific Jemalloc +# features (in order to understand if an allocation is causing fragmentation +# and to allocate it in a better place), and at the same time, will release the +# old copies of the data. This process, repeated incrementally for all the keys +# will cause the fragmentation to drop back to normal values. +# +# Important things to understand: +# +# 1. This feature is disabled by default, and only works if you compiled Redis +# to use the copy of Jemalloc we ship with the source code of Redis. +# This is the default with Linux builds. +# +# 2. You never need to enable this feature if you don't have fragmentation +# issues. +# +# 3. Once you experience fragmentation, you can enable this feature when +# needed with the command "CONFIG SET activedefrag yes". +# +# The configuration parameters are able to fine tune the behavior of the +# defragmentation process. If you are not sure about what they mean it is +# a good idea to leave the defaults untouched. + +# Enabled active defragmentation +# activedefrag yes + +# Minimum amount of fragmentation waste to start active defrag +# active-defrag-ignore-bytes 100mb + +# Minimum percentage of fragmentation to start active defrag +# active-defrag-threshold-lower 10 + +# Maximum percentage of fragmentation at which we use maximum effort +# active-defrag-threshold-upper 100 + +# Minimal effort for defrag in CPU percentage +# active-defrag-cycle-min 5 + +# Maximal effort for defrag in CPU percentage +# active-defrag-cycle-max 75 + +# Maximum number of set/hash/zset/list fields that will be processed from +# the main dictionary scan +# active-defrag-max-scan-fields 1000 From 76218808fdcfc1a16841ca12254342a3b453ffe9 Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 1 Mar 2019 18:24:14 +0800 Subject: [PATCH 114/589] Support PHP 7.3 (#2028) * Support PHP 7.3 * travics-ci build test by pass: * SSH2 extension does not yet support PHP 7.3 * V8JS extension does not yet support PHP 7.3. * xdebug extension does not yet support PHP 7.3. * memcached extension does not yet support PHP 7.3. --- .travis.yml | 3 + DOCUMENTATION/content/introduction/index.md | 2 +- env-example | 2 +- php-fpm/php7.3.ini | 1918 +++++++++++++++++++ travis-build.sh | 10 + 5 files changed, 1933 insertions(+), 2 deletions(-) create mode 100644 php-fpm/php7.3.ini diff --git a/.travis.yml b/.travis.yml index 12ad650..f93c859 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,13 @@ env: - PHP_VERSION=7.0 BUILD_SERVICE=workspace - PHP_VERSION=7.1 BUILD_SERVICE=workspace - PHP_VERSION=7.2 BUILD_SERVICE=workspace + - PHP_VERSION=7.3 BUILD_SERVICE=workspace - PHP_VERSION=5.6 BUILD_SERVICE=php-fpm - PHP_VERSION=7.0 BUILD_SERVICE=php-fpm - PHP_VERSION=7.1 BUILD_SERVICE=php-fpm - PHP_VERSION=7.2 BUILD_SERVICE=php-fpm + - PHP_VERSION=7.3 BUILD_SERVICE=php-fpm - PHP_VERSION=hhvm BUILD_SERVICE=hhvm @@ -23,6 +25,7 @@ env: - PHP_VERSION=7.0 BUILD_SERVICE=php-worker - PHP_VERSION=7.1 BUILD_SERVICE=php-worker - PHP_VERSION=7.2 BUILD_SERVICE=php-worker + - PHP_VERSION=7.3 BUILD_SERVICE=php-worker - PHP_VERSION=NA BUILD_SERVICE=solr - PHP_VERSION=NA BUILD_SERVICE="mssql rethinkdb aerospike" diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 97eb705..82c5b31 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -58,7 +58,7 @@ That's it! enjoy :) ## Features -- Easy switch between PHP versions: 7.2, 7.1, 5.6... +- Easy switch between PHP versions: 7.3, 7.2, 7.1, 5.6... - Choose your favorite database engine: MySQL, Postgres, MariaDB... - Run your own combination of software: Memcached, HHVM, Beanstalkd... - Every software runs on a separate container: PHP-FPM, NGINX, PHP-CLI... diff --git a/env-example b/env-example index e944f1a..228bc81 100644 --- a/env-example +++ b/env-example @@ -37,7 +37,7 @@ COMPOSE_PROJECT_NAME=laradock ### PHP Version ########################################### -# Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 7.2 - 7.1 - 7.0 - 5.6 +# Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 7.3 - 7.2 - 7.1 - 7.0 - 5.6 PHP_VERSION=7.2 ### Phalcon Version ########################################### diff --git a/php-fpm/php7.3.ini b/php-fpm/php7.3.ini new file mode 100644 index 0000000..9bf5f6c --- /dev/null +++ b/php-fpm/php7.3.ini @@ -0,0 +1,1918 @@ +[PHP] + +;;;;;;;;;;;;;;;;;;; +; About php.ini ; +;;;;;;;;;;;;;;;;;;; +; PHP's initialization file, generally called php.ini, is responsible for +; configuring many of the aspects of PHP's behavior. + +; PHP attempts to find and load this configuration from a number of locations. +; The following is a summary of its search order: +; 1. SAPI module specific location. +; 2. The PHPRC environment variable. (As of PHP 5.2.0) +; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) +; 4. Current working directory (except CLI) +; 5. The web server's directory (for SAPI modules), or directory of PHP +; (otherwise in Windows) +; 6. The directory from the --with-config-file-path compile time option, or the +; Windows directory (C:\windows or C:\winnt) +; See the PHP docs for more specific information. +; http://php.net/configuration.file + +; The syntax of the file is extremely simple. Whitespace and lines +; beginning with a semicolon are silently ignored (as you probably guessed). +; Section headers (e.g. [Foo]) are also silently ignored, even though +; they might mean something in the future. + +; Directives following the section heading [PATH=/www/mysite] only +; apply to PHP files in the /www/mysite directory. Directives +; following the section heading [HOST=www.example.com] only apply to +; PHP files served from www.example.com. Directives set in these +; special sections cannot be overridden by user-defined INI files or +; at runtime. Currently, [PATH=] and [HOST=] sections only work under +; CGI/FastCGI. +; http://php.net/ini.sections + +; Directives are specified using the following syntax: +; directive = value +; Directive names are *case sensitive* - foo=bar is different from FOO=bar. +; Directives are variables used to configure PHP or PHP extensions. +; There is no name validation. If PHP can't find an expected +; directive because it is not set or is mistyped, a default value will be used. + +; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one +; of the INI constants (On, Off, True, False, Yes, No and None) or an expression +; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a +; previously set variable or directive (e.g. ${foo}) + +; Expressions in the INI file are limited to bitwise operators and parentheses: +; | bitwise OR +; ^ bitwise XOR +; & bitwise AND +; ~ bitwise NOT +; ! boolean NOT + +; Boolean flags can be turned on using the values 1, On, True or Yes. +; They can be turned off using the values 0, Off, False or No. + +; An empty string can be denoted by simply not writing anything after the equal +; sign, or by using the None keyword: + +; foo = ; sets foo to an empty string +; foo = None ; sets foo to an empty string +; foo = "None" ; sets foo to the string 'None' + +; If you use constants in your value, and these constants belong to a +; dynamically loaded extension (either a PHP extension or a Zend extension), +; you may only use these constants *after* the line that loads the extension. + +;;;;;;;;;;;;;;;;;;; +; About this file ; +;;;;;;;;;;;;;;;;;;; +; PHP comes packaged with two INI files. One that is recommended to be used +; in production environments and one that is recommended to be used in +; development environments. + +; php.ini-production contains settings which hold security, performance and +; best practices at its core. But please be aware, these settings may break +; compatibility with older or less security conscience applications. We +; recommending using the production ini in production and testing environments. + +; php.ini-development is very similar to its production variant, except it is +; much more verbose when it comes to errors. We recommend using the +; development version only in development environments, as errors shown to +; application users can inadvertently leak otherwise secure information. + +; This is php.ini-production INI file. + +;;;;;;;;;;;;;;;;;;; +; Quick Reference ; +;;;;;;;;;;;;;;;;;;; +; The following are all the settings which are different in either the production +; or development versions of the INIs with respect to PHP's default behavior. +; Please see the actual settings later in the document for more details as to why +; we recommend these changes in PHP's behavior. + +; display_errors +; Default Value: On +; Development Value: On +; Production Value: Off + +; display_startup_errors +; Default Value: Off +; Development Value: On +; Production Value: Off + +; error_reporting +; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED +; Development Value: E_ALL +; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT + +; html_errors +; Default Value: On +; Development Value: On +; Production value: On + +; log_errors +; Default Value: Off +; Development Value: On +; Production Value: On + +; max_input_time +; Default Value: -1 (Unlimited) +; Development Value: 60 (60 seconds) +; Production Value: 60 (60 seconds) + +; output_buffering +; Default Value: Off +; Development Value: 4096 +; Production Value: 4096 + +; register_argc_argv +; Default Value: On +; Development Value: Off +; Production Value: Off + +; request_order +; Default Value: None +; Development Value: "GP" +; Production Value: "GP" + +; session.gc_divisor +; Default Value: 100 +; Development Value: 1000 +; Production Value: 1000 + +; session.sid_bits_per_character +; Default Value: 4 +; Development Value: 5 +; Production Value: 5 + +; short_open_tag +; Default Value: On +; Development Value: Off +; Production Value: Off + +; track_errors +; Default Value: Off +; Development Value: On +; Production Value: Off + +; variables_order +; Default Value: "EGPCS" +; Development Value: "GPCS" +; Production Value: "GPCS" + +;;;;;;;;;;;;;;;;;;;; +; php.ini Options ; +;;;;;;;;;;;;;;;;;;;; +; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" +;user_ini.filename = ".user.ini" + +; To disable this feature set this option to empty value +;user_ini.filename = + +; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) +;user_ini.cache_ttl = 300 + +;;;;;;;;;;;;;;;;;;;; +; Language Options ; +;;;;;;;;;;;;;;;;;;;; + +; Enable the PHP scripting language engine under Apache. +; http://php.net/engine +engine = On + +; This directive determines whether or not PHP will recognize code between +; tags as PHP source which should be processed as such. It is +; generally recommended that should be used and that this feature +; should be disabled, as enabling it may result in issues when generating XML +; documents, however this remains supported for backward compatibility reasons. +; Note that this directive does not control the would work. +; http://php.net/syntax-highlighting +;highlight.string = #DD0000 +;highlight.comment = #FF9900 +;highlight.keyword = #007700 +;highlight.default = #0000BB +;highlight.html = #000000 + +; If enabled, the request will be allowed to complete even if the user aborts +; the request. Consider enabling it if executing long requests, which may end up +; being interrupted by the user or a browser timing out. PHP's default behavior +; is to disable this feature. +; http://php.net/ignore-user-abort +;ignore_user_abort = On + +; Determines the size of the realpath cache to be used by PHP. This value should +; be increased on systems where PHP opens many files to reflect the quantity of +; the file operations performed. +; http://php.net/realpath-cache-size +;realpath_cache_size = 4096k + +; Duration of time, in seconds for which to cache realpath information for a given +; file or directory. For systems with rarely changing files, consider increasing this +; value. +; http://php.net/realpath-cache-ttl +;realpath_cache_ttl = 120 + +; Enables or disables the circular reference collector. +; http://php.net/zend.enable-gc +zend.enable_gc = On + +; If enabled, scripts may be written in encodings that are incompatible with +; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such +; encodings. To use this feature, mbstring extension must be enabled. +; Default: Off +;zend.multibyte = Off + +; Allows to set the default encoding for the scripts. This value will be used +; unless "declare(encoding=...)" directive appears at the top of the script. +; Only affects if zend.multibyte is set. +; Default: "" +;zend.script_encoding = + +;;;;;;;;;;;;;;;;; +; Miscellaneous ; +;;;;;;;;;;;;;;;;; + +; Decides whether PHP may expose the fact that it is installed on the server +; (e.g. by adding its signature to the Web server header). It is no security +; threat in any way, but it makes it possible to determine whether you use PHP +; on your server or not. +; http://php.net/expose-php +expose_php = On + +;;;;;;;;;;;;;;;;;;; +; Resource Limits ; +;;;;;;;;;;;;;;;;;;; + +; Maximum execution time of each script, in seconds +; http://php.net/max-execution-time +; Note: This directive is hardcoded to 0 for the CLI SAPI +max_execution_time = 600 + +; Maximum amount of time each script may spend parsing request data. It's a good +; idea to limit this time on productions servers in order to eliminate unexpectedly +; long running scripts. +; Note: This directive is hardcoded to -1 for the CLI SAPI +; Default Value: -1 (Unlimited) +; Development Value: 60 (60 seconds) +; Production Value: 60 (60 seconds) +; http://php.net/max-input-time +max_input_time = 120 + +; Maximum input variable nesting level +; http://php.net/max-input-nesting-level +;max_input_nesting_level = 64 + +; How many GET/POST/COOKIE input variables may be accepted +; max_input_vars = 1000 + +; Maximum amount of memory a script may consume (128MB) +; http://php.net/memory-limit +memory_limit = 256M + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Error handling and logging ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; This directive informs PHP of which errors, warnings and notices you would like +; it to take action for. The recommended way of setting values for this +; directive is through the use of the error level constants and bitwise +; operators. The error level constants are below here for convenience as well as +; some common settings and their meanings. +; By default, PHP is set to take action on all errors, notices and warnings EXCEPT +; those related to E_NOTICE and E_STRICT, which together cover best practices and +; recommended coding standards in PHP. For performance reasons, this is the +; recommend error reporting setting. Your production server shouldn't be wasting +; resources complaining about best practices and coding standards. That's what +; development servers and development settings are for. +; Note: The php.ini-development file has this setting as E_ALL. This +; means it pretty much reports everything which is exactly what you want during +; development and early testing. +; +; Error Level Constants: +; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0) +; E_ERROR - fatal run-time errors +; E_RECOVERABLE_ERROR - almost fatal run-time errors +; E_WARNING - run-time warnings (non-fatal errors) +; E_PARSE - compile-time parse errors +; E_NOTICE - run-time notices (these are warnings which often result +; from a bug in your code, but it's possible that it was +; intentional (e.g., using an uninitialized variable and +; relying on the fact it is automatically initialized to an +; empty string) +; E_STRICT - run-time notices, enable to have PHP suggest changes +; to your code which will ensure the best interoperability +; and forward compatibility of your code +; E_CORE_ERROR - fatal errors that occur during PHP's initial startup +; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's +; initial startup +; E_COMPILE_ERROR - fatal compile-time errors +; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) +; E_USER_ERROR - user-generated error message +; E_USER_WARNING - user-generated warning message +; E_USER_NOTICE - user-generated notice message +; E_DEPRECATED - warn about code that will not work in future versions +; of PHP +; E_USER_DEPRECATED - user-generated deprecation warnings +; +; Common Values: +; E_ALL (Show all errors, warnings and notices including coding standards.) +; E_ALL & ~E_NOTICE (Show all errors, except for notices) +; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.) +; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) +; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED +; Development Value: E_ALL +; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT +; http://php.net/error-reporting +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT + +; This directive controls whether or not and where PHP will output errors, +; notices and warnings too. Error output is very useful during development, but +; it could be very dangerous in production environments. Depending on the code +; which is triggering the error, sensitive information could potentially leak +; out of your application such as database usernames and passwords or worse. +; For production environments, we recommend logging errors rather than +; sending them to STDOUT. +; Possible Values: +; Off = Do not display any errors +; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) +; On or stdout = Display errors to STDOUT +; Default Value: On +; Development Value: On +; Production Value: Off +; http://php.net/display-errors +display_errors = Off + +; The display of errors which occur during PHP's startup sequence are handled +; separately from display_errors. PHP's default behavior is to suppress those +; errors from clients. Turning the display of startup errors on can be useful in +; debugging configuration problems. We strongly recommend you +; set this to 'off' for production servers. +; Default Value: Off +; Development Value: On +; Production Value: Off +; http://php.net/display-startup-errors +display_startup_errors = Off + +; Besides displaying errors, PHP can also log errors to locations such as a +; server-specific log, STDERR, or a location specified by the error_log +; directive found below. While errors should not be displayed on productions +; servers they should still be monitored and logging is a great way to do that. +; Default Value: Off +; Development Value: On +; Production Value: On +; http://php.net/log-errors +log_errors = On + +; Set maximum length of log_errors. In error_log information about the source is +; added. The default is 1024 and 0 allows to not apply any maximum length at all. +; http://php.net/log-errors-max-len +log_errors_max_len = 1024 + +; Do not log repeated messages. Repeated errors must occur in same file on same +; line unless ignore_repeated_source is set true. +; http://php.net/ignore-repeated-errors +ignore_repeated_errors = Off + +; Ignore source of message when ignoring repeated messages. When this setting +; is On you will not log errors with repeated messages from different files or +; source lines. +; http://php.net/ignore-repeated-source +ignore_repeated_source = Off + +; If this parameter is set to Off, then memory leaks will not be shown (on +; stdout or in the log). This has only effect in a debug compile, and if +; error reporting includes E_WARNING in the allowed list +; http://php.net/report-memleaks +report_memleaks = On + +; This setting is on by default. +;report_zend_debug = 0 + +; Store the last error/warning message in $php_errormsg (boolean). Setting this value +; to On can assist in debugging and is appropriate for development servers. It should +; however be disabled on production servers. +; Default Value: Off +; Development Value: On +; Production Value: Off +; http://php.net/track-errors +track_errors = Off + +; Turn off normal error reporting and emit XML-RPC error XML +; http://php.net/xmlrpc-errors +;xmlrpc_errors = 0 + +; An XML-RPC faultCode +;xmlrpc_error_number = 0 + +; When PHP displays or logs an error, it has the capability of formatting the +; error message as HTML for easier reading. This directive controls whether +; the error message is formatted as HTML or not. +; Note: This directive is hardcoded to Off for the CLI SAPI +; Default Value: On +; Development Value: On +; Production value: On +; http://php.net/html-errors +html_errors = On + +; If html_errors is set to On *and* docref_root is not empty, then PHP +; produces clickable error messages that direct to a page describing the error +; or function causing the error in detail. +; You can download a copy of the PHP manual from http://php.net/docs +; and change docref_root to the base URL of your local copy including the +; leading '/'. You must also specify the file extension being used including +; the dot. PHP's default behavior is to leave these settings empty, in which +; case no links to documentation are generated. +; Note: Never use this feature for production boxes. +; http://php.net/docref-root +; Examples +;docref_root = "/phpmanual/" + +; http://php.net/docref-ext +;docref_ext = .html + +; String to output before an error message. PHP's default behavior is to leave +; this setting blank. +; http://php.net/error-prepend-string +; Example: +;error_prepend_string = "" + +; String to output after an error message. PHP's default behavior is to leave +; this setting blank. +; http://php.net/error-append-string +; Example: +;error_append_string = "" + +; Log errors to specified file. PHP's default behavior is to leave this value +; empty. +; http://php.net/error-log +; Example: +;error_log = php_errors.log +; Log errors to syslog (Event Log on Windows). +;error_log = syslog + +;windows.show_crt_warning +; Default value: 0 +; Development value: 0 +; Production value: 0 + +;;;;;;;;;;;;;;;;; +; Data Handling ; +;;;;;;;;;;;;;;;;; + +; The separator used in PHP generated URLs to separate arguments. +; PHP's default setting is "&". +; http://php.net/arg-separator.output +; Example: +;arg_separator.output = "&" + +; List of separator(s) used by PHP to parse input URLs into variables. +; PHP's default setting is "&". +; NOTE: Every character in this directive is considered as separator! +; http://php.net/arg-separator.input +; Example: +;arg_separator.input = ";&" + +; This directive determines which super global arrays are registered when PHP +; starts up. G,P,C,E & S are abbreviations for the following respective super +; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty +; paid for the registration of these arrays and because ENV is not as commonly +; used as the others, ENV is not recommended on productions servers. You +; can still get access to the environment variables through getenv() should you +; need to. +; Default Value: "EGPCS" +; Development Value: "GPCS" +; Production Value: "GPCS"; +; http://php.net/variables-order +variables_order = "GPCS" + +; This directive determines which super global data (G,P & C) should be +; registered into the super global array REQUEST. If so, it also determines +; the order in which that data is registered. The values for this directive +; are specified in the same manner as the variables_order directive, +; EXCEPT one. Leaving this value empty will cause PHP to use the value set +; in the variables_order directive. It does not mean it will leave the super +; globals array REQUEST empty. +; Default Value: None +; Development Value: "GP" +; Production Value: "GP" +; http://php.net/request-order +request_order = "GP" + +; This directive determines whether PHP registers $argv & $argc each time it +; runs. $argv contains an array of all the arguments passed to PHP when a script +; is invoked. $argc contains an integer representing the number of arguments +; that were passed when the script was invoked. These arrays are extremely +; useful when running scripts from the command line. When this directive is +; enabled, registering these variables consumes CPU cycles and memory each time +; a script is executed. For performance reasons, this feature should be disabled +; on production servers. +; Note: This directive is hardcoded to On for the CLI SAPI +; Default Value: On +; Development Value: Off +; Production Value: Off +; http://php.net/register-argc-argv +register_argc_argv = Off + +; When enabled, the ENV, REQUEST and SERVER variables are created when they're +; first used (Just In Time) instead of when the script starts. If these +; variables are not used within a script, having this directive on will result +; in a performance gain. The PHP directive register_argc_argv must be disabled +; for this directive to have any affect. +; http://php.net/auto-globals-jit +auto_globals_jit = On + +; Whether PHP will read the POST data. +; This option is enabled by default. +; Most likely, you won't want to disable this option globally. It causes $_POST +; and $_FILES to always be empty; the only way you will be able to read the +; POST data will be through the php://input stream wrapper. This can be useful +; to proxy requests or to process the POST data in a memory efficient fashion. +; http://php.net/enable-post-data-reading +;enable_post_data_reading = Off + +; Maximum size of POST data that PHP will accept. +; Its value may be 0 to disable the limit. It is ignored if POST data reading +; is disabled through enable_post_data_reading. +; http://php.net/post-max-size +post_max_size = 8M + +; Automatically add files before PHP document. +; http://php.net/auto-prepend-file +auto_prepend_file = + +; Automatically add files after PHP document. +; http://php.net/auto-append-file +auto_append_file = + +; By default, PHP will output a media type using the Content-Type header. To +; disable this, simply set it to be empty. +; +; PHP's built-in default media type is set to text/html. +; http://php.net/default-mimetype +default_mimetype = "text/html" + +; PHP's default character set is set to UTF-8. +; http://php.net/default-charset +default_charset = "UTF-8" + +; PHP internal character encoding is set to empty. +; If empty, default_charset is used. +; http://php.net/internal-encoding +;internal_encoding = + +; PHP input character encoding is set to empty. +; If empty, default_charset is used. +; http://php.net/input-encoding +;input_encoding = + +; PHP output character encoding is set to empty. +; If empty, default_charset is used. +; See also output_buffer. +; http://php.net/output-encoding +;output_encoding = + +;;;;;;;;;;;;;;;;;;;;;;;;; +; Paths and Directories ; +;;;;;;;;;;;;;;;;;;;;;;;;; + +; UNIX: "/path1:/path2" +;include_path = ".:/php/includes" +; +; Windows: "\path1;\path2" +;include_path = ".;c:\php\includes" +; +; PHP's default setting for include_path is ".;/path/to/php/pear" +; http://php.net/include-path + +; The root of the PHP pages, used only if nonempty. +; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root +; if you are running php as a CGI under any web server (other than IIS) +; see documentation for security issues. The alternate is to use the +; cgi.force_redirect configuration below +; http://php.net/doc-root +doc_root = + +; The directory under which PHP opens the script using /~username used only +; if nonempty. +; http://php.net/user-dir +user_dir = + +; Directory in which the loadable extensions (modules) reside. +; http://php.net/extension-dir +; extension_dir = "./" +; On windows: +; extension_dir = "ext" + +; Directory where the temporary files should be placed. +; Defaults to the system default (see sys_get_temp_dir) +; sys_temp_dir = "/tmp" + +; Whether or not to enable the dl() function. The dl() function does NOT work +; properly in multithreaded servers, such as IIS or Zeus, and is automatically +; disabled on them. +; http://php.net/enable-dl +enable_dl = Off + +; cgi.force_redirect is necessary to provide security running PHP as a CGI under +; most web servers. Left undefined, PHP turns this on by default. You can +; turn it off here AT YOUR OWN RISK +; **You CAN safely turn this off for IIS, in fact, you MUST.** +; http://php.net/cgi.force-redirect +;cgi.force_redirect = 1 + +; if cgi.nph is enabled it will force cgi to always sent Status: 200 with +; every request. PHP's default behavior is to disable this feature. +;cgi.nph = 1 + +; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape +; (iPlanet) web servers, you MAY need to set an environment variable name that PHP +; will look for to know it is OK to continue execution. Setting this variable MAY +; cause security issues, KNOW WHAT YOU ARE DOING FIRST. +; http://php.net/cgi.redirect-status-env +;cgi.redirect_status_env = + +; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's +; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok +; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting +; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting +; of zero causes PHP to behave as before. Default is 1. You should fix your scripts +; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. +; http://php.net/cgi.fix-pathinfo +;cgi.fix_pathinfo=1 + +; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside +; of the web tree and people will not be able to circumvent .htaccess security. +; http://php.net/cgi.dicard-path +;cgi.discard_path=1 + +; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate +; security tokens of the calling client. This allows IIS to define the +; security context that the request runs under. mod_fastcgi under Apache +; does not currently support this feature (03/17/2002) +; Set to 1 if running under IIS. Default is zero. +; http://php.net/fastcgi.impersonate +;fastcgi.impersonate = 1 + +; Disable logging through FastCGI connection. PHP's default behavior is to enable +; this feature. +;fastcgi.logging = 0 + +; cgi.rfc2616_headers configuration option tells PHP what type of headers to +; use when sending HTTP response code. If set to 0, PHP sends Status: header that +; is supported by Apache. When this option is set to 1, PHP will send +; RFC2616 compliant header. +; Default is zero. +; http://php.net/cgi.rfc2616-headers +;cgi.rfc2616_headers = 0 + +; cgi.check_shebang_line controls whether CGI PHP checks for line starting with #! +; (shebang) at the top of the running script. This line might be needed if the +; script support running both as stand-alone script and via PHP CGI<. PHP in CGI +; mode skips this line and ignores its content if this directive is turned on. +; http://php.net/cgi.check-shebang-line +;cgi.check_shebang_line=1 + +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; + +; Whether to allow HTTP file uploads. +; http://php.net/file-uploads +file_uploads = On + +; Temporary directory for HTTP uploaded files (will use system default if not +; specified). +; http://php.net/upload-tmp-dir +;upload_tmp_dir = + +; Maximum allowed size for uploaded files. +; http://php.net/upload-max-filesize +upload_max_filesize = 2M + +; Maximum number of files that can be uploaded via a single request +max_file_uploads = 20 + +;;;;;;;;;;;;;;;;;; +; Fopen wrappers ; +;;;;;;;;;;;;;;;;;; + +; Whether to allow the treatment of URLs (like http:// or ftp://) as files. +; http://php.net/allow-url-fopen +allow_url_fopen = On + +; Whether to allow include/require to open URLs (like http:// or ftp://) as files. +; http://php.net/allow-url-include +allow_url_include = Off + +; Define the anonymous ftp password (your email address). PHP's default setting +; for this is empty. +; http://php.net/from +;from="john@doe.com" + +; Define the User-Agent string. PHP's default setting for this is empty. +; http://php.net/user-agent +;user_agent="PHP" + +; Default timeout for socket based streams (seconds) +; http://php.net/default-socket-timeout +default_socket_timeout = 60 + +; If your scripts have to deal with files from Macintosh systems, +; or you are running on a Mac and need to deal with files from +; unix or win32 systems, setting this flag will cause PHP to +; automatically detect the EOL character in those files so that +; fgets() and file() will work regardless of the source of the file. +; http://php.net/auto-detect-line-endings +;auto_detect_line_endings = Off + +;;;;;;;;;;;;;;;;;;;;;; +; Dynamic Extensions ; +;;;;;;;;;;;;;;;;;;;;;; + +; If you wish to have an extension loaded automatically, use the following +; syntax: +; +; extension=modulename.extension +; +; For example, on Windows: +; +; extension=mysqli.dll +; +; ... or under UNIX: +; +; extension=mysqli.so +; +; ... or with a path: +; +; extension=/path/to/extension/mysqli.so +; +; If you only provide the name of the extension, PHP will look for it in its +; default extension directory. +; +; Windows Extensions +; Note that ODBC support is built in, so no dll is needed for it. +; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5+) +; extension folders as well as the separate PECL DLL download (PHP 5+). +; Be sure to appropriately set the extension_dir directive. +; +;extension=php_bz2.dll +;extension=php_curl.dll +;extension=php_fileinfo.dll +;extension=php_ftp.dll +;extension=php_gd2.dll +;extension=php_gettext.dll +;extension=php_gmp.dll +;extension=php_intl.dll +;extension=php_imap.dll +;extension=php_interbase.dll +;extension=php_ldap.dll +;extension=php_mbstring.dll +;extension=php_exif.dll ; Must be after mbstring as it depends on it +;extension=php_mysqli.dll +;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client +;extension=php_openssl.dll +;extension=php_pdo_firebird.dll +;extension=php_pdo_mysql.dll +;extension=php_pdo_oci.dll +;extension=php_pdo_odbc.dll +;extension=php_pdo_pgsql.dll +;extension=php_pdo_sqlite.dll +;extension=php_pgsql.dll +;extension=php_shmop.dll + +; The MIBS data available in the PHP distribution must be installed. +; See http://www.php.net/manual/en/snmp.installation.php +;extension=php_snmp.dll + +;extension=php_soap.dll +;extension=php_sockets.dll +;extension=php_sqlite3.dll +;extension=php_tidy.dll +;extension=php_xmlrpc.dll +;extension=php_xsl.dll + +;;;;;;;;;;;;;;;;;;; +; Module Settings ; +;;;;;;;;;;;;;;;;;;; + +[CLI Server] +; Whether the CLI web server uses ANSI color coding in its terminal output. +cli_server.color = On + +[Date] +; Defines the default timezone used by the date functions +; http://php.net/date.timezone +;date.timezone = + +; http://php.net/date.default-latitude +;date.default_latitude = 31.7667 + +; http://php.net/date.default-longitude +;date.default_longitude = 35.2333 + +; http://php.net/date.sunrise-zenith +;date.sunrise_zenith = 90.583333 + +; http://php.net/date.sunset-zenith +;date.sunset_zenith = 90.583333 + +[filter] +; http://php.net/filter.default +;filter.default = unsafe_raw + +; http://php.net/filter.default-flags +;filter.default_flags = + +[iconv] +; Use of this INI entry is deprecated, use global input_encoding instead. +; If empty, default_charset or input_encoding or iconv.input_encoding is used. +; The precedence is: default_charset < intput_encoding < iconv.input_encoding +;iconv.input_encoding = + +; Use of this INI entry is deprecated, use global internal_encoding instead. +; If empty, default_charset or internal_encoding or iconv.internal_encoding is used. +; The precedence is: default_charset < internal_encoding < iconv.internal_encoding +;iconv.internal_encoding = + +; Use of this INI entry is deprecated, use global output_encoding instead. +; If empty, default_charset or output_encoding or iconv.output_encoding is used. +; The precedence is: default_charset < output_encoding < iconv.output_encoding +; To use an output encoding conversion, iconv's output handler must be set +; otherwise output encoding conversion cannot be performed. +;iconv.output_encoding = + +[intl] +;intl.default_locale = +; This directive allows you to produce PHP errors when some error +; happens within intl functions. The value is the level of the error produced. +; Default is 0, which does not produce any errors. +;intl.error_level = E_WARNING +;intl.use_exceptions = 0 + +[sqlite3] +;sqlite3.extension_dir = + +[Pcre] +;PCRE library backtracking limit. +; http://php.net/pcre.backtrack-limit +;pcre.backtrack_limit=100000 + +;PCRE library recursion limit. +;Please note that if you set this value to a high number you may consume all +;the available process stack and eventually crash PHP (due to reaching the +;stack size limit imposed by the Operating System). +; http://php.net/pcre.recursion-limit +;pcre.recursion_limit=100000 + +;Enables or disables JIT compilation of patterns. This requires the PCRE +;library to be compiled with JIT support. +;pcre.jit=1 + +[Pdo] +; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off" +; http://php.net/pdo-odbc.connection-pooling +;pdo_odbc.connection_pooling=strict + +;pdo_odbc.db2_instance_name + +[Pdo_mysql] +; If mysqlnd is used: Number of cache slots for the internal result set cache +; http://php.net/pdo_mysql.cache_size +pdo_mysql.cache_size = 2000 + +; Default socket name for local MySQL connects. If empty, uses the built-in +; MySQL defaults. +; http://php.net/pdo_mysql.default-socket +pdo_mysql.default_socket= + +[Phar] +; http://php.net/phar.readonly +;phar.readonly = On + +; http://php.net/phar.require-hash +;phar.require_hash = On + +;phar.cache_list = + +[mail function] +; For Win32 only. +; http://php.net/smtp +SMTP = localhost +; http://php.net/smtp-port +smtp_port = 25 + +; For Win32 only. +; http://php.net/sendmail-from +;sendmail_from = me@example.com + +; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). +; http://php.net/sendmail-path +;sendmail_path = + +; Force the addition of the specified parameters to be passed as extra parameters +; to the sendmail binary. These parameters will always replace the value of +; the 5th parameter to mail(). +;mail.force_extra_parameters = + +; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename +mail.add_x_header = On + +; The path to a log file that will log all mail() calls. Log entries include +; the full path of the script, line number, To address and headers. +;mail.log = +; Log mail to syslog (Event Log on Windows). +;mail.log = syslog + +[ODBC] +; http://php.net/odbc.default-db +;odbc.default_db = Not yet implemented + +; http://php.net/odbc.default-user +;odbc.default_user = Not yet implemented + +; http://php.net/odbc.default-pw +;odbc.default_pw = Not yet implemented + +; Controls the ODBC cursor model. +; Default: SQL_CURSOR_STATIC (default). +;odbc.default_cursortype + +; Allow or prevent persistent links. +; http://php.net/odbc.allow-persistent +odbc.allow_persistent = On + +; Check that a connection is still valid before reuse. +; http://php.net/odbc.check-persistent +odbc.check_persistent = On + +; Maximum number of persistent links. -1 means no limit. +; http://php.net/odbc.max-persistent +odbc.max_persistent = -1 + +; Maximum number of links (persistent + non-persistent). -1 means no limit. +; http://php.net/odbc.max-links +odbc.max_links = -1 + +; Handling of LONG fields. Returns number of bytes to variables. 0 means +; passthru. +; http://php.net/odbc.defaultlrl +odbc.defaultlrl = 4096 + +; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char. +; See the documentation on odbc_binmode and odbc_longreadlen for an explanation +; of odbc.defaultlrl and odbc.defaultbinmode +; http://php.net/odbc.defaultbinmode +odbc.defaultbinmode = 1 + +;birdstep.max_links = -1 + +[Interbase] +; Allow or prevent persistent links. +ibase.allow_persistent = 1 + +; Maximum number of persistent links. -1 means no limit. +ibase.max_persistent = -1 + +; Maximum number of links (persistent + non-persistent). -1 means no limit. +ibase.max_links = -1 + +; Default database name for ibase_connect(). +;ibase.default_db = + +; Default username for ibase_connect(). +;ibase.default_user = + +; Default password for ibase_connect(). +;ibase.default_password = + +; Default charset for ibase_connect(). +;ibase.default_charset = + +; Default timestamp format. +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" + +; Default date format. +ibase.dateformat = "%Y-%m-%d" + +; Default time format. +ibase.timeformat = "%H:%M:%S" + +[MySQLi] + +; Maximum number of persistent links. -1 means no limit. +; http://php.net/mysqli.max-persistent +mysqli.max_persistent = -1 + +; Allow accessing, from PHP's perspective, local files with LOAD DATA statements +; http://php.net/mysqli.allow_local_infile +;mysqli.allow_local_infile = On + +; Allow or prevent persistent links. +; http://php.net/mysqli.allow-persistent +mysqli.allow_persistent = On + +; Maximum number of links. -1 means no limit. +; http://php.net/mysqli.max-links +mysqli.max_links = -1 + +; If mysqlnd is used: Number of cache slots for the internal result set cache +; http://php.net/mysqli.cache_size +mysqli.cache_size = 2000 + +; Default port number for mysqli_connect(). If unset, mysqli_connect() will use +; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the +; compile-time value defined MYSQL_PORT (in that order). Win32 will only look +; at MYSQL_PORT. +; http://php.net/mysqli.default-port +mysqli.default_port = 3306 + +; Default socket name for local MySQL connects. If empty, uses the built-in +; MySQL defaults. +; http://php.net/mysqli.default-socket +mysqli.default_socket = + +; Default host for mysql_connect() (doesn't apply in safe mode). +; http://php.net/mysqli.default-host +mysqli.default_host = + +; Default user for mysql_connect() (doesn't apply in safe mode). +; http://php.net/mysqli.default-user +mysqli.default_user = + +; Default password for mysqli_connect() (doesn't apply in safe mode). +; Note that this is generally a *bad* idea to store passwords in this file. +; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") +; and reveal this password! And of course, any users with read access to this +; file will be able to reveal the password as well. +; http://php.net/mysqli.default-pw +mysqli.default_pw = + +; Allow or prevent reconnect +mysqli.reconnect = Off + +[mysqlnd] +; Enable / Disable collection of general statistics by mysqlnd which can be +; used to tune and monitor MySQL operations. +; http://php.net/mysqlnd.collect_statistics +mysqlnd.collect_statistics = On + +; Enable / Disable collection of memory usage statistics by mysqlnd which can be +; used to tune and monitor MySQL operations. +; http://php.net/mysqlnd.collect_memory_statistics +mysqlnd.collect_memory_statistics = Off + +; Records communication from all extensions using mysqlnd to the specified log +; file. +; http://php.net/mysqlnd.debug +;mysqlnd.debug = + +; Defines which queries will be logged. +; http://php.net/mysqlnd.log_mask +;mysqlnd.log_mask = 0 + +; Default size of the mysqlnd memory pool, which is used by result sets. +; http://php.net/mysqlnd.mempool_default_size +;mysqlnd.mempool_default_size = 16000 + +; Size of a pre-allocated buffer used when sending commands to MySQL in bytes. +; http://php.net/mysqlnd.net_cmd_buffer_size +;mysqlnd.net_cmd_buffer_size = 2048 + +; Size of a pre-allocated buffer used for reading data sent by the server in +; bytes. +; http://php.net/mysqlnd.net_read_buffer_size +;mysqlnd.net_read_buffer_size = 32768 + +; Timeout for network requests in seconds. +; http://php.net/mysqlnd.net_read_timeout +;mysqlnd.net_read_timeout = 31536000 + +; SHA-256 Authentication Plugin related. File with the MySQL server public RSA +; key. +; http://php.net/mysqlnd.sha256_server_public_key +;mysqlnd.sha256_server_public_key = + +[OCI8] + +; Connection: Enables privileged connections using external +; credentials (OCI_SYSOPER, OCI_SYSDBA) +; http://php.net/oci8.privileged-connect +;oci8.privileged_connect = Off + +; Connection: The maximum number of persistent OCI8 connections per +; process. Using -1 means no limit. +; http://php.net/oci8.max-persistent +;oci8.max_persistent = -1 + +; Connection: The maximum number of seconds a process is allowed to +; maintain an idle persistent connection. Using -1 means idle +; persistent connections will be maintained forever. +; http://php.net/oci8.persistent-timeout +;oci8.persistent_timeout = -1 + +; Connection: The number of seconds that must pass before issuing a +; ping during oci_pconnect() to check the connection validity. When +; set to 0, each oci_pconnect() will cause a ping. Using -1 disables +; pings completely. +; http://php.net/oci8.ping-interval +;oci8.ping_interval = 60 + +; Connection: Set this to a user chosen connection class to be used +; for all pooled server requests with Oracle 11g Database Resident +; Connection Pooling (DRCP). To use DRCP, this value should be set to +; the same string for all web servers running the same application, +; the database pool must be configured, and the connection string must +; specify to use a pooled server. +;oci8.connection_class = + +; High Availability: Using On lets PHP receive Fast Application +; Notification (FAN) events generated when a database node fails. The +; database must also be configured to post FAN events. +;oci8.events = Off + +; Tuning: This option enables statement caching, and specifies how +; many statements to cache. Using 0 disables statement caching. +; http://php.net/oci8.statement-cache-size +;oci8.statement_cache_size = 20 + +; Tuning: Enables statement prefetching and sets the default number of +; rows that will be fetched automatically after statement execution. +; http://php.net/oci8.default-prefetch +;oci8.default_prefetch = 100 + +; Compatibility. Using On means oci_close() will not close +; oci_connect() and oci_new_connect() connections. +; http://php.net/oci8.old-oci-close-semantics +;oci8.old_oci_close_semantics = Off + +[PostgreSQL] +; Allow or prevent persistent links. +; http://php.net/pgsql.allow-persistent +pgsql.allow_persistent = On + +; Detect broken persistent links always with pg_pconnect(). +; Auto reset feature requires a little overheads. +; http://php.net/pgsql.auto-reset-persistent +pgsql.auto_reset_persistent = Off + +; Maximum number of persistent links. -1 means no limit. +; http://php.net/pgsql.max-persistent +pgsql.max_persistent = -1 + +; Maximum number of links (persistent+non persistent). -1 means no limit. +; http://php.net/pgsql.max-links +pgsql.max_links = -1 + +; Ignore PostgreSQL backends Notice message or not. +; Notice message logging require a little overheads. +; http://php.net/pgsql.ignore-notice +pgsql.ignore_notice = 0 + +; Log PostgreSQL backends Notice message or not. +; Unless pgsql.ignore_notice=0, module cannot log notice message. +; http://php.net/pgsql.log-notice +pgsql.log_notice = 0 + +[bcmath] +; Number of decimal digits for all bcmath functions. +; http://php.net/bcmath.scale +bcmath.scale = 0 + +[browscap] +; http://php.net/browscap +;browscap = extra/browscap.ini + +[Session] +; Handler used to store/retrieve data. +; http://php.net/session.save-handler +session.save_handler = files + +; Argument passed to save_handler. In the case of files, this is the path +; where data files are stored. Note: Windows users have to change this +; variable in order to use PHP's session functions. +; +; The path can be defined as: +; +; session.save_path = "N;/path" +; +; where N is an integer. Instead of storing all the session files in +; /path, what this will do is use subdirectories N-levels deep, and +; store the session data in those directories. This is useful if +; your OS has problems with many files in one directory, and is +; a more efficient layout for servers that handle many sessions. +; +; NOTE 1: PHP will not create this directory structure automatically. +; You can use the script in the ext/session dir for that purpose. +; NOTE 2: See the section on garbage collection below if you choose to +; use subdirectories for session storage +; +; The file storage module creates files using mode 600 by default. +; You can change that by using +; +; session.save_path = "N;MODE;/path" +; +; where MODE is the octal representation of the mode. Note that this +; does not overwrite the process's umask. +; http://php.net/session.save-path +session.save_path = "/tmp" + +; Whether to use strict session mode. +; Strict session mode does not accept uninitialized session ID and regenerate +; session ID if browser sends uninitialized session ID. Strict mode protects +; applications from session fixation via session adoption vulnerability. It is +; disabled by default for maximum compatibility, but enabling it is encouraged. +; https://wiki.php.net/rfc/strict_sessions +session.use_strict_mode = 0 + +; Whether to use cookies. +; http://php.net/session.use-cookies +session.use_cookies = 1 + +; http://php.net/session.cookie-secure +;session.cookie_secure = + +; This option forces PHP to fetch and use a cookie for storing and maintaining +; the session id. We encourage this operation as it's very helpful in combating +; session hijacking when not specifying and managing your own session id. It is +; not the be-all and end-all of session hijacking defense, but it's a good start. +; http://php.net/session.use-only-cookies +session.use_only_cookies = 1 + +; Name of the session (used as cookie name). +; http://php.net/session.name +session.name = PHPSESSID + +; Initialize session on request startup. +; http://php.net/session.auto-start +session.auto_start = 0 + +; Lifetime in seconds of cookie or, if 0, until browser is restarted. +; http://php.net/session.cookie-lifetime +session.cookie_lifetime = 0 + +; The path for which the cookie is valid. +; http://php.net/session.cookie-path +session.cookie_path = / + +; The domain for which the cookie is valid. +; http://php.net/session.cookie-domain +session.cookie_domain = + +; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. +; http://php.net/session.cookie-httponly +session.cookie_httponly = + +; Handler used to serialize data. php is the standard serializer of PHP. +; http://php.net/session.serialize-handler +session.serialize_handler = php + +; Defines the probability that the 'garbage collection' process is started +; on every session initialization. The probability is calculated by using +; gc_probability/gc_divisor. Where session.gc_probability is the numerator +; and gc_divisor is the denominator in the equation. Setting this value to 1 +; when the session.gc_divisor value is 100 will give you approximately a 1% chance +; the gc will run on any give request. +; Default Value: 1 +; Development Value: 1 +; Production Value: 1 +; http://php.net/session.gc-probability +session.gc_probability = 1 + +; Defines the probability that the 'garbage collection' process is started on every +; session initialization. The probability is calculated by using the following equation: +; gc_probability/gc_divisor. Where session.gc_probability is the numerator and +; session.gc_divisor is the denominator in the equation. Setting this value to 1 +; when the session.gc_divisor value is 100 will give you approximately a 1% chance +; the gc will run on any give request. Increasing this value to 1000 will give you +; a 0.1% chance the gc will run on any give request. For high volume production servers, +; this is a more efficient approach. +; Default Value: 100 +; Development Value: 1000 +; Production Value: 1000 +; http://php.net/session.gc-divisor +session.gc_divisor = 1000 + +; After this number of seconds, stored data will be seen as 'garbage' and +; cleaned up by the garbage collection process. +; http://php.net/session.gc-maxlifetime +session.gc_maxlifetime = 1440 + +; NOTE: If you are using the subdirectory option for storing session files +; (see session.save_path above), then garbage collection does *not* +; happen automatically. You will need to do your own garbage +; collection through a shell script, cron entry, or some other method. +; For example, the following script would is the equivalent of +; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): +; find /path/to/sessions -cmin +24 -type f | xargs rm + +; Check HTTP Referer to invalidate externally stored URLs containing ids. +; HTTP_REFERER has to contain this substring for the session to be +; considered as valid. +; http://php.net/session.referer-check +session.referer_check = + +; Set to {nocache,private,public,} to determine HTTP caching aspects +; or leave this empty to avoid sending anti-caching headers. +; http://php.net/session.cache-limiter +session.cache_limiter = nocache + +; Document expires after n minutes. +; http://php.net/session.cache-expire +session.cache_expire = 180 + +; trans sid support is disabled by default. +; Use of trans sid may risk your users' security. +; Use this option with caution. +; - User may send URL contains active session ID +; to other person via. email/irc/etc. +; - URL that contains active session ID may be stored +; in publicly accessible computer. +; - User may access your site with the same session ID +; always using URL stored in browser's history or bookmarks. +; http://php.net/session.use-trans-sid +session.use_trans_sid = 0 + +; Set session ID character length. This value could be between 22 to 256. +; Shorter length than default is supported only for compatibility reason. +; Users should use 32 or more chars. +; http://php.net/session.sid-length +; Default Value: 32 +; Development Value: 26 +; Production Value: 26 +session.sid_length = 26 + +; The URL rewriter will look for URLs in a defined set of HTML tags. +;

is special; if you include them here, the rewriter will +; add a hidden field with the info which is otherwise appended +; to URLs. tag's action attribute URL will not be modified +; unless it is specified. +; Note that all valid entries require a "=", even if no value follows. +; Default Value: "a=href,area=href,frame=src,form=" +; Development Value: "a=href,area=href,frame=src,form=" +; Production Value: "a=href,area=href,frame=src,form=" +; http://php.net/url-rewriter.tags +session.trans_sid_tags = "a=href,area=href,frame=src,form=" + +; URL rewriter does not rewrite absolute URLs by default. +; To enable rewrites for absolute pathes, target hosts must be specified +; at RUNTIME. i.e. use ini_set() +; tags is special. PHP will check action attribute's URL regardless +; of session.trans_sid_tags setting. +; If no host is defined, HTTP_HOST will be used for allowed host. +; Example value: php.net,www.php.net,wiki.php.net +; Use "," for multiple hosts. No spaces are allowed. +; Default Value: "" +; Development Value: "" +; Production Value: "" +;session.trans_sid_hosts="" + +; Define how many bits are stored in each character when converting +; the binary hash data to something readable. +; Possible values: +; 4 (4 bits: 0-9, a-f) +; 5 (5 bits: 0-9, a-v) +; 6 (6 bits: 0-9, a-z, A-Z, "-", ",") +; Default Value: 4 +; Development Value: 5 +; Production Value: 5 +; http://php.net/session.hash-bits-per-character +session.sid_bits_per_character = 5 + +; Enable upload progress tracking in $_SESSION +; Default Value: On +; Development Value: On +; Production Value: On +; http://php.net/session.upload-progress.enabled +;session.upload_progress.enabled = On + +; Cleanup the progress information as soon as all POST data has been read +; (i.e. upload completed). +; Default Value: On +; Development Value: On +; Production Value: On +; http://php.net/session.upload-progress.cleanup +;session.upload_progress.cleanup = On + +; A prefix used for the upload progress key in $_SESSION +; Default Value: "upload_progress_" +; Development Value: "upload_progress_" +; Production Value: "upload_progress_" +; http://php.net/session.upload-progress.prefix +;session.upload_progress.prefix = "upload_progress_" + +; The index name (concatenated with the prefix) in $_SESSION +; containing the upload progress information +; Default Value: "PHP_SESSION_UPLOAD_PROGRESS" +; Development Value: "PHP_SESSION_UPLOAD_PROGRESS" +; Production Value: "PHP_SESSION_UPLOAD_PROGRESS" +; http://php.net/session.upload-progress.name +;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" + +; How frequently the upload progress should be updated. +; Given either in percentages (per-file), or in bytes +; Default Value: "1%" +; Development Value: "1%" +; Production Value: "1%" +; http://php.net/session.upload-progress.freq +;session.upload_progress.freq = "1%" + +; The minimum delay between updates, in seconds +; Default Value: 1 +; Development Value: 1 +; Production Value: 1 +; http://php.net/session.upload-progress.min-freq +;session.upload_progress.min_freq = "1" + +; Only write session data when session data is changed. Enabled by default. +; http://php.net/session.lazy-write +;session.lazy_write = On + +[Assertion] +; Switch whether to compile assertions at all (to have no overhead at run-time) +; -1: Do not compile at all +; 0: Jump over assertion at run-time +; 1: Execute assertions +; Changing from or to a negative value is only possible in php.ini! (For turning assertions on and off at run-time, see assert.active, when zend.assertions = 1) +; Default Value: 1 +; Development Value: 1 +; Production Value: -1 +; http://php.net/zend.assertions +zend.assertions = -1 + +; Assert(expr); active by default. +; http://php.net/assert.active +;assert.active = On + +; Throw an AssertationException on failed assertions +; http://php.net/assert.exception +;assert.exception = On + +; Issue a PHP warning for each failed assertion. (Overridden by assert.exception if active) +; http://php.net/assert.warning +;assert.warning = On + +; Don't bail out by default. +; http://php.net/assert.bail +;assert.bail = Off + +; User-function to be called if an assertion fails. +; http://php.net/assert.callback +;assert.callback = 0 + +; Eval the expression with current error_reporting(). Set to true if you want +; error_reporting(0) around the eval(). +; http://php.net/assert.quiet-eval +;assert.quiet_eval = 0 + +[COM] +; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs +; http://php.net/com.typelib-file +;com.typelib_file = + +; allow Distributed-COM calls +; http://php.net/com.allow-dcom +;com.allow_dcom = true + +; autoregister constants of a components typlib on com_load() +; http://php.net/com.autoregister-typelib +;com.autoregister_typelib = true + +; register constants casesensitive +; http://php.net/com.autoregister-casesensitive +;com.autoregister_casesensitive = false + +; show warnings on duplicate constant registrations +; http://php.net/com.autoregister-verbose +;com.autoregister_verbose = true + +; The default character set code-page to use when passing strings to and from COM objects. +; Default: system ANSI code page +;com.code_page= + +[mbstring] +; language for internal character representation. +; This affects mb_send_mail() and mbstring.detect_order. +; http://php.net/mbstring.language +;mbstring.language = Japanese + +; Use of this INI entry is deprecated, use global internal_encoding instead. +; internal/script encoding. +; Some encoding cannot work as internal encoding. (e.g. SJIS, BIG5, ISO-2022-*) +; If empty, default_charset or internal_encoding or iconv.internal_encoding is used. +; The precedence is: default_charset < internal_encoding < iconv.internal_encoding +;mbstring.internal_encoding = + +; Use of this INI entry is deprecated, use global input_encoding instead. +; http input encoding. +; mbstring.encoding_traslation = On is needed to use this setting. +; If empty, default_charset or input_encoding or mbstring.input is used. +; The precedence is: default_charset < intput_encoding < mbsting.http_input +; http://php.net/mbstring.http-input +;mbstring.http_input = + +; Use of this INI entry is deprecated, use global output_encoding instead. +; http output encoding. +; mb_output_handler must be registered as output buffer to function. +; If empty, default_charset or output_encoding or mbstring.http_output is used. +; The precedence is: default_charset < output_encoding < mbstring.http_output +; To use an output encoding conversion, mbstring's output handler must be set +; otherwise output encoding conversion cannot be performed. +; http://php.net/mbstring.http-output +;mbstring.http_output = + +; enable automatic encoding translation according to +; mbstring.internal_encoding setting. Input chars are +; converted to internal encoding by setting this to On. +; Note: Do _not_ use automatic encoding translation for +; portable libs/applications. +; http://php.net/mbstring.encoding-translation +;mbstring.encoding_translation = Off + +; automatic encoding detection order. +; "auto" detect order is changed according to mbstring.language +; http://php.net/mbstring.detect-order +;mbstring.detect_order = auto + +; substitute_character used when character cannot be converted +; one from another +; http://php.net/mbstring.substitute-character +;mbstring.substitute_character = none + +; overload(replace) single byte functions by mbstring functions. +; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), +; etc. Possible values are 0,1,2,4 or combination of them. +; For example, 7 for overload everything. +; 0: No overload +; 1: Overload mail() function +; 2: Overload str*() functions +; 4: Overload ereg*() functions +; http://php.net/mbstring.func-overload +;mbstring.func_overload = 0 + +; enable strict encoding detection. +; Default: Off +;mbstring.strict_detection = On + +; This directive specifies the regex pattern of content types for which mb_output_handler() +; is activated. +; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml) +;mbstring.http_output_conv_mimetype= + +[gd] +; Tell the jpeg decode to ignore warnings and try to create +; a gd image. The warning will then be displayed as notices +; disabled by default +; http://php.net/gd.jpeg-ignore-warning +;gd.jpeg_ignore_warning = 1 + +[exif] +; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS. +; With mbstring support this will automatically be converted into the encoding +; given by corresponding encode setting. When empty mbstring.internal_encoding +; is used. For the decode settings you can distinguish between motorola and +; intel byte order. A decode setting cannot be empty. +; http://php.net/exif.encode-unicode +;exif.encode_unicode = ISO-8859-15 + +; http://php.net/exif.decode-unicode-motorola +;exif.decode_unicode_motorola = UCS-2BE + +; http://php.net/exif.decode-unicode-intel +;exif.decode_unicode_intel = UCS-2LE + +; http://php.net/exif.encode-jis +;exif.encode_jis = + +; http://php.net/exif.decode-jis-motorola +;exif.decode_jis_motorola = JIS + +; http://php.net/exif.decode-jis-intel +;exif.decode_jis_intel = JIS + +[Tidy] +; The path to a default tidy configuration file to use when using tidy +; http://php.net/tidy.default-config +;tidy.default_config = /usr/local/lib/php/default.tcfg + +; Should tidy clean and repair output automatically? +; WARNING: Do not use this option if you are generating non-html content +; such as dynamic images +; http://php.net/tidy.clean-output +tidy.clean_output = Off + +[soap] +; Enables or disables WSDL caching feature. +; http://php.net/soap.wsdl-cache-enabled +soap.wsdl_cache_enabled=1 + +; Sets the directory name where SOAP extension will put cache files. +; http://php.net/soap.wsdl-cache-dir +soap.wsdl_cache_dir="/tmp" + +; (time to live) Sets the number of second while cached file will be used +; instead of original one. +; http://php.net/soap.wsdl-cache-ttl +soap.wsdl_cache_ttl=86400 + +; Sets the size of the cache limit. (Max. number of WSDL files to cache) +soap.wsdl_cache_limit = 5 + +[sysvshm] +; A default size of the shared memory segment +;sysvshm.init_mem = 10000 + +[ldap] +; Sets the maximum number of open links or -1 for unlimited. +ldap.max_links = -1 + +[dba] +;dba.default_handler= + +[opcache] +; Determines if Zend OPCache is enabled +;opcache.enable=1 + +; Determines if Zend OPCache is enabled for the CLI version of PHP +;opcache.enable_cli=1 + +; The OPcache shared memory storage size. +;opcache.memory_consumption=128 + +; The amount of memory for interned strings in Mbytes. +;opcache.interned_strings_buffer=8 + +; The maximum number of keys (scripts) in the OPcache hash table. +; Only numbers between 200 and 1000000 are allowed. +;opcache.max_accelerated_files=10000 + +; The maximum percentage of "wasted" memory until a restart is scheduled. +;opcache.max_wasted_percentage=5 + +; When this directive is enabled, the OPcache appends the current working +; directory to the script key, thus eliminating possible collisions between +; files with the same name (basename). Disabling the directive improves +; performance, but may break existing applications. +;opcache.use_cwd=1 + +; When disabled, you must reset the OPcache manually or restart the +; webserver for changes to the filesystem to take effect. +;opcache.validate_timestamps=1 + +; How often (in seconds) to check file timestamps for changes to the shared +; memory storage allocation. ("1" means validate once per second, but only +; once per request. "0" means always validate) +;opcache.revalidate_freq=2 + +; Enables or disables file search in include_path optimization +;opcache.revalidate_path=0 + +; If disabled, all PHPDoc comments are dropped from the code to reduce the +; size of the optimized code. +;opcache.save_comments=1 + +; If enabled, a fast shutdown sequence is used for the accelerated code +; Depending on the used Memory Manager this may cause some incompatibilities. +;opcache.fast_shutdown=0 + +; Allow file existence override (file_exists, etc.) performance feature. +;opcache.enable_file_override=0 + +; A bitmask, where each bit enables or disables the appropriate OPcache +; passes +;opcache.optimization_level=0xffffffff + +;opcache.inherited_hack=1 +;opcache.dups_fix=0 + +; The location of the OPcache blacklist file (wildcards allowed). +; Each OPcache blacklist file is a text file that holds the names of files +; that should not be accelerated. The file format is to add each filename +; to a new line. The filename may be a full path or just a file prefix +; (i.e., /var/www/x blacklists all the files and directories in /var/www +; that start with 'x'). Line starting with a ; are ignored (comments). +;opcache.blacklist_filename= + +; Allows exclusion of large files from being cached. By default all files +; are cached. +;opcache.max_file_size=0 + +; Check the cache checksum each N requests. +; The default value of "0" means that the checks are disabled. +;opcache.consistency_checks=0 + +; How long to wait (in seconds) for a scheduled restart to begin if the cache +; is not being accessed. +;opcache.force_restart_timeout=180 + +; OPcache error_log file name. Empty string assumes "stderr". +;opcache.error_log= + +; All OPcache errors go to the Web server log. +; By default, only fatal errors (level 0) or errors (level 1) are logged. +; You can also enable warnings (level 2), info messages (level 3) or +; debug messages (level 4). +;opcache.log_verbosity_level=1 + +; Preferred Shared Memory back-end. Leave empty and let the system decide. +;opcache.preferred_memory_model= + +; Protect the shared memory from unexpected writing during script execution. +; Useful for internal debugging only. +;opcache.protect_memory=0 + +; Allows calling OPcache API functions only from PHP scripts which path is +; started from specified string. The default "" means no restriction +;opcache.restrict_api= + +; Mapping base of shared memory segments (for Windows only). All the PHP +; processes have to map shared memory into the same address space. This +; directive allows to manually fix the "Unable to reattach to base address" +; errors. +;opcache.mmap_base= + +; Enables and sets the second level cache directory. +; It should improve performance when SHM memory is full, at server restart or +; SHM reset. The default "" disables file based caching. +;opcache.file_cache= + +; Enables or disables opcode caching in shared memory. +;opcache.file_cache_only=0 + +; Enables or disables checksum validation when script loaded from file cache. +;opcache.file_cache_consistency_checks=1 + +; Implies opcache.file_cache_only=1 for a certain process that failed to +; reattach to the shared memory (for Windows only). Explicitly enabled file +; cache is required. +;opcache.file_cache_fallback=1 + +; Enables or disables copying of PHP code (text segment) into HUGE PAGES. +; This should improve performance, but requires appropriate OS configuration. +;opcache.huge_code_pages=1 + +; Validate cached file permissions. +;opcache.validate_permission=0 + +; Prevent name collisions in chroot'ed environment. +;opcache.validate_root=0 + +[curl] +; A default value for the CURLOPT_CAINFO option. This is required to be an +; absolute path. +;curl.cainfo = + +[openssl] +; The location of a Certificate Authority (CA) file on the local filesystem +; to use when verifying the identity of SSL/TLS peers. Most users should +; not specify a value for this directive as PHP will attempt to use the +; OS-managed cert stores in its absence. If specified, this value may still +; be overridden on a per-stream basis via the "cafile" SSL stream context +; option. +;openssl.cafile= + +; If openssl.cafile is not specified or if the CA file is not found, the +; directory pointed to by openssl.capath is searched for a suitable +; certificate. This value must be a correctly hashed certificate directory. +; Most users should not specify a value for this directive as PHP will +; attempt to use the OS-managed cert stores in its absence. If specified, +; this value may still be overridden on a per-stream basis via the "capath" +; SSL stream context option. +;openssl.capath= + +; Local Variables: +; tab-width: 4 +; End: diff --git a/travis-build.sh b/travis-build.sh index 2270683..18f0910 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -20,6 +20,16 @@ if [ -n "${PHP_VERSION}" ]; then # https://github.com/aerospike/aerospike-client-php5/issues/145 sed -i -- 's/PHP_FPM_INSTALL_AEROSPIKE=true/PHP_FPM_INSTALL_AEROSPIKE=false/g' .env fi + if [ "${PHP_VERSION}" == "7.3" ]; then + # V8JS extension does not yet support PHP 7.3. + sed -i -- 's/WORKSPACE_INSTALL_V8JS=true/WORKSPACE_INSTALL_V8JS=false/g' .env + # This ssh2 extension does not yet support PHP 7.3. + sed -i -- 's/PHP_FPM_INSTALL_SSH2=true/PHP_FPM_INSTALL_SSH2=false/g' .env + # xdebug extension does not yet support PHP 7.3. + sed -i -- 's/PHP_FPM_INSTALL_XDEBUG=true/PHP_FPM_INSTALL_XDEBUG=false/g' .env + # memcached extension does not yet support PHP 7.3. + sed -i -- 's/PHP_FPM_INSTALL_MEMCACHED=true/PHP_FPM_INSTALL_MEMCACHED=false/g' .env + fi cat .env docker-compose build ${BUILD_SERVICE} docker images From e105ec95692e3efc5287938f37304db45a979f99 Mon Sep 17 00:00:00 2001 From: Jasper Frumau Date: Sat, 2 Mar 2019 11:50:52 +0700 Subject: [PATCH 115/589] Update index.md (#1531) Docker-compose is installed on a Digital Ocean Docker Image already --- DOCUMENTATION/content/guides/index.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index 03f0b96..ec7f903 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -50,12 +50,6 @@ $root@server:~/laravel/ git submodule add https://github.com/Laradock/laradock.g $root@server:~/laravel/ cd laradock ``` -## Install docker-compose command - -``` -$root@server:~/laravel/laradock# curl -L https://github.com/docker/compose/releases/download/1.8.0/run.sh > /usr/local/bin/docker-compose -$root@server:~/chmod +x /usr/local/bin/docker-compose -``` ## Enter the laradock folder and rename env-example to .env. ``` $root@server:~/laravel/laradock# cp env-example .env From 329462a637af77f466c2fd041c3d9a80d4ddd30c Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Sun, 3 Mar 2019 20:57:07 +0800 Subject: [PATCH 116/589] update base image (#2034) --- php-fpm/Dockerfile | 2 +- workspace/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 4cabe57..af3428f 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -15,7 +15,7 @@ ARG LARADOCK_PHP_VERSION # FROM laradock/php-fpm:2.2-${LARADOCK_PHP_VERSION} -FROM letsdockerize/laradock-php-fpm:2.3-${LARADOCK_PHP_VERSION} +FROM letsdockerize/laradock-php-fpm:2.4-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 17a4886..ff529c4 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -15,7 +15,7 @@ ARG LARADOCK_PHP_VERSION # FROM laradock/workspace:2.2-${LARADOCK_PHP_VERSION} -FROM letsdockerize/laradock-workspace:2.3-${LARADOCK_PHP_VERSION} +FROM letsdockerize/laradock-workspace:2.4-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " From 6c8adbc19570f17b2a799d1a20ba81d7daead468 Mon Sep 17 00:00:00 2001 From: mintalicious Date: Tue, 5 Mar 2019 04:08:40 +0100 Subject: [PATCH 117/589] Add ghostscript to php worker (#2035) * Update docker-compose.yml * Update Dockerfile * Update env-example --- docker-compose.yml | 1 + env-example | 1 + php-worker/Dockerfile | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index e7aff2a..91e088f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -198,6 +198,7 @@ services: - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} + - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: diff --git a/env-example b/env-example index 228bc81..7054334 100644 --- a/env-example +++ b/env-example @@ -185,6 +185,7 @@ PHP_WORKER_INSTALL_SOAP=false PHP_WORKER_INSTALL_ZIP_ARCHIVE=false PHP_WORKER_INSTALL_MYSQL_CLIENT=false PHP_WORKER_INSTALL_AMQP=false +PHP_WORKER_INSTALL_GHOSTSCRIPT=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 25bcf83..b268b7a 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -93,6 +93,10 @@ RUN if [ $INSTALL_PHALCON = true ]; then \ && rm -rf /tmp/cphalcon* \ ;fi +RUN if [ $INSTALL_GHOSTSCRIPT = true ]; then \ + apk --update add ghostscript \ +;fi + RUN rm /var/cache/apk/* \ && mkdir -p /var/www From 8ca26e6c06c5841c8ca2c328ea5a0220209a3d71 Mon Sep 17 00:00:00 2001 From: Adrian Nuta Date: Wed, 6 Mar 2019 14:50:00 +0200 Subject: [PATCH 118/589] Add Manticore Search (#2036) * Add Manticore Search --- .travis.yml | 2 +- docker-compose.yml | 15 +++++++++++++++ env-example | 7 +++++++ manticore/Dockerfile | 5 +++++ manticore/config/sphinx.conf | 25 +++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 manticore/Dockerfile create mode 100644 manticore/config/sphinx.conf diff --git a/.travis.yml b/.travis.yml index f93c859..d473177 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: - PHP_VERSION=NA BUILD_SERVICE="adminer phpmyadmin pgadmin" - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy" - PHP_VERSION=NA BUILD_SERVICE="kibana grafana laravel-echo-server" - - PHP_VERSION=NA BUILD_SERVICE="ipython-controller" + - PHP_VERSION=NA BUILD_SERVICE="ipython-controller manticore" # - PHP_VERSION=NA BUILD_SERVICE="aws" # Installing a newer Docker version diff --git a/docker-compose.yml b/docker-compose.yml index 91e088f..8077019 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1400,3 +1400,18 @@ services: - "${COUCHDB_PORT}:5984" networks: - backend + +### Manticore Search ########################################### + manticore: + build: + context: ./manticore + volumes: + - ${MANTICORE_CONFIG_PATH}:/etc/sphinxsearch + - ${DATA_PATH_HOST}/manticore/data:/var/lib/manticore/data + - ${DATA_PATH_HOST}/manticore/log:/var/lib/manticore/log + ports: + - "${MANTICORE_API_PORT}:9312" + - "${MANTICORE_SPHINXQL_PORT}:9306" + - "${MANTICORE_HTTP_PORT}:9308" + networks: + - backend diff --git a/env-example b/env-example index 7054334..c836386 100644 --- a/env-example +++ b/env-example @@ -658,3 +658,10 @@ MOSQUITTO_PORT=9001 ### COUCHDB ################################################### COUCHDB_PORT=5984 + +### Manticore Search ########################################## + +MANTICORE_CONFIG_PATH=./manticore/config +MANTICORE_API_PORT=9312 +MANTICORE_SPHINXQL_PORT=9306 +MANTICORE_HTTP_PORT=9308 diff --git a/manticore/Dockerfile b/manticore/Dockerfile new file mode 100644 index 0000000..2b78830 --- /dev/null +++ b/manticore/Dockerfile @@ -0,0 +1,5 @@ +FROM manticoresearch/manticore + +EXPOSE 9306 +EXPOSE 9308 +EXPOSE 9312 diff --git a/manticore/config/sphinx.conf b/manticore/config/sphinx.conf new file mode 100644 index 0000000..0a992b9 --- /dev/null +++ b/manticore/config/sphinx.conf @@ -0,0 +1,25 @@ +index testrt { + type = rt + rt_mem_limit = 128M + path = /var/lib/manticore/data/testrt + rt_field = title + rt_field = content + rt_attr_uint = gid +} + +searchd { + listen = 9312 + listen = 9308:http + listen = 9306:mysql41 + log = /var/lib/manticore/log/searchd.log + # you can also send query_log to /dev/stdout to be shown in docker logs + query_log = /var/lib/manticore/log/query.log + read_timeout = 5 + max_children = 30 + pid_file = /var/run/searchd.pid + seamless_rotate = 1 + preopen_indexes = 1 + unlink_old = 1 + binlog_path = /var/lib/manticore/data +} + From 254a9ae19490b53fc8f0647d81b7581c312f0724 Mon Sep 17 00:00:00 2001 From: Yu Li Date: Fri, 15 Mar 2019 10:17:55 +0800 Subject: [PATCH 119/589] php-woker add swoole (#2045) --- docker-compose.yml | 1 + env-example | 1 + php-worker/Dockerfile | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 8077019..aeb6d16 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -199,6 +199,7 @@ services: - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} + - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: diff --git a/env-example b/env-example index c836386..674547d 100644 --- a/env-example +++ b/env-example @@ -186,6 +186,7 @@ PHP_WORKER_INSTALL_ZIP_ARCHIVE=false PHP_WORKER_INSTALL_MYSQL_CLIENT=false PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_INSTALL_GHOSTSCRIPT=false +PHP_WORKER_INSTALL_SWOOLE=true PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index b268b7a..fe9f53b 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -100,6 +100,28 @@ RUN if [ $INSTALL_GHOSTSCRIPT = true ]; then \ RUN rm /var/cache/apk/* \ && mkdir -p /var/www + +########################################################################### +# Swoole EXTENSION +########################################################################### + +ARG INSTALL_SWOOLE=false + +RUN if [ ${INSTALL_SWOOLE} = true ]; then \ + # Install Php Swoole Extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl -q install swoole-2.0.10; \ + else \ + if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \ + pecl install swoole-2.2.0; \ + else \ + pecl install swoole; \ + fi \ + fi \ + && docker-php-ext-enable swoole \ +;fi + + # #-------------------------------------------------------------------------- # Optional Supervisord Configuration From 6f4664c5796201f02270a278b93a4db90f807a7a Mon Sep 17 00:00:00 2001 From: Robert Fridzema Date: Wed, 20 Mar 2019 14:49:40 +0100 Subject: [PATCH 120/589] Consistency fix (#2053) Self explaining --- php-fpm/opcache.ini | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/php-fpm/opcache.ini b/php-fpm/opcache.ini index 9a3f646..bf3d08e 100644 --- a/php-fpm/opcache.ini +++ b/php-fpm/opcache.ini @@ -1,9 +1,9 @@ ; NOTE: The actual opcache.so extention is NOT SET HERE but rather (/usr/local/etc/php/conf.d/docker-php-ext-opcache.ini) -opcache.enable="1" -opcache.memory_consumption="256" -opcache.use_cwd="0" -opcache.max_file_size="0" -opcache.max_accelerated_files = 30000 -opcache.validate_timestamps="1" -opcache.revalidate_freq="0" +opcache.enable=1 +opcache.memory_consumption=256 +opcache.use_cwd=0 +opcache.max_file_size=0 +opcache.max_accelerated_files=30000 +opcache.validate_timestamps=1 +opcache.revalidate_freq=0 From 9920397463b4d8acb73e63aeed884dbe6959da70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E5=8B=87?= <412039588@qq.com> Date: Wed, 20 Mar 2019 08:51:29 -0500 Subject: [PATCH 121/589] =?UTF-8?q?add=20`force`=20option=20when=20start?= =?UTF-8?q?=20laravel-echo-server,=20update=20laravel-ech=E2=80=A6=20(#205?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add `force` option when start laravel-echo-server, update laravel-echo-server version' * move --force ottion to dockerfile --- laravel-echo-server/Dockerfile | 2 +- laravel-echo-server/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/laravel-echo-server/Dockerfile b/laravel-echo-server/Dockerfile index 6a338f4..da6b256 100644 --- a/laravel-echo-server/Dockerfile +++ b/laravel-echo-server/Dockerfile @@ -19,4 +19,4 @@ RUN npm install COPY laravel-echo-server.json /usr/src/app/laravel-echo-server.json EXPOSE 3000 -CMD [ "npm", "start" ] +CMD [ "npm", "start", "--force" ] diff --git a/laravel-echo-server/package.json b/laravel-echo-server/package.json index 2784a03..4e8d6c1 100644 --- a/laravel-echo-server/package.json +++ b/laravel-echo-server/package.json @@ -4,9 +4,9 @@ "version": "0.0.1", "license": "MIT", "dependencies": { - "laravel-echo-server": "^1.2.8" + "laravel-echo-server": "^1.5.0" }, "scripts": { "start": "laravel-echo-server start" } -} \ No newline at end of file +} From d1f3bc8e5c3b2a5644752a86d20d7ac09480ef30 Mon Sep 17 00:00:00 2001 From: andreypaa Date: Thu, 21 Mar 2019 18:19:32 +0300 Subject: [PATCH 122/589] Pgadmin newest version 4.x (#2054) * new last version pgadmin --- docker-compose.yml | 10 +++++++--- env-example | 6 ++++++ pgadmin/Dockerfile | 10 ---------- 3 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 pgadmin/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index aeb6d16..0d18592 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -595,11 +595,15 @@ services: ### pgAdmin ############################################## pgadmin: - build: ./pgadmin + container_name: pgadmin + image: dpage/pgadmin4:latest + environment: + - "PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}" + - "PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}" ports: - - "5050:5050" + - "${PGADMIN_PORT}:80" volumes: - - ${DATA_PATH_HOST}/pgadmin-backup:/var/lib/pgadmin/storage/pgadmin4 + - ${DATA_PATH_HOST}/pgadmin:/var/lib/pgadmin depends_on: - postgres networks: diff --git a/env-example b/env-example index 674547d..704f0b7 100644 --- a/env-example +++ b/env-example @@ -666,3 +666,9 @@ MANTICORE_CONFIG_PATH=./manticore/config MANTICORE_API_PORT=9312 MANTICORE_SPHINXQL_PORT=9306 MANTICORE_HTTP_PORT=9308 + +### pgadmin ################################################## +# use this address http://ip6-localhost:5050 +PGADMIN_PORT=5050 +PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org +PGADMIN_DEFAULT_PASSWORD=admin diff --git a/pgadmin/Dockerfile b/pgadmin/Dockerfile deleted file mode 100644 index f0ec44b..0000000 --- a/pgadmin/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM fenglc/pgadmin4:alpine - -LABEL maintainer="Huadong Zuo " - -# user: pgadmin4@pgadmin.org -# password: admin -# pg_dump & postgresql all in "/usr/bin" -# backup in "/var/lib/pgadmin/storage/pgadmin4" - -EXPOSE 5050 From b1cbd48221723a8e13b1b08f753b5cadc3456f77 Mon Sep 17 00:00:00 2001 From: Robert Fridzema Date: Fri, 22 Mar 2019 02:19:53 +0100 Subject: [PATCH 123/589] Fix url (#2051) --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 2de4462..2c71178 100644 --- a/.github/README.md +++ b/.github/README.md @@ -16,7 +16,7 @@

Use Docker First And Learn About It Later

- forthebadge + forthebadge

From c8b526be13051fef5a8ebb1c19f26c020d092e0e Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Fri, 22 Mar 2019 09:24:58 +0800 Subject: [PATCH 124/589] Fix URL (#2055) * Fix URL --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 2c71178..834b878 100644 --- a/.github/README.md +++ b/.github/README.md @@ -16,7 +16,7 @@

Use Docker First And Learn About It Later

- forthebadge + forthebadge

From 1f22e86d927a86e262ad9352de2ce170a5bb3afd Mon Sep 17 00:00:00 2001 From: Yu Li Date: Tue, 26 Mar 2019 19:00:58 +0800 Subject: [PATCH 125/589] workspace add inotify and fswatch (#2059) --- env-example | 2 ++ workspace/Dockerfile | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/env-example b/env-example index 704f0b7..3b565f8 100644 --- a/env-example +++ b/env-example @@ -131,6 +131,8 @@ WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_INSTALL_MYSQL_CLIENT=false +WORKSPACE_INSTALL_INOTIFY=false +WORKSPACE_INSTALL_FSWATCH=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 diff --git a/workspace/Dockerfile b/workspace/Dockerfile index ff529c4..f50f362 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -446,6 +446,31 @@ RUN if [ ${INSTALL_LIBPNG} = true ]; then \ apt-get install libpng16-16 \ ;fi +########################################################################### +# Inotify EXTENSION: +########################################################################### + +ARG INSTALL_INOTIFY=false + +RUN if [ ${INSTALL_INOTIFY} = true ]; then \ + pecl -q install inotify && \ + echo "extension=inotify.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/inotify.ini && \ + ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/inotify.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-inotify.ini \ +;fi + +########################################################################### +# fswatch +########################################################################### + +ARG INSTALL_FSWATCH=false + +RUN if [ ${INSTALL_FSWATCH} = true ]; then \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 47FE03C1 \ + && add-apt-repository -y ppa:hadret/fswatch \ + || apt-get update -yqq \ + && apt-get -y install fswatch \ +;fi + ########################################################################### # IonCube Loader ########################################################################### From 58d7d4fa0bfc6bf8980d1553a72c78aa8c097897 Mon Sep 17 00:00:00 2001 From: ahkui <14049597+ahkui@users.noreply.github.com> Date: Thu, 28 Mar 2019 09:54:51 +0800 Subject: [PATCH 126/589] add powerline to workspace (#2062) --- DOCUMENTATION/content/documentation/index.md | 21 +++++++++++++++++--- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 17 ++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 1fa6ff6..9fe1b7f 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -631,12 +631,12 @@ docker-compose up -d metabase 1) Boot the container `docker-compose up -d jenkins`. To enter the container type `docker-compose exec jenkins bash`. -2) Go to `http://localhost:8090/` (if you didn't chanhed your default port mapping) +2) Go to `http://localhost:8090/` (if you didn't chanhed your default port mapping) 3) Authenticate from the web app. - Default username is `admin`. -- Default password is `docker-compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword`. +- Default password is `docker-compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword`. (To enter container as root type `docker-compose exec --user root jenkins bash`). @@ -1289,6 +1289,21 @@ To install CodeIgniter 3 on Laradock all you have to do is the following simple +
+ +## Install Powerline + +1 - Open the `.env` file and set `WORKSPACE_INSTALL_POWERLINE` and `WORKSPACE_INSTALL_PYTHON` to `true`. + +2 - Run `docker-compose build workspace`, after the step above. + +Powerline is required python + + + + + +
## Install Symfony @@ -2104,7 +2119,7 @@ This error sometimes happens because your Laravel application isn't running on t ## I get stuck when building nginx on `fetch http://mirrors.aliyun.com/alpine/v3.5/main/x86_64/APKINDEX.tar.gz` -As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-419652646), Already fixed,just set `CHANGE_SOURCE` to false. +As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-419652646), Already fixed,just set `CHANGE_SOURCE` to false. ## Custom composer repo packagist url and npm registry url diff --git a/docker-compose.yml b/docker-compose.yml index 0d18592..a924b49 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -108,6 +108,7 @@ services: - TZ=${WORKSPACE_TIMEZONE} - BLACKFIRE_CLIENT_ID=${BLACKFIRE_CLIENT_ID} - BLACKFIRE_CLIENT_TOKEN=${BLACKFIRE_CLIENT_TOKEN} + - INSTALL_POWERLINE=${WORKSPACE_INSTALL_POWERLINE} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} extra_hosts: diff --git a/env-example b/env-example index 3b565f8..928d2fe 100644 --- a/env-example +++ b/env-example @@ -121,6 +121,7 @@ WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false WORKSPACE_INSTALL_SYMFONY=false WORKSPACE_INSTALL_PYTHON=false +WORKSPACE_INSTALL_POWERLINE=false WORKSPACE_INSTALL_IMAGE_OPTIMIZERS=false WORKSPACE_INSTALL_IMAGEMAGICK=false WORKSPACE_INSTALL_TERRAFORM=false diff --git a/workspace/Dockerfile b/workspace/Dockerfile index f50f362..8f8e23f 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -871,6 +871,23 @@ RUN if [ ${INSTALL_PYTHON} = true ]; then \ && python -m pip install --upgrade virtualenv \ ;fi +########################################################################### +# POWERLINE: +########################################################################### + +USER root +ARG INSTALL_POWERLINE=false + +RUN if [ ${INSTALL_POWERLINE} = true ]; then \ + if [ ${INSTALL_PYTHON} = true ]; then \ + python -m pip install --upgrade powerline-status && \ + echo "" >> /etc/bash.bashrc && \ + echo ". /usr/local/lib/python2.7/dist-packages/powerline/bindings/bash/powerline.sh" >> /etc/bash.bashrc \ + ;fi \ +;fi + +USER laradock + ########################################################################### # ImageMagick: ########################################################################### From 95965b12e707f8adceb835fc4784e5e0548f2c3a Mon Sep 17 00:00:00 2001 From: Yu Li Date: Tue, 9 Apr 2019 10:17:43 +0800 Subject: [PATCH 127/589] php-worker swoole false (#2079) --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index 928d2fe..ffb94c3 100644 --- a/env-example +++ b/env-example @@ -189,7 +189,7 @@ PHP_WORKER_INSTALL_ZIP_ARCHIVE=false PHP_WORKER_INSTALL_MYSQL_CLIENT=false PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_INSTALL_GHOSTSCRIPT=false -PHP_WORKER_INSTALL_SWOOLE=true +PHP_WORKER_INSTALL_SWOOLE=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 From a03c225e279910b9393b5e95fbffe5081b9e5a95 Mon Sep 17 00:00:00 2001 From: Tunde Aromire Date: Tue, 9 Apr 2019 07:32:40 +0100 Subject: [PATCH 128/589] Installation of ffmpeg (#2078) * Install ffmpeg in workspace. * Documented the process for install ffmpeg. --- DOCUMENTATION/content/documentation/index.md | 16 ++++++++++++++++ docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 9fe1b7f..17847a3 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1716,6 +1716,22 @@ Linuxbrew is a package manager for Linux. It is the Linux version of MacOS Homeb +
+ +## Install FFMPEG + +To install FFMPEG in the Workspace container + +1 - Open the `.env` file + +2 - Search for the `WORKSPACE_INSTALL_FFMPEG` argument under the Workspace Container and set it to `true` + +3 - Re-build the container `docker-compose build workspace` + + + + +
diff --git a/docker-compose.yml b/docker-compose.yml index a924b49..afb9f7e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -109,6 +109,7 @@ services: - BLACKFIRE_CLIENT_ID=${BLACKFIRE_CLIENT_ID} - BLACKFIRE_CLIENT_TOKEN=${BLACKFIRE_CLIENT_TOKEN} - INSTALL_POWERLINE=${WORKSPACE_INSTALL_POWERLINE} + - INSTALL_FFMPEG=${WORKSPACE_INSTALL_FFMPEG} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} extra_hosts: diff --git a/env-example b/env-example index ffb94c3..a39d8e7 100644 --- a/env-example +++ b/env-example @@ -139,6 +139,7 @@ WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 WORKSPACE_TIMEZONE=UTC WORKSPACE_SSH_PORT=2222 +WORKSPACE_INSTALL_FFMPEG=false ### PHP_FPM ############################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 8f8e23f..56a1dd4 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -990,6 +990,18 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ apt-get -y install mysql-client \ ;fi +########################################################################### +# FFMpeg: +########################################################################### + +USER root + +ARG INSTALL_FFMPEG=false + +RUN if [ ${INSTALL_FFMPEG} = true ]; then \ + apt-get -y install ffmpeg \ +;fi + ########################################################################### # Check PHP version: ########################################################################### From 83a24efa709d15037b0d06ca7f4df235e240d642 Mon Sep 17 00:00:00 2001 From: "Guilherme A. Girardi" Date: Thu, 18 Apr 2019 20:54:13 -0300 Subject: [PATCH 129/589] fix pgadmin workstation name (#2088) The generated name did not follow the pattern of the other. --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index afb9f7e..8494a85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -597,7 +597,6 @@ services: ### pgAdmin ############################################## pgadmin: - container_name: pgadmin image: dpage/pgadmin4:latest environment: - "PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}" From 5b07fbb9c4f8a33f3dc4c21ccac789bacdf43855 Mon Sep 17 00:00:00 2001 From: Sascha Brendel Date: Tue, 23 Apr 2019 10:19:05 +0200 Subject: [PATCH 130/589] Switched base image to fix recurrent caddy issues. (#2095) --- caddy/Dockerfile | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 1f2ed64..c9b74b7 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -1,30 +1,5 @@ -FROM golang:alpine +FROM abiosoft/caddy:no-stats -LABEL maintainer="Huadong Zuo " +CMD ["--conf", "/etc/caddy/Caddyfile", "--log", "stdout", "--agree=true"] -RUN apk add --no-cache \ - openssh \ - git \ - build-base \ - && mkdir -p $GOPATH/src/golang.org/x/ \ - && cd $GOPATH/src/golang.org/x/ \ - && git clone https://github.com/golang/sys.git sys \ - && go get github.com/abiosoft/caddyplug/caddyplug \ - && caddyplug install-caddy \ - apk del build-base - -ARG plugins="cors" - -## ARG plugins="cors cgi cloudflare azure linode" - -RUN caddyplug install ${plugins} - -RUN apk add --no-cache inotify-tools \ - && echo -e "#!/bin/sh\nwhile inotifywait -e modify /etc/caddy; do\n\tpkill caddy\ndone " >> /start.sh \ - && chmod +x /start.sh - -EXPOSE 80 443 - -WORKDIR /var/www/public - -CMD ["sh","-c","/start.sh & /usr/bin/caddy -conf /etc/caddy/Caddyfile -agree"] +EXPOSE 80 443 2015 From f5c80cd2514d6fd9aec130a7aec8f1394f0027b0 Mon Sep 17 00:00:00 2001 From: Przemek Dziewa Date: Tue, 23 Apr 2019 10:22:55 +0200 Subject: [PATCH 131/589] Added docker-compose run workspace example (#2094) --- DOCUMENTATION/content/guides/index.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index ec7f903..388edf4 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -69,6 +69,14 @@ Note that more containers are available, find them in the [docs](http://laradock docker-compose exec workspace bash ``` +## Execute commands + +If you want to only execute some command and don't want to enter bash, you can execute `docker-compose run workspace `. + +``` +docker-compose run workspace php artisan migrate +``` + ## Install and configure Laravel Let's install Laravel's dependencies, add the `.env` file, generate the key and give proper permissions to the cache folder. From cbbdb0a86b88e285d4551593e64bcf15908560cb Mon Sep 17 00:00:00 2001 From: xiagw Date: Wed, 8 May 2019 18:10:22 +0800 Subject: [PATCH 132/589] add sonarqube to docker-compose (#2113) * add sonarqube to docker-compose * change volume dir * add postgres init db * add comment for sonarqube error --- docker-compose.yml | 29 ++++++++++++ env-example | 16 +++++++ .../docker-entrypoint-initdb.d/.gitignore | 1 + .../init_jupyterhub_db.sh | 2 +- .../init_sonarqube_db.sh | 44 +++++++++++++++++++ sonarqube/Dockerfile | 3 ++ 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 postgres/docker-entrypoint-initdb.d/init_sonarqube_db.sh create mode 100644 sonarqube/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 8494a85..04c099e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,8 @@ volumes: driver: ${VOLUMES_DRIVER} mosquitto: driver: ${VOLUMES_DRIVER} + sonarqube: + driver: ${VOLUMES_DRIVER} services: @@ -403,6 +405,10 @@ services: - JUPYTERHUB_POSTGRES_USER=${JUPYTERHUB_POSTGRES_USER} - JUPYTERHUB_POSTGRES_PASSWORD=${JUPYTERHUB_POSTGRES_PASSWORD} - JUPYTERHUB_POSTGRES_DB=${JUPYTERHUB_POSTGRES_DB} + - SONARQUBE_POSTGRES_INIT=${SONARQUBE_POSTGRES_INIT} + - SONARQUBE_POSTGRES_DB=${SONARQUBE_POSTGRES_DB} + - SONARQUBE_POSTGRES_USER=${SONARQUBE_POSTGRES_USER} + - SONARQUBE_POSTGRES_PASSWORD=${SONARQUBE_POSTGRES_PASSWORD} networks: - backend @@ -1421,3 +1427,26 @@ services: - "${MANTICORE_HTTP_PORT}:9308" networks: - backend + +### SONARQUBE ################################################ + sonarqube: + build: + context: ./sonarqube + hostname: "${SONARQUBE_HOSTNAME}" + volumes: + - ${DATA_PATH_HOST}/sonarqube/conf:/opt/sonarqube/conf + - ${DATA_PATH_HOST}/sonarqube/data:/opt/sonarqube/data + - ${DATA_PATH_HOST}/sonarqube/logs:/opt/sonarqube/logs + - ${DATA_PATH_HOST}/sonarqube/extensions:/opt/sonarqube/extensions + - ${DATA_PATH_HOST}/sonarqube/plugins:/opt/sonarqube/lib/bundled-plugins + ports: + - ${SONARQUBE_PORT}:9000 + depends_on: + - postgres + environment: + - sonar.jdbc.username=${SONARQUBE_POSTGRES_USER} + - sonar.jdbc.password=${SONARQUBE_POSTGRES_PASSWORD} + - sonar.jdbc.url=jdbc:postgresql://${SONARQUBE_POSTGRES_HOST}:5432/${SONARQUBE_POSTGRES_DB} + networks: + - backend + - frontend diff --git a/env-example b/env-example index a39d8e7..4876ba9 100644 --- a/env-example +++ b/env-example @@ -676,3 +676,19 @@ MANTICORE_HTTP_PORT=9308 PGADMIN_PORT=5050 PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org PGADMIN_DEFAULT_PASSWORD=admin + +### SONARQUBE ################################################ +## docker-compose up -d sonarqube +## (If you encounter a database error) +## docker-compose exec --user=root postgres +## source docker-entrypoint-initdb.d/init_sonarqube_db.sh +## (If you encounter logs error) +## docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs + +SONARQUBE_HOSTNAME=sonar.example.com +SONARQUBE_PORT=9000 +SONARQUBE_POSTGRES_INIT=true +SONARQUBE_POSTGRES_HOST=postgres +SONARQUBE_POSTGRES_DB=sonar +SONARQUBE_POSTGRES_USER=sonar +SONARQUBE_POSTGRES_PASSWORD=sonarPass diff --git a/postgres/docker-entrypoint-initdb.d/.gitignore b/postgres/docker-entrypoint-initdb.d/.gitignore index c462039..0721338 100644 --- a/postgres/docker-entrypoint-initdb.d/.gitignore +++ b/postgres/docker-entrypoint-initdb.d/.gitignore @@ -1,3 +1,4 @@ *.sh !init_gitlab_db.sh !init_jupyterhub_db.sh +!init_sonarqube_db.sh diff --git a/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh b/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh index 787fabc..c386979 100644 --- a/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh +++ b/postgres/docker-entrypoint-initdb.d/init_jupyterhub_db.sh @@ -33,7 +33,7 @@ # EOSQL # ### default database and user for jupyterhub ############################################## -if [ $JUPYTERHUB_POSTGRES_INIT == 'true' ]; then +if [ "$JUPYTERHUB_POSTGRES_INIT" == 'true' ]; then psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL CREATE USER $JUPYTERHUB_POSTGRES_USER WITH PASSWORD '$JUPYTERHUB_POSTGRES_PASSWORD'; CREATE DATABASE $JUPYTERHUB_POSTGRES_DB; diff --git a/postgres/docker-entrypoint-initdb.d/init_sonarqube_db.sh b/postgres/docker-entrypoint-initdb.d/init_sonarqube_db.sh new file mode 100644 index 0000000..fea961d --- /dev/null +++ b/postgres/docker-entrypoint-initdb.d/init_sonarqube_db.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copy createdb.sh.example to createdb.sh +# then uncomment then set database name and username to create you need databases +# +# example: .env POSTGRES_USER=appuser and need db name is myshop_db +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER myuser WITH PASSWORD 'mypassword'; +# CREATE DATABASE myshop_db; +# GRANT ALL PRIVILEGES ON DATABASE myshop_db TO myuser; +# EOSQL +# +# this sh script will auto run when the postgres container starts and the $DATA_PATH_HOST/postgres not found. +# +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db1 WITH PASSWORD 'db1'; +# CREATE DATABASE db1; +# GRANT ALL PRIVILEGES ON DATABASE db1 TO db1; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db2 WITH PASSWORD 'db2'; +# CREATE DATABASE db2; +# GRANT ALL PRIVILEGES ON DATABASE db2 TO db2; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db3 WITH PASSWORD 'db3'; +# CREATE DATABASE db3; +# GRANT ALL PRIVILEGES ON DATABASE db3 TO db3; +# EOSQL +# +### default database and user for gitlab ############################################## +if [ "$SONARQUBE_POSTGRES_INIT" == 'true' ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER $SONARQUBE_POSTGRES_USER WITH PASSWORD '$SONARQUBE_POSTGRES_PASSWORD'; + CREATE DATABASE $SONARQUBE_POSTGRES_DB; + GRANT ALL PRIVILEGES ON DATABASE $SONARQUBE_POSTGRES_DB TO $SONARQUBE_POSTGRES_USER; + ALTER ROLE $SONARQUBE_POSTGRES_USER CREATEROLE SUPERUSER; + EOSQL + echo +fi diff --git a/sonarqube/Dockerfile b/sonarqube/Dockerfile new file mode 100644 index 0000000..7b32ead --- /dev/null +++ b/sonarqube/Dockerfile @@ -0,0 +1,3 @@ +FROM sonarqube:latest + +LABEL maintainer="xiagw " From d34602ae29d679b9d65804c4e8c3ff63f37ebb83 Mon Sep 17 00:00:00 2001 From: Panagiotis Koursaris Date: Wed, 8 May 2019 13:13:59 +0300 Subject: [PATCH 133/589] remove unnecessary .gitkeep (#2070) --- nginx/ssl/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 nginx/ssl/.gitkeep diff --git a/nginx/ssl/.gitkeep b/nginx/ssl/.gitkeep deleted file mode 100644 index e69de29..0000000 From d8b3cb5a52df3fba294eb4ec27859c9ac5cb5203 Mon Sep 17 00:00:00 2001 From: Rainer Eli Date: Wed, 8 May 2019 04:15:09 -0600 Subject: [PATCH 134/589] Add PHP_FPM_INSTALL_RDKAFKA as an option to install rdkafka extension (#2040) --- docker-compose.yml | 1 + env-example | 1 + php-fpm/Dockerfile | 12 ++++++++++++ 3 files changed, 14 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 04c099e..b52cbd8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -167,6 +167,7 @@ services: - INSTALL_IONCUBE=${PHP_FPM_INSTALL_IONCUBE} - INSTALL_APCU=${PHP_FPM_INSTALL_APCU} - INSTALL_YAML=${PHP_FPM_INSTALL_YAML} + - INSTALL_RDKAFKA=${PHP_FPM_INSTALL_RDKAFKA} - INSTALL_ADDITIONAL_LOCALES=${PHP_FPM_INSTALL_ADDITIONAL_LOCALES} - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} diff --git a/env-example b/env-example index 4876ba9..42ef3ad 100644 --- a/env-example +++ b/env-example @@ -173,6 +173,7 @@ PHP_FPM_INSTALL_PCNTL=false PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false PHP_FPM_INSTALL_IONCUBE=false +PHP_FPM_INSTALL_RDKAFKA=false PHP_FPM_FAKETIME=-0 PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index af3428f..d816424 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -598,6 +598,18 @@ RUN if [ ${INSTALL_YAML} = true ]; then \ docker-php-ext-enable yaml \ ;fi +########################################################################### +# RDKAFKA: +########################################################################### + +ARG INSTALL_RDKAFKA=false + +RUN if [ ${INSTALL_RDKAFKA} = true ]; then \ + apt-get install -y librdkafka-dev && \ + pecl install rdkafka && \ + docker-php-ext-enable rdkafka \ +;fi + ########################################################################### # Install additional locales: ########################################################################### From 09805230490833910e6f2cc92e1484e9bc7d2fc6 Mon Sep 17 00:00:00 2001 From: Silvio Ney Date: Wed, 8 May 2019 11:17:08 +0100 Subject: [PATCH 135/589] POSTGIS Postgres Extension (#2110) * created PHP_FPM_INSTALL_POSTGIS variable * install postgis if needs * install_postgis variable --- docker-compose.yml | 1 + env-example | 1 + php-fpm/Dockerfile | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b52cbd8..0ae4f2f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -155,6 +155,7 @@ services: - INSTALL_MYSQLI=${PHP_FPM_INSTALL_MYSQLI} - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_PG_CLIENT=${PHP_FPM_INSTALL_PG_CLIENT} + - INSTALL_POSTGIS=${PHP_FPM_INSTALL_POSTGIS} - INSTALL_INTL=${PHP_FPM_INSTALL_INTL} - INSTALL_GHOSTSCRIPT=${PHP_FPM_INSTALL_GHOSTSCRIPT} - INSTALL_LDAP=${PHP_FPM_INSTALL_LDAP} diff --git a/env-example b/env-example index 42ef3ad..ae649e5 100644 --- a/env-example +++ b/env-example @@ -169,6 +169,7 @@ PHP_FPM_INSTALL_LDAP=false PHP_FPM_INSTALL_PHALCON=false PHP_FPM_INSTALL_SWOOLE=false PHP_FPM_INSTALL_PG_CLIENT=false +PHP_FPM_INSTALL_POSTGIS=false PHP_FPM_INSTALL_PCNTL=false PHP_FPM_INSTALL_CALENDAR=false PHP_FPM_INSTALL_FAKETIME=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index d816424..55caca1 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -128,13 +128,17 @@ RUN if [ ${INSTALL_PGSQL} = true ]; then \ ########################################################################### ARG INSTALL_PG_CLIENT=false +ARG INSTALL_POSTGIS=false RUN if [ ${INSTALL_PG_CLIENT} = true ]; then \ # Create folders if not exists (https://github.com/tianon/docker-brew-debian/issues/65) mkdir -p /usr/share/man/man1 && \ mkdir -p /usr/share/man/man7 && \ # Install the pgsql client - apt-get install -y postgresql-client \ + apt-get install -y postgresql-client && \ + if [ ${INSTALL_POSTGIS} = true ]; then \ + apt-get install -y postgis; \ + fi \ ;fi ########################################################################### From 4417083a80870340189b2ddf05e55c7c7863fcde Mon Sep 17 00:00:00 2001 From: Tunde Aromire Date: Wed, 8 May 2019 16:27:39 +0200 Subject: [PATCH 136/589] Installation of ffmpeg (#2118) * Install ffmpeg in workspace and php-worker. --- DOCUMENTATION/content/documentation/index.md | 4 ++++ docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 13 +++++++++++++ php-worker/Dockerfile | 6 ++++++ 5 files changed, 27 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 17847a3..d77adee 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1728,6 +1728,10 @@ To install FFMPEG in the Workspace container 3 - Re-build the container `docker-compose build workspace` +4 - If you use the `php-worker` container too, please follow the same steps above especially if you have conversions that have been queued. + +**PS** Don't forget to install the binary in the `php-fpm` container too by applying the same steps above to its container, otherwise the you'll get an error when running the `php-ffmpeg` binary. + diff --git a/docker-compose.yml b/docker-compose.yml index 0ae4f2f..b7ec7d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -172,6 +172,7 @@ services: - INSTALL_ADDITIONAL_LOCALES=${PHP_FPM_INSTALL_ADDITIONAL_LOCALES} - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} + - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} @@ -206,6 +207,7 @@ services: - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} + - INSTALL_FFMPEG=${PHP_WORKER_INSTALL_FFMPEG} - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: diff --git a/env-example b/env-example index ae649e5..e5536f7 100644 --- a/env-example +++ b/env-example @@ -180,6 +180,7 @@ PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false PHP_FPM_INSTALL_MYSQL_CLIENT=false +PHP_FPM_FFMPEG=false PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" ### PHP_WORKER ############################################ @@ -193,6 +194,7 @@ PHP_WORKER_INSTALL_MYSQL_CLIENT=false PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_INSTALL_GHOSTSCRIPT=false PHP_WORKER_INSTALL_SWOOLE=false +PHP_WORKER_INSTALL_FFMPEG=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 55caca1..17a9841 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -643,6 +643,19 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ apt-get -y install mysql-client \ ;fi +########################################################################### +# FFMPEG: +########################################################################### + +USER root + +ARG INSTALL_FFMPEG=false + +RUN if [ ${INSTALL_FFMPEG} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install ffmpeg \ +;fi + ########################################################################### # Check PHP version: ########################################################################### diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index fe9f53b..dd7ed04 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -69,6 +69,12 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ apk --update add mysql-client \ ;fi +# Install FFMPEG: +ARG INSTALL_FFMPEG=false +RUN if [ ${INSTALL_FFMPEG} = true ]; then \ + apk --update add ffmpeg \ +;fi + # Install AMQP: ARG INSTALL_AMQP=false From e8d84cf9a3b2bffefcc8515430193cb075be3e51 Mon Sep 17 00:00:00 2001 From: Daniel Seif Date: Thu, 9 May 2019 07:41:09 +0200 Subject: [PATCH 137/589] Aerospike environment (#2119) * aerospike's config file is not being used but overwritten on container start * added environment variable handling for aerospike configuration --- aerospike/Dockerfile | 4 --- aerospike/aerospike.conf | 77 ---------------------------------------- docker-compose.yml | 4 +++ env-example | 3 ++ 4 files changed, 7 insertions(+), 81 deletions(-) delete mode 100644 aerospike/aerospike.conf diff --git a/aerospike/Dockerfile b/aerospike/Dockerfile index a85bc20..abf0e37 100644 --- a/aerospike/Dockerfile +++ b/aerospike/Dockerfile @@ -1,7 +1,3 @@ FROM aerospike:latest LABEL maintainer="Luciano Jr " - -RUN rm /etc/aerospike/aerospike.conf - -COPY aerospike.conf /etc/aerospike/aerospike.conf diff --git a/aerospike/aerospike.conf b/aerospike/aerospike.conf deleted file mode 100644 index 5e57775..0000000 --- a/aerospike/aerospike.conf +++ /dev/null @@ -1,77 +0,0 @@ -# Aerospike database configuration file. - -# This stanza must come first. -service { - user root - group root - paxos-single-replica-limit 1 # Number of nodes where the replica count is automatically reduced to 1. - pidfile /var/run/aerospike/asd.pid - service-threads 4 - transaction-queues 4 - transaction-threads-per-queue 4 - proto-fd-max 15000 -} - -logging { - - # Log file must be an absolute path. - file /var/log/aerospike/aerospike.log { - context any info - } - - # Send log messages to stdout - console { - context any critical - } -} - -network { - service { - address any - port 3000 - - # Uncomment the following to set the `access-address` parameter to the - # IP address of the Docker host. This will the allow the server to correctly - # publish the address which applications and other nodes in the cluster to - # use when addressing this node. - # access-address - } - - heartbeat { - - # mesh is used for environments that do not support multicast - mode mesh - port 3002 - - # use asinfo -v 'tip:host=;port=3002' to inform cluster of - # other mesh nodes - mesh-port 3002 - - interval 150 - timeout 10 - } - - fabric { - port 3001 - } - - info { - port 3003 - } -} - -namespace test { - replication-factor 2 - memory-size 1G - default-ttl 5d # 5 days, use 0 to never expire/evict. - - # storage-engine memory - - # To use file storage backing, comment out the line above and use the - # following lines instead. - storage-engine device { - file /opt/aerospike/data/test.dat - filesize 4G - data-in-memory true # Store data in memory in addition to file. - } -} diff --git a/docker-compose.yml b/docker-compose.yml index b7ec7d0..824e6c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -503,6 +503,10 @@ services: - "${AEROSPIKE_FABRIC_PORT}:3001" - "${AEROSPIKE_HEARTBEAT_PORT}:3002" - "${AEROSPIKE_INFO_PORT}:3003" + environment: + - STORAGE_GB=${AEROSPIKE_STORAGE_GB} + - MEM_GB=${AEROSPIKE_MEM_GB} + - NAMESPACE=${AEROSPIKE_NAMESPACE} networks: - backend diff --git a/env-example b/env-example index e5536f7..1459885 100644 --- a/env-example +++ b/env-example @@ -383,6 +383,9 @@ AEROSPIKE_SERVICE_PORT=3000 AEROSPIKE_FABRIC_PORT=3001 AEROSPIKE_HEARTBEAT_PORT=3002 AEROSPIKE_INFO_PORT=3003 +AEROSPIKE_STORAGE_GB=1 +AEROSPIKE_MEM_GB=1 +AEROSPIKE_NAMESPACE=test ### RETHINKDB ############################################# From c7289f7db3b96be585a879ceaf0f208102f8233f Mon Sep 17 00:00:00 2001 From: Daniel Seif Date: Thu, 9 May 2019 07:42:50 +0200 Subject: [PATCH 138/589] GNU parallel in workspace container (#2102) * added parallel workers * removed debug sleep * added documentation how to install GNU parallel --- DOCUMENTATION/content/documentation/index.md | 21 ++++++++++++++++++++ docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile | 13 ++++++++++++ 4 files changed, 36 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index d77adee..c93d173 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1737,6 +1737,27 @@ To install FFMPEG in the Workspace container +
+ +## Install GNU Parallel + +GNU Parallel is a command line tool to run multiple processes in parallel. + +(see https://www.gnu.org/software/parallel/parallel_tutorial.html) + +To install GNU Parallel in the Workspace container + +1 - Open the `.env` file + +2 - Search for the `WORKSPACE_INSTALL_GNU_PARALLEL` argument under the Workspace Container and set it to `true` + +3 - Re-build the container `docker-compose build workspace` + + + + + +

diff --git a/docker-compose.yml b/docker-compose.yml index 824e6c4..52f0cf3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -112,6 +112,7 @@ services: - BLACKFIRE_CLIENT_TOKEN=${BLACKFIRE_CLIENT_TOKEN} - INSTALL_POWERLINE=${WORKSPACE_INSTALL_POWERLINE} - INSTALL_FFMPEG=${WORKSPACE_INSTALL_FFMPEG} + - INSTALL_GNU_PARALLEL=${WORKSPACE_INSTALL_GNU_PARALLEL} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} extra_hosts: diff --git a/env-example b/env-example index 1459885..d7bbc98 100644 --- a/env-example +++ b/env-example @@ -140,6 +140,7 @@ WORKSPACE_CHROME_DRIVER_VERSION=2.42 WORKSPACE_TIMEZONE=UTC WORKSPACE_SSH_PORT=2222 WORKSPACE_INSTALL_FFMPEG=false +WORKSPACE_INSTALL_GNU_PARALLEL=false ### PHP_FPM ############################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 56a1dd4..7dd79bd 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -1002,6 +1002,19 @@ RUN if [ ${INSTALL_FFMPEG} = true ]; then \ apt-get -y install ffmpeg \ ;fi +########################################################################### +# GNU Parallel: +########################################################################### + +USER root + +ARG INSTALL_GNU_PARALLEL=false + +RUN if [ ${INSTALL_GNU_PARALLEL} = true ]; then \ + apt-get -y install parallel \ +;fi + + ########################################################################### # Check PHP version: ########################################################################### From 76b71d264d0c360a9061289ba3362d3b1aa96e47 Mon Sep 17 00:00:00 2001 From: sevillaarvin <33614172+sevillaarvin@users.noreply.github.com> Date: Sat, 18 May 2019 10:53:26 +0800 Subject: [PATCH 139/589] Add gitlab-runner documentation (#2131) --- DOCUMENTATION/content/documentation/index.md | 61 ++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index c93d173..0704aba 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -862,6 +862,67 @@ docker-compose up -d gitlab +
+ +## Use Gitlab Runner + +1 - Retrieve the registration token in your gitlab project (Settings > CI / CD > Runners > Set up a specific Runner manually) + +2 - Open the `.env` file and set the following changes: +``` +# so that gitlab container will pass the correct domain to gitlab-runner container +GITLAB_DOMAIN_NAME=http://gitlab + +GITLAB_RUNNER_REGISTRATION_TOKEN= + +# so that gitlab-runner container will send POST request for registration to correct domain +GITLAB_CI_SERVER_URL=http://gitlab +``` + +3 - Open the `docker-compose.yml` file and add the following changes: +```yml + gitlab-runner: + environment: # these values will be used during `gitlab-runner register` + - RUNNER_EXECUTOR=docker # change from shell (default) + - DOCKER_IMAGE=alpine + - DOCKER_NETWORK_MODE=laradock_backend + networks: + - backend # connect to network where gitlab service is connected +``` + +4 - Run the Gitlab-Runner Container (`gitlab-runner`) with the `docker-compose up` command. Example: + +```bash +docker-compose up -d gitlab-runner +``` + +5 - Register the gitlab-runner to the gitlab container + +```bash +docker-compose exec gitlab-runner bash +gitlab-runner register +``` + +6 - Create a `.gitlab-ci.yml` file for your pipeline + +```yml +before_script: + - echo Hello! + +job1: + scripts: + - echo job1 +``` + +7 - Push changes to gitlab + +8 - Verify that pipeline is run successful + + + + + +
## Use Adminer From 7ea44ca25a159deb234c0e41e5670fe50e89c09b Mon Sep 17 00:00:00 2001 From: vlauciani Date: Sat, 18 May 2019 04:54:45 +0200 Subject: [PATCH 140/589] Set 'logrotate' for 'nginx' logs (#2111) * Update Dockerfile Install 'logrotate' for nginx log. Issue https://github.com/laradock/laradock/issues/1357 * Create nginx Create 'logrotate' file for nginx log. Issue https://github.com/laradock/laradock/issues/1357 * Update Dockerfile Copy 'logrotate' config file. Issue https://github.com/laradock/laradock/issues/1357 * Update nginx Add 'nodateext' logrotate option to archive with sequence number * Update startup.sh Add line to start 'crond' demon * Update nginx Update permissions --- nginx/Dockerfile | 7 +++++++ nginx/logrotate/nginx | 14 ++++++++++++++ nginx/startup.sh | 4 ++++ 3 files changed, 25 insertions(+) create mode 100644 nginx/logrotate/nginx diff --git a/nginx/Dockerfile b/nginx/Dockerfile index 12c456d..c98498f 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -14,6 +14,7 @@ RUN if [ ${CHANGE_SOURCE} = true ]; then \ RUN apk update \ && apk upgrade \ + && apk --update add logrotate \ && apk add --no-cache openssl \ && apk add --no-cache bash \ && adduser -D -H -u 1000 -s /bin/bash www-data @@ -21,6 +22,12 @@ RUN apk update \ ARG PHP_UPSTREAM_CONTAINER=php-fpm ARG PHP_UPSTREAM_PORT=9000 +# Create 'messages' file used from 'logrotate' +RUN touch /var/log/messages + +# Copy 'logrotate' config file +COPY logrotate/nginx /etc/logrotate.d/ + # Set upstream conf and remove the default conf RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \ && rm /etc/nginx/conf.d/default.conf diff --git a/nginx/logrotate/nginx b/nginx/logrotate/nginx new file mode 100644 index 0000000..8c89a83 --- /dev/null +++ b/nginx/logrotate/nginx @@ -0,0 +1,14 @@ +/var/log/nginx/*.log { + daily + missingok + rotate 32 + compress + delaycompress + nodateext + notifempty + create 644 www-data root + sharedscripts + postrotate + [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` + endscript +} diff --git a/nginx/startup.sh b/nginx/startup.sh index 069d141..f8e7b22 100644 --- a/nginx/startup.sh +++ b/nginx/startup.sh @@ -6,4 +6,8 @@ if [ ! -f /etc/nginx/ssl/default.crt ]; then openssl x509 -req -days 365 -in "/etc/nginx/ssl/default.csr" -signkey "/etc/nginx/ssl/default.key" -out "/etc/nginx/ssl/default.crt" fi +# Start crond in background +crond -l 2 -b + +# Start nginx in foreground nginx From fbdfc419274fd0d2d7644845399782d6c942a166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E6=AD=A3=E6=B5=B7?= Date: Sat, 18 May 2019 10:57:01 +0800 Subject: [PATCH 141/589] feat: Add PHP_FPM_INSTALL_XHPROF as an option to install xhprof extension (#2077) * feat: Add PHP_FPM_INSTALL_XHPROF as an option to install xhprof extension * fix: INSTALL_XHPROF default value set false --- .gitignore | 2 ++ env-example | 1 + php-fpm/Dockerfile | 28 ++++++++++++++++++++++++++++ php-fpm/xhprof.ini | 8 ++++++++ 4 files changed, 39 insertions(+) create mode 100644 php-fpm/xhprof.ini diff --git a/.gitignore b/.gitignore index affb5c6..0673206 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ /nginx/ssl/*.crt /nginx/ssl/*.key /nginx/ssl/*.csr + +.DS_Store \ No newline at end of file diff --git a/env-example b/env-example index d7bbc98..b5986c1 100644 --- a/env-example +++ b/env-example @@ -153,6 +153,7 @@ PHP_FPM_INSTALL_IMAGE_OPTIMIZERS=true PHP_FPM_INSTALL_PHPREDIS=true PHP_FPM_INSTALL_MEMCACHED=false PHP_FPM_INSTALL_XDEBUG=false +PHP_FPM_INSTALL_XHPROF=false PHP_FPM_INSTALL_PHPDBG=false PHP_FPM_INSTALL_IMAP=false PHP_FPM_INSTALL_MONGO=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 17a9841..9d90ee6 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -239,6 +239,34 @@ RUN if [ ${INSTALL_MONGO} = true ]; then \ docker-php-ext-enable mongodb \ ;fi +########################################################################### +# Xhprof: +########################################################################### + +ARG INSTALL_XHPROF=false + +RUN if [ ${INSTALL_XHPROF} = true ]; then \ + # Install the php xhprof extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = 7 ]; then \ + curl -L -o /tmp/xhprof.tar.gz "https://github.com/tideways/php-xhprof-extension/archive/v4.1.6.tar.gz"; \ + else \ + curl -L -o /tmp/xhprof.tar.gz "https://codeload.github.com/phacility/xhprof/tar.gz/master"; \ + fi \ + && mkdir -p xhprof \ + && tar -C xhprof -zxvf /tmp/xhprof.tar.gz --strip 1 \ + && ( \ + cd xhprof \ + && phpize \ + && ./configure \ + && make \ + && make install \ + ) \ + && rm -r xhprof \ + && rm /tmp/xhprof.tar.gz \ +;fi + +COPY ./xhprof.ini /usr/local/etc/php/conf.d + ########################################################################### # AMQP: ########################################################################### diff --git a/php-fpm/xhprof.ini b/php-fpm/xhprof.ini new file mode 100644 index 0000000..1b010b9 --- /dev/null +++ b/php-fpm/xhprof.ini @@ -0,0 +1,8 @@ +[xhprof] +; extension=xhprof.so +extension=tideways.so +xhprof.output_dir=/var/www/xhprof +; no need to autoload, control in the program +tideways.auto_prepend_library=0 +; set default rate +tideways.sample_rate=100 \ No newline at end of file From 23193babf416102ce61001b829c8afdb53fa5d91 Mon Sep 17 00:00:00 2001 From: Alexandr Shevchenko Date: Sat, 18 May 2019 08:06:30 +0300 Subject: [PATCH 142/589] Workspace: blackfire gpg.key url fixed (#2133) --- workspace/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 7dd79bd..d286ece 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -345,7 +345,7 @@ ARG BLACKFIRE_CLIENT_TOKEN ENV BLACKFIRE_CLIENT_TOKEN ${BLACKFIRE_CLIENT_TOKEN} RUN if [ ${INSTALL_XDEBUG} = false -a ${INSTALL_BLACKFIRE} = true ]; then \ - curl -L https://packagecloud.io/gpg.key | apt-key add - && \ + curl -L https://packages.blackfire.io/gpg.key | apt-key add - && \ echo "deb http://packages.blackfire.io/debian any main" | tee /etc/apt/sources.list.d/blackfire.list && \ apt-get update -yqq && \ apt-get install blackfire-agent \ From 8027a98f72d2d30161c0a193ceef467c05e629df Mon Sep 17 00:00:00 2001 From: Anton Sannikov Date: Mon, 20 May 2019 22:36:08 +0200 Subject: [PATCH 143/589] Confluence config added --- docker-compose.yml | 20 +++++++++ env-example | 8 ++++ .../docker-entrypoint-initdb.d/.gitignore | 1 + .../init_confluence_db.sh | 44 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 postgres/docker-entrypoint-initdb.d/init_confluence_db.sh diff --git a/docker-compose.yml b/docker-compose.yml index 52f0cf3..b022bbd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,8 @@ volumes: driver: ${VOLUMES_DRIVER} mosquitto: driver: ${VOLUMES_DRIVER} + confluence: + driver: ${VOLUMES_DRIVER} sonarqube: driver: ${VOLUMES_DRIVER} @@ -414,6 +416,10 @@ services: - SONARQUBE_POSTGRES_DB=${SONARQUBE_POSTGRES_DB} - SONARQUBE_POSTGRES_USER=${SONARQUBE_POSTGRES_USER} - SONARQUBE_POSTGRES_PASSWORD=${SONARQUBE_POSTGRES_PASSWORD} + - POSTGRES_CONFLUENCE_INIT=${CONFLUENCE_POSTGRES_INIT} + - POSTGRES_CONFLUENCE_DB=${CONFLUENCE_POSTGRES_DB} + - POSTGRES_CONFLUENCE_USER=${CONFLUENCE_POSTGRES_USER} + - POSTGRES_CONFLUENCE_PASSWORD=${CONFLUENCE_POSTGRES_PASSWORD} networks: - backend @@ -1459,3 +1465,17 @@ services: networks: - backend - frontend +### CONFLUENCE ################################################ + confluence: + container_name: Confluence + image: atlassian/confluence-server:${CONFLUENCE_VERSION} + restart: always + ports: + - "${CONFLUENCE_HOST_HTTP_PORT}:8090" + networks: + - frontend + - backend + depends_on: + - postgres + volumes: + - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data \ No newline at end of file diff --git a/env-example b/env-example index b5986c1..9ba3cdd 100644 --- a/env-example +++ b/env-example @@ -366,6 +366,14 @@ JENKINS_HOST_HTTP_PORT=8090 JENKINS_HOST_SLAVE_AGENT_PORT=50000 JENKINS_HOME=./jenkins/jenkins_home +### CONFLUENCE ############################################### +CONFLUENCE_POSTGRES_INIT=true +CONFLUENCE_VERSION=6.13-ubuntu-18.04-adoptopenjdk8 +CONFLUENCE_POSTGRES_DB=laradock_confluence +CONFLUENCE_POSTGRES_USER=laradock_confluence +CONFLUENCE_POSTGRES_PASSWORD=laradock_confluence +CONFLUENCE_HOST_HTTP_PORT=8090 + ### GRAFANA ############################################### GRAFANA_PORT=3000 diff --git a/postgres/docker-entrypoint-initdb.d/.gitignore b/postgres/docker-entrypoint-initdb.d/.gitignore index 0721338..a56b450 100644 --- a/postgres/docker-entrypoint-initdb.d/.gitignore +++ b/postgres/docker-entrypoint-initdb.d/.gitignore @@ -2,3 +2,4 @@ !init_gitlab_db.sh !init_jupyterhub_db.sh !init_sonarqube_db.sh +!init_confluence_db.sh \ No newline at end of file diff --git a/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh b/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh new file mode 100644 index 0000000..ce5e9f7 --- /dev/null +++ b/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copy createdb.sh.example to createdb.sh +# then uncomment then set database name and username to create you need databases +# +# example: .env POSTGRES_USER=appuser and need db name is myshop_db +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER myuser WITH PASSWORD 'mypassword'; +# CREATE DATABASE myshop_db; +# GRANT ALL PRIVILEGES ON DATABASE myshop_db TO myuser; +# EOSQL +# +# this sh script will auto run when the postgres container starts and the $DATA_PATH_HOST/postgres not found. +# +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db1 WITH PASSWORD 'db1'; +# CREATE DATABASE db1; +# GRANT ALL PRIVILEGES ON DATABASE db1 TO db1; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db2 WITH PASSWORD 'db2'; +# CREATE DATABASE db2; +# GRANT ALL PRIVILEGES ON DATABASE db2 TO db2; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db3 WITH PASSWORD 'db3'; +# CREATE DATABASE db3; +# GRANT ALL PRIVILEGES ON DATABASE db3 TO db3; +# EOSQL +# +### default database and user for confluence ############################################## +if [ "$POSTGRES_CONFLUENCE_INIT" == 'true' ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER $POSTGRES_CONFLUENCE_USER WITH PASSWORD '$POSTGRES_CONFLUENCE_PASSWORD'; + CREATE DATABASE $POSTGRES_CONFLUENCE_DB; + GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_CONFLUENCE_DB TO $POSTGRES_CONFLUENCE_USER; + ALTER ROLE $POSTGRES_CONFLUENCE_USER CREATEROLE SUPERUSER; + EOSQL + echo +fi \ No newline at end of file From f23149115d7f8c8ecfe18f82b62f57f02d4d56bc Mon Sep 17 00:00:00 2001 From: Anton Sannikov Date: Mon, 20 May 2019 22:51:36 +0200 Subject: [PATCH 144/589] Confluence docs added --- DOCUMENTATION/content/documentation/index.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 0704aba..22aa559 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1023,8 +1023,21 @@ _Note: You can customize the port on which beanstalkd console is listening by ch +
+ +## Use Confluence +1 - Run the Confluence Container (`confluence`) with the `docker-compose up` command. Example: +```bash +docker-compose up -d confluence +``` + +2 - Open your browser and visit the localhost on port **8090**: `http://localhost:8090` + +**Note:** You can you trial version and then you have to buy a licence to use it. + +You can set custom confluence version in `CONFLUENCE_VERSION`. [Find more info in section 'Versioning'](https://hub.docker.com/r/atlassian/confluence-server/)
From 2dd64aef55044c37972f74a7284de086c3d36a31 Mon Sep 17 00:00:00 2001 From: vlauciani Date: Wed, 29 May 2019 02:53:13 +0200 Subject: [PATCH 145/589] Update Dockerfile (#2147) Solve issue https://github.com/laradock/laradock/issues/2146 --- laravel-horizon/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index 35a6955..f21dfdd 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -20,7 +20,8 @@ RUN apk --update add wget \ autoconf \ cyrus-sasl-dev \ libgsasl-dev \ - supervisor + supervisor \ + procps RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached From dba1594b05ef7493de9af6a6f08a50f475426ec3 Mon Sep 17 00:00:00 2001 From: Mateusz Qunabu Date: Wed, 29 May 2019 02:54:20 +0200 Subject: [PATCH 146/589] allowing php-worker to install gmp extension (#2152) --- docker-compose.yml | 1 + env-example | 2 ++ php-worker/Dockerfile | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 52f0cf3..18ff561 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -209,6 +209,7 @@ services: - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} - INSTALL_FFMPEG=${PHP_WORKER_INSTALL_FFMPEG} + - INSTALL_GMP=${PHP_WORKER_INSTALL_GMP} - PUID=${PHP_WORKER_PUID} - PGID=${PHP_WORKER_PGID} volumes: diff --git a/env-example b/env-example index b5986c1..810dee1 100644 --- a/env-example +++ b/env-example @@ -197,6 +197,8 @@ PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_INSTALL_GHOSTSCRIPT=false PHP_WORKER_INSTALL_SWOOLE=false PHP_WORKER_INSTALL_FFMPEG=false +PHP_WORKER_INSTALL_GMP=false + PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index dd7ed04..328a541 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -103,6 +103,14 @@ RUN if [ $INSTALL_GHOSTSCRIPT = true ]; then \ apk --update add ghostscript \ ;fi +#Install GMP package: +ARG INSTALL_GMP=false +RUN if [ ${INSTALL_GMP} = true ]; then \ + apk add --update --no-cache gmp gmp-dev \ + && docker-php-ext-install gmp \ +;fi + + RUN rm /var/cache/apk/* \ && mkdir -p /var/www From bc8772441bc326c6a0bad89aef358ebb8d141344 Mon Sep 17 00:00:00 2001 From: xiagw Date: Wed, 29 May 2019 08:56:40 +0800 Subject: [PATCH 147/589] add php ext "taint" (#2150) * add php ext "taint", only support php7. --- docker-compose.yml | 3 +++ env-example | 3 +++ php-fpm/Dockerfile | 15 +++++++++++++++ php-worker/Dockerfile | 13 +++++++++++++ workspace/Dockerfile | 16 ++++++++++++++++ 5 files changed, 50 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 18ff561..b49eee6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -98,6 +98,7 @@ services: - INSTALL_PG_CLIENT=${WORKSPACE_INSTALL_PG_CLIENT} - INSTALL_PHALCON=${WORKSPACE_INSTALL_PHALCON} - INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE} + - INSTALL_TAINT=${WORKSPACE_INSTALL_TAINT} - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} - INSTALL_IONCUBE=${WORKSPACE_INSTALL_IONCUBE} - INSTALL_MYSQL_CLIENT=${WORKSPACE_INSTALL_MYSQL_CLIENT} @@ -162,6 +163,7 @@ services: - INSTALL_LDAP=${PHP_FPM_INSTALL_LDAP} - INSTALL_PHALCON=${PHP_FPM_INSTALL_PHALCON} - INSTALL_SWOOLE=${PHP_FPM_INSTALL_SWOOLE} + - INSTALL_TAINT=${PHP_FPM_INSTALL_TAINT} - INSTALL_IMAGE_OPTIMIZERS=${PHP_FPM_INSTALL_IMAGE_OPTIMIZERS} - INSTALL_IMAGEMAGICK=${PHP_FPM_INSTALL_IMAGEMAGICK} - INSTALL_CALENDAR=${PHP_FPM_INSTALL_CALENDAR} @@ -208,6 +210,7 @@ services: - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} + - INSTALL_TAINT=${PHP_WORKER_INSTALL_TAINT} - INSTALL_FFMPEG=${PHP_WORKER_INSTALL_FFMPEG} - INSTALL_GMP=${PHP_WORKER_INSTALL_GMP} - PUID=${PHP_WORKER_PUID} diff --git a/env-example b/env-example index 810dee1..84d9dd2 100644 --- a/env-example +++ b/env-example @@ -129,6 +129,7 @@ WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false WORKSPACE_INSTALL_PHALCON=false WORKSPACE_INSTALL_SWOOLE=false +WORKSPACE_INSTALL_TAINT=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_INSTALL_MYSQL_CLIENT=false @@ -170,6 +171,7 @@ PHP_FPM_INSTALL_GHOSTSCRIPT=false PHP_FPM_INSTALL_LDAP=false PHP_FPM_INSTALL_PHALCON=false PHP_FPM_INSTALL_SWOOLE=false +PHP_FPM_INSTALL_TAINT=false PHP_FPM_INSTALL_PG_CLIENT=false PHP_FPM_INSTALL_POSTGIS=false PHP_FPM_INSTALL_PCNTL=false @@ -196,6 +198,7 @@ PHP_WORKER_INSTALL_MYSQL_CLIENT=false PHP_WORKER_INSTALL_AMQP=false PHP_WORKER_INSTALL_GHOSTSCRIPT=false PHP_WORKER_INSTALL_SWOOLE=false +PHP_WORKER_INSTALL_TAINT=false PHP_WORKER_INSTALL_FFMPEG=false PHP_WORKER_INSTALL_GMP=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 9d90ee6..60fc5a9 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -223,6 +223,21 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ && php -m | grep -q 'swoole' \ ;fi +########################################################################### +# Taint EXTENSION +########################################################################### + +ARG INSTALL_TAINT=false + +RUN if [ ${INSTALL_TAINT} = true ]; then \ + # Install Php TAINT Extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ + pecl install taint && \ + docker-php-ext-enable taint && \ + php -m | grep -q 'taint'; \ + fi \ +;fi + ########################################################################### # MongoDB: ########################################################################### diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 328a541..5297c7b 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -135,6 +135,19 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ && docker-php-ext-enable swoole \ ;fi +########################################################################### +# Taint EXTENSION +########################################################################### + +ARG INSTALL_TAINT=false + +RUN if [ ${INSTALL_TAINT} = true ]; then \ + # Install Php TAINT Extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ + pecl install taint; \ + fi && \ + docker-php-ext-enable taint \ +;fi # #-------------------------------------------------------------------------- diff --git a/workspace/Dockerfile b/workspace/Dockerfile index d286ece..0ac035e 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -435,6 +435,22 @@ RUN if [ ${INSTALL_SWOOLE} = true ]; then \ && php -m | grep -q 'swoole' \ ;fi +########################################################################### +# Taint EXTENSION +########################################################################### + +ARG INSTALL_TAINT=false + +RUN if [ "${INSTALL_TAINT}" = true ]; then \ + # Install Php TAINT Extension + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ + pecl install taint && \ + echo "extension=taint.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/taint.ini && \ + ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/taint.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-taint.ini && \ + php -m | grep -q 'taint'; \ + fi \ +;fi + ########################################################################### # Libpng16 EXTENSION ########################################################################### From fbae49b898e4df253fe8f5087879d4e8ab697b9a Mon Sep 17 00:00:00 2001 From: xiagw Date: Wed, 29 May 2019 08:57:01 +0800 Subject: [PATCH 148/589] add docs for sonarqube (#2149) --- DOCUMENTATION/content/documentation/index.md | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 0704aba..aa0fd03 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -394,6 +394,37 @@ Always download the latest version of [Loaders for ionCube ](http://www.ioncube. +
+ + +## Install SonarQube (automatic code review tool) +SonarQube® is an automatic code review tool to detect bugs, vulnerabilities and code smells in your code. It can integrate with your existing workflow to enable continuous code inspection across your project branches and pull requests. +
+1 - Open the `.env` file +
+2 - Search for the `SONARQUBE_HOSTNAME=sonar.example.com` argument +
+3 - Set it to your-domain `sonar.example.com` +
+4 - `docker-compose up -d sonarqube` +
+5 - Open your browser: http://localhost:9000/ + +Troubleshooting: + +if you encounter a database error: +``` +docker-compose exec --user=root postgres +source docker-entrypoint-initdb.d/init_sonarqube_db.sh +``` + +If you encounter logs error: +``` +docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs +``` +[**SonarQube Documentation Here**](https://docs.sonarqube.org/latest/) + + From 9e537ee16ba90d782a9ab4614c520a5aa1118296 Mon Sep 17 00:00:00 2001 From: salvo-github <36646452+salvo-github@users.noreply.github.com> Date: Wed, 29 May 2019 03:04:50 +0200 Subject: [PATCH 149/589] Update docker-compose.yml (#2124) The proxy args added allow to use the local env variable if setted. In this way there is not need to add the proxy server to .env file. --- docker-compose.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b49eee6..6427e2c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -114,6 +114,9 @@ services: - INSTALL_POWERLINE=${WORKSPACE_INSTALL_POWERLINE} - INSTALL_FFMPEG=${WORKSPACE_INSTALL_FFMPEG} - INSTALL_GNU_PARALLEL=${WORKSPACE_INSTALL_GNU_PARALLEL} + - http_proxy + - https_proxy + - no_proxy volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} extra_hosts: @@ -176,6 +179,9 @@ services: - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} + - http_proxy + - https_proxy + - no_proxy volumes: - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} @@ -251,6 +257,9 @@ services: - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER} - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} - CHANGE_SOURCE=${CHANGE_SOURCE} + - http_proxy + - https_proxy + - no_proxy volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} - ${NGINX_HOST_LOG_PATH}:/var/log/nginx @@ -380,7 +389,12 @@ services: ### MariaDB ############################################## mariadb: - build: ./mariadb + build: + context: ./mariadb + args: + - http_proxy + - https_proxy + - no_proxy volumes: - ${DATA_PATH_HOST}/mariadb:/var/lib/mysql - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d From c0b28fc404bbb7bcaaa91e1e3615be88663d9b4c Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Wed, 5 Jun 2019 17:46:02 +0200 Subject: [PATCH 150/589] Ignore -pem files in nginx/ssl (#2121) --- nginx/ssl/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/nginx/ssl/.gitignore b/nginx/ssl/.gitignore index f98d0ee..003cd8e 100644 --- a/nginx/ssl/.gitignore +++ b/nginx/ssl/.gitignore @@ -1,3 +1,4 @@ *.crt *.csr *.key +*.pem \ No newline at end of file From c0a36a5a4d7107b1eb4b8637cd8a70c696fe780c Mon Sep 17 00:00:00 2001 From: Seb Garwood Date: Wed, 5 Jun 2019 16:47:08 +0100 Subject: [PATCH 151/589] Removing mention of production-docker-compose.yml file (#2093) The production-docker-compose.yml file was removed in https://github.com/laradock/laradock/issues/524, updating the docs to reflect this --- DOCUMENTATION/content/documentation/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index aa0fd03..47796d4 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -440,7 +440,9 @@ docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/son ## Prepare Laradock for Production -It's recommended for production to create a custom `docker-compose.yml` file. For that reason, Laradock is shipped with `production-docker-compose.yml` which should contain only the containers you are planning to run on production (usage example: `docker-compose -f production-docker-compose.yml up -d nginx mysql redis ...`). +It's recommended for production to create a custom `docker-compose.yml` file, for example `production-docker-compose.yml` + +In your new production `docker-compose.yml` file you should contain only the containers you are planning to run in production (usage example: `docker-compose -f production-docker-compose.yml up -d nginx mysql redis ...`). Note: The Database (MySQL/MariaDB/...) ports should not be forwarded on production, because Docker will automatically publish the port on the host, which is quite insecure, unless specifically told not to. So make sure to remove these lines: From 5bf8be6303d678e113a7a8a511143cc52763ad76 Mon Sep 17 00:00:00 2001 From: vlauciani Date: Thu, 6 Jun 2019 05:59:13 +0200 Subject: [PATCH 152/589] Add 'sshpass' and 'ping' packages into 'workspace' and 'php-fpm' Docker image (#2164) * Update env-example Added variables to install 'ping' and 'sshpass' * Update docker-compose.yml Import variable from '.env' to set 'INSTALL_MYSQL_CLIENT' and 'INSTALL_PING' * Update Dockerfile Add code to import variables from 'docker-compose.yml' to install 'ping' and/or 'sshpass' --- docker-compose.yml | 4 ++++ env-example | 4 ++++ php-fpm/Dockerfile | 26 ++++++++++++++++++++++++++ workspace/Dockerfile | 26 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 6427e2c..bd3d4ae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,6 +102,8 @@ services: - INSTALL_LIBPNG=${WORKSPACE_INSTALL_LIBPNG} - INSTALL_IONCUBE=${WORKSPACE_INSTALL_IONCUBE} - INSTALL_MYSQL_CLIENT=${WORKSPACE_INSTALL_MYSQL_CLIENT} + - INSTALL_PING=${WORKSPACE_INSTALL_PING} + - INSTALL_SSHPASS=${WORKSPACE_INSTALL_SSHPASS} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} @@ -177,6 +179,8 @@ services: - INSTALL_RDKAFKA=${PHP_FPM_INSTALL_RDKAFKA} - INSTALL_ADDITIONAL_LOCALES=${PHP_FPM_INSTALL_ADDITIONAL_LOCALES} - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} + - INSTALL_PING=${PHP_FPM_INSTALL_PING} + - INSTALL_SSHPASS=${PHP_FPM_INSTALL_SSHPASS} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} - http_proxy diff --git a/env-example b/env-example index 84d9dd2..b1c0e73 100644 --- a/env-example +++ b/env-example @@ -133,6 +133,8 @@ WORKSPACE_INSTALL_TAINT=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_INSTALL_MYSQL_CLIENT=false +WORKSPACE_INSTALL_PING=false +WORKSPACE_INSTALL_SSHPASS=false WORKSPACE_INSTALL_INOTIFY=false WORKSPACE_INSTALL_FSWATCH=false WORKSPACE_PUID=1000 @@ -184,6 +186,8 @@ PHP_FPM_INSTALL_APCU=false PHP_FPM_INSTALL_YAML=false PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false PHP_FPM_INSTALL_MYSQL_CLIENT=false +PHP_FPM_INSTALL_PING=false +PHP_FPM_INSTALL_SSHPASS=false PHP_FPM_FFMPEG=false PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 60fc5a9..ab6ba6b 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -686,6 +686,32 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ apt-get -y install mysql-client \ ;fi +########################################################################### +# ping: +########################################################################### + +USER root + +ARG INSTALL_PING=false + +RUN if [ ${INSTALL_PING} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install inetutils-ping \ +;fi + +########################################################################### +# sshpass: +########################################################################### + +USER root + +ARG INSTALL_SSHPASS=false + +RUN if [ ${INSTALL_SSHPASS} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install sshpass \ +;fi + ########################################################################### # FFMPEG: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 0ac035e..4d405da 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -1006,6 +1006,32 @@ RUN if [ ${INSTALL_MYSQL_CLIENT} = true ]; then \ apt-get -y install mysql-client \ ;fi +########################################################################### +# ping: +########################################################################### + +USER root + +ARG INSTALL_PING=false + +RUN if [ ${INSTALL_PING} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install inetutils-ping \ +;fi + +########################################################################### +# sshpass: +########################################################################### + +USER root + +ARG INSTALL_SSHPASS=false + +RUN if [ ${INSTALL_SSHPASS} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install sshpass \ +;fi + ########################################################################### # FFMpeg: ########################################################################### From 623ff66f40ed6d8f626bfd8dbe164ff3a902bd6f Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Thu, 6 Jun 2019 12:25:25 +0800 Subject: [PATCH 153/589] Fix ci build failed and nginx adduser error (#2165) * CI build no need CHANGE_SOURCE * fix 'adduser: group 'www-data' in use' error --- nginx/Dockerfile | 3 +-- travis-build.sh | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nginx/Dockerfile b/nginx/Dockerfile index c98498f..f7ef409 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -16,8 +16,7 @@ RUN apk update \ && apk upgrade \ && apk --update add logrotate \ && apk add --no-cache openssl \ - && apk add --no-cache bash \ - && adduser -D -H -u 1000 -s /bin/bash www-data + && apk add --no-cache bash ARG PHP_UPSTREAM_CONTAINER=php-fpm ARG PHP_UPSTREAM_PORT=9000 diff --git a/travis-build.sh b/travis-build.sh index 18f0910..e773b82 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -30,6 +30,9 @@ if [ -n "${PHP_VERSION}" ]; then # memcached extension does not yet support PHP 7.3. sed -i -- 's/PHP_FPM_INSTALL_MEMCACHED=true/PHP_FPM_INSTALL_MEMCACHED=false/g' .env fi + + sed -i -- 's/CHANGE_SOURCE=true/CHANGE_SOURCE=false/g' .env + cat .env docker-compose build ${BUILD_SERVICE} docker images From 63fc1fde44cc00aacb89511a441cb83685e8010c Mon Sep 17 00:00:00 2001 From: esfahanweb Date: Thu, 6 Jun 2019 09:32:45 +0430 Subject: [PATCH 154/589] Update Dockerfile (#2162) the first time, I ran apache2 container with other things such as MariaDB & PHPMyAdmin the second time, I decided to run nginx instead of apache2 and I faced an error that said "adduser: group 'www-data' in use", so I solved and shared it to others. --- nginx/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nginx/Dockerfile b/nginx/Dockerfile index f7ef409..eb1015b 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -18,6 +18,10 @@ RUN apk update \ && apk add --no-cache openssl \ && apk add --no-cache bash +RUN set -x ; \ + addgroup -g 82 -S www-data ; \ + adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1 + ARG PHP_UPSTREAM_CONTAINER=php-fpm ARG PHP_UPSTREAM_PORT=9000 From d1015e5e9687d31bf178ec75243825c606cc49e4 Mon Sep 17 00:00:00 2001 From: Anton Sannikov Date: Wed, 19 Jun 2019 11:19:20 +0200 Subject: [PATCH 155/589] Confluence container added (#2140) * Confluence config added * Confluence docs added --- DOCUMENTATION/content/documentation/index.md | 13 ++++++ docker-compose.yml | 20 +++++++++ env-example | 8 ++++ .../docker-entrypoint-initdb.d/.gitignore | 1 + .../init_confluence_db.sh | 44 +++++++++++++++++++ 5 files changed, 86 insertions(+) create mode 100644 postgres/docker-entrypoint-initdb.d/init_confluence_db.sh diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 47796d4..f523259 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1056,8 +1056,21 @@ _Note: You can customize the port on which beanstalkd console is listening by ch +
+ +## Use Confluence +1 - Run the Confluence Container (`confluence`) with the `docker-compose up` command. Example: +```bash +docker-compose up -d confluence +``` + +2 - Open your browser and visit the localhost on port **8090**: `http://localhost:8090` + +**Note:** You can you trial version and then you have to buy a licence to use it. + +You can set custom confluence version in `CONFLUENCE_VERSION`. [Find more info in section 'Versioning'](https://hub.docker.com/r/atlassian/confluence-server/)
diff --git a/docker-compose.yml b/docker-compose.yml index bd3d4ae..1a729e8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,8 @@ volumes: driver: ${VOLUMES_DRIVER} mosquitto: driver: ${VOLUMES_DRIVER} + confluence: + driver: ${VOLUMES_DRIVER} sonarqube: driver: ${VOLUMES_DRIVER} @@ -436,6 +438,10 @@ services: - SONARQUBE_POSTGRES_DB=${SONARQUBE_POSTGRES_DB} - SONARQUBE_POSTGRES_USER=${SONARQUBE_POSTGRES_USER} - SONARQUBE_POSTGRES_PASSWORD=${SONARQUBE_POSTGRES_PASSWORD} + - POSTGRES_CONFLUENCE_INIT=${CONFLUENCE_POSTGRES_INIT} + - POSTGRES_CONFLUENCE_DB=${CONFLUENCE_POSTGRES_DB} + - POSTGRES_CONFLUENCE_USER=${CONFLUENCE_POSTGRES_USER} + - POSTGRES_CONFLUENCE_PASSWORD=${CONFLUENCE_POSTGRES_PASSWORD} networks: - backend @@ -1481,3 +1487,17 @@ services: networks: - backend - frontend +### CONFLUENCE ################################################ + confluence: + container_name: Confluence + image: atlassian/confluence-server:${CONFLUENCE_VERSION} + restart: always + ports: + - "${CONFLUENCE_HOST_HTTP_PORT}:8090" + networks: + - frontend + - backend + depends_on: + - postgres + volumes: + - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data \ No newline at end of file diff --git a/env-example b/env-example index b1c0e73..6bc5a3f 100644 --- a/env-example +++ b/env-example @@ -375,6 +375,14 @@ JENKINS_HOST_HTTP_PORT=8090 JENKINS_HOST_SLAVE_AGENT_PORT=50000 JENKINS_HOME=./jenkins/jenkins_home +### CONFLUENCE ############################################### +CONFLUENCE_POSTGRES_INIT=true +CONFLUENCE_VERSION=6.13-ubuntu-18.04-adoptopenjdk8 +CONFLUENCE_POSTGRES_DB=laradock_confluence +CONFLUENCE_POSTGRES_USER=laradock_confluence +CONFLUENCE_POSTGRES_PASSWORD=laradock_confluence +CONFLUENCE_HOST_HTTP_PORT=8090 + ### GRAFANA ############################################### GRAFANA_PORT=3000 diff --git a/postgres/docker-entrypoint-initdb.d/.gitignore b/postgres/docker-entrypoint-initdb.d/.gitignore index 0721338..a56b450 100644 --- a/postgres/docker-entrypoint-initdb.d/.gitignore +++ b/postgres/docker-entrypoint-initdb.d/.gitignore @@ -2,3 +2,4 @@ !init_gitlab_db.sh !init_jupyterhub_db.sh !init_sonarqube_db.sh +!init_confluence_db.sh \ No newline at end of file diff --git a/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh b/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh new file mode 100644 index 0000000..ce5e9f7 --- /dev/null +++ b/postgres/docker-entrypoint-initdb.d/init_confluence_db.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copy createdb.sh.example to createdb.sh +# then uncomment then set database name and username to create you need databases +# +# example: .env POSTGRES_USER=appuser and need db name is myshop_db +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER myuser WITH PASSWORD 'mypassword'; +# CREATE DATABASE myshop_db; +# GRANT ALL PRIVILEGES ON DATABASE myshop_db TO myuser; +# EOSQL +# +# this sh script will auto run when the postgres container starts and the $DATA_PATH_HOST/postgres not found. +# +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db1 WITH PASSWORD 'db1'; +# CREATE DATABASE db1; +# GRANT ALL PRIVILEGES ON DATABASE db1 TO db1; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db2 WITH PASSWORD 'db2'; +# CREATE DATABASE db2; +# GRANT ALL PRIVILEGES ON DATABASE db2 TO db2; +# EOSQL +# +# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL +# CREATE USER db3 WITH PASSWORD 'db3'; +# CREATE DATABASE db3; +# GRANT ALL PRIVILEGES ON DATABASE db3 TO db3; +# EOSQL +# +### default database and user for confluence ############################################## +if [ "$POSTGRES_CONFLUENCE_INIT" == 'true' ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER $POSTGRES_CONFLUENCE_USER WITH PASSWORD '$POSTGRES_CONFLUENCE_PASSWORD'; + CREATE DATABASE $POSTGRES_CONFLUENCE_DB; + GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_CONFLUENCE_DB TO $POSTGRES_CONFLUENCE_USER; + ALTER ROLE $POSTGRES_CONFLUENCE_USER CREATEROLE SUPERUSER; + EOSQL + echo +fi \ No newline at end of file From ca80dd169474c6994efc347eaf79cb3e8fee815e Mon Sep 17 00:00:00 2001 From: Artyom Mezin Date: Wed, 19 Jun 2019 12:21:28 +0300 Subject: [PATCH 156/589] Add laravel installer for root user (#2176) --- workspace/Dockerfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 4d405da..3a07eee 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -124,6 +124,10 @@ COPY ./auth.json /home/laradock/.composer/auth.json # Make sure that ~/.composer belongs to laradock RUN chown -R laradock:laradock /home/laradock/.composer +# Export composer vendor path +RUN echo "" >> ~/.bashrc && \ + echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bashrc + USER laradock # Check if global install need to be ran @@ -715,6 +719,15 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ USER laradock +ARG INSTALL_LARAVEL_INSTALLER=false + +RUN if [ ${INSTALL_LARAVEL_INSTALLER} = true ]; then \ + # Install the Laravel Installer + composer global require "laravel/installer" \ +;fi + +USER root + ARG COMPOSER_REPO_PACKAGIST ENV COMPOSER_REPO_PACKAGIST ${COMPOSER_REPO_PACKAGIST} From a2c7b467662706ba1af118048baeaf6e27f6a74d Mon Sep 17 00:00:00 2001 From: StefanT123 Date: Wed, 19 Jun 2019 16:46:22 +0200 Subject: [PATCH 157/589] Added graylog to the list of softwares. (#2177) --- DOCUMENTATION/content/documentation/index.md | 46 +- docker-compose.yml | 32 +- env-example | 18 +- graylog/Dockerfile | 3 + graylog/config/graylog.conf | 481 +++++++++++++++++++ graylog/config/log4j2.xml | 35 ++ 6 files changed, 603 insertions(+), 12 deletions(-) create mode 100644 graylog/Dockerfile create mode 100644 graylog/config/graylog.conf create mode 100644 graylog/config/log4j2.xml diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index f523259..9169370 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -398,29 +398,29 @@ Always download the latest version of [Loaders for ionCube ](http://www.ioncube. ## Install SonarQube (automatic code review tool) -SonarQube® is an automatic code review tool to detect bugs, vulnerabilities and code smells in your code. It can integrate with your existing workflow to enable continuous code inspection across your project branches and pull requests. +SonarQube® is an automatic code review tool to detect bugs, vulnerabilities and code smells in your code. It can integrate with your existing workflow to enable continuous code inspection across your project branches and pull requests.
-1 - Open the `.env` file +1 - Open the `.env` file
-2 - Search for the `SONARQUBE_HOSTNAME=sonar.example.com` argument +2 - Search for the `SONARQUBE_HOSTNAME=sonar.example.com` argument
-3 - Set it to your-domain `sonar.example.com` +3 - Set it to your-domain `sonar.example.com`
-4 - `docker-compose up -d sonarqube` +4 - `docker-compose up -d sonarqube`
5 - Open your browser: http://localhost:9000/ -Troubleshooting: +Troubleshooting: if you encounter a database error: ``` -docker-compose exec --user=root postgres +docker-compose exec --user=root postgres source docker-entrypoint-initdb.d/init_sonarqube_db.sh ``` If you encounter logs error: ``` -docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs +docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs ``` [**SonarQube Documentation Here**](https://docs.sonarqube.org/latest/) @@ -1267,6 +1267,36 @@ docker-compose up -d grafana +
+ +## Use Graylog + +1 - Boot the container `docker-compose up -d graylog` + +2 - Open your Laravel's `.env` file and set the `GRAYLOG_PASSWORD` to some passsword, and `GRAYLOG_SHA256_PASSWORD` to the sha256 representation of your password (`GRAYLOG_SHA256_PASSWORD` is what matters, `GRAYLOG_PASSWORD` is just a reminder of your password). + +> Your password must be at least 16 characters long +> You can generate sha256 of some password with the following command `echo -n somesupersecretpassword | sha256sum` + +```env +GRAYLOG_PASSWORD=somesupersecretpassword +GRAYLOG_SHA256_PASSWORD=b1cb6e31e172577918c9e7806c572b5ed8477d3f57aa737bee4b5b1db3696f09 +``` + +3 - Go to `http://localhost:9000/` (if your port is not changed) + +4 - Authenticate from the app. + +> Username: admin +> Password: somesupersecretpassword (if you haven't changed the password) + +5 - Go to the system->inputs and launch new input + + + + + +
## Use Traefik diff --git a/docker-compose.yml b/docker-compose.yml index 1a729e8..a136f74 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -821,6 +821,36 @@ services: networks: - backend +### Graylog ####################################### + graylog: + build: ./graylog + environment: + - GRAYLOG_PASSWORD_SECRET=${GRAYLOG_PASSWORD} + - GRAYLOG_ROOT_PASSWORD_SHA2=${GRAYLOG_SHA256_PASSWORD} + - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:${GRAYLOG_PORT}/ + links: + - mongo + - elasticsearch + depends_on: + - mongo + - elasticsearch + ports: + # Graylog web interface and REST API + - ${GRAYLOG_PORT}:9000 + # Syslog TCP + - ${GRAYLOG_SYSLOG_TCP_PORT}:514 + # Syslog UDP + - ${GRAYLOG_SYSLOG_UDP_PORT}:514/udp + # GELF TCP + - ${GRAYLOG_GELF_TCP_PORT}:12201 + # GELF UDP + - ${GRAYLOG_GELF_UDP_PORT}:12201/udp + user: root + volumes: + - ./graylog/config:/usr/share/graylog/data/config + networks: + - backend + ### Laravel Echo Server ####################################### laravel-echo-server: build: @@ -1461,7 +1491,7 @@ services: ports: - "${MANTICORE_API_PORT}:9312" - "${MANTICORE_SPHINXQL_PORT}:9306" - - "${MANTICORE_HTTP_PORT}:9308" + - "${MANTICORE_HTTP_PORT}:9308" networks: - backend diff --git a/env-example b/env-example index 6bc5a3f..8a75452 100644 --- a/env-example +++ b/env-example @@ -387,6 +387,18 @@ CONFLUENCE_HOST_HTTP_PORT=8090 GRAFANA_PORT=3000 +### GRAYLOG ############################################### + +# password must be 16 characters long +GRAYLOG_PASSWORD=somesupersecretpassword +# sha256 representation of the password +GRAYLOG_SHA256_PASSWORD=b1cb6e31e172577918c9e7806c572b5ed8477d3f57aa737bee4b5b1db3696f09 +GRAYLOG_PORT=9000 +GRAYLOG_SYSLOG_TCP_PORT=514 +GRAYLOG_SYSLOG_UDP_PORT=514 +GRAYLOG_GELF_TCP_PORT=12201 +GRAYLOG_GELF_UDP_PORT=12201 + ### BLACKFIRE ############################################# # Create an account on blackfire.io. Don't enable blackfire and xDebug at the same time. # visit https://blackfire.io/docs/24-days/06-installation#install-probe-debian for more info. @@ -704,12 +716,12 @@ PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org PGADMIN_DEFAULT_PASSWORD=admin ### SONARQUBE ################################################ -## docker-compose up -d sonarqube +## docker-compose up -d sonarqube ## (If you encounter a database error) -## docker-compose exec --user=root postgres +## docker-compose exec --user=root postgres ## source docker-entrypoint-initdb.d/init_sonarqube_db.sh ## (If you encounter logs error) -## docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs +## docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs SONARQUBE_HOSTNAME=sonar.example.com SONARQUBE_PORT=9000 diff --git a/graylog/Dockerfile b/graylog/Dockerfile new file mode 100644 index 0000000..c9b2209 --- /dev/null +++ b/graylog/Dockerfile @@ -0,0 +1,3 @@ +FROM graylog/graylog:3.0 + +EXPOSE 9000 diff --git a/graylog/config/graylog.conf b/graylog/config/graylog.conf new file mode 100644 index 0000000..ff8200b --- /dev/null +++ b/graylog/config/graylog.conf @@ -0,0 +1,481 @@ +############################ +# GRAYLOG CONFIGURATION FILE +############################ +# +# This is the Graylog configuration file. The file has to use ISO 8859-1/Latin-1 character encoding. +# Characters that cannot be directly represented in this encoding can be written using Unicode escapes +# as defined in https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.3, using the \u prefix. +# For example, \u002c. +# +# * Entries are generally expected to be a single line of the form, one of the following: +# +# propertyName=propertyValue +# propertyName:propertyValue +# +# * White space that appears between the property name and property value is ignored, +# so the following are equivalent: +# +# name=Stephen +# name = Stephen +# +# * White space at the beginning of the line is also ignored. +# +# * Lines that start with the comment characters ! or # are ignored. Blank lines are also ignored. +# +# * The property value is generally terminated by the end of the line. White space following the +# property value is not ignored, and is treated as part of the property value. +# +# * A property value can span several lines if each line is terminated by a backslash (‘\’) character. +# For example: +# +# targetCities=\ +# Detroit,\ +# Chicago,\ +# Los Angeles +# +# This is equivalent to targetCities=Detroit,Chicago,Los Angeles (white space at the beginning of lines is ignored). +# +# * The characters newline, carriage return, and tab can be inserted with characters \n, \r, and \t, respectively. +# +# * The backslash character must be escaped as a double backslash. For example: +# +# path=c:\\docs\\doc1 +# + +# If you are running more than one instances of Graylog server you have to select one of these +# instances as master. The master will perform some periodical tasks that non-masters won't perform. +is_master = true + +# The auto-generated node ID will be stored in this file and read after restarts. It is a good idea +# to use an absolute file path here if you are starting Graylog server from init scripts or similar. +node_id_file = /usr/share/graylog/data/config/node-id + +# You MUST set a secret to secure/pepper the stored user passwords here. Use at least 64 characters. +# Generate one by using for example: pwgen -N 1 -s 96 +password_secret = replacethiswithyourownsecret! + +# The default root user is named 'admin' +#root_username = admin + +# You MUST specify a hash password for the root user (which you only need to initially set up the +# system and in case you lose connectivity to your authentication backend) +# This password cannot be changed using the API or via the web interface. If you need to change it, +# modify it in this file. +# Create one by using for example: echo -n yourpassword | shasum -a 256 +# and put the resulting hash value into the following line + +# Default password: admin +# CHANGE THIS! +root_password_sha2 = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 + +# The email address of the root user. +# Default is empty +#root_email = "" + +# The time zone setting of the root user. See http://www.joda.org/joda-time/timezones.html for a list of valid time zones. +# Default is UTC +#root_timezone = UTC + +# Set plugin directory here (relative or absolute) +plugin_dir = /usr/share/graylog/plugin + +############### +# HTTP settings +############### + +#### HTTP bind address +# +# The network interface used by the Graylog HTTP interface. +# +# This network interface must be accessible by all Graylog nodes in the cluster and by all clients +# using the Graylog web interface. +# +# If the port is omitted, Graylog will use port 9000 by default. +# +# Default: 127.0.0.1:9000 +#http_bind_address = 127.0.0.1:9000 +#http_bind_address = [2001:db8::1]:9000 +http_bind_address = 0.0.0.0:9000 + +#### HTTP publish URI +# +# The HTTP URI of this Graylog node which is used to communicate with the other Graylog nodes in the cluster and by all +# clients using the Graylog web interface. +# +# The URI will be published in the cluster discovery APIs, so that other Graylog nodes will be able to find and connect to this Graylog node. +# +# This configuration setting has to be used if this Graylog node is available on another network interface than $http_bind_address, +# for example if the machine has multiple network interfaces or is behind a NAT gateway. +# +# If $http_bind_address contains a wildcard IPv4 address (0.0.0.0), the first non-loopback IPv4 address of this machine will be used. +# This configuration setting *must not* contain a wildcard address! +# +# Default: http://$http_bind_address/ +#http_publish_uri = http://192.168.1.1:9000/ + +#### External Graylog URI +# +# The public URI of Graylog which will be used by the Graylog web interface to communicate with the Graylog REST API. +# +# The external Graylog URI usually has to be specified, if Graylog is running behind a reverse proxy or load-balancer +# and it will be used to generate URLs addressing entities in the Graylog REST API (see $http_bind_address). +# +# When using Graylog Collector, this URI will be used to receive heartbeat messages and must be accessible for all collectors. +# +# This setting can be overriden on a per-request basis with the "X-Graylog-Server-URL" HTTP request header. +# +# Default: $http_publish_uri +#http_external_uri = + +#### Enable CORS headers for HTTP interface +# +# This is necessary for JS-clients accessing the server directly. +# If these are disabled, modern browsers will not be able to retrieve resources from the server. +# This is enabled by default. Uncomment the next line to disable it. +#http_enable_cors = false + +#### Enable GZIP support for HTTP interface +# +# This compresses API responses and therefore helps to reduce +# overall round trip times. This is enabled by default. Uncomment the next line to disable it. +#http_enable_gzip = false + +# The maximum size of the HTTP request headers in bytes. +#http_max_header_size = 8192 + +# The size of the thread pool used exclusively for serving the HTTP interface. +#http_thread_pool_size = 16 + +################ +# HTTPS settings +################ + +#### Enable HTTPS support for the HTTP interface +# +# This secures the communication with the HTTP interface with TLS to prevent request forgery and eavesdropping. +# +# Default: false +#http_enable_tls = true + +# The X.509 certificate chain file in PEM format to use for securing the HTTP interface. +#http_tls_cert_file = /path/to/graylog.crt + +# The PKCS#8 private key file in PEM format to use for securing the HTTP interface. +#http_tls_key_file = /path/to/graylog.key + +# The password to unlock the private key used for securing the HTTP interface. +#http_tls_key_password = secret + + +# Comma separated list of trusted proxies that are allowed to set the client address with X-Forwarded-For +# header. May be subnets, or hosts. +#trusted_proxies = 127.0.0.1/32, 0:0:0:0:0:0:0:1/128 + +# List of Elasticsearch hosts Graylog should connect to. +# Need to be specified as a comma-separated list of valid URIs for the http ports of your elasticsearch nodes. +# If one or more of your elasticsearch hosts require authentication, include the credentials in each node URI that +# requires authentication. +# +# Default: http://127.0.0.1:9200 +elasticsearch_hosts = http://elasticsearch:9200 + +# Maximum amount of time to wait for successfull connection to Elasticsearch HTTP port. +# +# Default: 10 Seconds +#elasticsearch_connect_timeout = 10s + +# Maximum amount of time to wait for reading back a response from an Elasticsearch server. +# +# Default: 60 seconds +#elasticsearch_socket_timeout = 60s + +# Maximum idle time for an Elasticsearch connection. If this is exceeded, this connection will +# be tore down. +# +# Default: inf +#elasticsearch_idle_timeout = -1s + +# Maximum number of total connections to Elasticsearch. +# +# Default: 20 +#elasticsearch_max_total_connections = 20 + +# Maximum number of total connections per Elasticsearch route (normally this means per +# elasticsearch server). +# +# Default: 2 +#elasticsearch_max_total_connections_per_route = 2 + +# Maximum number of times Graylog will retry failed requests to Elasticsearch. +# +# Default: 2 +#elasticsearch_max_retries = 2 + +# Enable automatic Elasticsearch node discovery through Nodes Info, +# see https://www.elastic.co/guide/en/elasticsearch/reference/5.4/cluster-nodes-info.html +# +# WARNING: Automatic node discovery does not work if Elasticsearch requires authentication, e. g. with Shield. +# +# Default: false +#elasticsearch_discovery_enabled = true + +# Filter for including/excluding Elasticsearch nodes in discovery according to their custom attributes, +# see https://www.elastic.co/guide/en/elasticsearch/reference/5.4/cluster.html#cluster-nodes +# +# Default: empty +#elasticsearch_discovery_filter = rack:42 + +# Frequency of the Elasticsearch node discovery. +# +# Default: 30s +# elasticsearch_discovery_frequency = 30s + +# Enable payload compression for Elasticsearch requests. +# +# Default: false +#elasticsearch_compression_enabled = true + +# Disable checking the version of Elasticsearch for being compatible with this Graylog release. +# WARNING: Using Graylog with unsupported and untested versions of Elasticsearch may lead to data loss! +#elasticsearch_disable_version_check = true + +# Disable message retention on this node, i. e. disable Elasticsearch index rotation. +#no_retention = false + +# Do you want to allow searches with leading wildcards? This can be extremely resource hungry and should only +# be enabled with care. See also: http://docs.graylog.org/en/2.1/pages/queries.html +allow_leading_wildcard_searches = false + +# Do you want to allow searches to be highlighted? Depending on the size of your messages this can be memory hungry and +# should only be enabled after making sure your Elasticsearch cluster has enough memory. +allow_highlighting = false + +# Global request timeout for Elasticsearch requests (e. g. during search, index creation, or index time-range +# calculations) based on a best-effort to restrict the runtime of Elasticsearch operations. +# Default: 1m +#elasticsearch_request_timeout = 1m + +# Global timeout for index optimization (force merge) requests. +# Default: 1h +#elasticsearch_index_optimization_timeout = 1h + +# Maximum number of concurrently running index optimization (force merge) jobs. +# If you are using lots of different index sets, you might want to increase that number. +# Default: 20 +#elasticsearch_index_optimization_jobs = 20 + +# Time interval for index range information cleanups. This setting defines how often stale index range information +# is being purged from the database. +# Default: 1h +#index_ranges_cleanup_interval = 1h + +# Batch size for the Elasticsearch output. This is the maximum (!) number of messages the Elasticsearch output +# module will get at once and write to Elasticsearch in a batch call. If the configured batch size has not been +# reached within output_flush_interval seconds, everything that is available will be flushed at once. Remember +# that every outputbuffer processor manages its own batch and performs its own batch write calls. +# ("outputbuffer_processors" variable) +output_batch_size = 500 + +# Flush interval (in seconds) for the Elasticsearch output. This is the maximum amount of time between two +# batches of messages written to Elasticsearch. It is only effective at all if your minimum number of messages +# for this time period is less than output_batch_size * outputbuffer_processors. +output_flush_interval = 1 + +# As stream outputs are loaded only on demand, an output which is failing to initialize will be tried over and +# over again. To prevent this, the following configuration options define after how many faults an output will +# not be tried again for an also configurable amount of seconds. +output_fault_count_threshold = 5 +output_fault_penalty_seconds = 30 + +# The number of parallel running processors. +# Raise this number if your buffers are filling up. +processbuffer_processors = 5 +outputbuffer_processors = 3 + +# The following settings (outputbuffer_processor_*) configure the thread pools backing each output buffer processor. +# See https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html for technical details + +# When the number of threads is greater than the core (see outputbuffer_processor_threads_core_pool_size), +# this is the maximum time in milliseconds that excess idle threads will wait for new tasks before terminating. +# Default: 5000 +#outputbuffer_processor_keep_alive_time = 5000 + +# The number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set +# Default: 3 +#outputbuffer_processor_threads_core_pool_size = 3 + +# The maximum number of threads to allow in the pool +# Default: 30 +#outputbuffer_processor_threads_max_pool_size = 30 + +# UDP receive buffer size for all message inputs (e. g. SyslogUDPInput). +#udp_recvbuffer_sizes = 1048576 + +# Wait strategy describing how buffer processors wait on a cursor sequence. (default: sleeping) +# Possible types: +# - yielding +# Compromise between performance and CPU usage. +# - sleeping +# Compromise between performance and CPU usage. Latency spikes can occur after quiet periods. +# - blocking +# High throughput, low latency, higher CPU usage. +# - busy_spinning +# Avoids syscalls which could introduce latency jitter. Best when threads can be bound to specific CPU cores. +processor_wait_strategy = blocking + +# Size of internal ring buffers. Raise this if raising outputbuffer_processors does not help anymore. +# For optimum performance your LogMessage objects in the ring buffer should fit in your CPU L3 cache. +# Must be a power of 2. (512, 1024, 2048, ...) +ring_size = 65536 + +inputbuffer_ring_size = 65536 +inputbuffer_processors = 2 +inputbuffer_wait_strategy = blocking + +# Enable the disk based message journal. +message_journal_enabled = true + +# The directory which will be used to store the message journal. The directory must me exclusively used by Graylog and +# must not contain any other files than the ones created by Graylog itself. +# +# ATTENTION: +# If you create a seperate partition for the journal files and use a file system creating directories like 'lost+found' +# in the root directory, you need to create a sub directory for your journal. +# Otherwise Graylog will log an error message that the journal is corrupt and Graylog will not start. +message_journal_dir = /usr/share/graylog/data/journal + +# Journal hold messages before they could be written to Elasticsearch. +# For a maximum of 12 hours or 5 GB whichever happens first. +# During normal operation the journal will be smaller. +#message_journal_max_age = 12h +#message_journal_max_size = 5gb + +#message_journal_flush_age = 1m +#message_journal_flush_interval = 1000000 +#message_journal_segment_age = 1h +#message_journal_segment_size = 100mb + +# Number of threads used exclusively for dispatching internal events. Default is 2. +#async_eventbus_processors = 2 + +# How many seconds to wait between marking node as DEAD for possible load balancers and starting the actual +# shutdown process. Set to 0 if you have no status checking load balancers in front. +lb_recognition_period_seconds = 3 + +# Journal usage percentage that triggers requesting throttling for this server node from load balancers. The feature is +# disabled if not set. +#lb_throttle_threshold_percentage = 95 + +# Every message is matched against the configured streams and it can happen that a stream contains rules which +# take an unusual amount of time to run, for example if its using regular expressions that perform excessive backtracking. +# This will impact the processing of the entire server. To keep such misbehaving stream rules from impacting other +# streams, Graylog limits the execution time for each stream. +# The default values are noted below, the timeout is in milliseconds. +# If the stream matching for one stream took longer than the timeout value, and this happened more than "max_faults" times +# that stream is disabled and a notification is shown in the web interface. +#stream_processing_timeout = 2000 +#stream_processing_max_faults = 3 + +# Length of the interval in seconds in which the alert conditions for all streams should be checked +# and alarms are being sent. +#alert_check_interval = 60 + +# Since 0.21 the Graylog server supports pluggable output modules. This means a single message can be written to multiple +# outputs. The next setting defines the timeout for a single output module, including the default output module where all +# messages end up. +# +# Time in milliseconds to wait for all message outputs to finish writing a single message. +#output_module_timeout = 10000 + +# Time in milliseconds after which a detected stale master node is being rechecked on startup. +#stale_master_timeout = 2000 + +# Time in milliseconds which Graylog is waiting for all threads to stop on shutdown. +#shutdown_timeout = 30000 + +# MongoDB connection string +# See https://docs.mongodb.com/manual/reference/connection-string/ for details +mongodb_uri = mongodb://mongo/graylog + +# Authenticate against the MongoDB server +#mongodb_uri = mongodb://grayloguser:secret@mongo:27017/graylog + +# Use a replica set instead of a single host +#mongodb_uri = mongodb://grayloguser:secret@mongo:27017,mongo:27018,mongo:27019/graylog + +# Increase this value according to the maximum connections your MongoDB server can handle from a single client +# if you encounter MongoDB connection problems. +mongodb_max_connections = 100 + +# Number of threads allowed to be blocked by MongoDB connections multiplier. Default: 5 +# If mongodb_max_connections is 100, and mongodb_threads_allowed_to_block_multiplier is 5, +# then 500 threads can block. More than that and an exception will be thrown. +# http://api.mongodb.com/java/current/com/mongodb/MongoOptions.html#threadsAllowedToBlockForConnectionMultiplier +mongodb_threads_allowed_to_block_multiplier = 5 + +# Drools Rule File (Use to rewrite incoming log messages) +# See: http://docs.graylog.org/en/2.1/pages/drools.html +#rules_file = /etc/graylog/server/rules.drl + +# Email transport +#transport_email_enabled = false +#transport_email_hostname = mail.example.com +#transport_email_port = 587 +#transport_email_use_auth = true +#transport_email_use_tls = true +#transport_email_use_ssl = true +#transport_email_auth_username = you@example.com +#transport_email_auth_password = secret +#transport_email_subject_prefix = [graylog] +#transport_email_from_email = graylog@example.com + +# Specify and uncomment this if you want to include links to the stream in your stream alert mails. +# This should define the fully qualified base url to your web interface exactly the same way as it is accessed by your users. +#transport_email_web_interface_url = https://graylog.example.com + +# The default connect timeout for outgoing HTTP connections. +# Values must be a positive duration (and between 1 and 2147483647 when converted to milliseconds). +# Default: 5s +#http_connect_timeout = 5s + +# The default read timeout for outgoing HTTP connections. +# Values must be a positive duration (and between 1 and 2147483647 when converted to milliseconds). +# Default: 10s +#http_read_timeout = 10s + +# The default write timeout for outgoing HTTP connections. +# Values must be a positive duration (and between 1 and 2147483647 when converted to milliseconds). +# Default: 10s +#http_write_timeout = 10s + +# HTTP proxy for outgoing HTTP connections +#http_proxy_uri = + +# The threshold of the garbage collection runs. If GC runs take longer than this threshold, a system notification +# will be generated to warn the administrator about possible problems with the system. Default is 1 second. +#gc_warning_threshold = 1s + +# Connection timeout for a configured LDAP server (e. g. ActiveDirectory) in milliseconds. +#ldap_connection_timeout = 2000 + +# Disable the use of SIGAR for collecting system stats +#disable_sigar = false + +# The default cache time for dashboard widgets. (Default: 10 seconds, minimum: 1 second) +#dashboard_widget_default_cache_time = 10s + +# Automatically load content packs in "content_packs_dir" on the first start of Graylog. +content_packs_loader_enabled = true + +# The directory which contains content packs which should be loaded on the first start of Graylog. +content_packs_dir = /usr/share/graylog/data/contentpacks + +# A comma-separated list of content packs (files in "content_packs_dir") which should be applied on +# the first start of Graylog. +# Default: empty +content_packs_auto_load = grok-patterns.json + +# For some cluster-related REST requests, the node must query all other nodes in the cluster. This is the maximum number +# of threads available for this. Increase it, if '/cluster/*' requests take long to complete. +# Should be http_thread_pool_size * average_cluster_size if you have a high number of concurrent users. +proxied_requests_thread_pool_size = 32 diff --git a/graylog/config/log4j2.xml b/graylog/config/log4j2.xml new file mode 100644 index 0000000..03d1d12 --- /dev/null +++ b/graylog/config/log4j2.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5d56cc83e64b4311854c22a024a4c7c652e95fda Mon Sep 17 00:00:00 2001 From: "Daniel F. J. Dantur" Date: Sat, 29 Jun 2019 01:34:49 -0300 Subject: [PATCH 158/589] Add LOG_STDOUT and LOG_SDERR required environment variables Fixes Apache crashes due permission errors related to log files docker.stdout and docker.stderr. Logs are now created in /var/log/apache2 as defined in docker-compose.yml apahce2 volumes. Logs are named access.log and error.log like the Apache default log names are. --- apache2/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apache2/Dockerfile b/apache2/Dockerfile index 71cad50..58cc12f 100644 --- a/apache2/Dockerfile +++ b/apache2/Dockerfile @@ -13,6 +13,10 @@ ENV WEB_DOCUMENT_ROOT=${DOCUMENT_ROOT} ENV WEB_PHP_TIMEOUT=${PHP_UPSTREAM_TIMEOUT} +ENV LOG_STDOUT=/var/log/apache2/access.log + +ENV LOG_STDERR=/var/log/apache2/error.log + EXPOSE 80 443 WORKDIR /var/www/ From e9eacfafa7d2fe23bf23ff2aaaeb6adcd63027bd Mon Sep 17 00:00:00 2001 From: skipworkgh Date: Tue, 2 Jul 2019 16:11:58 +0200 Subject: [PATCH 159/589] Added support for the mailparse php pecl extension --- docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 13 +++++++++++++ workspace/Dockerfile | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index a136f74..4babebc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -106,6 +106,7 @@ services: - INSTALL_MYSQL_CLIENT=${WORKSPACE_INSTALL_MYSQL_CLIENT} - INSTALL_PING=${WORKSPACE_INSTALL_PING} - INSTALL_SSHPASS=${WORKSPACE_INSTALL_SSHPASS} + - INSTALL_MAILPARSE=${WORKSPACE_INSTALL_MAILPARSE} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} @@ -183,6 +184,7 @@ services: - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - INSTALL_PING=${PHP_FPM_INSTALL_PING} - INSTALL_SSHPASS=${PHP_FPM_INSTALL_SSHPASS} + - INSTALL_MAILPARSE=${PHP_FPM_INSTALL_MAILPARSE} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} - http_proxy diff --git a/env-example b/env-example index 8a75452..2e38d39 100644 --- a/env-example +++ b/env-example @@ -137,6 +137,7 @@ WORKSPACE_INSTALL_PING=false WORKSPACE_INSTALL_SSHPASS=false WORKSPACE_INSTALL_INOTIFY=false WORKSPACE_INSTALL_FSWATCH=false +WORKSPACE_INSTALL_MAILPARSE=true WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 @@ -188,6 +189,7 @@ PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false PHP_FPM_INSTALL_MYSQL_CLIENT=false PHP_FPM_INSTALL_PING=false PHP_FPM_INSTALL_SSHPASS=false +PHP_FPM_INSTALL_MAILPARSE=true PHP_FPM_FFMPEG=false PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index ab6ba6b..bc7112a 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -725,6 +725,19 @@ RUN if [ ${INSTALL_FFMPEG} = true ]; then \ apt-get -y install ffmpeg \ ;fi +########################################################################### +# Mailparse extension: +########################################################################### + +ARG INSTALL_MAILPARSE=false + +RUN if [ ${INSTALL_MAILPARSE} = true ]; then \ + # Install mailparse extension + printf "\n" | pecl install -o -f mailparse \ + && rm -rf /tmp/pear \ + && docker-php-ext-enable mailparse \ +;fi + ########################################################################### # Check PHP version: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 3a07eee..32d2c24 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -1057,6 +1057,16 @@ RUN if [ ${INSTALL_FFMPEG} = true ]; then \ apt-get -y install ffmpeg \ ;fi +########################################################################### +# Mailparse extension: +########################################################################### + +ARG INSTALL_MAILPARSE=false + +RUN if [ ${INSTALL_MAILPARSE} = true ]; then \ + apt-get install -yqq php-mailparse \ +;fi + ########################################################################### # GNU Parallel: ########################################################################### From 9a0f9cfa74876b0bcda19561e270c63a360cd810 Mon Sep 17 00:00:00 2001 From: skipworkgh Date: Tue, 2 Jul 2019 16:36:08 +0200 Subject: [PATCH 160/589] Lets not enable them by default... --- env-example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/env-example b/env-example index 2e38d39..f0fa329 100644 --- a/env-example +++ b/env-example @@ -137,7 +137,7 @@ WORKSPACE_INSTALL_PING=false WORKSPACE_INSTALL_SSHPASS=false WORKSPACE_INSTALL_INOTIFY=false WORKSPACE_INSTALL_FSWATCH=false -WORKSPACE_INSTALL_MAILPARSE=true +WORKSPACE_INSTALL_MAILPARSE=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 @@ -189,7 +189,7 @@ PHP_FPM_INSTALL_ADDITIONAL_LOCALES=false PHP_FPM_INSTALL_MYSQL_CLIENT=false PHP_FPM_INSTALL_PING=false PHP_FPM_INSTALL_SSHPASS=false -PHP_FPM_INSTALL_MAILPARSE=true +PHP_FPM_INSTALL_MAILPARSE=false PHP_FPM_FFMPEG=false PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" From f73a66da131c374758ef706f2e89e2424a33f379 Mon Sep 17 00:00:00 2001 From: Rex Tsou Date: Thu, 4 Jul 2019 15:05:03 +0800 Subject: [PATCH 161/589] Fix php-fpm build fail (php5) pecl redis no longer support php5 --- php-fpm/Dockerfile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index ab6ba6b..fb306b3 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -197,9 +197,13 @@ ARG INSTALL_PHPREDIS=false RUN if [ ${INSTALL_PHPREDIS} = true ]; then \ # Install Php Redis Extension - printf "\n" | pecl install -o -f redis \ - && rm -rf /tmp/pear \ - && docker-php-ext-enable redis \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + pecl install -o -f redis-4.3.0; \ + else \ + pecl install -o -f redis; \ + fi \ + && rm -rf /tmp/pear \ + && docker-php-ext-enable redis \ ;fi ########################################################################### From f8ec06ac1cd32aee0f5083fe847b6b510c04fa02 Mon Sep 17 00:00:00 2001 From: anribras Date: Sat, 6 Jul 2019 17:41:11 +0800 Subject: [PATCH 162/589] Add mariadb timezone setting via WORKSPACE_TIMEZONE in .env --- docker-compose.yml | 1 + mariadb/Dockerfile | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index a136f74..49a4c3a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -407,6 +407,7 @@ services: ports: - "${MARIADB_PORT}:3306" environment: + - TZ=${WORKSPACE_TIMEZONE} - MYSQL_DATABASE=${MARIADB_DATABASE} - MYSQL_USER=${MARIADB_USER} - MYSQL_PASSWORD=${MARIADB_PASSWORD} diff --git a/mariadb/Dockerfile b/mariadb/Dockerfile index 0dcb948..7538b4e 100644 --- a/mariadb/Dockerfile +++ b/mariadb/Dockerfile @@ -2,6 +2,13 @@ FROM mariadb:latest LABEL maintainer="Mahmoud Zalt " +##################################### +# Set Timezone +##################################### + +ARG TZ=UTC +ENV TZ ${TZ} +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && chown -R mysql:root /var/lib/mysql/ COPY my.cnf /etc/mysql/conf.d/my.cnf CMD ["mysqld"] From cd80ca59df6589b88bb3e00b205ee23c3b82f835 Mon Sep 17 00:00:00 2001 From: Caesar Chi Date: Mon, 8 Jul 2019 23:36:07 +0800 Subject: [PATCH 163/589] gcloud registry auth step for docker build nowaday, the docker image build from gcloud registry, so you need auth the configure and login the gcloud first to build the docker image. --- DOCUMENTATION/content/getting-started/index.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index 8262ead..be9dba4 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -8,6 +8,7 @@ weight: 2 - [Git](https://git-scm.com/downloads) - [Docker](https://www.docker.com/products/docker/) `>= 17.12` +- [gcloud](https://cloud.google.com/sdk/install) @@ -24,6 +25,17 @@ Choose the setup the best suits your needs. - [A.2) Don't have a PHP project yet](#A2) - [B) Setup for Multiple Projects](#B) +### Setup gcloud for docker registry + +``` +gcloud auth configure-docker +``` + +and login to gcloud for use the registry and auth the permission. + +``` +gcloud auth login +``` ### A) Setup for Single Project From cd8dc6cc2226380a1da8b90ab389abdbb36b5b94 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 9 Jul 2019 21:50:05 +0200 Subject: [PATCH 164/589] fix the main image and update sponsors section --- .github/README.md | 13 +++--- DOCUMENTATION/content/introduction/index.md | 48 +++++++++------------ 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/.github/README.md b/.github/README.md index 834b878..6a6148e 100644 --- a/.github/README.md +++ b/.github/README.md @@ -24,16 +24,12 @@

- Laradock Docs + Laradock Docs

-## Sponsors - -Support this project by becoming a sponsor. - -Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. [[Become a sponsor](https://opencollective.com/laradock#sponsor)] +## Sponsors @@ -43,9 +39,10 @@ Your logo will show up on the [github repository](https://github.com/laradock/la - - +For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. + +Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. ## Contributors diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 82c5b31..1fdd83e 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -9,12 +9,29 @@ weight: 1 A full PHP development environment for Docker. -Includes pre-packaged Docker Images, all pre-configured to provide a wonderful PHP development environment. - -Laradock is well known in the Laravel community, as the project started with single focus on running Laravel projects on Docker. Later and due to the large adoption from the PHP community, it started supporting other PHP projects like Symfony, CodeIgniter, WordPress, Drupal... +Includes a lot of useful Docker Images, all pre-configured to provide a wonderful PHP development environment. -![](https://s19.postimg.org/jblfytw9f/laradock-logo.jpg) +![](https://raw.githubusercontent.com/laradock/laradock/master/.github/home-page-images/laradock-logo.jpg) + + + + + +## Sponsors + + + + + + + + + + +For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. +
+Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. ## Quick Overview @@ -116,29 +133,6 @@ If you can't find your Software in the list, build it yourself and submit it. Co -## Sponsors - - - - - -Support this project by becoming a sponsor. - -Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. [[Become a sponsor](https://opencollective.com/laradock#sponsor)] - - - - - - - - - - - - - - ## What is Docker? From 9df9a90b12bd96d887088d811f1a5fd13865c9b7 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 9 Jul 2019 21:50:31 +0200 Subject: [PATCH 165/589] add txt file for google ads --- DOCUMENTATION/static/ads.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 DOCUMENTATION/static/ads.txt diff --git a/DOCUMENTATION/static/ads.txt b/DOCUMENTATION/static/ads.txt new file mode 100644 index 0000000..2230196 --- /dev/null +++ b/DOCUMENTATION/static/ads.txt @@ -0,0 +1 @@ +google.com, pub-9826129398689742, DIRECT, f08c47fec0942fa0 From 6003de2754167dc19f85a746a1fdc8eb1cc68db3 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 9 Jul 2019 21:57:10 +0200 Subject: [PATCH 166/589] update documentation button design --- .github/README.md | 2 +- .../home-page-images/documentation-button.png | Bin 0 -> 24622 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .github/home-page-images/documentation-button.png diff --git a/.github/README.md b/.github/README.md index 6a6148e..7614dd3 100644 --- a/.github/README.md +++ b/.github/README.md @@ -24,7 +24,7 @@

- Laradock Docs + Laradock Docs

diff --git a/.github/home-page-images/documentation-button.png b/.github/home-page-images/documentation-button.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab17161925d30691efbe141f077d7be113ce6fe GIT binary patch literal 24622 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 literal 0 HcmV?d00001 From 8ae02d5d96ce7e7f6984c550a75496671ded7881 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 9 Jul 2019 21:58:23 +0200 Subject: [PATCH 167/589] fix button extension --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 7614dd3..dc37653 100644 --- a/.github/README.md +++ b/.github/README.md @@ -24,7 +24,7 @@

- Laradock Docs + Laradock Docs

From 60afd8feb3cfabbf84c7e4d4982a38c9c32574e0 Mon Sep 17 00:00:00 2001 From: Mahdi Hazaveh Date: Fri, 12 Jul 2019 09:57:17 +0800 Subject: [PATCH 168/589] run apt-get update before attempting to install php-redis on workspace container Fixes E: Failed to fetch http://ppa.launchpad.net/ondrej/php/ubuntu/pool/main/p/php-redis/php-redis_4.2.0-1+ubuntu16.04.1+deb.sury.org+1_amd64.deb 404 Not Found --- workspace/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 3a07eee..6cb8bde 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -414,6 +414,7 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ ARG INSTALL_PHPREDIS=false RUN if [ ${INSTALL_PHPREDIS} = true ]; then \ + apt-get update -yqq && \ apt-get install -yqq php-redis \ ;fi From 6eaf587803a8eb2957fc67ff68dafbab1cd387ad Mon Sep 17 00:00:00 2001 From: anribras Date: Sun, 14 Jul 2019 11:41:12 +0800 Subject: [PATCH 169/589] Add mariadb timezone setting via WORKSPACE_TIMEZONE in .env (#2197) --- docker-compose.yml | 1 + mariadb/Dockerfile | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index a136f74..49a4c3a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -407,6 +407,7 @@ services: ports: - "${MARIADB_PORT}:3306" environment: + - TZ=${WORKSPACE_TIMEZONE} - MYSQL_DATABASE=${MARIADB_DATABASE} - MYSQL_USER=${MARIADB_USER} - MYSQL_PASSWORD=${MARIADB_PASSWORD} diff --git a/mariadb/Dockerfile b/mariadb/Dockerfile index 0dcb948..7538b4e 100644 --- a/mariadb/Dockerfile +++ b/mariadb/Dockerfile @@ -2,6 +2,13 @@ FROM mariadb:latest LABEL maintainer="Mahmoud Zalt " +##################################### +# Set Timezone +##################################### + +ARG TZ=UTC +ENV TZ ${TZ} +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && chown -R mysql:root /var/lib/mysql/ COPY my.cnf /etc/mysql/conf.d/my.cnf CMD ["mysqld"] From ce00c5ea278df5b29781d3c29e6e8cdfaddc945b Mon Sep 17 00:00:00 2001 From: airguillaume Date: Sun, 14 Jul 2019 05:44:21 +0200 Subject: [PATCH 170/589] Update to Elasticsearch 7.1.1 (#2179) * Update Elasticsearch to 7.1.1 * Removed unnecessary quotes --- docker-compose.yml | 4 +++- elasticsearch/Dockerfile | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 49a4c3a..09d7ffb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -662,8 +662,10 @@ services: - elasticsearch:/usr/share/elasticsearch/data environment: - cluster.name=laradock-cluster + - node.name=laradock-node - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - cluster.initial_master_nodes=laradock-node ulimits: memlock: soft: -1 @@ -1531,4 +1533,4 @@ services: depends_on: - postgres volumes: - - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data \ No newline at end of file + - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data diff --git a/elasticsearch/Dockerfile b/elasticsearch/Dockerfile index d3ff4f4..dcc2874 100644 --- a/elasticsearch/Dockerfile +++ b/elasticsearch/Dockerfile @@ -1,3 +1,3 @@ -FROM docker.elastic.co/elasticsearch/elasticsearch:6.6.0 +FROM docker.elastic.co/elasticsearch/elasticsearch:7.1.1 EXPOSE 9200 9300 From 01eb934863ccf6b9b566470ebcbe0a53c4db2b15 Mon Sep 17 00:00:00 2001 From: Meng Ye <4025839+jk2K@users.noreply.github.com> Date: Sun, 14 Jul 2019 11:44:52 +0800 Subject: [PATCH 171/589] fix: exec: zookeeper: not found (#2199) refer to [Zookeeper latest 3.5.5 Dockerfile](https://github.com/31z4/zookeeper-docker/blob/c978f835bc33509324b51cb210c8c5c9934c38ff/3.5.5/Dockerfile) --- zookeeper/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zookeeper/Dockerfile b/zookeeper/Dockerfile index 8d5723d..3fc8abd 100644 --- a/zookeeper/Dockerfile +++ b/zookeeper/Dockerfile @@ -7,4 +7,4 @@ VOLUME /datalog EXPOSE 2181 -CMD ["zookeeper"] +CMD ["zkServer.sh", "start-foreground"] From 4e257c8e8f810f9688c5dfbae7a6dc0b0e730696 Mon Sep 17 00:00:00 2001 From: zslavis <50221726+zslavis@users.noreply.github.com> Date: Sat, 13 Jul 2019 20:46:21 -0700 Subject: [PATCH 172/589] Update to include MARIADB_VERSION in env file which sets the mariadb version (#2185) --- docker-compose.yml | 1 + env-example | 1 + mariadb/Dockerfile | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 09d7ffb..7edfa77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -401,6 +401,7 @@ services: - http_proxy - https_proxy - no_proxy + - MARIADB_VERSION=${MARIADB_VERSION} volumes: - ${DATA_PATH_HOST}/mariadb:/var/lib/mysql - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d diff --git a/env-example b/env-example index 8a75452..a7bf59b 100644 --- a/env-example +++ b/env-example @@ -269,6 +269,7 @@ MSSQL_PORT=1433 ### MARIADB ############################################### +MARIADB_VERSION=latest MARIADB_DATABASE=default MARIADB_USER=default MARIADB_PASSWORD=secret diff --git a/mariadb/Dockerfile b/mariadb/Dockerfile index 7538b4e..1d04826 100644 --- a/mariadb/Dockerfile +++ b/mariadb/Dockerfile @@ -1,4 +1,5 @@ -FROM mariadb:latest +ARG MARIADB_VERSION=latest +FROM mariadb:${MARIADB_VERSION} LABEL maintainer="Mahmoud Zalt " From 4814490e2ad80e4bfcab1bd5bd9218072bf319ce Mon Sep 17 00:00:00 2001 From: Mahmoudz Date: Mon, 15 Jul 2019 18:59:43 +0200 Subject: [PATCH 173/589] enhance documentation readability --- .github/README.md | 14 +- DOCUMENTATION/config.toml | 16 +- DOCUMENTATION/content/contributing/index.md | 2 +- DOCUMENTATION/content/documentation/index.md | 162 +--- .../content/getting-started/index.md | 18 +- DOCUMENTATION/content/guides/index.md | 729 +++++++++--------- DOCUMENTATION/content/help/index.md | 120 ++- DOCUMENTATION/content/introduction/index.md | 133 +++- DOCUMENTATION/content/license/index.md | 2 +- .../content/related-projects/index.md | 2 +- 10 files changed, 609 insertions(+), 589 deletions(-) diff --git a/.github/README.md b/.github/README.md index dc37653..29b2cca 100644 --- a/.github/README.md +++ b/.github/README.md @@ -42,7 +42,7 @@ For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. -Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. +*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website.* ## Contributors @@ -71,18 +71,18 @@ Your logo will show up on the [github repository](https://github.com/laradock/la > Help keeping the project development going, by [contributing](http://laradock.io/contributing) or donating a little. > Thanks in advance. -Donate directly via [Paypal](https://www.paypal.me/mzalt) +Donate directly via [Paypal](https://paypal.me/mzmmzz) -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/mzalt) - -or become a backer on [Open Collective](https://opencollective.com/laradock#backer) - - +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) or show your support via [Beerpay](https://beerpay.io/laradock/laradock) [![Beerpay](https://beerpay.io/laradock/laradock/badge.svg?style=flat)](https://beerpay.io/laradock/laradock) +or become a backer on [Open Collective](https://opencollective.com/laradock#backer) + + + ## License diff --git a/DOCUMENTATION/config.toml b/DOCUMENTATION/config.toml index 91fd072..8fd6062 100644 --- a/DOCUMENTATION/config.toml +++ b/DOCUMENTATION/config.toml @@ -48,42 +48,42 @@ googleAnalytics = "UA-37514928-9" # ------- MENU START ----------------------------------------- [[menu.main]] - name = "Introduction" + name = "1. Introduction" url = "introduction/" weight = 1 [[menu.main]] - name = "Getting Started" + name = "2. Getting Started" url = "getting-started/" weight = 2 [[menu.main]] - name = "Documentation" + name = "3. Documentation" url = "documentation/" weight = 3 [[menu.main]] - name = "Guides" + name = "4. Guides" url = "guides/" weight = 4 [[menu.main]] - name = "Help & Questions" + name = "5. Help & Questions" url = "help/" weight = 5 [[menu.main]] - name = "Related Projects" + name = "6. Related Projects" url = "related-projects/" weight = 6 [[menu.main]] - name = "Contributing" + name = "7. Contributing" url = "contributing/" weight = 7 [[menu.main]] - name = "License" + name = "8. License" url = "license/" weight = 8 diff --git a/DOCUMENTATION/content/contributing/index.md b/DOCUMENTATION/content/contributing/index.md index 24ab633..1d58dcf 100644 --- a/DOCUMENTATION/content/contributing/index.md +++ b/DOCUMENTATION/content/contributing/index.md @@ -1,5 +1,5 @@ --- -title: Contributing +title: 7. Contributing type: index weight: 7 --- diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 9169370..2560a8e 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1,5 +1,5 @@ --- -title: Documentation +title: 3. Documentation type: index weight: 3 --- @@ -320,21 +320,6 @@ PHP_FPM_INSTALL_PHPDBG=true ``` - -## Setup remote debugging for PhpStorm on Linux - - - Make sure you have followed the steps above in the [Install Xdebug section](#install-xdebug). - - - Make sure Xdebug accepts connections and listens on port 9000. (Should be default configuration). - -![Debug Configuration](/images/photos/PHPStorm/linux/configuration/debugConfiguration.png "Debug Configuration"). - - - Create a server with name `laradock` (matches **PHP_IDE_CONFIG** key in environment file) and make sure to map project root path with server correctly. - -![Server Configuration](/images/photos/PHPStorm/linux/configuration/serverConfiguration.png "Server Configuration"). - - - Start listening for debug connections, place a breakpoint and you are good to go ! -
@@ -2029,22 +2014,6 @@ Remote debug Laravel web and phpunit tests. -
- -## Upgrading Laradock - -Moving from Docker Toolbox (VirtualBox) to Docker Native (for Mac/Windows). Requires upgrading Laradock from v3.* to v4.*: - -1. Stop the docker VM `docker-machine stop {default}` -2. Install Docker for [Mac](https://docs.docker.com/docker-for-mac/) or [Windows](https://docs.docker.com/docker-for-windows/). -3. Upgrade Laradock to `v4.*.*` (`git pull origin master`) -4. Use Laradock as you used to do: `docker-compose up -d nginx mysql`. - -**Note:** If you face any problem with the last step above: rebuild all your containers -`docker-compose build --no-cache` -"Warning Containers Data might be lost!" - - @@ -2212,126 +2181,17 @@ docker-compose up ... - - -
- -## Common Problems + +## Upgrade Laradock -*Here's a list of the common problems you might face, and the possible solutions.* +Moving from Docker Toolbox (VirtualBox) to Docker Native (for Mac/Windows). Requires upgrading Laradock from v3.* to v4.*: +1. Stop the docker VM `docker-machine stop {default}` +2. Install Docker for [Mac](https://docs.docker.com/docker-for-mac/) or [Windows](https://docs.docker.com/docker-for-windows/). +3. Upgrade Laradock to `v4.*.*` (`git pull origin master`) +4. Use Laradock as you used to do: `docker-compose up -d nginx mysql`. - - - - -
-## I see a blank (white) page instead of the Laravel 'Welcome' page! - -Run the following command from the Laravel root directory: - -```bash -sudo chmod -R 777 storage bootstrap/cache -``` - - - - - - -
-## I see "Welcome to nginx" instead of the Laravel App! - -Use `http://127.0.0.1` instead of `http://localhost` in your browser. - - - - - - -
-## I see an error message containing `address already in use` or `port is already allocated` - -Make sure the ports for the services that you are trying to run (22, 80, 443, 3306, etc.) are not being used already by other programs on the host, such as a built in `apache`/`httpd` service or other development tools you have installed. - - - - - - -
-## I get NGINX error 404 Not Found on Windows. - -1. Go to docker Settings on your Windows machine. -2. Click on the `Shared Drives` tab and check the drive that contains your project files. -3. Enter your windows username and password. -4. Go to the `reset` tab and click restart docker. - - - - - - -
-## The time in my services does not match the current time - -1. Make sure you've [changed the timezone](#Change-the-timezone). -2. Stop and rebuild the containers (`docker-compose up -d --build `) - - - - - - -
-## I get MySQL connection refused - -This error sometimes happens because your Laravel application isn't running on the container localhost IP (Which is 127.0.0.1). Steps to fix it: - -* Option A - 1. Check your running Laravel application IP by dumping `Request::ip()` variable using `dd(Request::ip())` anywhere on your application. The result is the IP of your Laravel container. - 2. Change the `DB_HOST` variable on env with the IP that you received from previous step. -* Option B - 1. Change the `DB_HOST` value to the same name as the MySQL docker container. The Laradock docker-compose file currently has this as `mysql` - -## I get stuck when building nginx on `fetch http://mirrors.aliyun.com/alpine/v3.5/main/x86_64/APKINDEX.tar.gz` - -As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-419652646), Already fixed,just set `CHANGE_SOURCE` to false. - -## Custom composer repo packagist url and npm registry url - -In China, the origin source of composer and npm is very slow. You can add `WORKSPACE_NPM_REGISTRY` and `WORKSPACE_COMPOSER_REPO_PACKAGIST` config in `.env` to use your custom source. - -Example: -```bash -WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org -WORKSPACE_COMPOSER_REPO_PACKAGIST=https://packagist.phpcomposer.com -``` - -
- -## I get `Module build failed: Error: write EPIPE` while compiling react application - -When you run `npm build` or `yarn dev` building a react application using webpack with elixir you may receive a `Error: write EPIPE` while processing .jpg images. - -This is caused of an outdated library for processing **.jpg files** in ubuntu 16.04. - -To fix the problem you can follow those steps - -1 - Open the `.env`. - -2 - Search for `WORKSPACE_INSTALL_LIBPNG` or add the key if missing. - -3 - Set the value to true: - -```dotenv -WORKSPACE_INSTALL_LIBPNG=true -``` - -4 - Finally rebuild the workspace image - -```bash -docker-compose build workspace -``` - +**Note:** If you face any problem with the last step above: rebuild all your containers +`docker-compose build --no-cache` +"Warning Containers Data might be lost!" diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index 8262ead..d4f6d54 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -1,10 +1,10 @@ --- -title: Getting Started +title: 2. Getting Started type: index weight: 2 --- -## Requirements +## 2.1 Requirements - [Git](https://git-scm.com/downloads) - [Docker](https://www.docker.com/products/docker/) `>= 17.12` @@ -12,10 +12,7 @@ weight: 2 - - - -## Installation +## 2.2 Installation Choose the setup the best suits your needs. @@ -110,9 +107,11 @@ Your folder structure should look like this: + project-2 ``` -2 - Go to `nginx/sites` and create config files to point to different project directory when visiting different domains. +2 - Go to your web server and create config files to point to different project directory when visiting different domains: -Laradock by default includes `app.conf.example`, `laravel.conf.example` and `symfony.conf.example` as working samples. +For **Nginx** go to `nginx/sites`, for **Apache2** `apache2/sites`. + +Laradock by default includes some sample files for you to copy `app.conf.example`, `laravel.conf.example` and `symfony.conf.example`. 3 - change the default names `*.conf`: @@ -125,6 +124,7 @@ You can rename the config files, project folders and domains as you like, just m 127.0.0.1 project-2.test ... ``` + If you use Chrome 63 or above for development, don't use `.dev`. [Why?](https://laravel-news.com/chrome-63-now-forces-dev-domains-https). Instead use `.localhost`, `.invalid`, `.test`, or `.example`. > **Now jump to the [Usage](#Usage) section.** @@ -136,7 +136,7 @@ If you use Chrome 63 or above for development, don't use `.dev`. [Why?](https:// -## Usage +## 2.3 Usage **Read Before starting:** diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index 388edf4..451c002 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -1,21 +1,14 @@ --- -title: Guides +title: 4. Guides type: index weight: 4 --- - -* [Production Setup on Digital Ocean](#Digital-Ocean) -* [PHPStorm XDebug Setup](#PHPStorm-Debugging) -* [Running Laravel Dusk Test](#Laravel-Dusk) - - - -# Production Setup on Digital Ocean +## Production Setup on Digital Ocean -## Install Docker +### Install Docker - Visit [DigitalOcean](https://cloud.digitalocean.com/login) and login. - Click the `Create Droplet` button. @@ -24,7 +17,7 @@ weight: 4 - Continue creating the droplet as you normally would. - If needed, check your e-mail for the droplet root password. -## SSH to your Server +### SSH to your Server Find the IP address of the droplet in the DigitalOcean interface. Use it to connect to the server. @@ -40,7 +33,7 @@ You can now check if Docker is available: $root@server:~# docker ``` -## Set Up Your Laravel Project +### Set Up Your Laravel Project ``` $root@server:~# apt-get install git @@ -50,12 +43,12 @@ $root@server:~/laravel/ git submodule add https://github.com/Laradock/laradock.g $root@server:~/laravel/ cd laradock ``` -## Enter the laradock folder and rename env-example to .env. +### Enter the laradock folder and rename env-example to .env. ``` $root@server:~/laravel/laradock# cp env-example .env ``` -## Create Your Laradock Containers +### Create Your Laradock Containers ``` $root@server:~/laravel/laradock# docker-compose up -d nginx mysql @@ -63,13 +56,13 @@ $root@server:~/laravel/laradock# docker-compose up -d nginx mysql Note that more containers are available, find them in the [docs](http://laradock.io/introduction/#supported-software-containers) or the `docker-compose.yml` file. -## Go to Your Workspace +### Go to Your Workspace ``` docker-compose exec workspace bash ``` -## Execute commands +### Execute commands If you want to only execute some command and don't want to enter bash, you can execute `docker-compose run workspace `. @@ -77,7 +70,7 @@ If you want to only execute some command and don't want to enter bash, you can e docker-compose run workspace php artisan migrate ``` -## Install and configure Laravel +### Install and configure Laravel Let's install Laravel's dependencies, add the `.env` file, generate the key and give proper permissions to the cache folder. @@ -100,7 +93,7 @@ It should show you the Laravel default welcome page. However, we want it to show up using your custom domain name, as well. -## Using Your Own Domain Name +### Using Your Own Domain Name Login to your DNS provider, such as Godaddy, Namecheap. @@ -118,7 +111,7 @@ Visit: https://cloud.digitalocean.com/networking/domains Add your domain name and choose the server IP you'd provision earlier. -## Serving Site With NGINX (HTTP ONLY) +### Serving Site With NGINX (HTTP ONLY) Go back to command line. @@ -142,14 +135,14 @@ And add `server_name` (your custom domain) server_name yourdomain.com; ``` -## Rebuild Your Nginx +### Rebuild Your Nginx ``` $root@server:~/laravel/laradock# docker-compose down $root@server:~/laravel/laradock# docker-compose build nginx ``` -## Re Run Your Containers MYSQL and NGINX +### Re Run Your Containers MYSQL and NGINX ``` $root@server:~/laravel/laradock/nginx# docker-compose up -d nginx mysql @@ -157,7 +150,7 @@ $root@server:~/laravel/laradock/nginx# docker-compose up -d nginx mysql **View Your Site with HTTP ONLY (http://yourdomain.com)** -## Run Site on SSL with Let's Encrypt Certificate +### Run Site on SSL with Let's Encrypt Certificate **Note: You need to Use Caddy here Instead of Nginx** @@ -196,7 +189,7 @@ tls serverbreaker@gmai.com This is needed Prior to Creating Let's Encypt -## Run Your Caddy Container without the -d flag and Generate SSL with Let's Encrypt +### Run Your Caddy Container without the -d flag and Generate SSL with Let's Encrypt ``` $root@server:~/laravel/laradock# docker-compose up caddy @@ -217,7 +210,7 @@ caddy_1 | http://yourdomain.com After it finishes, press `Ctrl` + `C` to exit. -## Stop All Containers and ReRun Caddy and Other Containers on Background +### Stop All Containers and ReRun Caddy and Other Containers on Background ``` $root@server:~/laravel/laradock# docker-compose down @@ -238,326 +231,6 @@ View your Site in the Browser Securely Using HTTPS (https://yourdomain.com) - [https://caddyserver.com/docs/tls](https://caddyserver.com/docs/tls) - [https://caddyserver.com/docs/caddyfile](https://caddyserver.com/docs/caddyfile) - - - - -
-
-
-
-
- - -# PHPStorm XDebug Setup - -- [Intro](#Intro) -- [Installation](#Installation) - - [Customize laradock/docker-compose.yml](#CustomizeDockerCompose) - - [Clean House](#InstallCleanHouse) - - [Laradock Dial Tone](#InstallLaradockDialTone) - - [hosts](#AddToHosts) - - [Firewall](#FireWall) - - [Enable xDebug on php-fpm](#enablePhpXdebug) - - [PHPStorm Settings](#InstallPHPStorm) - - [Configs](#InstallPHPStormConfigs) -- [Usage](#Usage) - - [Laravel](#UsageLaravel) - - [Run ExampleTest](#UsagePHPStormRunExampleTest) - - [Debug ExampleTest](#UsagePHPStormDebugExampleTest) - - [Debug Web Site](#UsagePHPStormDebugSite) -- [SSH into workspace](#SSHintoWorkspace) - - [KiTTY](#InstallKiTTY) - - -## Intro - -Wiring up [Laravel](https://laravel.com/), [Laradock](https://github.com/Laradock/laradock) [Laravel+Docker] and [PHPStorm](https://www.jetbrains.com/phpstorm/) to play nice together complete with remote xdebug'ing as icing on top! Although this guide is based on `PHPStorm Windows`, -you should be able to adjust accordingly. This guide was written based on Docker for Windows Native. - - -## Installation - -- This guide assumes the following: - - you have already installed and are familiar with Laravel, Laradock and PHPStorm. - - you have installed Laravel as a parent of `laradock`. This guide assumes `/c/_dk/laravel`. - - -## hosts -- Add `laravel` to your hosts file located on Windows 10 at `C:\Windows\System32\drivers\etc\hosts`. It should be set to the IP of your running container. Mine is: `10.0.75.2` -On Windows you can find it by opening Windows `Hyper-V Manager`. - - ![Windows Hyper-V Manager](images/photos/PHPStorm/Settings/WindowsHyperVManager.png) - -- [Hosts File Editor](https://github.com/scottlerch/HostsFileEditor) makes it easy to change your hosts file. - - Set `laravel` to your docker host IP. See [Example](images/photos/SimpleHostsEditor/AddHost_laravel.png). - - - -## Firewall -Your PHPStorm will need to be able to receive a connection from PHP xdebug either your running workspace or php-fpm containers on port 9000. This means that your Windows Firewall should either enable connections from the Application PHPStorm OR the port. - -- It is important to note that if the Application PHPStorm is NOT enabled in the firewall, you will not be able to recreate a rule to override that. -- Also be aware that if you are installing/upgrade different versions of PHPStorm, you MAY have orphaned references to PHPStorm in your Firewall! You may decide to remove orphaned references however in either case, make sure that they are set to receive public TCP traffic. - -### Edit laradock/docker-compose.yml -Set the following variables: -``` -### Workspace Utilities Container ############### - - workspace: - build: - context: ./workspace - args: - - INSTALL_XDEBUG=true - - INSTALL_WORKSPACE_SSH=true - ... - - -### PHP-FPM Container ##################### - - php-fpm: - build: - context: ./php-fpm - args: - - INSTALL_XDEBUG=true - ... - -``` - -### Edit xdebug.ini files -- `laradock/workspace/xdebug.ini` -- `laradock/php-fpm/xdebug.ini` - -Set the following variables: - -``` -xdebug.remote_autostart=1 -xdebug.remote_enable=1 -xdebug.remote_connect_back=1 -xdebug.cli_color=1 -``` - - - -### Need to clean house first? - -Make sure you are starting with a clean state. For example, do you have other Laradock containers and images? -Here are a few things I use to clean things up. - -- Delete all containers using `grep laradock_` on the names, see: [Remove all containers based on docker image name](https://linuxconfig.org/remove-all-containners-based-on-docker-image-name). - -`docker ps -a | awk '{ print $1,$2 }' | grep laradock_ | awk '{print $1}' | xargs -I {} docker rm {}` - -- Delete all images containing `laradock`. - -`docker images | awk '{print $1,$2,$3}' | grep laradock_ | awk '{print $3}' | xargs -I {} docker rmi {}` -**Note:** This will only delete images that were built with `Laradock`, **NOT** `laradock/*` which are pulled down by `Laradock` such as `laradock/workspace`, etc. -**Note:** Some may fail with: -`Error response from daemon: conflict: unable to delete 3f38eaed93df (cannot be forced) - image has dependent child images` - -- I added this to my `.bashrc` to remove orphaned images. - -``` -dclean() { - processes=`docker ps -q -f status=exited` - if [ -n "$processes" ]; then - docker rm $processes - fi - - images=`docker images -q -f dangling=true` - if [ -n "$images" ]; then - docker rmi $images - fi -} -``` - -- If you frequently switch configurations for Laradock, you may find that adding the following and added to your `.bashrc` or equivalent useful: - -``` -# remove laravel* containers -# remove laravel_* images -dcleanlaradockfunction() -{ - echo 'Removing ALL containers associated with laradock' - docker ps -a | awk '{ print $1,$2 }' | grep laradock | awk '{print $1}' | xargs -I {} docker rm {} - - # remove ALL images associated with laradock_ - # does NOT delete laradock/* which are hub images - echo 'Removing ALL images associated with laradock_' - docker images | awk '{print $1,$2,$3}' | grep laradock_ | awk '{print $3}' | xargs -I {} docker rmi {} - - echo 'Listing all laradock docker hub images...' - docker images | grep laradock - - echo 'dcleanlaradock completed' -} -# associate the above function with an alias -# so can recall/lookup by typing 'alias' -alias dcleanlaradock=dcleanlaradockfunction -``` - - -## Let's get a dial-tone with Laravel - -``` -# barebones at this point -docker-compose up -d nginx mysql - -# run -docker-compose ps - -# Should see: - Name Command State Ports ------------------------------------------------------------------------------------------------------------ -laradock_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp -laradock_nginx_1 nginx Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp -laradock_php-fpm_1 php-fpm Up 9000/tcp -laradock_volumes_data_1 true Exit 0 -laradock_volumes_source_1 true Exit 0 -laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp -``` - - -## Enable xDebug on php-fpm - -In a host terminal sitting in the laradock folder, run: `./php-fpm/xdebug status` -You should see something like the following: - -``` -xDebug status -laradock_php-fpm_1 -PHP 7.0.9 (cli) (built: Aug 10 2016 19:45:48) ( NTS ) -Copyright (c) 1997-2016 The PHP Group -Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies - with Xdebug v2.4.1, Copyright (c) 2002-2016, by Derick Rethans -``` - -Other commands include `./php-fpm/xdebug start | stop`. - -If you have enabled `xdebug=true` in `docker-compose.yml/php-fpm`, `xdebug` will already be running when -`php-fpm` is started and listening for debug info on port 9000. - - - -## PHPStorm Settings - -- Here are some settings that are known to work: - - `Settings/BuildDeploymentConnection` - - ![Settings/BuildDeploymentConnection](/images/photos/PHPStorm/Settings/BuildDeploymentConnection.png) - - - `Settings/BuildDeploymentConnectionMappings` - - ![Settings/BuildDeploymentConnectionMappings](/images/photos/PHPStorm/Settings/BuildDeploymentConnectionMappings.png) - - - `Settings/BuildDeploymentDebugger` - - ![Settings/BuildDeploymentDebugger](/images/photos/PHPStorm/Settings/BuildDeploymentDebugger.png) - - - `Settings/EditRunConfigurationRemoteWebDebug` - - ![Settings/EditRunConfigurationRemoteWebDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteWebDebug.png) - - - `Settings/EditRunConfigurationRemoteExampleTestDebug` - - ![Settings/EditRunConfigurationRemoteExampleTestDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteExampleTestDebug.png) - - - `Settings/LangsPHPDebug` - - ![Settings/LangsPHPDebug](/images/photos/PHPStorm/Settings/LangsPHPDebug.png) - - - `Settings/LangsPHPInterpreters` - - ![Settings/LangsPHPInterpreters](/images/photos/PHPStorm/Settings/LangsPHPInterpreters.png) - - - `Settings/LangsPHPPHPUnit` - - ![Settings/LangsPHPPHPUnit](/images/photos/PHPStorm/Settings/LangsPHPPHPUnit.png) - - - `Settings/LangsPHPServers` - - ![Settings/LangsPHPServers](/images/photos/PHPStorm/Settings/LangsPHPServers.png) - - - `RemoteHost` - To switch on this view, go to: `Menu/Tools/Deployment/Browse Remote Host`. - - ![RemoteHost](/images/photos/PHPStorm/RemoteHost.png) - - - `RemoteWebDebug` - - ![DebugRemoteOn](/images/photos/PHPStorm/DebugRemoteOn.png) - - - `EditRunConfigurationRemoteWebDebug` - Go to: `Menu/Run/Edit Configurations`. - - ![EditRunConfigurationRemoteWebDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteWebDebug.png) - - - `EditRunConfigurationRemoteExampleTestDebug` - Go to: `Menu/Run/Edit Configurations`. - - ![EditRunConfigurationRemoteExampleTestDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteExampleTestDebug.png) - - - `WindowsFirewallAllowedApps` - Go to: `Control Panel\All Control Panel Items\Windows Firewall\Allowed apps`. - - ![WindowsFirewallAllowedApps.png](/images/photos/PHPStorm/Settings/WindowsFirewallAllowedApps.png) - - - `hosts` - Edit: `C:\Windows\System32\drivers\etc\hosts`. - - ![WindowsFirewallAllowedApps.png](/images/photos/PHPStorm/Settings/hosts.png) - - - [Enable xDebug on php-fpm](#enablePhpXdebug) - - - - -## Usage - - -### Run ExampleTest -- right-click on `tests/ExampleTest.php` - - Select: `Run 'ExampleTest.php'` or `Ctrl+Shift+F10`. - - Should pass!! You just ran a remote test via SSH! - - -### Debug ExampleTest -- Open to edit: `tests/ExampleTest.php` -- Add a BreakPoint on line 16: `$this->visit('/')` -- right-click on `tests/ExampleTest.php` - - Select: `Debug 'ExampleTest.php'`. - - Should have stopped at the BreakPoint!! You are now debugging locally against a remote Laravel project via SSH! - - ![Remote Test Debugging Success](/images/photos/PHPStorm/RemoteTestDebuggingSuccess.png) - - - -### Debug WebSite -- In case xDebug is disabled, from the `laradock` folder run: -`./php-fpm/xdebug start`. - - To switch xdebug off, run: -`./php-fpm/xdebug stop` - -- Start Remote Debugging - - ![DebugRemoteOn](/images/photos/PHPStorm/DebugRemoteOn.png) - -- Open to edit: `bootstrap/app.php` -- Add a BreakPoint on line 14: `$app = new Illuminate\Foundation\Application(` -- Reload [Laravel Site](http://laravel/) - - Should have stopped at the BreakPoint!! You are now debugging locally against a remote Laravel project via SSH! - - ![Remote Debugging Success](/images/photos/PHPStorm/RemoteDebuggingSuccess.png) - - - -## Let's shell into workspace -Assuming that you are in laradock folder, type: -`ssh -i workspace/insecure_id_rsa -p2222 root@laravel` -**Cha Ching!!!!** -- `workspace/insecure_id_rsa.ppk` may become corrupted. In which case: - - fire up `puttygen` - - import `workspace/insecure_id_rsa` - - save private key to `workspace/insecure_id_rsa.ppk` - - - -### KiTTY -[Kitty](http://www.9bis.net/kitty/) KiTTY is a fork from version 0.67 of PuTTY. - -- Here are some settings that are working for me: - - ![Session](/images/photos/KiTTY/Session.png) - - ![Terminal](/images/photos/KiTTY/Terminal.png) - - ![Window](/images/photos/KiTTY/Window.png) - - ![WindowAppearance](/images/photos/KiTTY/WindowAppearance.png) - - ![Connection](/images/photos/KiTTY/Connection.png) - - ![ConnectionData](/images/photos/KiTTY/ConnectionData.png) - - ![ConnectionSSH](/images/photos/KiTTY/ConnectionSSH.png) - - ![ConnectionSSHAuth](/images/photos/KiTTY/ConnectionSSHAuth.png) - - ![TerminalShell](/images/photos/KiTTY/TerminalShell.png) -


@@ -565,13 +238,9 @@ Assuming that you are in laradock folder, type:
-# Running Laravel Dusk Tests +## Running Laravel Dusk Tests -- [Option 1: Without Selenium](#option1-dusk) -- [Option 2: With Selenium](#option2-dusk) - - -## Option 1: Without Selenium +### Option 1: Without Selenium - [Intro](#option1-dusk-intro) - [Workspace Setup](#option1-workspace-setup) @@ -579,14 +248,12 @@ Assuming that you are in laradock folder, type: - [Choose Chrome Driver Version (Optional)](#option1-choose-chrome-driver-version) - [Run Dusk Tests](#option1-run-dusk-tests) - -### Intro +#### Intro This is a guide to run Dusk tests in your `workspace` container with headless google-chrome and chromedriver. It has been tested with Laravel 5.4 and 5.5. - -### Workspace Setup +#### Workspace Setup Update your .env with following entries: @@ -606,8 +273,7 @@ Then run below to build your workspace. docker-compose build workspace ``` - -### Application Setup +#### Application Setup Run a `workspace` container and you will be inside the container at `/var/www` directory. @@ -672,8 +338,7 @@ abstract class DuskTestCase extends BaseTestCase } ``` - -### Choose Chrome Driver Version (Optional) +#### Choose Chrome Driver Version (Optional) You could choose to use either: @@ -727,8 +392,7 @@ abstract class DuskTestCase extends BaseTestCase } ``` - -### Run Dusk Tests +#### Run Dusk Tests Run local server in `workspace` container and run Dusk tests. @@ -745,8 +409,7 @@ PHPUnit 6.4.0 by Sebastian Bergmann and contributors. Time: 837 ms, Memory: 6.00MB ``` - -## Option 2: With Selenium +### Option 2: With Selenium - [Intro](#dusk-intro) - [DNS Setup](#dns-setup) @@ -754,8 +417,7 @@ Time: 837 ms, Memory: 6.00MB - [Laravel Dusk Setup](#laravel-dusk-setup) - [Running Laravel Dusk Tests](#running-tests) - -### Intro +#### Intro Setting up Laravel Dusk tests to run with Laradock appears be something that eludes most Laradock users. This guide is designed to show you how to wire them up to work together. This guide is written with macOS and Linux in mind. As such, @@ -765,8 +427,7 @@ for Windows-specific instructions. This guide assumes you know how to use a DNS forwarder such as `dnsmasq` or are comfortable with editing the `/etc/hosts` file for one-off DNS changes. - -### DNS Setup +#### DNS Setup According to RFC-2606, only four TLDs are reserved for local testing[^1]: - `.test` @@ -799,8 +460,7 @@ For example, in your `/etc/hosts` file: This will ensure that when navigating to `myapp.test`, it will route the request to `127.0.0.1` which will be handled by Nginx in Laradock. - -### Docker Compose setup +#### Docker Compose setup In order to make the Selenium container talk to the Nginx container appropriately, the `docker-compose.yml` needs to be edited to accommodate this. Make the following changes: @@ -822,8 +482,7 @@ the Selenium container to make requests to the Nginx container, which is necessary for running Dusk tests. These changes also link the `nginx` environment variable to the domain you wired up in your hosts file. - -### Laravel Dusk Setup +#### Laravel Dusk Setup In order to make Laravel Dusk make the proper request to the Selenium container, you have to edit the `DuskTestCase.php` file that's provided on the initial @@ -833,13 +492,13 @@ Remote Web Driver attempts to use to set up the Selenium session. One recommendation for this is to add a separate config option in your `.env.dusk.local` so it's still possible to run your Dusk tests locally should you want to. -#### .env.dusk.local +##### .env.dusk.local ``` ... USE_SELENIUM=true ``` -#### DuskTestCase.php +##### DuskTestCase.php ```php abstract class DuskTestCase extends BaseTestCase { @@ -859,8 +518,7 @@ abstract class DuskTestCase extends BaseTestCase } ``` - -### Running Laravel Dusk Tests +#### Running Laravel Dusk Tests Now that you have everything set up, to run your Dusk tests, you have to SSH into the workspace container as you normally would: @@ -885,3 +543,326 @@ This invokes the Dusk command from inside the workspace container but when the s execution, it returns your session to your project directory. [^1]: [Don't Use .dev for Development](https://iyware.com/dont-use-dev-for-development/) + + +
+
+
+
+
+ + +## PHPStorm XDebug Setup + +- [Intro](#Intro) +- [Installation](#Installation) + - [Customize laradock/docker-compose.yml](#CustomizeDockerCompose) + - [Clean House](#InstallCleanHouse) + - [Laradock Dial Tone](#InstallLaradockDialTone) + - [hosts](#AddToHosts) + - [Firewall](#FireWall) + - [Enable xDebug on php-fpm](#enablePhpXdebug) + - [PHPStorm Settings](#InstallPHPStorm) + - [Configs](#InstallPHPStormConfigs) +- [Usage](#Usage) + - [Laravel](#UsageLaravel) + - [Run ExampleTest](#UsagePHPStormRunExampleTest) + - [Debug ExampleTest](#UsagePHPStormDebugExampleTest) + - [Debug Web Site](#UsagePHPStormDebugSite) +- [SSH into workspace](#SSHintoWorkspace) + - [KiTTY](#InstallKiTTY) + +### Intro + +Wiring up [Laravel](https://laravel.com/), [Laradock](https://github.com/Laradock/laradock) [Laravel+Docker] and [PHPStorm](https://www.jetbrains.com/phpstorm/) to play nice together complete with remote xdebug'ing as icing on top! Although this guide is based on `PHPStorm Windows`, +you should be able to adjust accordingly. This guide was written based on Docker for Windows Native. + +### Installation + +- This guide assumes the following: + - you have already installed and are familiar with Laravel, Laradock and PHPStorm. + - you have installed Laravel as a parent of `laradock`. This guide assumes `/c/_dk/laravel`. + +### hosts +- Add `laravel` to your hosts file located on Windows 10 at `C:\Windows\System32\drivers\etc\hosts`. It should be set to the IP of your running container. Mine is: `10.0.75.2` +On Windows you can find it by opening Windows `Hyper-V Manager`. + - ![Windows Hyper-V Manager](images/photos/PHPStorm/Settings/WindowsHyperVManager.png) + +- [Hosts File Editor](https://github.com/scottlerch/HostsFileEditor) makes it easy to change your hosts file. + - Set `laravel` to your docker host IP. See [Example](images/photos/SimpleHostsEditor/AddHost_laravel.png). + + +### Firewall +Your PHPStorm will need to be able to receive a connection from PHP xdebug either your running workspace or php-fpm containers on port 9000. This means that your Windows Firewall should either enable connections from the Application PHPStorm OR the port. + +- It is important to note that if the Application PHPStorm is NOT enabled in the firewall, you will not be able to recreate a rule to override that. +- Also be aware that if you are installing/upgrade different versions of PHPStorm, you MAY have orphaned references to PHPStorm in your Firewall! You may decide to remove orphaned references however in either case, make sure that they are set to receive public TCP traffic. + +#### Edit laradock/docker-compose.yml +Set the following variables: +``` +### Workspace Utilities Container ############### + + workspace: + build: + context: ./workspace + args: + - INSTALL_XDEBUG=true + - INSTALL_WORKSPACE_SSH=true + ... + + +### PHP-FPM Container ##################### + + php-fpm: + build: + context: ./php-fpm + args: + - INSTALL_XDEBUG=true + ... + +``` + +#### Edit xdebug.ini files +- `laradock/workspace/xdebug.ini` +- `laradock/php-fpm/xdebug.ini` + +Set the following variables: + +``` +xdebug.remote_autostart=1 +xdebug.remote_enable=1 +xdebug.remote_connect_back=1 +xdebug.cli_color=1 +``` + + +#### Need to clean house first? + +Make sure you are starting with a clean state. For example, do you have other Laradock containers and images? +Here are a few things I use to clean things up. + +- Delete all containers using `grep laradock_` on the names, see: [Remove all containers based on docker image name](https://linuxconfig.org/remove-all-containners-based-on-docker-image-name). + +`docker ps -a | awk '{ print $1,$2 }' | grep laradock_ | awk '{print $1}' | xargs -I {} docker rm {}` + +- Delete all images containing `laradock`. + +`docker images | awk '{print $1,$2,$3}' | grep laradock_ | awk '{print $3}' | xargs -I {} docker rmi {}` +**Note:** This will only delete images that were built with `Laradock`, **NOT** `laradock/*` which are pulled down by `Laradock` such as `laradock/workspace`, etc. +**Note:** Some may fail with: +`Error response from daemon: conflict: unable to delete 3f38eaed93df (cannot be forced) - image has dependent child images` + +- I added this to my `.bashrc` to remove orphaned images. + +``` +dclean() { + processes=`docker ps -q -f status=exited` + if [ -n "$processes" ]; then + docker rm $processes + fi + + images=`docker images -q -f dangling=true` + if [ -n "$images" ]; then + docker rmi $images + fi +} +``` + +- If you frequently switch configurations for Laradock, you may find that adding the following and added to your `.bashrc` or equivalent useful: + +``` +# remove laravel* containers +# remove laravel_* images +dcleanlaradockfunction() +{ + echo 'Removing ALL containers associated with laradock' + docker ps -a | awk '{ print $1,$2 }' | grep laradock | awk '{print $1}' | xargs -I {} docker rm {} + + # remove ALL images associated with laradock_ + # does NOT delete laradock/* which are hub images + echo 'Removing ALL images associated with laradock_' + docker images | awk '{print $1,$2,$3}' | grep laradock_ | awk '{print $3}' | xargs -I {} docker rmi {} + + echo 'Listing all laradock docker hub images...' + docker images | grep laradock + + echo 'dcleanlaradock completed' +} +# associate the above function with an alias +# so can recall/lookup by typing 'alias' +alias dcleanlaradock=dcleanlaradockfunction +``` + + +### Let's get a dial-tone with Laravel + +``` +# barebones at this point +docker-compose up -d nginx mysql + +# run +docker-compose ps + +# Should see: + Name Command State Ports +----------------------------------------------------------------------------------------------------------- +laradock_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp +laradock_nginx_1 nginx Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp +laradock_php-fpm_1 php-fpm Up 9000/tcp +laradock_volumes_data_1 true Exit 0 +laradock_volumes_source_1 true Exit 0 +laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp +``` + +### Enable xDebug on php-fpm + +In a host terminal sitting in the laradock folder, run: `./php-fpm/xdebug status` +You should see something like the following: + +``` +xDebug status +laradock_php-fpm_1 +PHP 7.0.9 (cli) (built: Aug 10 2016 19:45:48) ( NTS ) +Copyright (c) 1997-2016 The PHP Group +Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies + with Xdebug v2.4.1, Copyright (c) 2002-2016, by Derick Rethans +``` + +Other commands include `./php-fpm/xdebug start | stop`. + +If you have enabled `xdebug=true` in `docker-compose.yml/php-fpm`, `xdebug` will already be running when +`php-fpm` is started and listening for debug info on port 9000. + + +### PHPStorm Settings + +- Here are some settings that are known to work: + - `Settings/BuildDeploymentConnection` + - ![Settings/BuildDeploymentConnection](/images/photos/PHPStorm/Settings/BuildDeploymentConnection.png) + + - `Settings/BuildDeploymentConnectionMappings` + - ![Settings/BuildDeploymentConnectionMappings](/images/photos/PHPStorm/Settings/BuildDeploymentConnectionMappings.png) + + - `Settings/BuildDeploymentDebugger` + - ![Settings/BuildDeploymentDebugger](/images/photos/PHPStorm/Settings/BuildDeploymentDebugger.png) + + - `Settings/EditRunConfigurationRemoteWebDebug` + - ![Settings/EditRunConfigurationRemoteWebDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteWebDebug.png) + + - `Settings/EditRunConfigurationRemoteExampleTestDebug` + - ![Settings/EditRunConfigurationRemoteExampleTestDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteExampleTestDebug.png) + + - `Settings/LangsPHPDebug` + - ![Settings/LangsPHPDebug](/images/photos/PHPStorm/Settings/LangsPHPDebug.png) + + - `Settings/LangsPHPInterpreters` + - ![Settings/LangsPHPInterpreters](/images/photos/PHPStorm/Settings/LangsPHPInterpreters.png) + + - `Settings/LangsPHPPHPUnit` + - ![Settings/LangsPHPPHPUnit](/images/photos/PHPStorm/Settings/LangsPHPPHPUnit.png) + + - `Settings/LangsPHPServers` + - ![Settings/LangsPHPServers](/images/photos/PHPStorm/Settings/LangsPHPServers.png) + + - `RemoteHost` + To switch on this view, go to: `Menu/Tools/Deployment/Browse Remote Host`. + - ![RemoteHost](/images/photos/PHPStorm/RemoteHost.png) + + - `RemoteWebDebug` + - ![DebugRemoteOn](/images/photos/PHPStorm/DebugRemoteOn.png) + + - `EditRunConfigurationRemoteWebDebug` + Go to: `Menu/Run/Edit Configurations`. + - ![EditRunConfigurationRemoteWebDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteWebDebug.png) + + - `EditRunConfigurationRemoteExampleTestDebug` + Go to: `Menu/Run/Edit Configurations`. + - ![EditRunConfigurationRemoteExampleTestDebug](/images/photos/PHPStorm/Settings/EditRunConfigurationRemoteExampleTestDebug.png) + + - `WindowsFirewallAllowedApps` + Go to: `Control Panel\All Control Panel Items\Windows Firewall\Allowed apps`. + - ![WindowsFirewallAllowedApps.png](/images/photos/PHPStorm/Settings/WindowsFirewallAllowedApps.png) + + - `hosts` + Edit: `C:\Windows\System32\drivers\etc\hosts`. + - ![WindowsFirewallAllowedApps.png](/images/photos/PHPStorm/Settings/hosts.png) + + - [Enable xDebug on php-fpm](#enablePhpXdebug) + + + +### Usage + +#### Run ExampleTest +- right-click on `tests/ExampleTest.php` + - Select: `Run 'ExampleTest.php'` or `Ctrl+Shift+F10`. + - Should pass!! You just ran a remote test via SSH! + +#### Debug ExampleTest +- Open to edit: `tests/ExampleTest.php` +- Add a BreakPoint on line 16: `$this->visit('/')` +- right-click on `tests/ExampleTest.php` + - Select: `Debug 'ExampleTest.php'`. + - Should have stopped at the BreakPoint!! You are now debugging locally against a remote Laravel project via SSH! + - ![Remote Test Debugging Success](/images/photos/PHPStorm/RemoteTestDebuggingSuccess.png) + +#### Debug WebSite +- In case xDebug is disabled, from the `laradock` folder run: +`./php-fpm/xdebug start`. + - To switch xdebug off, run: +`./php-fpm/xdebug stop` + +- Start Remote Debugging + - ![DebugRemoteOn](/images/photos/PHPStorm/DebugRemoteOn.png) + +- Open to edit: `bootstrap/app.php` +- Add a BreakPoint on line 14: `$app = new Illuminate\Foundation\Application(` +- Reload [Laravel Site](http://laravel/) + - Should have stopped at the BreakPoint!! You are now debugging locally against a remote Laravel project via SSH! + - ![Remote Debugging Success](/images/photos/PHPStorm/RemoteDebuggingSuccess.png) + + +### Let's shell into workspace +Assuming that you are in laradock folder, type: +`ssh -i workspace/insecure_id_rsa -p2222 root@laravel` +**Cha Ching!!!!** +- `workspace/insecure_id_rsa.ppk` may become corrupted. In which case: + - fire up `puttygen` + - import `workspace/insecure_id_rsa` + - save private key to `workspace/insecure_id_rsa.ppk` + +#### KiTTY +[Kitty](http://www.9bis.net/kitty/) KiTTY is a fork from version 0.67 of PuTTY. + +- Here are some settings that are working for me: + - ![Session](/images/photos/KiTTY/Session.png) + - ![Terminal](/images/photos/KiTTY/Terminal.png) + - ![Window](/images/photos/KiTTY/Window.png) + - ![WindowAppearance](/images/photos/KiTTY/WindowAppearance.png) + - ![Connection](/images/photos/KiTTY/Connection.png) + - ![ConnectionData](/images/photos/KiTTY/ConnectionData.png) + - ![ConnectionSSH](/images/photos/KiTTY/ConnectionSSH.png) + - ![ConnectionSSHAuth](/images/photos/KiTTY/ConnectionSSHAuth.png) + - ![TerminalShell](/images/photos/KiTTY/TerminalShell.png) + +
+
+
+
+
+ + +## Setup remote debugging for PhpStorm on Linux + + - Make sure you have followed the steps above in the [Install Xdebug section](#install-xdebug). + + - Make sure Xdebug accepts connections and listens on port 9000. (Should be default configuration). + +![Debug Configuration](/images/photos/PHPStorm/linux/configuration/debugConfiguration.png "Debug Configuration"). + + - Create a server with name `laradock` (matches **PHP_IDE_CONFIG** key in environment file) and make sure to map project root path with server correctly. + +![Server Configuration](/images/photos/PHPStorm/linux/configuration/serverConfiguration.png "Server Configuration"). + + - Start listening for debug connections, place a breakpoint and you are good to go ! diff --git a/DOCUMENTATION/content/help/index.md b/DOCUMENTATION/content/help/index.md index 3f2342d..1d971c5 100644 --- a/DOCUMENTATION/content/help/index.md +++ b/DOCUMENTATION/content/help/index.md @@ -1,5 +1,5 @@ --- -title: Help & Questions +title: 5. Help & Questions type: index weight: 5 --- @@ -7,3 +7,121 @@ weight: 5 Join the chat room on [Gitter](https://gitter.im/Laradock/laradock) and get help and support from the community. You can as well can open an [issue](https://github.com/laradock/laradock/issues) on Github (will be labeled as Question) and discuss it with people on [Gitter](https://gitter.im/Laradock/laradock). + + +
+ +# Common Problems + +*Here's a list of the common problems you might face, and the possible solutions.* + + +
+## I see a blank (white) page instead of the Laravel 'Welcome' page! + +Run the following command from the Laravel root directory: + +```bash +sudo chmod -R 777 storage bootstrap/cache +``` + + + + + + +
+## I see "Welcome to nginx" instead of the Laravel App! + +Use `http://127.0.0.1` instead of `http://localhost` in your browser. + + + + + + +
+## I see an error message containing `address already in use` or `port is already allocated` + +Make sure the ports for the services that you are trying to run (22, 80, 443, 3306, etc.) are not being used already by other programs on the host, such as a built in `apache`/`httpd` service or other development tools you have installed. + + + + + + +
+## I get NGINX error 404 Not Found on Windows. + +1. Go to docker Settings on your Windows machine. +2. Click on the `Shared Drives` tab and check the drive that contains your project files. +3. Enter your windows username and password. +4. Go to the `reset` tab and click restart docker. + + + + + + +
+## The time in my services does not match the current time + +1. Make sure you've [changed the timezone](#Change-the-timezone). +2. Stop and rebuild the containers (`docker-compose up -d --build `) + + + + + + +
+## I get MySQL connection refused + +This error sometimes happens because your Laravel application isn't running on the container localhost IP (Which is 127.0.0.1). Steps to fix it: + +* Option A + 1. Check your running Laravel application IP by dumping `Request::ip()` variable using `dd(Request::ip())` anywhere on your application. The result is the IP of your Laravel container. + 2. Change the `DB_HOST` variable on env with the IP that you received from previous step. +* Option B + 1. Change the `DB_HOST` value to the same name as the MySQL docker container. The Laradock docker-compose file currently has this as `mysql` + +## I get stuck when building nginx on `fetch http://mirrors.aliyun.com/alpine/v3.5/main/x86_64/APKINDEX.tar.gz` + +As stated on [#749](https://github.com/laradock/laradock/issues/749#issuecomment-419652646), Already fixed,just set `CHANGE_SOURCE` to false. + +## Custom composer repo packagist url and npm registry url + +In China, the origin source of composer and npm is very slow. You can add `WORKSPACE_NPM_REGISTRY` and `WORKSPACE_COMPOSER_REPO_PACKAGIST` config in `.env` to use your custom source. + +Example: +```bash +WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org +WORKSPACE_COMPOSER_REPO_PACKAGIST=https://packagist.phpcomposer.com +``` + +
+ +## I get `Module build failed: Error: write EPIPE` while compiling react application + +When you run `npm build` or `yarn dev` building a react application using webpack with elixir you may receive a `Error: write EPIPE` while processing .jpg images. + +This is caused of an outdated library for processing **.jpg files** in ubuntu 16.04. + +To fix the problem you can follow those steps + +1 - Open the `.env`. + +2 - Search for `WORKSPACE_INSTALL_LIBPNG` or add the key if missing. + +3 - Set the value to true: + +```dotenv +WORKSPACE_INSTALL_LIBPNG=true +``` + +4 - Finally rebuild the workspace image + +```bash +docker-compose build workspace +``` + diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 1fdd83e..610f031 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -1,5 +1,5 @@ --- -title: Introduction +title: 1. Introduction type: index weight: 1 --- @@ -9,7 +9,7 @@ weight: 1 A full PHP development environment for Docker. -Includes a lot of useful Docker Images, all pre-configured to provide a wonderful PHP development environment. +Supports a variety of useful Docker Images, pre-configured to provide a wonderful PHP development environment. ![](https://raw.githubusercontent.com/laradock/laradock/master/.github/home-page-images/laradock-logo.jpg) @@ -31,11 +31,11 @@ Includes a lot of useful Docker Images, all pre-configured to provide a wonderfu For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io.
-Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website. +*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website.* ## Quick Overview -Let's see how easy it is to install `NGINX`, `PHP`, `Composer`, `MySQL`, `Redis` and `Beanstalkd`: +Let's see how easy it is to setup our demo stack `PHP`, `NGINX`, `MySQL`, `Redis` and `Composer`: 1 - Clone Laradock inside your PHP project: @@ -77,8 +77,8 @@ That's it! enjoy :) - Easy switch between PHP versions: 7.3, 7.2, 7.1, 5.6... - Choose your favorite database engine: MySQL, Postgres, MariaDB... -- Run your own combination of software: Memcached, HHVM, Beanstalkd... -- Every software runs on a separate container: PHP-FPM, NGINX, PHP-CLI... +- Run your own stack: Memcached, HHVM, RabbitMQ... +- Each software runs on its own container: PHP-FPM, NGINX, PHP-CLI... - Easy to customize any container, with simple edit to the `Dockerfile`. - All Images extends from an official base Image. (Trusted base Images). - Pre-configured NGINX to host any code at your root directory. @@ -88,39 +88,101 @@ That's it! enjoy :) - Latest version of the Docker Compose file (`docker-compose`). - Everything is visible and editable. - Fast Images Builds. -- More to come every week.. - ## Supported Software (Images) -In adhering to the separation of concerns principle as promoted by Docker, Laradock runs each software on its own Container. -You can turn On/Off as many instances of as any container without worrying about the configurations, everything works like a charm. +> Laradock, adheres to the 'separation of concerns' principle, thus it runs each software on its own Docker Container. +> You can turn On/Off as many instances of as any container without worrying about the configurations. + +> To run a chosen container from the list below, run `docker-compose up -d {container-name}`. +> The container name `{container-name}` is the same as its folder name. Example to run the "PHP FPM" container use the name "php-fpm". + +- **Web Servers:** + * NGINX + * Apache2 + * Caddy + * HAProxy -- **Database Engines:** -MySQL - MariaDB - Percona - MongoDB - Neo4j - RethinkDB - MSSQL - PostgreSQL - Postgres-PostGIS. -- **Database Management:** -PhpMyAdmin - Adminer - PgAdmin -- **Cache Engines:** -Redis - Memcached - Aerospike -- **PHP Servers:** -NGINX - Apache2 - Caddy - **PHP Compilers:** -PHP FPM - HHVM -- **Message Queueing:** -Beanstalkd - RabbitMQ - PHP Worker -- **Queueing Management:** -Beanstalkd Console - RabbitMQ Console -- **Random Tools:** -Mailu - HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Grafana - Gitlab - Mailhog - MailDev - Minio - Varnish - Swoole - NetData - Portainer - Laravel Echo - Phalcon... + * PHP FPM + * HHVM -Laradock introduces the **Workspace** Image, as a development environment. -It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of Containers and tools you may choose. +- **Database Management Systems:** + * MySQL + * MariaDB + * Percona + * MongoDB + * Neo4j + * RethinkDB + * MSSQL + * PostgreSQL + * Postgres-PostGIS -**Workspace Image Tools** -PHP CLI - Composer - Git - Linuxbrew - Node - V8JS - Gulp - SQLite - xDebug - Envoy - Deployer - Vim - Yarn - SOAP - Drush - WP-CLI... +- **Database Management Apps:** + * PhpMyAdmin + * Adminer + * PgAdmin + +- **Cache Engines:** + * Redis + * Memcached + * Aerospike + * Varnish + +- **Message Brokers:** + * RabbitMQ (+ Admin Console) + * Beanstalkd (+ Admin Console) + * PHP Worker + +- **Mail Servers:** + * Mailu + * Mailhog + * MailDev + +- **Testing:** + * Selenium + +- **Monitoring:** + * Grafana + * NetData + +- **More Tools:** + * Certbot *(Automatically enable HTTPS on your website)* + * Swoole *(Production-Grade Async programming Framework for PHP)* + * ElasticSearch *(Search engine based on the Lucene library)* + * Kibana *(Visualize your Elasticsearch data and navigate the Elastic Stack)* + * Portainer *(Build and manage your Docker environments with ease)* + * Jenkins (automation server) + * Gitlab *(A single application for the entire software development lifecycle)* + * Blackfire *(Empowers all PHP developers and IT/Ops to continuously verify and improve their app's performance)* + * Laravel Echo *(Bring the power of WebSockets to your Laravel applications)* + * Phalcon *(A PHP web framework based on the model–view–controller pattern)* + * Minio *(Cloud storage server released under Apache License v2, compatible with Amazon S3)* + +- **Workspace Image Tools** + +> Laradock introduces the **Workspace** Image, as a development environment. +> It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of tools you choose. + + * PHP CLI + * Composer + * Git + * Vim + * xDebug + * Linuxbrew + * Node + * V8JS + * Gulp + * SQLite + * Envoy + * Deployer + * Yarn + * SOAP + * Drush + * Wordpress CLI You can choose, which tools to install in your workspace container and other containers, from the `.env` file. @@ -166,7 +228,6 @@ Most importantly Docker can run on Development and on Production (same environme What's better than a **Demo Video**: -- Laradock v5.* (should be next!) - Laradock [v4.*](https://www.youtube.com/watch?v=TQii1jDa96Y) - Laradock [v2.*](https://www.youtube.com/watch?v=-DamFMczwDA) - Laradock [v0.3](https://www.youtube.com/watch?v=jGkyO6Is_aI) @@ -195,14 +256,14 @@ You are welcome to join our chat room on Gitter. > Help keeping the project development going, by [contributing](http://laradock.io/contributing) or donating a little. > Thanks in advance. -Donate directly via [Paypal](https://www.paypal.me/mzalt) +Donate directly via [Paypal](https://paypal.me/mzmmzz) -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/mzalt) - -or become a backer on [Open Collective](https://opencollective.com/laradock#backer) - - +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) or show your support via [Beerpay](https://beerpay.io/laradock/laradock) [![Beerpay](https://beerpay.io/laradock/laradock/badge.svg?style=flat)](https://beerpay.io/laradock/laradock) + +or become a backer on [Open Collective](https://opencollective.com/laradock#backer) + + diff --git a/DOCUMENTATION/content/license/index.md b/DOCUMENTATION/content/license/index.md index 795d4c8..312b13d 100644 --- a/DOCUMENTATION/content/license/index.md +++ b/DOCUMENTATION/content/license/index.md @@ -1,5 +1,5 @@ --- -title: License +title: 8. License type: index weight: 8 --- diff --git a/DOCUMENTATION/content/related-projects/index.md b/DOCUMENTATION/content/related-projects/index.md index bc37d9b..a55343f 100644 --- a/DOCUMENTATION/content/related-projects/index.md +++ b/DOCUMENTATION/content/related-projects/index.md @@ -1,5 +1,5 @@ --- -title: Related Projects +title: 6. Related Projects type: index weight: 6 --- From c79d0671e2c20534d61057c29c74e08292987da7 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 15 Jul 2019 20:47:29 +0200 Subject: [PATCH 174/589] add missing supported images to the docs --- DOCUMENTATION/content/introduction/index.md | 161 ++++++++++++-------- 1 file changed, 95 insertions(+), 66 deletions(-) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 610f031..82e6ad9 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -92,97 +92,126 @@ That's it! enjoy :) -## Supported Software (Images) +## Supported Software (Docker Images) > Laradock, adheres to the 'separation of concerns' principle, thus it runs each software on its own Docker Container. -> You can turn On/Off as many instances of as any container without worrying about the configurations. +> You can turn On/Off as many instances as you want without worrying about the configurations. > To run a chosen container from the list below, run `docker-compose up -d {container-name}`. > The container name `{container-name}` is the same as its folder name. Example to run the "PHP FPM" container use the name "php-fpm". - **Web Servers:** - * NGINX - * Apache2 - * Caddy - * HAProxy + - NGINX + - Apache2 + - Caddy + +- **Load Balancers:** + - HAProxy + - Traefik - **PHP Compilers:** - * PHP FPM - * HHVM + - PHP FPM + - HHVM - **Database Management Systems:** - * MySQL - * MariaDB - * Percona - * MongoDB - * Neo4j - * RethinkDB - * MSSQL - * PostgreSQL - * Postgres-PostGIS + - MySQL + - PostgreSQL + - PostGIS + - MariaDB + - Percona + - MSSQL + - MongoDB + - MongoDB Web UI + - Neo4j + - CouchDB + - RethinkDB + - **Database Management Apps:** - * PhpMyAdmin - * Adminer - * PgAdmin + - PhpMyAdmin + - Adminer + - PgAdmin - **Cache Engines:** - * Redis - * Memcached - * Aerospike - * Varnish + - Redis + - Redis Web UI + - Redis Cluster + - Memcached + - Aerospike + - Varnish - **Message Brokers:** - * RabbitMQ (+ Admin Console) - * Beanstalkd (+ Admin Console) - * PHP Worker + - RabbitMQ + - RabbitMQ Admin Console + - Beanstalkd + - Beanstalkd Admin Console + - Eclipse Mosquitto + - PHP Worker + - Laravel Horizon - **Mail Servers:** - * Mailu - * Mailhog - * MailDev + - Mailu + - Mailhog + - MailDev + +- **Log Management:** + - GrayLog - **Testing:** - * Selenium + - Selenium - **Monitoring:** - * Grafana - * NetData + - Grafana + - NetData -- **More Tools:** - * Certbot *(Automatically enable HTTPS on your website)* - * Swoole *(Production-Grade Async programming Framework for PHP)* - * ElasticSearch *(Search engine based on the Lucene library)* - * Kibana *(Visualize your Elasticsearch data and navigate the Elastic Stack)* - * Portainer *(Build and manage your Docker environments with ease)* - * Jenkins (automation server) - * Gitlab *(A single application for the entire software development lifecycle)* - * Blackfire *(Empowers all PHP developers and IT/Ops to continuously verify and improve their app's performance)* - * Laravel Echo *(Bring the power of WebSockets to your Laravel applications)* - * Phalcon *(A PHP web framework based on the model–view–controller pattern)* - * Minio *(Cloud storage server released under Apache License v2, compatible with Amazon S3)* +- **Search Engines:** + - ElasticSearch + - Apache Solr + - Manticore Search -- **Workspace Image Tools** +- **IDE's** + - ICE Coder + - Theia + - Web IDE -> Laradock introduces the **Workspace** Image, as a development environment. -> It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of tools you choose. - - * PHP CLI - * Composer - * Git - * Vim - * xDebug - * Linuxbrew - * Node - * V8JS - * Gulp - * SQLite - * Envoy - * Deployer - * Yarn - * SOAP - * Drush - * Wordpress CLI +- **Miscellaneous:** + - Workspace: *(Laradock container that includes a rich set of pre-configured useful tools)* + - `PHP CLI` + - `Composer` + - `Git` + - `Vim` + - `xDebug` + - `Linuxbrew` + - `Node` + - `V8JS` + - `Gulp` + - `SQLite` + - `Laravel Envoy` + - `Deployer` + - `Yarn` + - `SOAP` + - `Drush` + - `Wordpress CLI` + - Apache ZooKeeper *(Centralized service for distributed systems to a hierarchical key-value store)* + - Kibana *(Visualize your Elasticsearch data and navigate the Elastic Stack)* + - LogStash *(Server-side data processing pipeline that ingests data from a multitude of sources simultaneously)* + - Jenkins *(automation server, that provides plugins to support building, deploying and automating any project)* + - Certbot *(Automatically enable HTTPS on your website)* + - Swoole *(Production-Grade Async programming Framework for PHP)* + - SonarQube *(continuous inspection of code quality to perform automatic reviews with static analysis of code to detect bugs and more)* + - Gitlab *(A single application for the entire software development lifecycle)* + - PostGIS *(Database extender for PostgreSQL. It adds support for geographic objects allowing location queries to be run in SQL)* + - Blackfire *(Empowers all PHP developers and IT/Ops to continuously verify and improve their app's performance)* + - Laravel Echo *(Bring the power of WebSockets to your Laravel applications)* + - Phalcon *(A PHP web framework based on the model–view–controller pattern)* + - Minio *(Cloud storage server released under Apache License v2, compatible with Amazon S3)* + - AWS EB CLI *(CLI that helps you deploy and manage your AWS Elastic Beanstalk applications and environments)* + - Thumbor *(Photo thumbnail service)* + - IPython *(Provides a rich architecture for interactive computing)* + - Jupyter Hub *(Jupyter notebook for multiple users)* + - Portainer *(Build and manage your Docker environments with ease)* + - Docker Registry *(The Docker Registry implementation for storing and distributing Docker images)* + - Docker Web UI *(A browser-based solution for browsing and modifying a private Docker registry)* You can choose, which tools to install in your workspace container and other containers, from the `.env` file. @@ -191,7 +220,7 @@ You can choose, which tools to install in your workspace container and other con -If you can't find your Software in the list, build it yourself and submit it. Contributions are welcomed :) +*If you can't find your Software in the list, build it yourself and submit it. Contributions are welcomed :)* From 26184055c5126dc51f2aadadd7a3b4a9506a1d04 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 15 Jul 2019 20:47:50 +0200 Subject: [PATCH 175/589] rename aws image to aws-eb-cli --- {aws => aws-eb-cli}/.gitignore | 0 {aws => aws-eb-cli}/Dockerfile | 0 docker-compose.yml | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename {aws => aws-eb-cli}/.gitignore (100%) rename {aws => aws-eb-cli}/Dockerfile (100%) diff --git a/aws/.gitignore b/aws-eb-cli/.gitignore similarity index 100% rename from aws/.gitignore rename to aws-eb-cli/.gitignore diff --git a/aws/Dockerfile b/aws-eb-cli/Dockerfile similarity index 100% rename from aws/Dockerfile rename to aws-eb-cli/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 7edfa77..86dfda7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1003,7 +1003,7 @@ services: ### AWS EB-CLI ################################################ aws: build: - context: ./aws + context: ./aws-eb-cli volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} depends_on: From db1a7cdbbc2258fb9ab4c0e7299935516ff1f07a Mon Sep 17 00:00:00 2001 From: Takafumi Enomoto Date: Mon, 22 Jul 2019 23:28:39 +0900 Subject: [PATCH 176/589] Add memcached extension support for PHP 7.3 (#2195) --- php-fpm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index ab6ba6b..cab7a83 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -353,7 +353,7 @@ RUN if [ ${INSTALL_MEMCACHED} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/2.2.0.tar.gz"; \ else \ - curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/php7.tar.gz"; \ + curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/master.tar.gz"; \ fi \ && mkdir -p memcached \ && tar -C memcached -zxvf /tmp/memcached.tar.gz --strip 1 \ From 69aa0b2b6a64a44659c815742039a9e24612b1a7 Mon Sep 17 00:00:00 2001 From: Yuqi Hao <45658979+haoyq02@users.noreply.github.com> Date: Mon, 22 Jul 2019 22:29:37 +0800 Subject: [PATCH 177/589] fix:laravel-horizon (#2181) --- docker-compose.yml | 1 + laravel-horizon/Dockerfile | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 86dfda7..69b5dc6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -245,6 +245,7 @@ services: - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_MEMCACHED=${PHP_FPM_INSTALL_MEMCACHED} + - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./laravel-horizon/supervisord.d:/etc/supervisord.d diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index f21dfdd..e89468e 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -32,6 +32,12 @@ RUN if [ ${INSTALL_BCMATH} = true ]; then \ docker-php-ext-install bcmath \ ;fi +#Install Sockets package: +ARG INSTALL_AMQP=false +RUN if [ ${INSTALL_AMQP} = true ]; then \ + docker-php-ext-install sockets \ + ;fi + # Install PostgreSQL drivers: ARG INSTALL_PGSQL=false RUN if [ ${INSTALL_PGSQL} = true ]; then \ From 3a4c9158d26ef8a13bf5040762095a815bbc8481 Mon Sep 17 00:00:00 2001 From: Marco Manieri Date: Mon, 22 Jul 2019 16:31:46 +0200 Subject: [PATCH 178/589] Cannot load Xdebug - it was already loaded (#2123) zend_extension=xdebug.so is already in /etc/php/7.2/cli/conf.d/20-xdebug.ini rediefing the alias causes the was already loaded notice. also /var/www/vendor/bin/phpunit instead of ./vendor/bin/phpunit breaks the alias when vendor directory is not directly under the root app directory --- workspace/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 3a07eee..bdc0349 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -314,8 +314,7 @@ ARG INSTALL_XDEBUG=false RUN if [ ${INSTALL_XDEBUG} = true ]; then \ # Load the xdebug extension only with phpunit commands apt-get install -y php${LARADOCK_PHP_VERSION}-xdebug && \ - sed -i 's/^;//g' /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-xdebug.ini && \ - echo "alias phpunit='php -dzend_extension=xdebug.so /var/www/vendor/bin/phpunit'" >> ~/.bashrc \ + sed -i 's/^;//g' /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-xdebug.ini \ ;fi # ADD for REMOTE debugging From 63a5c45bf86a037d16b31b024108ec96856b537a Mon Sep 17 00:00:00 2001 From: Hany alsamman Date: Tue, 23 Jul 2019 07:08:56 +0300 Subject: [PATCH 179/589] Add PCNTL option to php-fpm --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 69b5dc6..9e6bce9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -183,6 +183,7 @@ services: - INSTALL_MYSQL_CLIENT=${PHP_FPM_INSTALL_MYSQL_CLIENT} - INSTALL_PING=${PHP_FPM_INSTALL_PING} - INSTALL_SSHPASS=${PHP_FPM_INSTALL_SSHPASS} + - INSTALL_PCNTL=${PHP_FPM_INSTALL_PCNTL} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} - http_proxy From 440d865fc4579657f57eba24035674295cb4fdc5 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 23 Jul 2019 22:45:05 +0200 Subject: [PATCH 180/589] documentation text updates --- .github/README.md | 12 ++--- DOCUMENTATION/content/documentation/index.md | 52 +++++++------------ .../content/getting-started/index.md | 19 +++++-- DOCUMENTATION/content/introduction/index.md | 6 +-- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/.github/README.md b/.github/README.md index 29b2cca..529d832 100644 --- a/.github/README.md +++ b/.github/README.md @@ -2,7 +2,7 @@ Laradock Logo

-

A Docker PHP development environment that facilitates running PHP Apps on Docker

+

PHP development environment that runs on Docker

Build status @@ -13,7 +13,7 @@ contributions welcome

-

Use Docker First And Learn About It Later

+

Use Docker First - Then Learn About It Later

forthebadge @@ -44,9 +44,9 @@ For basic sponsorships go to [Open Collective](https://opencollective.com/larado *Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website.* -## Contributors +## People -#### Core contributors: +#### Maintainers: - [Mahmoud Zalt](https://github.com/Mahmoudz) @mahmoudz | [Twitter](https://twitter.com/Mahmoud_Zalt) | [Site](http://zalt.me) - [Bo-Yi Wu](https://github.com/appleboy) @appleboy | [Twitter](https://twitter.com/appleboy) - [Philippe Trépanier](https://github.com/philtrep) @philtrep @@ -59,9 +59,9 @@ For basic sponsorships go to [Open Collective](https://opencollective.com/larado - [Milan Urukalo](https://github.com/urukalo) @urukalo - [Vince Chu](https://github.com/vwchu) @vwchu - [Huadong Zuo](https://github.com/zuohuadong) @zuohuadong -- Join us, by submitting 20 useful PR's. +- Join us. -#### Awesome contributors: +#### Awesome Contributors: diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 2560a8e..a9aeb8a 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -297,6 +297,24 @@ e) set it to `true` For information on how to configure xDebug with your IDE and work it out, check this [Repository](https://github.com/LarryEitel/laravel-laradock-phpstorm) or follow up on the next section if you use linux and PhpStorm. + + +
+ +## Start/Stop xDebug: + +By installing xDebug, you are enabling it to run on startup by default. + +To control the behavior of xDebug (in the `php-fpm` Container), you can run the following commands from the Laradock root folder, (at the same prompt where you run docker-compose): + +- Stop xDebug from running by default: `.php-fpm/xdebug stop`. +- Start xDebug by default: `.php-fpm/xdebug start`. +- See the status: `.php-fpm/xdebug status`. + +Note: If `.php-fpm/xdebug` doesn't execute and gives `Permission Denied` error the problem can be that file `xdebug` doesn't have execution access. This can be fixed by running `chmod` command with desired access permissions. + + +
## Install phpdbg @@ -321,22 +339,6 @@ PHP_FPM_INSTALL_PHPDBG=true -
- -## Start/Stop xDebug: - -By installing xDebug, you are enabling it to run on startup by default. - -To control the behavior of xDebug (in the `php-fpm` Container), you can run the following commands from the Laradock root folder, (at the same prompt where you run docker-compose): - -- Stop xDebug from running by default: `.php-fpm/xdebug stop`. -- Start xDebug by default: `.php-fpm/xdebug start`. -- See the status: `.php-fpm/xdebug status`. - -Note: If `.php-fpm/xdebug` doesn't execute and gives `Permission Denied` error the problem can be that file `xdebug` doesn't have execution access. This can be fixed by running `chmod` command with desired access permissions. - - -
@@ -1566,22 +1568,6 @@ Available versions are: 5.5, 5.6, 5.7, 8.0, or latest. See https://store.docker -
- -## MySQL access from host - -You can forward the MySQL/MariaDB port to your host by making sure these lines are added to the `mysql` or `mariadb` section of the `docker-compose.yml` or in your [environment specific Compose](https://docs.docker.com/compose/extends/) file. - -``` -ports: - - "3306:3306" -``` - - - - - -
## MySQL root access @@ -1682,7 +1668,7 @@ Enabling Global Composer Install during the build for the container allows you t
-## Magento 2 authentication credential (composer install) +## Add authentication credential for Magento 2 1 - Open the `.env` file diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index d4f6d54..f71661d 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -41,7 +41,7 @@ Note: If you are not using Git yet for your project, you can use `git clone` ins *To keep track of your Laradock changes, between your projects and also keep Laradock updated [check these docs](/documentation/#keep-track-of-your-laradock-changes)* -Your folder structure should look like this: +2 - Make sure your folder structure should look like this: ``` + project-a @@ -52,7 +52,7 @@ Your folder structure should look like this: *(It's important to rename the laradock folders to unique name in each project, if you want to run laradock per project).* -> **Now jump to the [Usage](#Usage) section.** +3 - Go to the [Usage](#Usage) section. ### A.2) Don't have a PHP project yet: @@ -86,7 +86,7 @@ APP_CODE_PATH_HOST=../project-z/ Make sure to replace `project-z` with your project folder name. -> **Now jump to the [Usage](#Usage) section.** +3 - Go to the [Usage](#Usage) section. @@ -127,7 +127,7 @@ You can rename the config files, project folders and domains as you like, just m If you use Chrome 63 or above for development, don't use `.dev`. [Why?](https://laravel-news.com/chrome-63-now-forces-dev-domains-https). Instead use `.localhost`, `.invalid`, `.test`, or `.example`. -> **Now jump to the [Usage](#Usage) section.** +4 - Go to the [Usage](#Usage) section. @@ -213,7 +213,16 @@ Open your PHP project's `.env` file or whichever configuration file you are read DB_HOST=mysql ``` +You need to use the Laradock's default DB credentials which can be found in the `.env` file (ex: `MYSQL_USER=`). +Or you can change them and rebuild the container. + *If you want to install Laravel as PHP project, see [How to Install Laravel in a Docker Container](#Install-Laravel).*
-5 - Open your browser and visit your localhost address `http://localhost/`. If you followed the multiple projects setup, you can visit `http://project-1.test/` and `http://project-2.test/`. +5 - Open your browser and visit your localhost address. + +If you followed the multiple projects setup, you can visit `http://project-1.test/` and `http://project-2.test/`. + +[http://localhost:8080](http://localhost:8080) + +Make sure you add use the right port number as provided by your running server. Ex: NGINX uses port 8080 by default while Apache2 uses 80. diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 82e6ad9..4874e43 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -5,9 +5,9 @@ weight: 1 --- +## Use Docker First - Then Learn About It Later - -A full PHP development environment for Docker. +Laradock is a PHP development environment that runs on Docker. Supports a variety of useful Docker Images, pre-configured to provide a wonderful PHP development environment. @@ -175,7 +175,7 @@ That's it! enjoy :) - Web IDE - **Miscellaneous:** - - Workspace: *(Laradock container that includes a rich set of pre-configured useful tools)* + - Workspace *(Laradock container that includes a rich set of pre-configured useful tools)* - `PHP CLI` - `Composer` - `Git` From c604de0af0f2230dca3c53e96fd4a23bf3fc45e2 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 23 Jul 2019 22:45:54 +0200 Subject: [PATCH 181/589] add @lanphan and @ahkui to project maintainers --- .github/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/README.md b/.github/README.md index 529d832..c3b5c84 100644 --- a/.github/README.md +++ b/.github/README.md @@ -59,6 +59,8 @@ For basic sponsorships go to [Open Collective](https://opencollective.com/larado - [Milan Urukalo](https://github.com/urukalo) @urukalo - [Vince Chu](https://github.com/vwchu) @vwchu - [Huadong Zuo](https://github.com/zuohuadong) @zuohuadong +- [Lan Phan](https://github.com/lanphan) @lanphan +- [Ahkui](https://github.com/ahkui) @ahkui - Join us. #### Awesome Contributors: From 768f14b6dd13529842af521323776ee97d87efef Mon Sep 17 00:00:00 2001 From: Feng Hao Date: Wed, 24 Jul 2019 21:06:36 +0800 Subject: [PATCH 182/589] fix: apt error after imap installed (#2212) --- php-fpm/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index cab7a83..a25e5f4 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -573,7 +573,6 @@ ARG INSTALL_IMAP=false RUN if [ ${INSTALL_IMAP} = true ]; then \ apt-get install -y libc-client-dev libkrb5-dev && \ - rm -r /var/lib/apt/lists/* && \ docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \ docker-php-ext-install imap \ ;fi From 9a852e7bc7ad256a3dfd38e9cdb7b61f0e2fd7e9 Mon Sep 17 00:00:00 2001 From: Stefan Neuhaus Date: Thu, 25 Jul 2019 08:02:59 +0200 Subject: [PATCH 183/589] Implementing Cassandra DB & PHP Extension --- cassandra/Dockerfile | 5 +++++ docker-compose.yml | 38 ++++++++++++++++++++++++++++++++++++++ env-example | 36 ++++++++++++++++++++++++++++++++++++ laravel-horizon/Dockerfile | 22 ++++++++++++++++++++++ php-worker/Dockerfile | 20 ++++++++++++++++++++ workspace/Dockerfile | 31 +++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+) create mode 100644 cassandra/Dockerfile diff --git a/cassandra/Dockerfile b/cassandra/Dockerfile new file mode 100644 index 0000000..cdf280a --- /dev/null +++ b/cassandra/Dockerfile @@ -0,0 +1,5 @@ +ARG CASSANDRA_VERSION=latest +FROM bitnami/cassandra:${CASSANDRA_VERSION} + +LABEL maintainer="Stefan Neuhaus " + diff --git a/docker-compose.yml b/docker-compose.yml index 69b5dc6..6773264 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,8 @@ volumes: driver: ${VOLUMES_DRIVER} sonarqube: driver: ${VOLUMES_DRIVER} + cassandra: + driver: ${VOLUMES_DRIVER} services: @@ -67,6 +69,7 @@ services: - INSTALL_IMAP=${WORKSPACE_INSTALL_IMAP} - INSTALL_MONGO=${WORKSPACE_INSTALL_MONGO} - INSTALL_AMQP=${WORKSPACE_INSTALL_AMQP} + - INSTALL_CASSANDRA=${WORKSPACE_INSTALL_CASSANDRA} - INSTALL_PHPREDIS=${WORKSPACE_INSTALL_PHPREDIS} - INSTALL_MSSQL=${WORKSPACE_INSTALL_MSSQL} - INSTALL_NODE=${WORKSPACE_INSTALL_NODE} @@ -153,6 +156,7 @@ services: - INSTALL_IMAP=${PHP_FPM_INSTALL_IMAP} - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} - INSTALL_MSSQL=${PHP_FPM_INSTALL_MSSQL} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_GMP=${PHP_FPM_INSTALL_GMP} @@ -220,6 +224,7 @@ services: - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_WORKER_INSTALL_CASSANDRA} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} - INSTALL_TAINT=${PHP_WORKER_INSTALL_TAINT} @@ -246,6 +251,7 @@ services: - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_MEMCACHED=${PHP_FPM_INSTALL_MEMCACHED} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./laravel-horizon/supervisord.d:/etc/supervisord.d @@ -584,6 +590,38 @@ services: networks: - backend +### Cassandra ############################################ + cassandra: + build: ./cassandra + ports: + - "${CASSANDRA_TRANSPORT_PORT_NUMBER}:7000" + - "${CASSANDRA_JMX_PORT_NUMBER}:7199" + - "${CASSANDRA_CQL_PORT_NUMBER}:9042" + privileged: true + environment: + - CASSANDRA_VERSION=${CASSANDRA_VERSION} + - CASSANDRA_TRANSPORT_PORT_NUMBER=${CASSANDRA_TRANSPORT_PORT_NUMBER} + - CASSANDRA_JMX_PORT_NUMBER=${CASSANDRA_JMX_PORT_NUMBER} + - CASSANDRA_CQL_PORT_NUMBER=${CASSANDRA_CQL_PORT_NUMBER} + - CASSANDRA_USER=${CASSANDRA_USER} + - CASSANDRA_PASSWORD_SEEDER=${CASSANDRA_PASSWORD_SEEDER} + - CASSANDRA_PASSWORD=${CASSANDRA_PASSWORD} + - CASSANDRA_NUM_TOKENS=${CASSANDRA_NUM_TOKENS} + - CASSANDRA_HOST=${CASSANDRA_HOST} + - CASSANDRA_CLUSTER_NAME=${CASSANDRA_CLUSTER_NAME} + - CASSANDRA_SEEDS=${CASSANDRA_SEEDS} + - CASSANDRA_ENDPOINT_SNITCH=${CASSANDRA_ENDPOINT_SNITCH} + - CASSANDRA_ENABLE_RPC=${CASSANDRA_ENABLE_RPC} + - CASSANDRA_DATACENTER=${CASSANDRA_DATACENTER} + - CASSANDRA_RACK=${CASSANDRA_RACK} + hostname: laradock-cassandra + volumes: + - ${DATA_PATH_HOST}/cassandra:/var/lib/cassandra + depends_on: + - php-fpm + networks: + - backend + ### Beanstalkd Console ################################### beanstalkd-console: build: ./beanstalkd-console diff --git a/env-example b/env-example index a7bf59b..a4793a7 100644 --- a/env-example +++ b/env-example @@ -106,6 +106,7 @@ WORKSPACE_INSTALL_XSL=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false +WORKSPACE_INSTALL_CASSANDRA=false WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 @@ -161,6 +162,7 @@ PHP_FPM_INSTALL_PHPDBG=false PHP_FPM_INSTALL_IMAP=false PHP_FPM_INSTALL_MONGO=false PHP_FPM_INSTALL_AMQP=false +PHP_FPM_INSTALL_CASSANDRA=false PHP_FPM_INSTALL_MSSQL=false PHP_FPM_INSTALL_SSH2=false PHP_FPM_INSTALL_SOAP=false @@ -205,6 +207,7 @@ PHP_WORKER_INSTALL_SWOOLE=false PHP_WORKER_INSTALL_TAINT=false PHP_WORKER_INSTALL_FFMPEG=false PHP_WORKER_INSTALL_GMP=false +PHP_WORKER_INSTALL_CASSANDRA=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 @@ -731,3 +734,36 @@ SONARQUBE_POSTGRES_HOST=postgres SONARQUBE_POSTGRES_DB=sonar SONARQUBE_POSTGRES_USER=sonar SONARQUBE_POSTGRES_PASSWORD=sonarPass + +### CASSANDRA ################################################ + +# Cassandra Version, supported tags can be found at https://hub.docker.com/r/bitnami/cassandra/ +CASSANDRA_VERSION=latest +# Inter-node cluster communication port. Default: 7000 +CASSANDRA_TRANSPORT_PORT_NUMBER=7000 +# JMX connections port. Default: 7199 +CASSANDRA_JMX_PORT_NUMBER=7199 +# Client port. Default: 9042. +CASSANDRA_CQL_PORT_NUMBER=9042 +# Cassandra user name. Defaults: cassandra +CASSANDRA_USER=cassandra +# Password seeder will change the Cassandra default credentials at initialization. In clusters, only one node should be marked as password seeder. Default: no +CASSANDRA_PASSWORD_SEEDER=no +# Cassandra user password. Default: cassandra +CASSANDRA_PASSWORD=cassandra +# Number of tokens for the node. Default: 256. +CASSANDRA_NUM_TOKENS=256 +# Hostname used to configure Cassandra. It can be either an IP or a domain. If left empty, it will be resolved to the machine IP. +CASSANDRA_HOST= +# Cluster name to configure Cassandra.. Defaults: My Cluster +CASSANDRA_CLUSTER_NAME="My Cluster" +# : Hosts that will act as Cassandra seeds. No defaults. +CASSANDRA_SEEDS= + # Snitch name (which determines which data centers and racks nodes belong to). Default SimpleSnitch +CASSANDRA_ENDPOINT_SNITCH=SimpleSnitch + # Enable the thrift RPC endpoint. Default :true +CASSANDRA_ENABLE_RPC=true +# Datacenter name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: dc1. +CASSANDRA_DATACENTER=dc1 +# Rack name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: rack1. +CASSANDRA_RACK=rack1 \ No newline at end of file diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index e89468e..c948616 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -45,6 +45,28 @@ RUN if [ ${INSTALL_PGSQL} = true ]; then \ && docker-php-ext-install pdo_pgsql \ ;fi +# Install Cassandra drivers: +ARG INSTALL_CASSANDRA=false +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apk --update add cassandra-cpp-driver \ + ;fi + +WORKDIR /usr/src +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + git clone https://github.com/datastax/php-driver.git \ + && cd php-driver/ext \ + && phpize \ + && mkdir -p /usr/src/php-driver/build \ + && cd /usr/src/php-driver/build \ + && ../ext/configure > /dev/null \ + && make clean >/dev/null \ + && make >/dev/null 2>&1 \ + && make install \ + && docker-php-ext-enable cassandra \ +;fi + + + ########################################################################### # PHP Memcached: ########################################################################### diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 5297c7b..b8d482d 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -85,6 +85,26 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ docker-php-ext-install sockets \ ;fi +# Install Cassandra drivers: +ARG INSTALL_CASSANDRA=false +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apk --update add cassandra-cpp-driver \ + ;fi + +WORKDIR /usr/src +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + git clone https://github.com/datastax/php-driver.git \ + && cd php-driver/ext \ + && phpize \ + && mkdir -p /usr/src/php-driver/build \ + && cd /usr/src/php-driver/build \ + && ../ext/configure --with-php-config=/usr/bin/php-config7.1 > /dev/null \ + && make clean >/dev/null \ + && make >/dev/null 2>&1 \ + && make install \ + && docker-php-ext-enable cassandra \ +;fi + # Install Phalcon ext ARG INSTALL_PHALCON=false ARG PHALCON_VERSION diff --git a/workspace/Dockerfile b/workspace/Dockerfile index bdc0349..cbbeb2e 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -406,6 +406,37 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/amqp.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-amqp.ini \ ;fi +########################################################################### +# CASSANDRA: +########################################################################### + +ARG INSTALL_CASSANDRA=false + +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apt-get install libgmp-dev -y && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/dependencies/libuv/v1.28.0/libuv1-dev_1.28.0-1_amd64.deb -o libuv1-dev.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/dependencies/libuv/v1.28.0/libuv1_1.28.0-1_amd64.deb -o libuv1.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/cassandra/v2.12.0/cassandra-cpp-driver-dev_2.12.0-1_amd64.deb -o cassandra-cpp-driver-dev.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/cassandra/v2.12.0/cassandra-cpp-driver_2.12.0-1_amd64.deb -o cassandra-cpp-driver.deb && \ + dpkg -i libuv1.deb && \ + dpkg -i libuv1-dev.deb && \ + dpkg -i cassandra-cpp-driver.deb && \ + dpkg -i cassandra-cpp-driver-dev.deb && \ + rm libuv1.deb libuv1-dev.deb cassandra-cpp-driver-dev.deb cassandra-cpp-driver.deb && \ + cd /usr/src && \ + git clone https://github.com/datastax/php-driver.git && \ + cd /usr/src/php-driver/ext && \ + phpize && \ + mkdir /usr/src/php-driver/build && \ + cd /usr/src/php-driver/build && \ + ../ext/configure > /dev/null && \ + make clean >/dev/null && \ + make >/dev/null 2>&1 && \ + make install && \ + echo "extension=cassandra.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/cassandra.ini && \ + ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/cassandra.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-cassandra.ini \ +;fi + ########################################################################### # PHP REDIS EXTENSION ########################################################################### From 99ceef7b458973251d53c606eebf6277dcb0fe62 Mon Sep 17 00:00:00 2001 From: Stefan Neuhaus Date: Thu, 25 Jul 2019 08:08:01 +0200 Subject: [PATCH 184/589] Update documentation for Cassandra --- DOCUMENTATION/content/introduction/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 4874e43..143faa2 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -125,6 +125,7 @@ That's it! enjoy :) - Neo4j - CouchDB - RethinkDB + - Cassandra - **Database Management Apps:** From 4cb6ffc76655c8c70dc326f5f548d41cc2b37814 Mon Sep 17 00:00:00 2001 From: Stefan Neuhaus Date: Thu, 25 Jul 2019 08:14:50 +0200 Subject: [PATCH 185/589] Added Cassandra for testing CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d473177..8773aa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ env: - PHP_VERSION=NA BUILD_SERVICE=solr - PHP_VERSION=NA BUILD_SERVICE="mssql rethinkdb aerospike" - - PHP_VERSION=NA BUILD_SERVICE="blackfire minio percona nginx caddy apache2 mysql mariadb postgres postgres-postgis neo4j mongo redis" + - PHP_VERSION=NA BUILD_SERVICE="blackfire minio percona nginx caddy apache2 mysql mariadb postgres postgres-postgis neo4j mongo redis cassandra" - PHP_VERSION=NA BUILD_SERVICE="adminer phpmyadmin pgadmin" - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy" - PHP_VERSION=NA BUILD_SERVICE="kibana grafana laravel-echo-server" From 1602ff2dd054afd085881cffd5426246f880bfea Mon Sep 17 00:00:00 2001 From: stefan Date: Thu, 25 Jul 2019 10:18:33 +0200 Subject: [PATCH 186/589] Implement Cassandra DB & PHP Extension (#2214) * Implementing Cassandra DB & PHP Extension * Update documentation for Cassandra * Added Cassandra for testing CI --- .travis.yml | 2 +- DOCUMENTATION/content/introduction/index.md | 1 + cassandra/Dockerfile | 5 +++ docker-compose.yml | 38 +++++++++++++++++++++ env-example | 36 +++++++++++++++++++ laravel-horizon/Dockerfile | 22 ++++++++++++ php-worker/Dockerfile | 20 +++++++++++ workspace/Dockerfile | 31 +++++++++++++++++ 8 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 cassandra/Dockerfile diff --git a/.travis.yml b/.travis.yml index d473177..8773aa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ env: - PHP_VERSION=NA BUILD_SERVICE=solr - PHP_VERSION=NA BUILD_SERVICE="mssql rethinkdb aerospike" - - PHP_VERSION=NA BUILD_SERVICE="blackfire minio percona nginx caddy apache2 mysql mariadb postgres postgres-postgis neo4j mongo redis" + - PHP_VERSION=NA BUILD_SERVICE="blackfire minio percona nginx caddy apache2 mysql mariadb postgres postgres-postgis neo4j mongo redis cassandra" - PHP_VERSION=NA BUILD_SERVICE="adminer phpmyadmin pgadmin" - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy" - PHP_VERSION=NA BUILD_SERVICE="kibana grafana laravel-echo-server" diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 4874e43..143faa2 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -125,6 +125,7 @@ That's it! enjoy :) - Neo4j - CouchDB - RethinkDB + - Cassandra - **Database Management Apps:** diff --git a/cassandra/Dockerfile b/cassandra/Dockerfile new file mode 100644 index 0000000..cdf280a --- /dev/null +++ b/cassandra/Dockerfile @@ -0,0 +1,5 @@ +ARG CASSANDRA_VERSION=latest +FROM bitnami/cassandra:${CASSANDRA_VERSION} + +LABEL maintainer="Stefan Neuhaus " + diff --git a/docker-compose.yml b/docker-compose.yml index 69b5dc6..6773264 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,8 @@ volumes: driver: ${VOLUMES_DRIVER} sonarqube: driver: ${VOLUMES_DRIVER} + cassandra: + driver: ${VOLUMES_DRIVER} services: @@ -67,6 +69,7 @@ services: - INSTALL_IMAP=${WORKSPACE_INSTALL_IMAP} - INSTALL_MONGO=${WORKSPACE_INSTALL_MONGO} - INSTALL_AMQP=${WORKSPACE_INSTALL_AMQP} + - INSTALL_CASSANDRA=${WORKSPACE_INSTALL_CASSANDRA} - INSTALL_PHPREDIS=${WORKSPACE_INSTALL_PHPREDIS} - INSTALL_MSSQL=${WORKSPACE_INSTALL_MSSQL} - INSTALL_NODE=${WORKSPACE_INSTALL_NODE} @@ -153,6 +156,7 @@ services: - INSTALL_IMAP=${PHP_FPM_INSTALL_IMAP} - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} - INSTALL_MSSQL=${PHP_FPM_INSTALL_MSSQL} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_GMP=${PHP_FPM_INSTALL_GMP} @@ -220,6 +224,7 @@ services: - INSTALL_ZIP_ARCHIVE=${PHP_WORKER_INSTALL_ZIP_ARCHIVE} - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_WORKER_INSTALL_CASSANDRA} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} - INSTALL_TAINT=${PHP_WORKER_INSTALL_TAINT} @@ -246,6 +251,7 @@ services: - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_MEMCACHED=${PHP_FPM_INSTALL_MEMCACHED} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} + - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} - ./laravel-horizon/supervisord.d:/etc/supervisord.d @@ -584,6 +590,38 @@ services: networks: - backend +### Cassandra ############################################ + cassandra: + build: ./cassandra + ports: + - "${CASSANDRA_TRANSPORT_PORT_NUMBER}:7000" + - "${CASSANDRA_JMX_PORT_NUMBER}:7199" + - "${CASSANDRA_CQL_PORT_NUMBER}:9042" + privileged: true + environment: + - CASSANDRA_VERSION=${CASSANDRA_VERSION} + - CASSANDRA_TRANSPORT_PORT_NUMBER=${CASSANDRA_TRANSPORT_PORT_NUMBER} + - CASSANDRA_JMX_PORT_NUMBER=${CASSANDRA_JMX_PORT_NUMBER} + - CASSANDRA_CQL_PORT_NUMBER=${CASSANDRA_CQL_PORT_NUMBER} + - CASSANDRA_USER=${CASSANDRA_USER} + - CASSANDRA_PASSWORD_SEEDER=${CASSANDRA_PASSWORD_SEEDER} + - CASSANDRA_PASSWORD=${CASSANDRA_PASSWORD} + - CASSANDRA_NUM_TOKENS=${CASSANDRA_NUM_TOKENS} + - CASSANDRA_HOST=${CASSANDRA_HOST} + - CASSANDRA_CLUSTER_NAME=${CASSANDRA_CLUSTER_NAME} + - CASSANDRA_SEEDS=${CASSANDRA_SEEDS} + - CASSANDRA_ENDPOINT_SNITCH=${CASSANDRA_ENDPOINT_SNITCH} + - CASSANDRA_ENABLE_RPC=${CASSANDRA_ENABLE_RPC} + - CASSANDRA_DATACENTER=${CASSANDRA_DATACENTER} + - CASSANDRA_RACK=${CASSANDRA_RACK} + hostname: laradock-cassandra + volumes: + - ${DATA_PATH_HOST}/cassandra:/var/lib/cassandra + depends_on: + - php-fpm + networks: + - backend + ### Beanstalkd Console ################################### beanstalkd-console: build: ./beanstalkd-console diff --git a/env-example b/env-example index a7bf59b..a4793a7 100644 --- a/env-example +++ b/env-example @@ -106,6 +106,7 @@ WORKSPACE_INSTALL_XSL=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false +WORKSPACE_INSTALL_CASSANDRA=false WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 @@ -161,6 +162,7 @@ PHP_FPM_INSTALL_PHPDBG=false PHP_FPM_INSTALL_IMAP=false PHP_FPM_INSTALL_MONGO=false PHP_FPM_INSTALL_AMQP=false +PHP_FPM_INSTALL_CASSANDRA=false PHP_FPM_INSTALL_MSSQL=false PHP_FPM_INSTALL_SSH2=false PHP_FPM_INSTALL_SOAP=false @@ -205,6 +207,7 @@ PHP_WORKER_INSTALL_SWOOLE=false PHP_WORKER_INSTALL_TAINT=false PHP_WORKER_INSTALL_FFMPEG=false PHP_WORKER_INSTALL_GMP=false +PHP_WORKER_INSTALL_CASSANDRA=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 @@ -731,3 +734,36 @@ SONARQUBE_POSTGRES_HOST=postgres SONARQUBE_POSTGRES_DB=sonar SONARQUBE_POSTGRES_USER=sonar SONARQUBE_POSTGRES_PASSWORD=sonarPass + +### CASSANDRA ################################################ + +# Cassandra Version, supported tags can be found at https://hub.docker.com/r/bitnami/cassandra/ +CASSANDRA_VERSION=latest +# Inter-node cluster communication port. Default: 7000 +CASSANDRA_TRANSPORT_PORT_NUMBER=7000 +# JMX connections port. Default: 7199 +CASSANDRA_JMX_PORT_NUMBER=7199 +# Client port. Default: 9042. +CASSANDRA_CQL_PORT_NUMBER=9042 +# Cassandra user name. Defaults: cassandra +CASSANDRA_USER=cassandra +# Password seeder will change the Cassandra default credentials at initialization. In clusters, only one node should be marked as password seeder. Default: no +CASSANDRA_PASSWORD_SEEDER=no +# Cassandra user password. Default: cassandra +CASSANDRA_PASSWORD=cassandra +# Number of tokens for the node. Default: 256. +CASSANDRA_NUM_TOKENS=256 +# Hostname used to configure Cassandra. It can be either an IP or a domain. If left empty, it will be resolved to the machine IP. +CASSANDRA_HOST= +# Cluster name to configure Cassandra.. Defaults: My Cluster +CASSANDRA_CLUSTER_NAME="My Cluster" +# : Hosts that will act as Cassandra seeds. No defaults. +CASSANDRA_SEEDS= + # Snitch name (which determines which data centers and racks nodes belong to). Default SimpleSnitch +CASSANDRA_ENDPOINT_SNITCH=SimpleSnitch + # Enable the thrift RPC endpoint. Default :true +CASSANDRA_ENABLE_RPC=true +# Datacenter name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: dc1. +CASSANDRA_DATACENTER=dc1 +# Rack name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: rack1. +CASSANDRA_RACK=rack1 \ No newline at end of file diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index e89468e..c948616 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -45,6 +45,28 @@ RUN if [ ${INSTALL_PGSQL} = true ]; then \ && docker-php-ext-install pdo_pgsql \ ;fi +# Install Cassandra drivers: +ARG INSTALL_CASSANDRA=false +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apk --update add cassandra-cpp-driver \ + ;fi + +WORKDIR /usr/src +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + git clone https://github.com/datastax/php-driver.git \ + && cd php-driver/ext \ + && phpize \ + && mkdir -p /usr/src/php-driver/build \ + && cd /usr/src/php-driver/build \ + && ../ext/configure > /dev/null \ + && make clean >/dev/null \ + && make >/dev/null 2>&1 \ + && make install \ + && docker-php-ext-enable cassandra \ +;fi + + + ########################################################################### # PHP Memcached: ########################################################################### diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 5297c7b..b8d482d 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -85,6 +85,26 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ docker-php-ext-install sockets \ ;fi +# Install Cassandra drivers: +ARG INSTALL_CASSANDRA=false +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apk --update add cassandra-cpp-driver \ + ;fi + +WORKDIR /usr/src +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + git clone https://github.com/datastax/php-driver.git \ + && cd php-driver/ext \ + && phpize \ + && mkdir -p /usr/src/php-driver/build \ + && cd /usr/src/php-driver/build \ + && ../ext/configure --with-php-config=/usr/bin/php-config7.1 > /dev/null \ + && make clean >/dev/null \ + && make >/dev/null 2>&1 \ + && make install \ + && docker-php-ext-enable cassandra \ +;fi + # Install Phalcon ext ARG INSTALL_PHALCON=false ARG PHALCON_VERSION diff --git a/workspace/Dockerfile b/workspace/Dockerfile index bdc0349..cbbeb2e 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -406,6 +406,37 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/amqp.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-amqp.ini \ ;fi +########################################################################### +# CASSANDRA: +########################################################################### + +ARG INSTALL_CASSANDRA=false + +RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ + apt-get install libgmp-dev -y && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/dependencies/libuv/v1.28.0/libuv1-dev_1.28.0-1_amd64.deb -o libuv1-dev.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/dependencies/libuv/v1.28.0/libuv1_1.28.0-1_amd64.deb -o libuv1.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/cassandra/v2.12.0/cassandra-cpp-driver-dev_2.12.0-1_amd64.deb -o cassandra-cpp-driver-dev.deb && \ + curl https://downloads.datastax.com/cpp-driver/ubuntu/18.04/cassandra/v2.12.0/cassandra-cpp-driver_2.12.0-1_amd64.deb -o cassandra-cpp-driver.deb && \ + dpkg -i libuv1.deb && \ + dpkg -i libuv1-dev.deb && \ + dpkg -i cassandra-cpp-driver.deb && \ + dpkg -i cassandra-cpp-driver-dev.deb && \ + rm libuv1.deb libuv1-dev.deb cassandra-cpp-driver-dev.deb cassandra-cpp-driver.deb && \ + cd /usr/src && \ + git clone https://github.com/datastax/php-driver.git && \ + cd /usr/src/php-driver/ext && \ + phpize && \ + mkdir /usr/src/php-driver/build && \ + cd /usr/src/php-driver/build && \ + ../ext/configure > /dev/null && \ + make clean >/dev/null && \ + make >/dev/null 2>&1 && \ + make install && \ + echo "extension=cassandra.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/cassandra.ini && \ + ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/cassandra.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-cassandra.ini \ +;fi + ########################################################################### # PHP REDIS EXTENSION ########################################################################### From 044261b06fe461c5193581c9863531b06cc343df Mon Sep 17 00:00:00 2001 From: Stefan Neuhaus Date: Thu, 25 Jul 2019 12:03:21 +0200 Subject: [PATCH 187/589] Implement Gearman Message broker & PHP Extension --- .travis.yml | 2 +- DOCUMENTATION/content/introduction/index.md | 1 + docker-compose.yml | 36 +++++++++++++++ env-example | 50 ++++++++++++++++++++- gearman/Dockerfile | 5 +++ php-fpm/Dockerfile | 24 ++++++++++ php-worker/Dockerfile | 7 +++ workspace/Dockerfile | 12 +++++ 8 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 gearman/Dockerfile diff --git a/.travis.yml b/.travis.yml index 8773aa3..8d92a02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ env: - PHP_VERSION=NA BUILD_SERVICE="mssql rethinkdb aerospike" - PHP_VERSION=NA BUILD_SERVICE="blackfire minio percona nginx caddy apache2 mysql mariadb postgres postgres-postgis neo4j mongo redis cassandra" - PHP_VERSION=NA BUILD_SERVICE="adminer phpmyadmin pgadmin" - - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy" + - PHP_VERSION=NA BUILD_SERVICE="memcached beanstalkd beanstalkd-console rabbitmq elasticsearch certbot mailhog maildev selenium jenkins proxy proxy2 haproxy gearman" - PHP_VERSION=NA BUILD_SERVICE="kibana grafana laravel-echo-server" - PHP_VERSION=NA BUILD_SERVICE="ipython-controller manticore" # - PHP_VERSION=NA BUILD_SERVICE="aws" diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 143faa2..48acd74 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -149,6 +149,7 @@ That's it! enjoy :) - Eclipse Mosquitto - PHP Worker - Laravel Horizon + - Gearman - **Mail Servers:** - Mailu diff --git a/docker-compose.yml b/docker-compose.yml index 6773264..6712fd4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -70,6 +70,7 @@ services: - INSTALL_MONGO=${WORKSPACE_INSTALL_MONGO} - INSTALL_AMQP=${WORKSPACE_INSTALL_AMQP} - INSTALL_CASSANDRA=${WORKSPACE_INSTALL_CASSANDRA} + - INSTALL_GEARMAN=${WORKSPACE_INSTALL_GEARMAN} - INSTALL_PHPREDIS=${WORKSPACE_INSTALL_PHPREDIS} - INSTALL_MSSQL=${WORKSPACE_INSTALL_MSSQL} - INSTALL_NODE=${WORKSPACE_INSTALL_NODE} @@ -157,6 +158,7 @@ services: - INSTALL_MONGO=${PHP_FPM_INSTALL_MONGO} - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} + - INSTALL_GEARMAN=${PHP_FPM_INSTALL_GEARMAN} - INSTALL_MSSQL=${PHP_FPM_INSTALL_MSSQL} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_GMP=${PHP_FPM_INSTALL_GMP} @@ -225,6 +227,7 @@ services: - INSTALL_MYSQL_CLIENT=${PHP_WORKER_INSTALL_MYSQL_CLIENT} - INSTALL_AMQP=${PHP_WORKER_INSTALL_AMQP} - INSTALL_CASSANDRA=${PHP_WORKER_INSTALL_CASSANDRA} + - INSTALL_GEARMAN=${PHP_WORKER_INSTALL_GEARMAN} - INSTALL_GHOSTSCRIPT=${PHP_WORKER_INSTALL_GHOSTSCRIPT} - INSTALL_SWOOLE=${PHP_WORKER_INSTALL_SWOOLE} - INSTALL_TAINT=${PHP_WORKER_INSTALL_TAINT} @@ -622,6 +625,39 @@ services: networks: - backend +### Gearman ############################################ + gearman: + build: ./gearman + ports: + - "${GEARMAN_PORT}:4730" + privileged: true + environment: + - GEARMAN_VERSION=${GEARMAN_VERSION} + - GEARMAN_VERBOSE=${GEARMAN_VERBOSE} + - GEARMAN_QUEUE_TYPE=${GEARMAN_QUEUE_TYPE} + - GEARMAN_THREADS=${GEARMAN_THREADS} + - GEARMAN_BACKLOG=${GEARMAN_BACKLOG} + - GEARMAN_FILE_DESCRIPTORS=${GEARMAN_FILE_DESCRIPTORS} + - GEARMAN_JOB_RETRIES=${GEARMAN_JOB_RETRIES} + - GEARMAN_ROUND_ROBIN=${GEARMAN_ROUND_ROBIN} + - GEARMAN_WORKER_WAKEUP=${GEARMAN_WORKER_WAKEUP} + - GEARMAN_KEEPALIVE=${GEARMAN_KEEPALIVE} + - GEARMAN_KEEPALIVE_IDLE=${GEARMAN_KEEPALIVE_IDLE} + - GEARMAN_KEEPALIVE_INTERVAL=${GEARMAN_KEEPALIVE_INTERVAL} + - GEARMAN_KEEPALIVE_COUNT=${GEARMAN_KEEPALIVE_COUNT} + - GEARMAN_MYSQL_HOST=${GEARMAN_MYSQL_HOST} + - GEARMAN_MYSQL_PORT=${GEARMAN_MYSQL_PORT} + - GEARMAN_MYSQL_USER=${GEARMAN_MYSQL_USER} + - GEARMAN_MYSQL_PASSWORD=${GEARMAN_MYSQL_PASSWORD} + - GEARMAN_MYSQL_PASSWORD_FILE=${GEARMAN_MYSQL_PASSWORD_FILE} + - GEARMAN_MYSQL_DB=${GEARMAN_MYSQL_DB} + - GEARMAN_MYSQL_TABLE=${GEARMAN_MYSQL_TABLE} + hostname: laradock-gearman + depends_on: + - php-fpm + networks: + - backend + ### Beanstalkd Console ################################### beanstalkd-console: build: ./beanstalkd-console diff --git a/env-example b/env-example index a4793a7..d8749d1 100644 --- a/env-example +++ b/env-example @@ -107,6 +107,7 @@ WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false WORKSPACE_INSTALL_CASSANDRA=false +WORKSPACE_INSTALL_GEARMAN=false WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 @@ -163,6 +164,7 @@ PHP_FPM_INSTALL_IMAP=false PHP_FPM_INSTALL_MONGO=false PHP_FPM_INSTALL_AMQP=false PHP_FPM_INSTALL_CASSANDRA=false +PHP_FPM_INSTALL_GEARMAN=false PHP_FPM_INSTALL_MSSQL=false PHP_FPM_INSTALL_SSH2=false PHP_FPM_INSTALL_SOAP=false @@ -208,6 +210,7 @@ PHP_WORKER_INSTALL_TAINT=false PHP_WORKER_INSTALL_FFMPEG=false PHP_WORKER_INSTALL_GMP=false PHP_WORKER_INSTALL_CASSANDRA=false +PHP_WORKER_INSTALL_GEARMAN=false PHP_WORKER_PUID=1000 PHP_WORKER_PGID=1000 @@ -766,4 +769,49 @@ CASSANDRA_ENABLE_RPC=true # Datacenter name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: dc1. CASSANDRA_DATACENTER=dc1 # Rack name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: rack1. -CASSANDRA_RACK=rack1 \ No newline at end of file +CASSANDRA_RACK=rack1 + +### GEARMAN ################################################## + +# Gearman version to use. See available tags at https://hub.docker.com/r/artefactual/gearmand +GEARMAN_VERSION=latest +# Port to use (Default: 6379) +GEARMAN_PORT=6379 +# Logging Level (Default: INFO) +GEARMAN_VERBOSE=INFO +# Persistent queue type to use (Default: builtin) +GEARMAN_QUEUE_TYPE=builtin +# Number of I/O threads to use (Default: 4) +GEARMAN_THREADS=4 +# Number of backlog connections for listen (Default: 32) +GEARMAN_BACKLOG=32 +# Number of file descriptors to allow for the process (Default is max allowed for user) +GEARMAN_FILE_DESCRIPTORS= +# Number of attempts to run the job before the job server removes it. (Default: no limit = 0) +GEARMAN_JOB_RETRIES=0 +# Assign work in round-robin order per worker connection (Default: 0) +GEARMAN_ROUND_ROBIN=0 +# Number of workers to wakeup for each job received (Default: 0) +GEARMAN_WORKER_WAKEUP=0 +# Enable keepalive on sockets (Default: 0) +GEARMAN_KEEPALIVE=0 +# The duration between two keepalive transmissions in idle condition (Default: 30) +GEARMAN_KEEPALIVE_IDLE=30 +# The duration between two successive keepalive retransmissions, if acknowledgement to the previous keepalive transmission is not received (Default: 10) +GEARMAN_KEEPALIVE_INTERVAL=10 +# The number of retransmissions to be carried out before declaring that remote end is not available (Default: 5) +GEARMAN_KEEPALIVE_COUNT=5 +# Mysql server host (Default: localhost) +GEARMAN_MYSQL_HOST=localhost +# Mysql server port (Default: 3306) +GEARMAN_MYSQL_PORT=3306 +# Mysql server user (Default: root) +GEARMAN_MYSQL_USER=root +# Mysql password +GEARMAN_MYSQL_PASSWORD= +# Path to file with mysql password(Docker secrets) +GEARMAN_MYSQL_PASSWORD_FILE= +# Database to use by Gearman (Default: Gearmand) +GEARMAN_MYSQL_DB=Gearmand +# Table to use by Gearman (Default: gearman_queue) +GEARMAN_MYSQL_TABLE=gearman_queue \ No newline at end of file diff --git a/gearman/Dockerfile b/gearman/Dockerfile new file mode 100644 index 0000000..79a0e75 --- /dev/null +++ b/gearman/Dockerfile @@ -0,0 +1,5 @@ +ARG GEARMAN_VERSION=latest +FROM artefactual/gearmand:${GEARMAN_VERSION} + +LABEL maintainer="Stefan Neuhaus " + diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index a25e5f4..54207db 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -306,6 +306,30 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ docker-php-ext-install sockets \ ;fi +########################################################################### +# GEARMAN: +########################################################################### + +ARG INSTALL_GEARMAN=false + +RUN if [ ${INSTALL_GEARMAN} = true ]; then \ + apt-get update && \ + apt-get -y install libgearman-dev && \ + cd /tmp && \ + curl -L https://github.com/wcgallego/pecl-gearman/archive/gearman-2.0.5.zip -O && \ + unzip gearman-2.0.5.zip && \ + mv pecl-gearman-gearman-2.0.5 pecl-gearman && \ + cd /tmp/pecl-gearman && \ + phpize && \ + ./configure && \ + make -j$(nproc) && \ + make install && \ + cd / && \ + rm /tmp/gearman-2.0.5.zip && \ + rm -r /tmp/pecl-gearman && \ + docker-php-ext-enable gearman \ +;fi + ########################################################################### # pcntl ########################################################################### diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index b8d482d..fdd527c 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -85,6 +85,13 @@ RUN if [ ${INSTALL_AMQP} = true ]; then \ docker-php-ext-install sockets \ ;fi +# Install Gearman: +ARG INSTALL_GEARMAN=false + +RUN if [ ${INSTALL_GEARMAN} = true ]; then \ + docker-php-ext-install gearman \ +;fi + # Install Cassandra drivers: ARG INSTALL_CASSANDRA=false RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ diff --git a/workspace/Dockerfile b/workspace/Dockerfile index cbbeb2e..06567f2 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -437,6 +437,18 @@ RUN if [ ${INSTALL_CASSANDRA} = true ]; then \ ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/cassandra.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/30-cassandra.ini \ ;fi +########################################################################### +# Gearman: +########################################################################### + +ARG INSTALL_GEARMAN=false + +RUN if [ ${INSTALL_GEARMAN} = true ]; then \ + add-apt-repository -y ppa:ondrej/pkg-gearman && \ + apt-get update && \ + apt-get install php-gearman -y \ +;fi + ########################################################################### # PHP REDIS EXTENSION ########################################################################### From 58d1eb876e199fb804c55d6a303fe34d0bad8472 Mon Sep 17 00:00:00 2001 From: Mahmoudz Date: Mon, 29 Jul 2019 16:52:27 +0200 Subject: [PATCH 188/589] add funding.yml --- .github/FUNDING.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..61a5c98 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,6 @@ +# DO NOT CHANGE THIS FILE PLEASE. + +open_collective: laradock +ko_fi: laradock +issuehunt: laradock +custom: ['beerpay.io/laradock/laradock', 'paypal.me/mzmmzz'] From 51c6d3549ccffa8f813ac3d7ed727ca0711bd47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E6=AD=A3=E6=B5=B7?= Date: Tue, 30 Jul 2019 12:47:43 +0800 Subject: [PATCH 189/589] fix: fix install xhprof error (#2141) * feat: Add PHP_FPM_INSTALL_XHPROF as an option to install xhprof extension * fix: INSTALL_XHPROF default value set false * fix: install xhprof error * fix: nginx build * fix: when INSTALL_XHPROF = false, rm xhprof.ini --- docker-compose.yml | 1 + php-fpm/Dockerfile | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6773264..00377e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,7 @@ services: - INSTALL_SSHPASS=${PHP_FPM_INSTALL_SSHPASS} - ADDITIONAL_LOCALES=${PHP_FPM_ADDITIONAL_LOCALES} - INSTALL_FFMPEG=${PHP_FPM_FFMPEG} + - INSTALL_XHPROF=${PHP_FPM_INSTALL_XHPROF} - http_proxy - https_proxy - no_proxy diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index a25e5f4..68a1933 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -263,7 +263,7 @@ ARG INSTALL_XHPROF=false RUN if [ ${INSTALL_XHPROF} = true ]; then \ # Install the php xhprof extension if [ $(php -r "echo PHP_MAJOR_VERSION;") = 7 ]; then \ - curl -L -o /tmp/xhprof.tar.gz "https://github.com/tideways/php-xhprof-extension/archive/v4.1.6.tar.gz"; \ + curl -L -o /tmp/xhprof.tar.gz "https://github.com/tideways/php-xhprof-extension/archive/v4.1.7.tar.gz"; \ else \ curl -L -o /tmp/xhprof.tar.gz "https://codeload.github.com/phacility/xhprof/tar.gz/master"; \ fi \ @@ -282,6 +282,10 @@ RUN if [ ${INSTALL_XHPROF} = true ]; then \ COPY ./xhprof.ini /usr/local/etc/php/conf.d +RUN if [ ${INSTALL_XHPROF} = false ]; then \ + rm /usr/local/etc/php/conf.d/xhprof.ini \ +;fi + ########################################################################### # AMQP: ########################################################################### From 2e928a492829cf41709f456f5e731c27e3afdc89 Mon Sep 17 00:00:00 2001 From: Valentino Lauciani Date: Tue, 30 Jul 2019 06:48:24 +0200 Subject: [PATCH 190/589] laravel-horizon: Install 'sockets' without install 'AMQP` (#2211) * Add LARAVEL_HORIZON_INSTALL_SOCKETS variable. Issue #2209 * Get LARAVEL_HORIZON_INSTALL_SOCKETS from .env. Issue #2209 * Get INSTALL_SOCKETS variable and install 'sockets' ext. Issue #2209 --- docker-compose.yml | 2 +- env-example | 4 ++++ laravel-horizon/Dockerfile | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 00377e9..e4a4fc4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -251,7 +251,7 @@ services: - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_BCMATH=${PHP_FPM_INSTALL_BCMATH} - INSTALL_MEMCACHED=${PHP_FPM_INSTALL_MEMCACHED} - - INSTALL_AMQP=${PHP_FPM_INSTALL_AMQP} + - INSTALL_SOCKETS=${LARAVEL_HORIZON_INSTALL_SOCKETS} - INSTALL_CASSANDRA=${PHP_FPM_INSTALL_CASSANDRA} volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER} diff --git a/env-example b/env-example index a4793a7..0e80c21 100644 --- a/env-example +++ b/env-example @@ -222,6 +222,10 @@ NGINX_PHP_UPSTREAM_CONTAINER=php-fpm NGINX_PHP_UPSTREAM_PORT=9000 NGINX_SSL_PATH=./nginx/ssl/ +### LARAVEL_HORIZON ################################################ + +LARAVEL_HORIZON_INSTALL_SOCKETS=false + ### APACHE ################################################ APACHE_HOST_HTTP_PORT=80 diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index c948616..9cc9ba8 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -33,8 +33,8 @@ RUN if [ ${INSTALL_BCMATH} = true ]; then \ ;fi #Install Sockets package: -ARG INSTALL_AMQP=false -RUN if [ ${INSTALL_AMQP} = true ]; then \ +ARG INSTALL_SOCKETS=false +RUN if [ ${INSTALL_SOCKETS} = true ]; then \ docker-php-ext-install sockets \ ;fi From 8254c3464743d86f42e9d7c83764bf3c385b6ad8 Mon Sep 17 00:00:00 2001 From: Majid Hadavand Date: Tue, 30 Jul 2019 09:24:56 +0430 Subject: [PATCH 191/589] Fix:Issue #2038 Install mongodb php extension (#2167) * Fix:Issue #2038 Install mongodb php extension - Make sure `INSTALL_MONGO` flag is `true` - Run pecl install mongodb and enable the extentions in `laravel-horizon` and `php-worker` images - Remember to rebuild images * INSTALL flag default set false --- laravel-horizon/Dockerfile | 2 +- php-worker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/laravel-horizon/Dockerfile b/laravel-horizon/Dockerfile index 9cc9ba8..ee5b9ff 100644 --- a/laravel-horizon/Dockerfile +++ b/laravel-horizon/Dockerfile @@ -24,7 +24,7 @@ RUN apk --update add wget \ procps RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl -RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached +RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 mongodb && docker-php-ext-enable memcached mongodb #Install BCMath package: ARG INSTALL_BCMATH=false diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index b8d482d..b2e496f 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -24,7 +24,7 @@ RUN apk --update add wget \ supervisor RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl -RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached +RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 mongodb && docker-php-ext-enable memcached mongodb # Add a non-root user: ARG PUID=1000 From c4a99cce57da0d47632586c6ee73de9c59d7d9ab Mon Sep 17 00:00:00 2001 From: Zack Craig Date: Fri, 2 Aug 2019 09:02:52 -0400 Subject: [PATCH 192/589] Add en_US.UTF-8 to the default list of extra locales Feel free to decline this, but I thought maybe adding US English to the default list of extra locales may be beneficial? --- env-example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/env-example b/env-example index 0e80c21..214b828 100644 --- a/env-example +++ b/env-example @@ -191,7 +191,7 @@ PHP_FPM_INSTALL_MYSQL_CLIENT=false PHP_FPM_INSTALL_PING=false PHP_FPM_INSTALL_SSHPASS=false PHP_FPM_FFMPEG=false -PHP_FPM_ADDITIONAL_LOCALES="es_ES.UTF-8 fr_FR.UTF-8" +PHP_FPM_ADDITIONAL_LOCALES="en_US.UTF-8 es_ES.UTF-8 fr_FR.UTF-8" ### PHP_WORKER ############################################ @@ -770,4 +770,4 @@ CASSANDRA_ENABLE_RPC=true # Datacenter name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: dc1. CASSANDRA_DATACENTER=dc1 # Rack name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: rack1. -CASSANDRA_RACK=rack1 \ No newline at end of file +CASSANDRA_RACK=rack1 From b2de93cc1ba10c06c39f5ff6cc58756c484e5960 Mon Sep 17 00:00:00 2001 From: Alec Joy Date: Sun, 4 Aug 2019 14:07:05 -0400 Subject: [PATCH 193/589] Add support for pcov code coverage driver --- DOCUMENTATION/content/documentation/index.md | 23 ++++++++++++++++++++ docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 19 ++++++++++++++++ workspace/Dockerfile | 19 ++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index a9aeb8a..55fbb1f 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -299,6 +299,29 @@ For information on how to configure xDebug with your IDE and work it out, check +
+ +## Install pcov + +1 - First install `pcov` in the Workspace and the PHP-FPM Containers: +
+a) open the `.env` file +
+b) search for the `WORKSPACE_INSTALL_PCOV` argument under the Workspace Container +
+c) set it to `true` +
+d) search for the `PHP_FPM_INSTALL_PCOV` argument under the PHP-FPM Container +
+e) set it to `true` + +2 - Re-build the containers `docker-compose build workspace php-fpm` + +Note that pcov is only supported on PHP 7.1 or newer. For more information on setting up pcov optimally, check the recommended section +of the [README](https://github.com/krakjoe/pcov) + + +
## Start/Stop xDebug: diff --git a/docker-compose.yml b/docker-compose.yml index e4a4fc4..5374b8d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,6 +59,7 @@ services: - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_SUBVERSION=${WORKSPACE_INSTALL_SUBVERSION} - INSTALL_XDEBUG=${WORKSPACE_INSTALL_XDEBUG} + - INSTALL_PCOV=${WORKSPACE_INSTALL_PCOV} - INSTALL_PHPDBG=${WORKSPACE_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} - INSTALL_SSH2=${WORKSPACE_INSTALL_SSH2} @@ -148,6 +149,7 @@ services: - LARADOCK_PHP_VERSION=${PHP_VERSION} - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_XDEBUG=${PHP_FPM_INSTALL_XDEBUG} + - INSTALL_PCOV=${PHP_FPM_INSTALL_PCOV} - INSTALL_PHPDBG=${PHP_FPM_INSTALL_PHPDBG} - INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE} - INSTALL_SSH2=${PHP_FPM_INSTALL_SSH2} diff --git a/env-example b/env-example index 0e80c21..39dd35c 100644 --- a/env-example +++ b/env-example @@ -97,6 +97,7 @@ WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_XDEBUG=false +WORKSPACE_INSTALL_PCOV=true WORKSPACE_INSTALL_PHPDBG=false WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false @@ -157,6 +158,7 @@ PHP_FPM_INSTALL_IMAGE_OPTIMIZERS=true PHP_FPM_INSTALL_PHPREDIS=true PHP_FPM_INSTALL_MEMCACHED=false PHP_FPM_INSTALL_XDEBUG=false +PHP_FPM_INSTALL_PCOV=false PHP_FPM_INSTALL_XHPROF=false PHP_FPM_INSTALL_PHPDBG=false PHP_FPM_INSTALL_IMAP=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 68a1933..bc74869 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -164,6 +164,25 @@ RUN sed -i "s/xdebug.remote_autostart=0/xdebug.remote_autostart=1/" /usr/local/e sed -i "s/xdebug.remote_enable=0/xdebug.remote_enable=1/" /usr/local/etc/php/conf.d/xdebug.ini && \ sed -i "s/xdebug.cli_color=0/xdebug.cli_color=1/" /usr/local/etc/php/conf.d/xdebug.ini +########################################################################### +# pcov: +########################################################################### + +USER root + +ARG INSTALL_PCOV=false + +RUN if [ ${INSTALL_PCOV} = true ]; then \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") != "0" ]; then \ + pecl install pcov && \ + echo "extension=pcov.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini && \ + echo "pcov.enabled" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ + ;fi \ + ;fi \ +;fi + + ########################################################################### # Phpdbg: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index cbbeb2e..788244b 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -324,6 +324,25 @@ RUN sed -i "s/xdebug.remote_autostart=0/xdebug.remote_autostart=1/" /etc/php/${L sed -i "s/xdebug.remote_enable=0/xdebug.remote_enable=1/" /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/xdebug.ini && \ sed -i "s/xdebug.cli_color=0/xdebug.cli_color=1/" /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/xdebug.ini +########################################################################### +# pcov: +########################################################################### + +USER root + +ARG INSTALL_PCOV=false + +RUN if [ ${INSTALL_PCOV} = true ]; then \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ + if [ $(php -r "echo PHP_MAJOR_VERSION;") != "0" ]; then \ + pecl install pcov && \ + echo "extension=pcov.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini && \ + echo "pcov.enabled" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ + ;fi \ + ;fi \ +;fi + + ########################################################################### # Phpdbg: ########################################################################### From c2caf730db7459469cb23d1a3fbc91806047c849 Mon Sep 17 00:00:00 2001 From: Alec Joy Date: Sun, 4 Aug 2019 14:14:32 -0400 Subject: [PATCH 194/589] Accidentally left the PCOV env file to defaul true and moved Pcov documentation section below all xdebug entries --- DOCUMENTATION/content/documentation/index.md | 32 ++++++++++---------- env-example | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 55fbb1f..79d2e41 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -299,6 +299,22 @@ For information on how to configure xDebug with your IDE and work it out, check +
+ +## Start/Stop xDebug: + +By installing xDebug, you are enabling it to run on startup by default. + +To control the behavior of xDebug (in the `php-fpm` Container), you can run the following commands from the Laradock root folder, (at the same prompt where you run docker-compose): + +- Stop xDebug from running by default: `.php-fpm/xdebug stop`. +- Start xDebug by default: `.php-fpm/xdebug start`. +- See the status: `.php-fpm/xdebug status`. + +Note: If `.php-fpm/xdebug` doesn't execute and gives `Permission Denied` error the problem can be that file `xdebug` doesn't have execution access. This can be fixed by running `chmod` command with desired access permissions. + + +
## Install pcov @@ -322,22 +338,6 @@ of the [README](https://github.com/krakjoe/pcov) -
- -## Start/Stop xDebug: - -By installing xDebug, you are enabling it to run on startup by default. - -To control the behavior of xDebug (in the `php-fpm` Container), you can run the following commands from the Laradock root folder, (at the same prompt where you run docker-compose): - -- Stop xDebug from running by default: `.php-fpm/xdebug stop`. -- Start xDebug by default: `.php-fpm/xdebug start`. -- See the status: `.php-fpm/xdebug status`. - -Note: If `.php-fpm/xdebug` doesn't execute and gives `Permission Denied` error the problem can be that file `xdebug` doesn't have execution access. This can be fixed by running `chmod` command with desired access permissions. - - -
## Install phpdbg diff --git a/env-example b/env-example index 39dd35c..3861cd7 100644 --- a/env-example +++ b/env-example @@ -97,7 +97,7 @@ WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_XDEBUG=false -WORKSPACE_INSTALL_PCOV=true +WORKSPACE_INSTALL_PCOV=false WORKSPACE_INSTALL_PHPDBG=false WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false From 47bb995cad1fb16c5e1dff001b917ad3f9c6a608 Mon Sep 17 00:00:00 2001 From: Alec Joy Date: Mon, 5 Aug 2019 09:53:36 -0400 Subject: [PATCH 195/589] Typo in PHP version check --- workspace/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 788244b..c70be91 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -334,7 +334,7 @@ ARG INSTALL_PCOV=false RUN if [ ${INSTALL_PCOV} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ - if [ $(php -r "echo PHP_MAJOR_VERSION;") != "0" ]; then \ + if [ $(php -r "echo PHP_MINOR_VERSION;") != "0" ]; then \ pecl install pcov && \ echo "extension=pcov.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini && \ echo "pcov.enabled" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ From bdf2a285a7d9f7d036794b410e85f97ee61aa8c0 Mon Sep 17 00:00:00 2001 From: Alec Joy Date: Mon, 5 Aug 2019 09:54:15 -0400 Subject: [PATCH 196/589] Typo in PHP Version check --- php-fpm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index bc74869..59d64b9 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -174,7 +174,7 @@ ARG INSTALL_PCOV=false RUN if [ ${INSTALL_PCOV} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ - if [ $(php -r "echo PHP_MAJOR_VERSION;") != "0" ]; then \ + if [ $(php -r "echo PHP_MINOR_VERSION;") != "0" ]; then \ pecl install pcov && \ echo "extension=pcov.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini && \ echo "pcov.enabled" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ From ff640a0ca2070b3e02773959504232a1ec494231 Mon Sep 17 00:00:00 2001 From: Alec Joy Date: Mon, 5 Aug 2019 10:45:12 -0400 Subject: [PATCH 197/589] Use docker command to enable pcov --- php-fpm/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 59d64b9..527d9c4 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -176,8 +176,7 @@ RUN if [ ${INSTALL_PCOV} = true ]; then \ if [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ]; then \ if [ $(php -r "echo PHP_MINOR_VERSION;") != "0" ]; then \ pecl install pcov && \ - echo "extension=pcov.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini && \ - echo "pcov.enabled" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ + docker-php-ext-enable pcov \ ;fi \ ;fi \ ;fi From f64adc211430a668021833f53a14db978f71c04e Mon Sep 17 00:00:00 2001 From: mouyong Date: Fri, 9 Aug 2019 08:52:32 +0800 Subject: [PATCH 198/589] workspace and php-fpm change source --- docker-compose.yml | 5 +++++ mysql/my.cnf | 8 +++++++- .../sites/{default.conf => default.conf.example} | 0 php-fpm/Dockerfile | 10 ++++++++++ php-fpm/debian.sources.list | 8 ++++++++ php-fpm/xdebug.ini | 9 +++++++-- workspace/Dockerfile | 9 +++++++++ workspace/ubuntu.sources.list | 15 +++++++++++++++ workspace/xdebug.ini | 9 +++++++-- 9 files changed, 68 insertions(+), 5 deletions(-) rename nginx/sites/{default.conf => default.conf.example} (100%) create mode 100644 php-fpm/debian.sources.list create mode 100644 workspace/ubuntu.sources.list diff --git a/docker-compose.yml b/docker-compose.yml index 462b085..2b9bff3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,7 @@ services: build: context: ./workspace args: + - CHANGE_SOURCE=${CHANGE_SOURCE} - LARADOCK_PHP_VERSION=${PHP_VERSION} - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_SUBVERSION=${WORKSPACE_INSTALL_SUBVERSION} @@ -126,6 +127,7 @@ services: - no_proxy volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG} + - "./workspace/crontab/laradock:/etc/cron.d/laradock" extra_hosts: - "dockerhost:${DOCKER_HOST_IP}" ports: @@ -145,6 +147,7 @@ services: build: context: ./php-fpm args: + - CHANGE_SOURCE=${CHANGE_SOURCE} - LARADOCK_PHP_VERSION=${PHP_VERSION} - LARADOCK_PHALCON_VERSION=${PHALCON_VERSION} - INSTALL_XDEBUG=${PHP_FPM_INSTALL_XDEBUG} @@ -200,6 +203,7 @@ services: - "9000" extra_hosts: - "dockerhost:${DOCKER_HOST_IP}" + dns: 114.114.114.114 environment: - PHP_IDE_CONFIG=${PHP_IDE_CONFIG} - DOCKER_HOST=tcp://docker-in-docker:2375 @@ -211,6 +215,7 @@ services: links: - docker-in-docker + ### PHP Worker ############################################ php-worker: build: diff --git a/mysql/my.cnf b/mysql/my.cnf index 68578ef..a7facd5 100644 --- a/mysql/my.cnf +++ b/mysql/my.cnf @@ -6,5 +6,11 @@ [mysql] [mysqld] -sql-mode="STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" +sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" character-set-server=utf8mb4 +skip-name-resolve +symbolic-links=0 +explicit_defaults_for_timestamp +default_authentication_plugin=mysql_native_password +#skip-grant-tables=1 + diff --git a/nginx/sites/default.conf b/nginx/sites/default.conf.example similarity index 100% rename from nginx/sites/default.conf rename to nginx/sites/default.conf.example diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 68a1933..183bd3c 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -24,6 +24,16 @@ ARG LARADOCK_PHP_VERSION # Set Environment Variables ENV DEBIAN_FRONTEND noninteractive +# If you're in China, or you need to change sources, will be set CHANGE_SOURCE to true in .env. + +ADD debian.sources.list /etc/apt/debian.sources.list +ARG CHANGE_SOURCE=false +RUN if [ ${CHANGE_SOURCE} = true ]; then \ + mv /etc/apt/sources.list /etc/apt/sources.list.back && \ + mv /etc/apt/debian.sources.list /etc/apt/sources.list \ +;fi + + # always run apt update when start and after add new source list, then clean up at end. RUN set -xe; \ apt-get update -yqq && \ diff --git a/php-fpm/debian.sources.list b/php-fpm/debian.sources.list new file mode 100644 index 0000000..4cf4976 --- /dev/null +++ b/php-fpm/debian.sources.list @@ -0,0 +1,8 @@ +deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib +deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib +deb http://mirrors.aliyun.com/debian-security stretch/updates main +deb-src http://mirrors.aliyun.com/debian-security stretch/updates main +deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib +deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib +deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib +deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib \ No newline at end of file diff --git a/php-fpm/xdebug.ini b/php-fpm/xdebug.ini index c3f32ec..42a7c9b 100644 --- a/php-fpm/xdebug.ini +++ b/php-fpm/xdebug.ini @@ -5,14 +5,19 @@ xdebug.remote_connect_back=1 xdebug.remote_port=9000 xdebug.idekey=PHPSTORM -xdebug.remote_autostart=0 +xdebug.remote_autostart=1 xdebug.remote_enable=0 -xdebug.cli_color=0 +xdebug.cli_color=1 xdebug.profiler_enable=0 xdebug.profiler_output_dir="~/xdebug/phpstorm/tmp/profiling" xdebug.remote_handler=dbgp xdebug.remote_mode=req +xdebug.remote_log=/var/log/php/xdebug_remote.log + +xdebug.auto_trace = 1 +xdebug.collect_params = 1 +xdebug.collect_return = 1 xdebug.var_display_max_children=-1 xdebug.var_display_max_data=-1 diff --git a/workspace/Dockerfile b/workspace/Dockerfile index cbbeb2e..fa2ea64 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -24,6 +24,15 @@ ARG LARADOCK_PHP_VERSION # Set Environment Variables ENV DEBIAN_FRONTEND noninteractive +# If you're in China, or you need to change sources, will be set CHANGE_SOURCE to true in .env. + +ADD ubuntu.sources.list /etc/apt/ubuntu.sources.list +ARG CHANGE_SOURCE=false +RUN if [ ${CHANGE_SOURCE} = true ]; then \ + mv /etc/apt/sources.list /etc/apt/sources.list.back && \ + mv /etc/apt/ubuntu.sources.list /etc/apt/sources.list \ +;fi + # Start as root USER root diff --git a/workspace/ubuntu.sources.list b/workspace/ubuntu.sources.list new file mode 100644 index 0000000..6edaa13 --- /dev/null +++ b/workspace/ubuntu.sources.list @@ -0,0 +1,15 @@ +deb http://mirrors.aliyun.com/ubuntu/ xenial main +deb-src http://mirrors.aliyun.com/ubuntu/ xenial main + +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main + +deb http://mirrors.aliyun.com/ubuntu/ xenial universe +deb-src http://mirrors.aliyun.com/ubuntu/ xenial universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates universe + +deb http://mirrors.aliyun.com/ubuntu/ xenial-security main +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main +deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security universe \ No newline at end of file diff --git a/workspace/xdebug.ini b/workspace/xdebug.ini index c3f32ec..42a7c9b 100644 --- a/workspace/xdebug.ini +++ b/workspace/xdebug.ini @@ -5,14 +5,19 @@ xdebug.remote_connect_back=1 xdebug.remote_port=9000 xdebug.idekey=PHPSTORM -xdebug.remote_autostart=0 +xdebug.remote_autostart=1 xdebug.remote_enable=0 -xdebug.cli_color=0 +xdebug.cli_color=1 xdebug.profiler_enable=0 xdebug.profiler_output_dir="~/xdebug/phpstorm/tmp/profiling" xdebug.remote_handler=dbgp xdebug.remote_mode=req +xdebug.remote_log=/var/log/php/xdebug_remote.log + +xdebug.auto_trace = 1 +xdebug.collect_params = 1 +xdebug.collect_return = 1 xdebug.var_display_max_children=-1 xdebug.var_display_max_data=-1 From f01cab7742eca0c4fbc7a3e9afc11acabcb903d0 Mon Sep 17 00:00:00 2001 From: mouyong Date: Fri, 9 Aug 2019 09:08:49 +0800 Subject: [PATCH 199/589] set xdebug.remote_autostart=0 https://github.com/laradock/laradock/issues/2112#issuecomment-489603086 --- php-fpm/xdebug.ini | 2 +- workspace/xdebug.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php-fpm/xdebug.ini b/php-fpm/xdebug.ini index 42a7c9b..1fef058 100644 --- a/php-fpm/xdebug.ini +++ b/php-fpm/xdebug.ini @@ -5,7 +5,7 @@ xdebug.remote_connect_back=1 xdebug.remote_port=9000 xdebug.idekey=PHPSTORM -xdebug.remote_autostart=1 +xdebug.remote_autostart=0 xdebug.remote_enable=0 xdebug.cli_color=1 xdebug.profiler_enable=0 diff --git a/workspace/xdebug.ini b/workspace/xdebug.ini index 42a7c9b..1fef058 100644 --- a/workspace/xdebug.ini +++ b/workspace/xdebug.ini @@ -5,7 +5,7 @@ xdebug.remote_connect_back=1 xdebug.remote_port=9000 xdebug.idekey=PHPSTORM -xdebug.remote_autostart=1 +xdebug.remote_autostart=0 xdebug.remote_enable=0 xdebug.cli_color=1 xdebug.profiler_enable=0 From 48933479809a318cb17bed7742655f65da4aac03 Mon Sep 17 00:00:00 2001 From: mouyong Date: Fri, 9 Aug 2019 09:14:10 +0800 Subject: [PATCH 200/589] remove setting remote_log --- php-fpm/xdebug.ini | 3 +-- workspace/xdebug.ini | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/php-fpm/xdebug.ini b/php-fpm/xdebug.ini index 1fef058..9bc6578 100644 --- a/php-fpm/xdebug.ini +++ b/php-fpm/xdebug.ini @@ -6,14 +6,13 @@ xdebug.remote_port=9000 xdebug.idekey=PHPSTORM xdebug.remote_autostart=0 -xdebug.remote_enable=0 +xdebug.remote_enable=1 xdebug.cli_color=1 xdebug.profiler_enable=0 xdebug.profiler_output_dir="~/xdebug/phpstorm/tmp/profiling" xdebug.remote_handler=dbgp xdebug.remote_mode=req -xdebug.remote_log=/var/log/php/xdebug_remote.log xdebug.auto_trace = 1 xdebug.collect_params = 1 diff --git a/workspace/xdebug.ini b/workspace/xdebug.ini index 1fef058..9bc6578 100644 --- a/workspace/xdebug.ini +++ b/workspace/xdebug.ini @@ -6,14 +6,13 @@ xdebug.remote_port=9000 xdebug.idekey=PHPSTORM xdebug.remote_autostart=0 -xdebug.remote_enable=0 +xdebug.remote_enable=1 xdebug.cli_color=1 xdebug.profiler_enable=0 xdebug.profiler_output_dir="~/xdebug/phpstorm/tmp/profiling" xdebug.remote_handler=dbgp xdebug.remote_mode=req -xdebug.remote_log=/var/log/php/xdebug_remote.log xdebug.auto_trace = 1 xdebug.collect_params = 1 From b8a971e634275bd290bc6f880e39f54f3344e1fd Mon Sep 17 00:00:00 2001 From: mouyong Date: Fri, 9 Aug 2019 09:26:40 +0800 Subject: [PATCH 201/589] fix in aliyun mirrors, hash check error. --- php-fpm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 183bd3c..d5aba61 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -574,7 +574,7 @@ USER root ARG INSTALL_IMAGEMAGICK=false RUN if [ ${INSTALL_IMAGEMAGICK} = true ]; then \ - apt-get install -y libmagickwand-dev imagemagick && \ + apt-get install -f -y libmagickwand-dev imagemagick && \ pecl install imagick && \ docker-php-ext-enable imagick \ ;fi From ab3a325ea3396fe95175986ab33290a630822cdf Mon Sep 17 00:00:00 2001 From: mouyong Date: Fri, 9 Aug 2019 13:11:03 +0800 Subject: [PATCH 202/589] fix apt install fail --- php-fpm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index d5aba61..3b0b600 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -574,7 +574,7 @@ USER root ARG INSTALL_IMAGEMAGICK=false RUN if [ ${INSTALL_IMAGEMAGICK} = true ]; then \ - apt-get install -f -y libmagickwand-dev imagemagick && \ + apt-get install --fix-missing -y libmagickwand-dev imagemagick && \ pecl install imagick && \ docker-php-ext-enable imagick \ ;fi From 4184f45fbd9630ce393a5291c29765eea8ca0c1f Mon Sep 17 00:00:00 2001 From: Adrian Nuta Date: Sat, 10 Aug 2019 11:04:26 +0200 Subject: [PATCH 203/589] update manticore log folder --- docker-compose.yml | 2 +- manticore/config/sphinx.conf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e4a4fc4..c3e0125 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1531,7 +1531,7 @@ services: volumes: - ${MANTICORE_CONFIG_PATH}:/etc/sphinxsearch - ${DATA_PATH_HOST}/manticore/data:/var/lib/manticore/data - - ${DATA_PATH_HOST}/manticore/log:/var/lib/manticore/log + - ${DATA_PATH_HOST}/manticore/log:/var/log/manticore ports: - "${MANTICORE_API_PORT}:9312" - "${MANTICORE_SPHINXQL_PORT}:9306" diff --git a/manticore/config/sphinx.conf b/manticore/config/sphinx.conf index 0a992b9..9824175 100644 --- a/manticore/config/sphinx.conf +++ b/manticore/config/sphinx.conf @@ -11,12 +11,12 @@ searchd { listen = 9312 listen = 9308:http listen = 9306:mysql41 - log = /var/lib/manticore/log/searchd.log + log = /var/log/manticore/searchd.log # you can also send query_log to /dev/stdout to be shown in docker logs - query_log = /var/lib/manticore/log/query.log + query_log = /var/log/manticore/query.log read_timeout = 5 max_children = 30 - pid_file = /var/run/searchd.pid + pid_file = /var/run/manticore/searchd.pid seamless_rotate = 1 preopen_indexes = 1 unlink_old = 1 From 493fc1a01047f285fb2bc768dbbaf62fdd804e02 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 12 Aug 2019 21:46:34 +0200 Subject: [PATCH 204/589] add spo 1 logo --- .github/README.md | 15 +++++++++++---- .github/home-page-images/sponsor-1.png | Bin 0 -> 71605 bytes DOCUMENTATION/config.toml | 2 +- DOCUMENTATION/content/introduction/index.md | 12 +++++++++++- DOCUMENTATION/static/custom-style.css | 13 +++++++++++++ .../layouts/partials/drawer.html | 2 +- 6 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 .github/home-page-images/sponsor-1.png create mode 100644 DOCUMENTATION/static/custom-style.css diff --git a/.github/README.md b/.github/README.md index c3b5c84..6b79353 100644 --- a/.github/README.md +++ b/.github/README.md @@ -16,7 +16,7 @@

Use Docker First - Then Learn About It Later

- forthebadge + forthebadge

@@ -24,13 +24,20 @@

- Laradock Docs + Laradock Documentation

- ## Sponsors +

+ + + Writing essays service Edubirdie + +

+ + @@ -42,7 +49,7 @@ For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. -*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website.* +*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page.* ## People diff --git a/.github/home-page-images/sponsor-1.png b/.github/home-page-images/sponsor-1.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9bbd948f9ce7b7126b5eb85e0e258443e50847 GIT binary patch literal 71605 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 ## Sponsors +

+ + + Writing essays service Edubirdie + +

+ +
+ + @@ -31,7 +41,7 @@ Supports a variety of useful Docker Images, pre-configured to provide a wonderfu For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io.
-*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page, with a link to your website.* +*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page.* ## Quick Overview diff --git a/DOCUMENTATION/static/custom-style.css b/DOCUMENTATION/static/custom-style.css new file mode 100644 index 0000000..0f3957f --- /dev/null +++ b/DOCUMENTATION/static/custom-style.css @@ -0,0 +1,13 @@ +/* Custom CSS */ + +.article a { + border-bottom: none; +} +.project .logo { + width: 200px; + padding-right: 0; +} +.project .banner { + height: 70px; + padding: 25px; +} diff --git a/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/drawer.html b/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/drawer.html index 62e6fa2..7fd69c9 100644 --- a/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/drawer.html +++ b/DOCUMENTATION/themes/hugo-material-docs/layouts/partials/drawer.html @@ -5,7 +5,7 @@ - Laradock + {{ end }} From fa1f33bc518f23b850e8056fccc04a58e5185eca Mon Sep 17 00:00:00 2001 From: "Shao Yu-Lung (Allen)" Date: Thu, 15 Aug 2019 10:02:21 +0800 Subject: [PATCH 205/589] php-fpm: update base image (#2239) --- php-fpm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 68a1933..9d8b9b2 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -15,7 +15,7 @@ ARG LARADOCK_PHP_VERSION # FROM laradock/php-fpm:2.2-${LARADOCK_PHP_VERSION} -FROM letsdockerize/laradock-php-fpm:2.4-${LARADOCK_PHP_VERSION} +FROM letsdockerize/laradock-php-fpm:2.4.1-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " From 5e4fda465982d60a09b801c8b4c738ebf810e352 Mon Sep 17 00:00:00 2001 From: Mahmoudz Date: Thu, 22 Aug 2019 09:53:30 +0200 Subject: [PATCH 206/589] replace the letsdockerize base images with the original once after creating tags for the images. Closing #26 #27 --- DOCUMENTATION/content/documentation/index.md | 1 - env-example | 4 ++-- php-fpm/Dockerfile | 3 +-- workspace/Dockerfile | 3 +-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index a9aeb8a..d83b442 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -250,7 +250,6 @@ docker-compose build php-fpm
## Change the PHP-CLI Version -By default **PHP-CLI 7.0** is running. >Note: it's not very essential to edit the PHP-CLI version. The PHP-CLI is only used for the Artisan Commands & Composer. It doesn't serve your Application code, this is the PHP-FPM job. diff --git a/env-example b/env-example index 0e80c21..76a4af3 100644 --- a/env-example +++ b/env-example @@ -38,7 +38,7 @@ COMPOSE_PROJECT_NAME=laradock ### PHP Version ########################################### # Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 7.3 - 7.2 - 7.1 - 7.0 - 5.6 -PHP_VERSION=7.2 +PHP_VERSION=7.3 ### Phalcon Version ########################################### @@ -770,4 +770,4 @@ CASSANDRA_ENABLE_RPC=true # Datacenter name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: dc1. CASSANDRA_DATACENTER=dc1 # Rack name for the cluster. Ignored in SimpleSnitch endpoint snitch. Default: rack1. -CASSANDRA_RACK=rack1 \ No newline at end of file +CASSANDRA_RACK=rack1 diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 9d8b9b2..27dcec7 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -14,8 +14,7 @@ ARG LARADOCK_PHP_VERSION -# FROM laradock/php-fpm:2.2-${LARADOCK_PHP_VERSION} -FROM letsdockerize/laradock-php-fpm:2.4.1-${LARADOCK_PHP_VERSION} +FROM laradock/php-fpm:2.5-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " diff --git a/workspace/Dockerfile b/workspace/Dockerfile index f41f163..0fd26b6 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -14,8 +14,7 @@ ARG LARADOCK_PHP_VERSION -# FROM laradock/workspace:2.2-${LARADOCK_PHP_VERSION} -FROM letsdockerize/laradock-workspace:2.4-${LARADOCK_PHP_VERSION} +FROM laradock/workspace:2.5-${LARADOCK_PHP_VERSION} LABEL maintainer="Mahmoud Zalt " From ae64a619b713b4d574967c1a7bbe318f8c6b1834 Mon Sep 17 00:00:00 2001 From: xiagw Date: Sun, 25 Aug 2019 17:24:17 +0800 Subject: [PATCH 207/589] add tomcat --- docker-compose.yml | 17 ++++++++++++++++- env-example | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1a729e8..2d06b7f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1487,6 +1487,7 @@ services: networks: - backend - frontend + ### CONFLUENCE ################################################ confluence: container_name: Confluence @@ -1500,4 +1501,18 @@ services: depends_on: - postgres volumes: - - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data \ No newline at end of file + - ${DATA_PATH_HOST}/Confluence:/var/atlassian/application-data + +### tomcat #################################################### + tomcat: + container_name: tomcat + image: tomcat:${TOMCAT_VERSION} + ports: + - "${TOMCAT_HOST_HTTP_PORT}:8080" + networks: + - frontend + - backend + volumes: + - ${DATA_PATH_HOST}/tomcat/webapps:/usr/local/tomcat/webapps + - ${DATA_PATH_HOST}/tomcat/logs:/usr/local/tomcat/logs + # restart: always \ No newline at end of file diff --git a/env-example b/env-example index 6bc5a3f..cf0ab26 100644 --- a/env-example +++ b/env-example @@ -718,3 +718,7 @@ SONARQUBE_POSTGRES_HOST=postgres SONARQUBE_POSTGRES_DB=sonar SONARQUBE_POSTGRES_USER=sonar SONARQUBE_POSTGRES_PASSWORD=sonarPass + +### TOMCAT ################################################ +TOMCAT_VERSION=8.5.43 +TOMCAT_HOST_HTTP_PORT=8080 From 4e306a6be0ac368cba8411325dbbd0385cc07f97 Mon Sep 17 00:00:00 2001 From: Atef Ben Ali Date: Thu, 29 Aug 2019 11:25:08 +0100 Subject: [PATCH 208/589] Fix typo It's `Laravel Dusk v2.x` not `Laravel v2.x` ! --- DOCUMENTATION/content/guides/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index 451c002..9ffd014 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -345,7 +345,7 @@ You could choose to use either: 1. Chrome Driver shipped with Laravel Dusk. (Default) 2. Chrome Driver installed in `workspace` container. (Required tweak on DuskTestCase class) -For Laravel 2.x, you need to update `DuskTestCase#prepare` method if you wish to go with option #2. +For Laravel Dusk 2.x, you need to update `DuskTestCase#prepare` method if you wish to go with option #2. ``` @@ -365,7 +365,7 @@ abstract class DuskTestCase extends BaseTestCase } ``` -For Laravel 1.x, you need to add `DuskTestCase#buildChromeProcess` method if you wish to go with option #2. +For Laravel Dusk 1.x, you need to add `DuskTestCase#buildChromeProcess` method if you wish to go with option #2. ``` Date: Wed, 11 Sep 2019 16:59:56 +0800 Subject: [PATCH 209/589] fix(compose file): add missing config for inotify and fswatch --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index e4a4fc4..9306d6d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -109,6 +109,8 @@ services: - INSTALL_MYSQL_CLIENT=${WORKSPACE_INSTALL_MYSQL_CLIENT} - INSTALL_PING=${WORKSPACE_INSTALL_PING} - INSTALL_SSHPASS=${WORKSPACE_INSTALL_SSHPASS} + - INSTALL_INOTIFY=${WORKSPACE_INSTALL_INOTIFY} + - INSTALL_FSWATCH=${WORKSPACE_INSTALL_FSWATCH} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION} From 2d444e094cd3bbfdc480ce44875dcc409429847a Mon Sep 17 00:00:00 2001 From: xiagw Date: Thu, 12 Sep 2019 08:36:11 +0800 Subject: [PATCH 210/589] php-fpm implement CHANGE_SOURCE WIP #2238 --- php-fpm/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 27dcec7..be2d159 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -23,6 +23,12 @@ ARG LARADOCK_PHP_VERSION # Set Environment Variables ENV DEBIAN_FRONTEND noninteractive +ARG CHANGE_SOURCE=false +RUN if [ ${CHANGE_SOURCE} = true ]; then \ + # Change application source from deb.debian.org to aliyun source + sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list \ +;fi + # always run apt update when start and after add new source list, then clean up at end. RUN set -xe; \ apt-get update -yqq && \ From 559acc278b0f461bdfb165fdbaa1bfde191d9df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Zonta?= Date: Wed, 11 Sep 2019 23:54:29 -0300 Subject: [PATCH 211/589] Added support for OCI8 extension in workspace and php-fpm containers. PHP 5.6, 7.0, 7.1, 7.2 and 7.3 --- docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile | 45 ++++++++++++++++++++++++++++++++++++++++++++ workspace/Dockerfile | 41 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index e4a4fc4..cf2c53c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -83,6 +83,7 @@ services: - INSTALL_WP_CLI=${WORKSPACE_INSTALL_WP_CLI} - INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE} - INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE} + - INSTALL_OCI8=${WORKSPACE_INSTALL_OCI8} - INSTALL_V8JS=${WORKSPACE_INSTALL_V8JS} - COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL} - COMPOSER_AUTH=${WORKSPACE_COMPOSER_AUTH} @@ -165,6 +166,7 @@ services: - INSTALL_OPCACHE=${PHP_FPM_INSTALL_OPCACHE} - INSTALL_EXIF=${PHP_FPM_INSTALL_EXIF} - INSTALL_AEROSPIKE=${PHP_FPM_INSTALL_AEROSPIKE} + - INSTALL_OCI8=${PHP_FPM_INSTALL_OCI8} - INSTALL_MYSQLI=${PHP_FPM_INSTALL_MYSQLI} - INSTALL_PGSQL=${PHP_FPM_INSTALL_PGSQL} - INSTALL_PG_CLIENT=${PHP_FPM_INSTALL_PG_CLIENT} diff --git a/env-example b/env-example index 76a4af3..f5d74ee 100644 --- a/env-example +++ b/env-example @@ -113,6 +113,7 @@ WORKSPACE_DRUSH_VERSION=8.1.17 WORKSPACE_INSTALL_DRUPAL_CONSOLE=false WORKSPACE_INSTALL_WP_CLI=false WORKSPACE_INSTALL_AEROSPIKE=false +WORKSPACE_INSTALL_OCI8=false WORKSPACE_INSTALL_V8JS=false WORKSPACE_INSTALL_LARAVEL_ENVOY=false WORKSPACE_INSTALL_LARAVEL_INSTALLER=false @@ -170,6 +171,7 @@ PHP_FPM_INSTALL_XSL=false PHP_FPM_INSTALL_GMP=false PHP_FPM_INSTALL_EXIF=false PHP_FPM_INSTALL_AEROSPIKE=false +PHP_FPM_INSTALL_OCI8=false PHP_FPM_INSTALL_PGSQL=false PHP_FPM_INSTALL_GHOSTSCRIPT=false PHP_FPM_INSTALL_LDAP=false diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 27dcec7..e769454 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -423,6 +423,51 @@ RUN set -xe; \ && docker-php-ext-enable aerospike \ ;fi +########################################################################### +# PHP OCI8: +########################################################################### + +ARG INSTALL_OCI8=false + +ENV LD_LIBRARY_PATH="/opt/oracle/instantclient_12_1" +ENV OCI_HOME="/opt/oracle/instantclient_12_1" +ENV OCI_LIB_DIR="/opt/oracle/instantclient_12_1" +ENV OCI_INCLUDE_DIR="/opt/oracle/instantclient_12_1/sdk/include" +ENV OCI_VERSION=12 + +RUN if [ ${INSTALL_OCI8} = true ]; then \ + # Install wget + apt-get update && apt-get install --no-install-recommends -y wget \ + # Install Oracle Instantclient + && mkdir /opt/oracle \ + && cd /opt/oracle \ + && wget https://github.com/diogomascarenha/oracle-instantclient/raw/master/instantclient-basic-linux.x64-12.1.0.2.0.zip \ + && wget https://github.com/diogomascarenha/oracle-instantclient/raw/master/instantclient-sdk-linux.x64-12.1.0.2.0.zip \ + && unzip /opt/oracle/instantclient-basic-linux.x64-12.1.0.2.0.zip -d /opt/oracle \ + && unzip /opt/oracle/instantclient-sdk-linux.x64-12.1.0.2.0.zip -d /opt/oracle \ + && ln -s /opt/oracle/instantclient_12_1/libclntsh.so.12.1 /opt/oracle/instantclient_12_1/libclntsh.so \ + && ln -s /opt/oracle/instantclient_12_1/libclntshcore.so.12.1 /opt/oracle/instantclient_12_1/libclntshcore.so \ + && ln -s /opt/oracle/instantclient_12_1/libocci.so.12.1 /opt/oracle/instantclient_12_1/libocci.so \ + && rm -rf /opt/oracle/*.zip \ + # Install PHP extensions deps + && apt-get update \ + && apt-get install --no-install-recommends -y \ + libaio-dev \ + freetds-dev && \ + # Install PHP extensions + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + echo 'instantclient,/opt/oracle/instantclient_12_1/' | pecl install oci8-2.0.10; \ + else \ + echo 'instantclient,/opt/oracle/instantclient_12_1/' | pecl install oci8; \ + fi \ + && docker-php-ext-configure pdo_oci --with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1 \ + && docker-php-ext-configure pdo_dblib --with-libdir=/lib/x86_64-linux-gnu \ + && docker-php-ext-install \ + pdo_oci \ + && docker-php-ext-enable \ + oci8 \ + ;fi + ########################################################################### # IonCube Loader: ########################################################################### diff --git a/workspace/Dockerfile b/workspace/Dockerfile index 0fd26b6..6cc6b97 100644 --- a/workspace/Dockerfile +++ b/workspace/Dockerfile @@ -708,6 +708,47 @@ RUN set -xe; \ && echo 'aerospike.udf.lua_user_path=/usr/local/aerospike/usr-lua' >> /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/aerospike.ini \ ;fi +########################################################################### +# PHP OCI8: +########################################################################### + +USER root +ARG INSTALL_OCI8=false + +ENV LD_LIBRARY_PATH="/opt/oracle/instantclient_12_1" +ENV OCI_HOME="/opt/oracle/instantclient_12_1" +ENV OCI_LIB_DIR="/opt/oracle/instantclient_12_1" +ENV OCI_INCLUDE_DIR="/opt/oracle/instantclient_12_1/sdk/include" +ENV OCI_VERSION=12 + +RUN if [ ${INSTALL_OCI8} = true ]; then \ + # Install wget + apt-get update && apt-get install --no-install-recommends -y wget \ + # Install Oracle Instantclient + && mkdir /opt/oracle \ + && cd /opt/oracle \ + && wget https://github.com/diogomascarenha/oracle-instantclient/raw/master/instantclient-basic-linux.x64-12.1.0.2.0.zip \ + && wget https://github.com/diogomascarenha/oracle-instantclient/raw/master/instantclient-sdk-linux.x64-12.1.0.2.0.zip \ + && unzip /opt/oracle/instantclient-basic-linux.x64-12.1.0.2.0.zip -d /opt/oracle \ + && unzip /opt/oracle/instantclient-sdk-linux.x64-12.1.0.2.0.zip -d /opt/oracle \ + && ln -s /opt/oracle/instantclient_12_1/libclntsh.so.12.1 /opt/oracle/instantclient_12_1/libclntsh.so \ + && ln -s /opt/oracle/instantclient_12_1/libclntshcore.so.12.1 /opt/oracle/instantclient_12_1/libclntshcore.so \ + && ln -s /opt/oracle/instantclient_12_1/libocci.so.12.1 /opt/oracle/instantclient_12_1/libocci.so \ + && rm -rf /opt/oracle/*.zip \ + # Install PHP extensions deps + && apt-get update \ + && apt-get install --no-install-recommends -y \ + libaio-dev && \ + # Install PHP extensions + if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \ + echo 'instantclient,/opt/oracle/instantclient_12_1/' | pecl install oci8-2.0.10; \ + else \ + echo 'instantclient,/opt/oracle/instantclient_12_1/' | pecl install oci8; \ + fi \ + && echo "extension=oci8.so" >> /etc/php/${LARADOCK_PHP_VERSION}/cli/php.ini \ + && php -m | grep -q 'oci8' \ +;fi + ########################################################################### # PHP V8JS: ########################################################################### From 9acb18aee158887a1ad1bb5f6bc1d62e049daa8e Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 13 Sep 2019 12:24:14 +0200 Subject: [PATCH 212/589] Redesign the README and update docs --- .github/README.md | 98 -------- .github/home-page-images/join-us.png | Bin 0 -> 130641 bytes .github/home-page-images/sponsor-1.png | Bin 71605 -> 0 bytes DOCUMENTATION/content/introduction/index.md | 218 ++++++++++++++--- .github/README-zh.md => README-zh.md | 0 README.md | 249 ++++++++++++++++++++ 6 files changed, 438 insertions(+), 127 deletions(-) delete mode 100644 .github/README.md create mode 100644 .github/home-page-images/join-us.png delete mode 100644 .github/home-page-images/sponsor-1.png rename .github/README-zh.md => README-zh.md (100%) create mode 100644 README.md diff --git a/.github/README.md b/.github/README.md deleted file mode 100644 index 6b79353..0000000 --- a/.github/README.md +++ /dev/null @@ -1,98 +0,0 @@ -

- Laradock Logo -

- -

PHP development environment that runs on Docker

- -

- Build status - GitHub stars - GitHub forks - GitHub issues - GitHub license - contributions welcome -

- -

Use Docker First - Then Learn About It Later

- -

- forthebadge -

- - ---- - -

- - Laradock Documentation - -

- -## Sponsors - -

- - - Writing essays service Edubirdie - -

- - - - - - - - - - - -For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. - -*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page.* - -## People - -#### Maintainers: -- [Mahmoud Zalt](https://github.com/Mahmoudz) @mahmoudz | [Twitter](https://twitter.com/Mahmoud_Zalt) | [Site](http://zalt.me) -- [Bo-Yi Wu](https://github.com/appleboy) @appleboy | [Twitter](https://twitter.com/appleboy) -- [Philippe Trépanier](https://github.com/philtrep) @philtrep -- [Mike Erickson](https://github.com/mikeerickson) @mikeerickson -- [Dwi Fahni Denni](https://github.com/zeroc0d3) @zeroc0d3 -- [Thor Erik](https://github.com/thorerik) @thorerik -- [Winfried van Loon](https://github.com/winfried-van-loon) @winfried-van-loon -- [TJ Miller](https://github.com/sixlive) @sixlive -- [Yu-Lung Shao (Allen)](https://github.com/bestlong) @bestlong -- [Milan Urukalo](https://github.com/urukalo) @urukalo -- [Vince Chu](https://github.com/vwchu) @vwchu -- [Huadong Zuo](https://github.com/zuohuadong) @zuohuadong -- [Lan Phan](https://github.com/lanphan) @lanphan -- [Ahkui](https://github.com/ahkui) @ahkui -- Join us. - -#### Awesome Contributors: - - - - -## Donations - -> Help keeping the project development going, by [contributing](http://laradock.io/contributing) or donating a little. -> Thanks in advance. - -Donate directly via [Paypal](https://paypal.me/mzmmzz) - -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) - -or show your support via [Beerpay](https://beerpay.io/laradock/laradock) - -[![Beerpay](https://beerpay.io/laradock/laradock/badge.svg?style=flat)](https://beerpay.io/laradock/laradock) - -or become a backer on [Open Collective](https://opencollective.com/laradock#backer) - - - - -## License - -[MIT License](https://github.com/laradock/laradock/blob/master/LICENSE) diff --git a/.github/home-page-images/join-us.png b/.github/home-page-images/join-us.png new file mode 100644 index 0000000000000000000000000000000000000000..c97f75f9fdb2354fd5a47e56e2717ea430761a79 GIT binary patch literal 130641 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

A*|? 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 literal 0 HcmV?d00001 diff --git a/.github/home-page-images/sponsor-1.png b/.github/home-page-images/sponsor-1.png deleted file mode 100644 index fc9bbd948f9ce7b7126b5eb85e0e258443e50847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71605 zcmbrkWmH_-5-y4p++719KyZS)ySux)HSSIzK!5WLQ``ok7-ebHs z?w{8`daa&4t5&VD`PG~irKBK>0;Po8%M_U3NJXM zUChbZ895kCS-x_Sb8<7Xuyb>XGP7_nF>^DqurV;R@Gx`pFtd>V_e1giG#4`q z9u+Z(|32&e7e9rSo0}646O)IB2cySVMn@M*CKhgPZYE|{CRSF4_ZbYXUJh=?o(vAI zlz(#&Gj}z0v37E^c61>Bi=(lLBfyQH;$71J^9uG(^78*&f5iCzob9USSZ zbu)G_HUFE|`X5@c|0^wzsEfI=o1=@Gqodv5)>E=_baQmIa&#gW75&Rvoa8j}#-`Q| ze+|<9rQrX{Ywlw0Zf+*w;%HC)9}V$X|4WMh;~{2_rtgwC{mqbvgX^maHwz0FgN2!i zDFX`&rzr!sv8g!&mkAfAIWsdSr-d;a#eccI)BaB%|3A1fy$j6rmka#MCH@|I_p`rl z|L5TEKmHdY<__<1;qo2;;jy{F5Rh1J(qh7Do=eA>@a=l$nRfvb+?J0kX+EwqQXlz0 z<%W`a5# zs<${B&c5-)HH?*bIUH}c6sKYF(x5cf;h#5DsqR_>uP)khst|wc%VFgjm;Rc?8&vkCOWCt!MI1 z5eo@2m6=(%s@u5dVYiaD-eB%Sn+;aaZi2>-3k_Ts*m^Dp zUaFYt@Mw0_7u3HNs@J9-B0zRlKwf#vhki!+GeVd<@uy5WSda7kpt3u=>m##y4cc)X z6BHrOtU(zg4{T?e_J1XPzXviQ6RNOtSIKDSiuLT zX>kH4^*hH{ifq*5X;A~W7MuxzqIQhs(p(fU3H6v0;WQTfi*=?=9oD;Pqu+{Ct{MD} ze+8kGYqSB=!yNe~-(tt~Ro_l-nK+a5^6O9LzC+8BdRL#td93L#wfl;HSm-r6o##u= zCSu=U6ooLPi`s&y-h;G(LfHtJYIr=F#p4w&0MWw-A4j1LC97`cPyQEW zSisA4#I3xPk7oy5*g8ziGuZqRBa!lm2)bSR%re_5FiT}H!CEpl>Q7gF|2e8OdaiA) z2iD!)&yqx_2F&{(@AymSFGfMF#v;0tU4CiZ<2XJ@hYdLnZ~-X?HO9{vu7lYRw@sW3 zom(fVzO&cu7?Pz0Yc81(UFIG9WCrZfvaqKTpWx^)gBIH;v;B@V(a!GYKmke1HHUMh zhQ1r{Q;XE3R9D<2oDQD}m6mF(LAQ=8*NexpU2lnxp6#dwZTX?@E$~KF{tAPh<5b;; zoDqTigE`|SN|rVMbzuBiaHQT^b{q8lE_^@p5WPg;^^%5?qr?Cc*TuE9?=jiwYNP(d>e|)9&UN1t%U=z$DNTOQ%Wv>CX2igN zXEC*!7BIJN=XF*(E7OW%HE9SLlOdd|Wl}dIOD(|9(Jnx9pA zL__A!VUjRzHSkVoYw_$!q<@f@_~0FYWU&NsMOClQJ}TfWeI_1|BjEE`wt;~{G9vSq zwC!=j+x5lqrDXCSl`NV?WZ_n2=o4c+|Dasy{UbmUi>`PWQU>x1eP79&s7 zdL)G{o-x-8b0NHRBBV)tv8|T7qLY9~oZ0o5uV-;dy3}Ui((g5jrjk((Z=_C(sgRWa4k#b@cwf#~y*Z5_p>$Y;e zklyg&pRfUFg|y;8bMUJoMc&BNgjF6`KomfaVHGi^zGNx-eFp5ctuI;@#=M%KhL8TP zNB;0i?3VrV2cu~CG;PHp;V|MeC zGUtqZ;aXlv_J;|AJuiEU`^}1De7J>|I~V+*l*opKSnmXHK zlM{ojx4@#CP5vbr*|Fwy&(;uFQ3rL>lde94>_W3JbBkRfNj-+Y?!7n&3}T*P-ylKK zVVk7@yvD*{ec7~_XM?`!g)8&0o0;i8u|!yTvwmx^N;re~msow*kGiw8HQJ4`L67+j zfd*&`Bgs1}eWtjE%vZf{x9UE7(pMg;ksj{dae~xV9LW70-wY`+x{}gtd&l{34`S)t{uG!+(i%C`%m#?~O#b;H&xpIAPE-q9gbji9m72)WNP>Nrvs@n)nTNnFau zinDX%xvCm>^5#W)V4q+jy1(KN7;Qg)qF(LHOb<~MgWhl#IX{hsS^&57f(9Bi+j<=z zzn)jlz^py0M zCbJP`gbjmb+R2Ca>w|o`hNY&!lZi$D4AZ`$ersp5&xnF}H-TzoW8>l=W0w0(F)$&~ zA|~<3br*+F7}2xTh`Y>)mr$#J*o85syB4^)5}wG=GyHSo2dsXNmz^A9tj+)x=aWlA zlM-u7M>t?Gy#56N=If8h;yA&x&}#&|tPM8@@C4u6h@XW4?8qf5P@J6JD^LPwRKL3eJjn zFC-{TYNdHiv6H1fHod(xtf|?yFU+aeb5?1uwrx#Jpte6RWY?9aRL}$LS1SWS45D_m zHRc1MU)TJ_XNDcS7E-#MLB7@`Bx24CyK;Chz=1XeKL`8^8WbnVtDk1eZVBPKh3Crs+4CXS%q8iNpD?XHZ=}#sjySi_|0-WtNb|hZUE_HD zmj2qvc99yz4LkNN2ThJ+!n^d;+~NqUem`D7qdW*fYDD zZ7^`)iH&z7`wC-c4wC4$CwULkhw&FbGOc1~i zbX}qK;u`c+o_WNIJtN+Ws1B+t&@u)vY$=4thBflw+FtyUE zfl42`^)Y=TgZ{u^3U%%LV}_A#0i}Ow!xxp$HtG}h@T|I*hH+))Sjh_X#m4$@BWQSu z2JS&j)X79edb%f&KPcNNWnpguAfpJ7EJ-fV1Yd04X6^)9pY{#!!#hk@zo@mN{9!!b zlnnYt{@(8Yk36xJh4=-`V zL4$5BIqU+9OtR9F?TJ@cR5bYl0GA+j1D2{MQ1kt_uc}DnT)B6r0d4uo6Rl{_4Z08U>AfCOgVb0Y^kqC74#d{TWP;4G96ZrZRbh%llaQodHy{cmBK7mjx}BJY6Idf;8(^`j{` z8~$d{2xmD+;<^NT)#Z7{e>;4}QzfVy=p=JviAP^sMC63ij?4R%=H&S9W2RAiyClqI zrF0HAhgL!*;%)yVZtCQV1}}G@@ofbMlP&`x2-Zc}l0QGmws+jph}3T?uQWSg}K z9lY8zaL6?PZH3n4(%yw*V=?Aca^qfd{YQO&1Mdt^>kS*-c7r$kZ$xcUgX*OeM}xoC zAk(t~4d*onUz<$MhTWC^;B4;7 z_^WWio_(lo2h*R*BTh2hG@Ynl)O>Jewb}IfpqG-%4|AqIVLPQUZ%BO$Im9AI7UJ*q z;JSEBc7KFN5v4}y3;wGvi7;NR_(e{DxdwIBUmCGM$68++93kY_f2Qb+iwTaG}1HPjh8EFMx10Z}H zO&29y!iw=$6L@erF!%k>86*`9nEkGrULW6f8arfw=PbyMw1dnOBM5u#X&vWHYi$Vk z4*)38IyFG!{!an&-x=;*$*4KE6M3Za5NH7gM%#%u=yjwy5e$b4^gkVR&WF#QyW7w6 zLAU$ZIX>e~};0m>=5qH1c@ zs-YD-qGgHi=pEk%wki>~%B~RaCV9En_Q}?)7y+7d8J^hd_b6?4%N=+OX`D~DLxu%< z3SuFmt|CSEp&kF`j2^Uxkrs=_IG9aURptd4)oSb1$fv)wz??=&>ekXo9`SY zU5bGXCFwX)j%0#oGwW~G{(Fam2cB*$F^Zl9jcqRH^MFH1ls%Z!d76Fv$R6Eo^@~*@ z{8n3D#&VC6_Kb=onJS%$c;s^v^iz0{hI@Vl7c=8U?@5_{ps7T~Et>C(MV+zSRqVRo zOIr^MnSi#Qc*803jsAvoSC_caB`qcvUTNL0-L}Yo!pguy2_!_S&fvMs2o)wk-iCCb zhg9J&wDHsMUV5M`w<-&#dhsoPXO}AxFW9^gAuY8Ej(*jGey( ze<#gk;YPbhop%RTYvV1tFA0Zp27&i=-i282N_yu-$Mfjd*qL|%y<0%=^*C`m4zJ&x z`{VKoJd+>Pb~Ef0{#D`-%D|5iekiYg?AW8>AVNA%PqH0SF2i|7s)%-iN1+nZcA`%M zL=1C2j2R-h431Bu?C3=`FL;LSD09g--tYC*%EP-2*5!l9ohN9&WN4{l*p4bL~b0AZq^nq}TLhlQ&Toef~s288>{Dt1Yat=j#RaOG|iV?Jy4Oz0kYJfK{ z8Yqw|B!CQtIauX3(uA{;hOqut6L&w7l;Jg9<1~ zF`g*rCk&Y&eM#ufh^8u{-{Ot>M|RZrB{qs(w&yti4f1&tNu;egj&xiy_?o!_&%)pe z?TrH0&`(@|m)VL2xE7opCJ$Vx6zW)R%1H;{ej4#?=_6#oQZA39MUNv4(cWa2X(ctA z54TbjQbNnvY<7cjuky-gB#V%3K>3`Hbz|Id{9s`F6Yb)4qh=_XoU>%RS{xuyrXz}+ z$AD5_^xWs^hP=WL(YD`1HS);&df4Fr6s&vNJbV3sgLl8Ab_cMaD+7h=kU{XG@m+HV zp*<@c5ySl}8S_BooVIjVz3CV&uKFPDmq1>7J0H%vBu;og`KYA4tPVcbdfgO>t+tvY z^6mb~^yl-o&ueDQz)CI7M>jKfh!Umo6rY|Zr=wRsl>WuNN}kxJnusTV3^^LHeZ%7b zp&qDDln#v4nyD;|vh=#4# zf2bm>@$qoKVSG4&KL6SU3UTF@E0-73ynxj5Bdb0pC13mPf%Q*rCP7y^(`Hg5LY|SmZLX#}e>eMQWNx7R$@_Q&%Fgb6nA2sKUR#=ap9L>_5iIWmDnq9%?Ev1t+{@4mz!5St$Ng$AOzz@k8A~RUX zZAuKkSS~!37uQPuUg_+QuxxF~QE7#c_b)2ZhM6#~jolHtn;B7fpu2Z(fFi2k7)Du- zz|b*}^Z9mYT4B)6mT5;;H^}})9k30SUOKv`PEXuk4_GdyJe;rT8NpDqsfd`+zt0F4 zCA3MLdYItkL*Vm(&vfq0{~r#*1w({9c0#nO&-^*JBzuVMdI|mdR3Yy0k<*1~Xp5wV ze4x%^ z+rY9_bW%*DC0F3~TP-|<_IN*Oqhz;(DneT(j~zrKuZg>__9%r*U-0lY@L^g$*A)+e zo$lJ3Ya&n?`be~Hu5 z=#y>nFC06u!Dnz;Y{vEdfe6l#dqy3n!VtGp-QL{c9i#iTpGWkjE~uGk(jTpSZ-*1I zG@m+6($T<4Bx}wQd(N8RTN&;cuO|jhvw4BG_Ga@%M74yGu#c7dh z71tb&ZPly&u$0l7KR>Hj^j~;-Wu$K4%wvP zb}(l*GF(9%45=7^=D- zV~L^bKfPeOwGyXuvceJhhkLeo!%zMsNaOEncLxRiu#<`L1HHX4hyD@*EQoYy-Bj<3 z*|)cLgV7)VwF?nZPCr}uljD;>W^mjI#7+Vt{r1rqen&ASaF<*F7mLA^dfa<(&~Zh+ zf5enl@E4J}4=BzY+Wyz9I4tww#EJIM2?0rfz=zc!K3cZo)-2@F)}IB=OEC0)@IH^J zjKvQ30|zd_>@6J-9-0^fJD*|*tjWLl(me;kTp1sa;2?RM{}Pt#5^}c;I?Z@ozSUG>^2*q3n^9e9WgdW*k7{)|H~1Jb`}{S|L15c2R%^54OKY?Nc#=AH+u9oBy+RqZEQayGtg^dq>DZh&hkz{@R4Z# z$ul``*Z*?+dEmRPbIP-uFVFM`YJLI(8)UOG9M&mh0!2|V94?)22q>Pa(a6}a?v^NaCwL2M#hx6L0EhRb z&_A>Yi#|K1<3@W3h#B+n9lcUn(0Vy2o)}IQ+~a*;sbmizkT6X9N#ns#6g#H{I9{6R zl=V$niXeF*T!Y_ix9Rt{@NH4(d2B~;%Xxaf`;e9CrzYCQP>glB>| zwivVBy|nAqo*|h0M-#S!>fixA@RprNeW4&bkl{vq2AgH5_NLVvcK0n5O6+jSDH=9& zQ!ie6xthF^%Zv^76Jd}Ul2|K_hA7==Q4KR@CC$x%GP>#J0M4W&c1#+J%zCWnY5bK=^hv-QD4^jf!0|x`Vy|C`E-a0NjXLmNXT-;T41jB!UH|{ydg<8v5y-GUoz(1o zRFKSDxUbRc_2C0T?91Mu;s|=adJ2~22BY5*cJ9*NPBx>QYLBl-1NMqkV%`OA>c!{L zUji7^Wc)aZv8gfhw^3Ghq#NSPU3nETdnL2zVm8>3CQ;2Mbhva7X@EMm}Ng^j9Jz7%%GLo z%5g1gD=&`PQAMku)M*{(AhgYTW;xG7731C%#?Ilj8W;QXQ>khLH~@Ta+rWGIjX(Rh zaVz|i)FVnqCQRi~e%ygQEwxb&V)a!jKMY<7Yr{b>7FNhsP?$O2r3bs#exsB6v|XKR zH0$Jw?oMja`Bg|W3Wtcwz+a0T^LuV?DS_#rd|wi!rSV?ILn;fHMvl+q3!$#=&7(|V zo=uq{;s!r#9S}-Qm)}uNo683nyk+;M$%|ex-#VrNYBTkDEWW>luS-yIpNqx0Hs^t(B(#_-ri&?FbzK+F zSAm}ASOGy=eIAYiITHEbT8GJ=BQ2Z;HQ+(c7awNn?fH5al@{hyBINCVAR1tUN@;kD z)ZK?Vnb>Eiug?|b``8Igr#YQF<8swU{cs!qIG+6`;w)o8vp2*=cqznMJ+{!3Jh~mG zTKUP$4#dk3sUl{F=TD<)O%Re~9;|yzdIdfF$x?Y*^b{!*`DV*DUU-d<$dK)jL|}LB z`)o^?`BUsj$ypA5!TfeFk!Zu;V}2x9qp*RDb%;YArKSs|OAvEmcV*iMM}8XFv;g8Q z#D$r%Y!t*+EDU70!)S89XCUOzO{TwfqsuW5q@OC3$*pGqFFS|hM>#~zA;y9W6j}xt@19M^r}fLNg_atDp&? z#B4pql1>)M!PNXUE7rFkh^{RH)58#lp+qL*N`(%WdQ4xQ>qf?sZHN$uWE;H=)T(yp zOofG8D+P(7w3dD=9Dz@I(teJd_fd8Y_TIe_P6)hwaJO3y)nfa0ds}1W;1Fc49rC&d zq@GN}=6d~r2F*=W1^6P=ggnPN_d@`F;660l`c-Jlyu>a8c+vS8$?+!85X^t3@guc(qSg%*w2+7`g1E8oAM|0P}G&9N;TI$ zhP{*LGRZ7asvy1Qtk#N|-?pYSmL%wYJCtNS3pJ(>Le>9;38=brIf2%VRkNc!l(P$i2Os{73iBR2@j|V=8Xa)s zw~spHV{%59gDNtqWR%Nd3;9~t_?JJV=N9$|_q9YmG9*d2*zvKCRj@Y)yJ;kd2UkL- zzZGdDt3c8;#Xh;Q#-%=%`vXh{PKhZeD<_IoYW-y?l}DQeF1s4Ke^5$@awkkqwC$At zKBpx)tqu2DRohrN@iY+~O*n}?NvvJKD!>|$&wvL1RumrPgO(62hY||FYQ4t)X_Tl< zlC2PEQ-Zhd{w)G&kLIA!BvPC~j7_e!IvR1sr>)xd3D-`i3l}`!9^6oF*fW4ql~?Wx zQJ9C)TaOWKj`5w4aA9~lORlKC{P__yZ*o&+e!rf*5>zTV{#!bFq6Z;*VxYjfE}m@~ zap`OGrCH9p`}zGN4JHPpqbjP29&z3-L~}P1+4Qi>DUcX~HP(<~{PHf7Z-xYR%z382 zIVr^18qMCie+faA1W9%Zm@B$h2aD#Xjkf$1j_0e$esn%MB%(U!AFu79+AP)m5^mHO z`3G0VBdu@R+vJ9;uq-wG+00JiaXl%qJjo}C%LzzpE+%^uf~}m*9Djf(sAVJdVcWCc z(IZo+eUGS;u#k`c$u#Ud8Em3)=H)!X+MR_gmto1FFSL$qR)tzq>E84vWRCZ)#8re}f)!KY6K+P6@R4kv0Gr@G7A&N2e~qP#tA#;MizM1?BCqR%mlS2)$# zA+XW7rpKX_@#@`gXLsh+?`VO;Jo+rMM{l+^AP2ZQzo|O~vUmm|uX`()Pg4HwpVhz{ zl!Mv(j+Z)VM^3_NtevE%sD{Cyy+|^bVkd0^3XIV7Xwhoy?@7~#>L@JPa)wle@hij< zm)`%(c7Fk0GUivq1Ck0v9GwtMeR@n0yq#`bUVCVP7$3PfgjLg>mHehoW)J5H=dPju zPlD>t5#THF(V*w>F^Rr|@2w+}$orBzIU4&3<7ELlQch<>)Z6O>kq^bB3BZ5u5({^e zM_KLUixA+`7-hv)WcmkT8jFQ&!4&3rmI6a8*u_+(a*!>iY}%qG*oI`PIow@FO%iwkG|kT~h5fou8iIwF9k$cla=$i>>b8W! zyh<^;P4rRcZmNvYx5?enT(BLbMK}O}h{uUDL(1RN&s_(zrw~alUb9=Kh#8(Orl`ic zouaLwX^!+WgA$c-5tYN^=lOw7RPj8W5mT8dZf+tTwng!9yffl_`j#-W|tCZ-2{2p-;sGJ<-kuw9z& zcvFbr)e`af?(*C){>(u7Gp>EKULQ+S^c~=ITS4L9#uj49A-+M#(iOv#S!NF{P|(!p z7fRar^pn%Av{B8Kjr;C+`_WH{NpYzeAhbdVH!yN}WLILq=o9|028%N2qh7J>5jR7_ zL-15%(KeyjMA(hq#xQtEdf*4wp-%U>CM7|XQ4O77Ghd5;HjA!_cUvJhGhwd9p+r0> z3jHAr5auw64On3GpjgEh{FEXX1L6VYZ{X7Y*4NGP>sBKN$Mhr)$MPeF+MVh z`N-Vw>aP#-ceN0;dF--PtN!Nx_M_>;5+#fM)ESseDew(Dk0>iNvY}VI0pfJLj@*(I zKHm>9MlFO4oiT*%hRqsdHuk-;qLpz6nQzz+ftU7yM{&EjP7lXWjNBYy18&4BT9GAw z-zNJ){p+s_fKoYz z{Wrl^f`L$N=Fj872dRitJg8Faq62d>d5D1wfJo#9RW%NWL5Q8`RVVD2nO33-OrXJz z$;ArXO;e$kVGytO*k(v)!Q*LTc2H;hM6T8lWy%Q5#GGwdyZc=6(uLZ{+F6yMW!9rz zDn@FMZNL|t!Ll_r{}#Te_LNWzWj`#p3bpmm9AyHM*S8<~8jw2hs@?770lmTelf2cN z^GJfbH}`MtPsyznUHc9`G>epF!cHB*2>+3K?wsZoa!+r`_TyFF3D@B@+5#8Mb`I|4)^n$DID~@_Go^CajP1Y z$Ei&9uKp0mOXB)AQq+=HsXF#@9ob6cWbAyfV8pyqgSHs*Y>)Hh{WA$s)+hp!E9dbR z$Nm@}ye%wFgJ^0}FOgpFIbuqN8%QGevFGEX9(C%#CWIld;L(+#J_eBu_Z0%jA z{?S<;{VEr!LwuO@%4=~{#kQZraB0M}zejI+jut}~k}c<0u+GJ>-Pus6r%;QXF(+A3 zYMfms35O>Ln4LnG+>3QQP&?ardpP8Oib+5&xFl7RcAm~kM}Gv2ouH3l&BiYKMs#|K z?Z;VtMieBbXsb$O=H#0X+(}q{Tw879ve#-~?S@ z9F1J!b65KWwfWf7>5t6sh?irVF(@0(fdW&O#E}V%5EJK(D79-? zuJ_L=Dst2N3_#h{(x0}VhD)MLf~N*Np`2wQOVZVKza8it z>vzENU2nbMd)$6%_=C?g@O=>Uy6@n7kT!Du{B?rj$4c*g7ikpS>7fhPaRp_j*cwU2 zQc=%x4|9qkdT(^_E0)5~qNcs76e^dxW zS+s}?AK^yNmmt=5Tc&WDipY@EOyS?dBDYl`O&4gb;0r0c+m&A=h73P5G9U8l1X7wb zOK!h;cPgBC;5}>IILY6*v@|-cwCci--*xLi?G=PEFBQS=!e~X5d>AS&ch9ql4hcH+ zoHOZZs8($#EaNX-sw=A`IDzoeR)jR5f!sY{B7MtiN~sK8>BQKZtz<4Pk*!hMsp}_H z__4twAlxt$4EAcYL5PHlypMX-d~$!3p_}wrDlcO|0D>*mbYTN15&;KNC{j*IHpM0G zWj3zrwg}{D68Y)DX9d)1KFSRYK2N;rSNvT0dyl`w1#{J98w?=4j!HTBd@>g%Ww8Vl zVf?g6_;Lsx`FEOOD3 zhO~K8uHe|NVXroX2f0zs9-Qe_W_vWX8Gmp;iW5dhx#e3n%ul-F>ygYiJ5xRqghJP~#}k;G_3 zo(?FT{O??*r@SmaE7FKdL^a-n`JP8}*#`j5B9n!7SLo!RtD!2at7Nj*G=YeUQ-j^i=W@Y>C*R;gS+bk^ZPCdS76fY~c;eJmSPO@rJZy5M=wqcm9a4i;_ouKUskVO%mx`IOreRrn zXC?I~)B(uP1lB=ZmX^8ZK%F7CFgN{=^oo^3VaDDzu)uS&Qt5`TN6Jz!D`*<=uj7Z3 zkIO1&)ZdGuFy;^-|3E6?myDML9LT^WVm?49Nm3Hh1CijKdDp}Y9og>rsqy0(RqV?I zqckor_)3(V0vErTy`lXXGfI&MWnM;(@`RACM37Y&qrd2fO?AWbT8{GmL51SxkPP zc_;bV@4k;1g`Th3rspO$&yj2=t@J?FTk={dauXubqUu{RfrclayC{pog7o0f+V3T6 z_cX}$ABpnlj}_L$-6e4|>D(#1zUHqk54!bzjEgZEw~lt|ZE2#(I>tZ#y>hX?waajq zyL>vo&Fu2#fArI`#`Cnr#>X0V!fW)G2iv&U2u}0UpdjfMRM$GC#@wA9oE1T0H&u#Z zj7QfK+|DeAf5Wjbe#Tw&$rQeSJW1sRm(!oEjV zV>OgJ{*zeW0$5jvwcO;`UnCE%xoDWvs=LJDYp_E(9#u#U6Zk-#D#-$m62J5{FkwkK ze-io+1=)9Mw_u)31fWWaVxP$m>8NJ*($$r4J6~iTOM@_zx>mT^LWp`;H@RQHPXst?!(hinZZ&}3x9mT0V?Hj3-W;q~tqNU$C z2r=()j-l0^gCw6W9Lrwlo}&!^)58%S=sh$?(l157#`a>*8NdM;{|+**{EYoXb{DZ? zF52{1Z=ze*7i(82;cw z&!;`@%IMx+4XvBKhRk_Jp2lq4Ac513$MTs47nFH(_(h8PX0P$1>T$$2A&s(x_r&jV zT@KUj*veE+^N)!A?cuYg3S2l{_rq~$D|X+PYE-5IT;_bL2ELO$vBjowlHGOOGdn!3 zo*-J2^qH`DVz)TLv7Bnee;B`91?89Z%MpAU_&UeJe6e(z;tX~KZTm%64PK}!syvC? zIUXWkIFuHcUZ(5n#LID-OxJ5`xgE7Esggf}8$3;X2qi2it9@u=fcxaw*Svnvt!0^! zYB`w+hd7to*wNf#IMsugrNTxahu3-r`7_vpM!whuVBv!I=on4oMDc-9W(*Md2ptK;u6ut(#{^g3P?1hY2XZYqIbcOhu!8;HnFZ3YAyg}8xDb&`1 z1q;@LTc?l<6hLr9osr=?pleWt9->kXi%L=R`C`QcFBCv7ez9k$dGZHz*mO-6GF)*7 zi-lGJQruR1a(6-_mMVmD>J)20D{~Jx=%^|4Q*CJKLVdzQ>4cw9J%O8>zofPJs|5;$ zF(yqSKFj_%)n)dY=yjWDJf<%0lxfFk=)F6EVI)U^0W(Odi8j)$3~Ly}NtuF%sgD>) zl%$UJbE=?3;rH!UIn&epve640q?U_Xqg*YKs{GEP!uj8?aJxwC zlYHqvf$A>$mdGd*i&d;xU@I_>Xdmlf+iU$9a7kOF>^Z7zlN2-fP%gy!Z36<-)t0So ztOo?wy@?oop5~-zKD<4cb`5Zn-7{h$z;;bpZ8VYl;;ob4uBnZPQ89*HPr#Mgk<&6!CgM;x^U|_4|nI4r%$G( z0;&yXr5q=KHMBIg+=ZJiq*Jnau!dS{XWUYvi#QX9`_uiimf5$ za8IUrq98E$URD4+%a8Zo4{RptCj>Stv^m#b%Af1M#xd@|K}EL+_0jbpn}5cuVTyV)M94h0+a8xklzF+gLV55efr3tlufCbkWh+QYtgs#d zQUX*O2F!Hl_P&OZKD!L3T>L4*`!O*%DM&t*t(=pU;v@rAWxvYyAsx8XG_a=udvt-( zQ7K7;Aa-#u?1tIo|DvGhw)m5I)}O!SS$pNR`wk~?u-=wiBx=Vh06Ez0#w9dii&jfv zkctqite?LiPy7=lEL$Jn4bNo8r<6;~)BBk>BcBO(vC&8Yx#Yu?rYo|M;fD_uutkav z61+Tfo%o(vB@N-XR|UmpzTZ*!KkxEPe)L5aV-{8#+Gm~wg^4icj|}|m zATPnFAkqgLUE3p#*Kukk>Zicw;3QYUa_gycYUJFN-iC?hknO`6xorwBk!ovX_kvAJ zA7wFH4*lgD)?dSfz4?FWUL2PBq57xx)o!dU;Ne-;Dhc?alXuX|RJ*j4nWRH%Z8su!{{ce-qc_YBO_ZaydScyBu1X)=wn-k#4iogngYJB1uc ziCu?KX!vS7ofatwLsmo#OCX~s;^>hLtUC;kxVvAg5~KS#Kj+I5mnBEG8**o?d>^iL zD06JkiKMU=L{Pr-bTJEVJc`NWJWn+ACp&Z_L^;HM-=z4quklP8=1Hni0VzHRe{H96 z6zTw^oLrniS$2OuDesiT5mFtoL;^tS7h@*`UHG7RYAY=_Z#oLZs!s5cQMr7K2ytA$ z6MXzyq?}kK^`Ya4>45i?&G9AA&O8g6`SA2ZMyZVNHo}U&2`jIrx;xA9W7bKk$59xTeVb2#4mpfqO=y z#I(ym?`O>}@US#EIavU~D#ME-T$WD|<&3z4lS=nl6QZ)a^T68FF}LJ=5#T3<+GzOZ zL@QJrb8>Wr8m3o1SYJ$MIvWP~Q@h5Ji-Xs7VuO9fU0*PB|3K+s+8g`b%E}5K>M-l1 zhn9=xcIP9axF-tSG?s~tA=MsjF6Lgjg@U$+6w<;D5Q1c9&S$Xc)3 zh#)qrRjBPe1w5@QL6t7R?joJNgwdP7Je$h0xOIkazT-HHdW?RQN5g}QS?ouA(gCiy zx@a@%J0gyQSdiUWHmt~S`9e)?jTuaT;P&IkT!(Mg$i#@G+@G`+=S!y;`SqEd#r57e zeZhr1{I#=A$an+XF*D^ATI~hS%R=T7k6w>uh4b7=meVt&*kR30>J36*JC6DGEAH9? zfpD57vdpBh`Nt=o%ruws0H|Yw%oF!y|n@sY! z9_~FMINC z_tD8N{Fn0i9MZe5J|IG=!&O}Wov<2b$m-p7#R>AbYah(=? zWp>yyoAbkaS@h?7{!JMvVIpc%;X{Sym;O|9)o)L8vopD1){~JSrjyou&%;8A8-P#}$!9o`K+%KrXj=&2Rr{cs}P4JYD_V^#FJ z7tQ!N%NyD|`GwTI(UQ4GkKd?@2Tudjpr9walzA*Z+9%#I=UEHsFn5um5vUoZH%=?z zJ0iSx`WBMS|NI@hrC#NCmFzw1q<6WE;J~^0IjZJV0j&8`Cw8ap6B585o%RB>Ae!_4 z0BJy$zpq~p`nQ=++dhe0&Tl(R_gw_nF_oR$$(I6)#bOPLGHX$I66J&$eH9nQA|l?X zMiDJI6hm+$O%uoh`l9L^m4RJpY0k2&#FVSQ^q-mZCshreF+Gt^_y-tu$_1v3Mjk;7D#l=%s`+9pc zte3%5Thhr2-!KL(AG#CKBTvvJ!zdm+cJy13i`@k8iJzzwJ@fz{chc! z61ME#hIk?d8T!>Fa_(H!iH(nK(DmSxO;JRX7Oc331#?cpC8vIP$a>fAdJf&Weg)@o zJ%K=${)pPfOY4`Rd!Prc=@xw)jiBtE5tO~tG5wA}Q$rk4*$>C@bmDb#f7i|Oo%x0I zP;?FSH_bxhj8o9LK3zu z)zyX?IET838u}?gMvb3b@W8u)bT!?Dnu~n};LYrG{kJb#=2HNAY4B6UL0k z@(n8?qkbhQ?Pae3KiUvOaiADvjjx7v-vUn{PF8b&v#z4p#z;gbuhSoK1FvkI=gh_A z4*xfwz?RC0ZQr^{XKIfJj-_O1&Z^e<&VNO8+9G(_ZvPEi!F(i!_**`K!t(oJW_t#Q z(BuV>Oaaqp9R-*6NA1Ha>sRULkg=e%(8sHPTLv2+-=JOJt(ZA@?5ID-&pnrXAFB3q zbI(fre(6t;FGi3n0>u(}6A)Y*=<4smtJ~M3bykZH&H|xiZ@%@MHXDx_h#D?Rj;qd_ zprsmN#k~QOCqwDR zkLrsB2URE_q*&&c*JNRnW!v*~IWdYAcQmkjIBN1-AG}?^4!d-uwhFgQY4%?m;hd3m zU0cj4>znFVs=dKKmtF|w)uUxtm^*E*g58q8UA4@sYhKaW+Jj40!*F!b6-X?)9A3V! zdRul8M%!c<^DnBZ{7lB_rj|CejU69MKseaEYm4u35b^{k%l?j+w(I10WbF@o1{880 zw(r_LxK7(C;IS8efp7lm7VPTDVjv>|Q1`RT>o|Se!KU3?2K!#`f09MXzBUf`_GbQls~1aEzo#KoRQD!q zStn30!RRBLd>#v@FVHUB*&<~YH??8jRYzjX%r@*^ zy&Ji%9L&hbUZ7-6A2Xv3iI$`v?H@q8)LG(7IAZK1%$ht?Z_ieAZQD7le0d3is%a>y zgJ-8xXuI$xKju0Fv4ip4o(psS`EZ{4$)N3I7=G`fOjO9|pwWgaJJ- z^b|0#eL$C*D>E{cnJX4NlyVXL^jAN?YnxZ0sVR-kJJ(|K)(r~ABS=plhmu-}qu}1Q z{nB)Lzf|k)@2SA>umgy|BZ5W^A~dQ9U1r+(fc{K0Y4>*UfVvQf-Okd%k~+4DOYJx)xg#2IjOyFfMH(roK^VB5p^<#rhrxyK|m?Ew;DL+d8DCbW!fk54C&U z>v!uck)z$M&h`4S^u!&oU%qFr_UjFwC@!h*zL{q(OuX&ZFX*Hi`*~x$QTLVz-SY=| z8gAjfevl@Zk`aNo&rRa3Gvk=suD*AphOQh!*YY3M7jVz&JhlzEXo!iu-Y<1uPcA-k z+r`Bv@AwgwHf4=;A7l|(c*Plsi$6D$?uoq>0Xbdw6B*!@tQ33M+U7!T$4QhRVH7|*aW+wD^BCVgUpI5sbJp5V#_pZsQ??!K5ub&x(hrW7Y z>DeFsf_@`dhndKGwU`;4%*}o8TEL3F`3Fy|H{@FKy8SZM_AB>e;46zUVtwjE=7+&| zQA%F*tq&UG<^WD{$Zt4djkzD=aXJcQc%|=d0%RF*5yACj^?Nc_jdRPHJiD5mVhzD)>QI4}+Ql zJee4yLy*fh(1I61gz&Q#(97B4qYBicrazTHA?v9)GQBzc;l%=Gj*DoQcbn>c+Ya)@ z0@|C~vG}Ny@tY@qhqRFjyr}*7_Gzb0!`g?|Dwr+Rhjr;gdU{*~#?2qEz*|&V)5$Pb zQlNhBiDw}ZPob-~N5{c$-LxLBu3irEwx{7dS*(+%UyaDbx$yG+{{HCt?PN{&FJ!4M z4&#UgaGP3TkXyXr^KZJL305THXOpM8@ie9G1wb4SeWAYqx9C*d_^BSeTC7Of?Ryl| zdwD$2{Rc#2R0}<#_DLX5iSg1!n2iY_B6ZgOa*1+Uzf+!M2_<>+d#MJ)8to;BK`a#b3O0R3v>)wBB`q+6Q)p}&O6vSvm z)}bj)7Cw4n8kf&WVyYSpn?|)|X-l7j`_|;~wPy#gs>{)X*uD8e7V)MwL=wlkyIy^8 zpU%y|F4fUpZ@S;m$R+3ggRr7WS+w{5cPyB>EjoUUOPU~w9K?Ie4gH?dccRWg;`!Hu zpLs;+>%`LSz(LafPG$@gB`%yE$F1i#W8t`=lS0Q$h~gbbCGoj4UHsoi`*8aU8TIq# z|B&yEjMga^c-@?e0BZwH{tVt>Q&p#A|Bb>>tEf+ zt&`RDv*{OnbsX+9S!%4dYaJg4*8X2gxn8)cy@`GoT18{W3AF|oDr9xptOTxHkU~q` z*r)j`!V_Eli2QkT5#L&p(coVmJAL(n7F>U9T2Hc;MPr-iwiNNfd%N*!kFCaA)nDku zIpY=Bf9JARoS}Y;!swb+W9XkP&*GC0_M+s;5q}G;XhZv0#GA)ZJ#kU5R92bm)Ikxc zG4QBPx1vOCBz6jZ4RwK`)^rkWIT@i*qi>auMG;R$@$|ABPFs+`!pR0oR91}KvTZ|K zxi4LOF`iiZG%|$@BGHH@Ay;iXIVOc!7tF$@XE$SDN56*ea;!4}DZx8g(h1U|N&jY5Rb)S=#x-cR- zgT2f;@cK&nSeOlCA;!)D);=}pWEoE+b)P7cJ-NKcsB|5T9K1@5Jh}7hWNHvq16p!@ z&koqIZBIkG8KIGFNoTe%65VBEZbqHs*dT}tQ48h*VV8G$pKd0)dgir9aK_XG z7EO#{T5|+V2~!Vz-)x{xM~UWd28x~nQx`AoDB@4+i+Ev2N#Ed!{TKiq44Fq9cLF7a zlul`{ApKJHg?RgAW6++ef5vFvCo6dW@QDq$`sfrs_PcKUNZt3Nhjp6VQr|UGjz7g- zcJG6S%a5kfF>A6l>#R# z;SlOt=~MSccizL!jEk-PE;gzAWK+L`?E@})3ZDL9BxsNA1Na^Y5oG<%32FT2MXfp+ z=|~#aVB+hSwBp$DQGD$FZav{TTG*0~4P*RKCx~b&B1>5ttdYN)CLMFK_G;UUYmdH* zzjA&vK5=T}u*=2OMMn1qwQCoqaP2QU@mjC5&#<0R*U#Ud(tt0kf!vJAwaw zcl!a^26;r0N8S5=-K7m5pFO=1A3u3$y>&7;oH99v|G2OPSKPI0X#REeqx8k|nsM%t zLo<()#r}rl(&$rTpie&3i}VO%W6Mf4k3odesL7$wR(2oImTebCN*#oRIzHJhf7F-n zrefwn88%rT)*BVb^#<|FRO7oLiQLW}-1TS{vfMjdZpED@OxqCjulVzCd ziC=%|b%@83=X6b#cGHiQ(JTFapP?ESpP7LOC zpqO?^@DEdcUcDYb`d}G5)y6ir4^CLPUb*aD0PBH!`>yUHijIkxQK@b37e=pUa+*MJ zf<9N>9CSDp(DlsyAiPveL3-AAcQ3=a2u(?aUK>mtryeP8Z$XEJTh467C38|p>Kq1t zS@G%bUXaw+!0*@Q@sAJpV)<@c!|9zU)uso$qfukb!1v$Q zhP>U0U#!{-SXTp6Ys#Wi4yPX>Yud?+MWU%e7W((?u%ho;btkm^Izq{NgGea*Z%y)pA6eId;YZ>5hH^ku2$7K5t}5uhpW7QT$R3?k>1< z7rNE?jO^uX7TtH(ACtmYE^OJW&wccy1~n}5@VP(rRat2E^nIv~%WSiK##DFviuHVz zuvo0aPSPW{WwT--_Klra%t;>5&0H`&p{?P&vM%0v)X3{TXIdObwMVgRS7~ruOn^`B z?ibCBkNDXu<|c9L6aC0K!&}uUY&t>J(|k{5(;YOyqQc(gBVnXkU^R~SO(yh%*1rQX z-&36}Fia#wpYe!qRrh?;u}H=dPsg$5)hzCQDyJaS(^hq=2~MqNpdaTfIvZD(?1z_qbKqhc)>}bTKV<%$Tsnam^l&Kg$e>_qO(rJ6NeA(jcCy-O?w~M&$;%jlt z>|^!%izQoI>t2508NBk+Gl<3fnRt;>@Ob)r)n|)7WHv@BFk9x(ggLmQ=EV6`9^H=W zzfL4apse1XHessY_aK&>T<2-BA=VJnFkN-+X~6eu!@xFg3+@lR0z>h55Ddes!oOV7n?+tqVQ7-$-y@_Axt(m?gPS?u%KEqu|C)p+uy zup7rh5TsMOdr{AFUfcY2(t!9Ka})UE_2claW70^d!7WXoP(P&{T2bIlJ;+qMebKB0 z{_wsIoO(n|!|fqCGZ{-ojB#_0CrjU`I7975L)5@mE@&P#q$4zcbF2E?xRg2Sgi2&V zGTNsfZ8UZ?A2y&q^`z7GHq{kbgl|x=@W}NYxOn!V59uTdb(zv^;er`)eCEt1{O;PZ zc>c!m_|eNfk|6*5uT?5ay>CAnbh zCd10o?983H_nv#cQ@*3&wi#X#5+9$j3FuFX7<)`Q)Bb0=7c+X8wo}PYdYt8 zGkDhn5f~xE@;=AB=^O?}0EENlFJ16`%sb(9R8&_ZK=HbV?aMSDW@NM`Z}r%&+X^H=68R`G%FJ4P}uSOG!HKw?Ln@$^OlX9sE>*ihiQe=wDQMH>rt(~WhwL;KRKTK zbeS1)`Q({d3`$P}QKF>g&(CHy`gA_SV59Iqg&0E2rEqI(9TUUiGb zKAnKNH$Mq_sQvsq{(Ew70(!lY#r667Mx*@nKp=>jBd5Y{vx{)``a^FxB-zC7!W!%^ zvq?K=v+>Pr6Dv79g4Q53|d%^l$E(mm()cgA7)GzF`z+H1n3c<$l4 z;65b$d=+ft&izi!6*;wczMPUjxTC~=Z2!x2D;>&>{jRkEsVeT7lZ@q8W#I>7+@kzn zj6Jnmc6t#VB4Od+uFYrOoCl<6qS8T!X0#q+pgs|*y+_?@r>Ovq^EVdIp+Ne3BOna`|O*)^UuQh-p_pP!%yC>z?X#~d|e#Ex&zj+wkRZ` z4%=#5O2hc7$U1j@v2{GTwhq_7Ss@^wC_>(WZDB&L4QVdRDaZRmqFut|ypHTi-+FPI z8VUMpOSW%#srLDs|1ab8EAKEQ2Hk-M&AgEY$V!HsKLI*ZTAL9_^by|l7L*w`TJ^$P z%Ttg2oaSN|MtumpoZyB=U^i6d!y~U&AP`K%{IO1i!!eJtAVYs6w-3-e6@9*@Qll*EW*=eO+oL;y|IUYa>br<@jOx^Q%o#BJf&Y6a>wLZ zrRsz?-KZzY3)A&8z3Di8%Bj)lfrxm!9kJ#Z#P%R|RVfVIZ=(=Gx zGR8>IK;XV=Z_{Dq8u4T2Bdlhlws;Ha2)24~-cYKqQJwTgbA|!x;^8hq8pl7&vUE%X z^VZs_{Tz6Bb#1&~JLE4&$sRhgqrN~si%VBA31C;+pfn9$yDWfLhjNhFtDez+L|o66 zIS5+su?T&~6d5&t%oxe(^_YR04xP{I>FRMV^i5HZ*|o#r@f`G$;0n1b-v(q{t5Jfsra=`%Eo0DQx>@Dw^ zEyvl~uz8>rjOD5@q<`Dc!zkF(I<5bu_JP)CH1w@YzWeI}mf!Ku%WH7o%39du2F;cu z=iax#qm>6~U%w-RNA<4Eyj@?@6fpX~_>n8l>NgVVZ2H&fM` z;@vxHp1k@es4J>AG#q~wTvb*2jt4pExft4K2!{0=hUCN)_yT?b(!)_Nvm!^Zxmd%4 z|9Al3tXm_z>71@^WcPt*<`o3KeWWB1D0a$dGhu)|&9-QbI?WC>y$|ZPEJv8h?W?O$ zd|)3kvvUMsuJP4k%-}JYHhL;PUiB&5E*B(SqDxa>2<-Qn+8asvNhse{PTviP(0Hz| z?(jO1)GHa@Jg*3O7hHCnP#LYq&On`00ac8^0vm&UXM=Uev}>(^F$oUCk8tJQ2B$fPz0-@5b0;G;F&8?42!CxU^~=^eo|Kvv zPv&{PaFDD1bskRuJ=XdWkYbQ)L?aeDCVAwPLoVDL91hZPZ#oODWM|hBfmku+cfkzh z9Wq5&d6}8<+=I&}nxPOn>XAEYHqKrXrgYRk!=uJV#3oPYhv0NXYp!yL z!n|7{C#1m)*3zflqPuTX2ojv-*j?FrMm3|q1*GXem40CJ_AMAOW|HOMCeR!RhH%OJ zi?MV6P81&84+r%VA~eDfUi6gwWF+S$iM)HxDVG)5Vuq&y7S?^ktj}AI&8F(w8qAqA zo8Hp`E4M!!7P;{vY9OLpo^`?89>$x?t5NM&;Bt`?!mN3GF^;3>8u!hJF3MmW8)WcSD&l}+M1 za@RMPc&;Gi%t7<-1STqCJgdp{&*Yu=X(f< z+l056!6?^S=M9y?IhQ$;Wy_mUM?k#B=c{KC=MZ-;DOX+_!RpP`cyCnzTlNtUU;PI- z}MQU5&LI3ztf26QghfS)>I zB7XM08-*c4+841(o77-Jw!-Lem6H&75a{;0n>^U(*f?40`2>qOspa@bmX0(?T z98>J>9c@<5N*u}<%`Y=pr*}zM*%NGXVrIIOn3YZw%S$ibX$_SWqRCZdR_xnBlg{>? z1iy++R?_<9N{QJ8QbJl1Pgb+~V3k>2v{x_vW}jI2M;dH+vy-Ewk%zYd4{(xmE5z}4%JkE^xB&-6r86K~W0D)ky+9 zg@kpf&k!Zny7~_HR_h(#e0i=0Yb(sUvV$%DfJ-vUw7fl!6q~Gjz{K39 zq|2-6+`;Kur=n70KwaQ1U*YCW9@A(e^gRmJ^$?`=fl!Apgud+GFdcLe!hPWn??Etk zH0*20(h6Xe0X|_J4dizEb!vHJh;SfTh5avxi6+iyo z_0TlCFiZ%qeUvdj2H4qKUs6_sr$4L(!E^%Z{QOQUB7!wFx4p&la6Y|D)nQidM%Y)= z5W&uza|M$H=oVI_NEi-p1`@J{psIKi?Ga`JIERVGq=FpXz~l;cMG|0DI!;5iN@zZE zsJGTpZJvR;ue>BKwxhp$|=~7nosx9ev6s zTdR)Z#%mgisw#P-dn@^4W@x=9o*?H8n<%IB8c5IPw4O~8oEh{i0i$g9Hrkk0(9fUC zo{TRcYujiuKeURZtV*OnWy`rEMspo>C3oZ$&a0PQ$!Wqm#eEd=DqTVN5CLJPBE)-@tmhMn^-SCB+8);F|TMES1Tgbg!H@a)jDv(iEEC)0C{iV@RRN z6ZuX;lo}vFcF-u^x?bP6_KV1#RbS|P)~u!P9%w7AgUKP~^nQJmg0bV(UK37Ga)wXh zd~eC_b~kJ+2FaJoa{b`;^?Kp@rIDS>J~s;2uhGkQ?}y&Kte2AJROQTpeP~ULQ+rRG zCT9&9OQ5fhC2!PtHD~yEDPzD;IUzkyawMeE*tuA?SuC^B z$eq}{BS6G^i0P{;F{+Ao8O2-HNA|5*uJ2jB(kS`n8#7cFK~L-KegZi;KU>KkHA>B; zy*zu^C^;#&KY`UO$?ozZ610Qli2K6(nz{~oUylTWW}vo$_L+TV$&SsD!u4P3d)F*8 ziZ*UCYD;R4-UVf6<9jb9fAknNf9xbVW8g?BIk%7OO38rcNF-UIh|VKCFWR`#tSgI)(1`YoB-%%Ysd;0jD80r{k<}+s`j2R zMNaEGlyuP?OBapxM~;qRROW~LHAY?e0keG1=Exp;4|~@v)%UJjXH*rI9kt7py8iL* zKog+Oy2+3<4HW?cy_@lue7q}wft}=diUD=r5!Je#t5?%xuY^4@NeE=Ah1MJe>tSe9 zuY&pY%P>N9Z2N~A2||DVhlqUtX=ZF~0P8TD=B=C2MBVH}D_^}PP)~3sX)2VoWXS#i zK`*nppXbA0B5A=_xkkr76fy){#PLhutO#61$Kg!AF;=s1Bj9%)qWvptO=e zJN@3ClmutCity*Rl4iDCgzIw!x*!2v`+0wWl9)vbejQ|wy`Joz&0CR%dUE0!I4{74 zs9nLd!ry7965rSIMkBa!2`x@~H8uP3_^T_CojMCcvLghZCGq&oI-ik}h5xQG=VS__6At!pG-gG9B(=3mAGq!jBk4L8K6mJ#lN3lm|g*y@9?1?N? z8UQ$re_~cY1ZqnW3RVeHlW2T?BagaO8{MPv@R|fH%tq75j7B{iAF=Q&_lHErhb=x_ zxHi36Zy$&WKS`E6>G|5A+Jv&F+1;I$uL-t@+e!O^YL5^?MMm7U60=WqB3n?a+Jn6}vYhHOx&Kf*fcBiEY5G2-YNX#2V!i~KV8EW4tv(^4HX4_4j zNu+9xioF{nJ3jv~wEFqS2)J({B|b$PK5xF-Z|WR5XT*3pDXTB76)U$%kIu#BYsKbC zAth?2+IQ+q`w3Taw3N>%+r3%e_tnzy=J#F+Z+QD7T4!;CEy?b-ky1KD=`~@p%IhL` zpBqJA zuhmO-79J|EI{{-w8!`WMZP?s%`FWJ2+`c6Dn#$pzzoGw_Gjtl@MeZ#2!7$y2#hqny@flSdq-OFt`d(>aK>6rS_}}^i0l(<)85<;IKt1n4Xai=^ zq^v@{AZY9=Zk$9=LGruYhbBy0(fn^Fgfjg!c>^4+tFuFj=AS88-enS2l4M4QJXS1T zCS6y7>QHHY*a<|ZLJyTA_|cCc?^z~*G|M{laT676`}78%&i=F&PQi}ZiT%wVP22~!9QOu!jcU#oEj}^k5ljfSU{TITxtT~ zv^8OSw}!+-U#%7gUcLq8>)xk5*cwl%-*g(!XQM#ftVap5tio4ShSEJNNj}iYs>1^8 znq8oLN!3uRt2k%47mqH^qDv`I6jiYG3&wtWKB1FEYq=k*pq*dytVfHnv@i%~N4;*2 z1Oz|(=db-Q{p^k=0x@%7o^8Z}bJU@yo~>jL9Y;#Mwes{(6qp-_Oop)smsv4aT$v^6 zp?9{G`3#JEutB=>sSru^D$PZnlPZkLeT9Lyet&al`M;m<5=PG&+}nBP zUH?!Ao_Kow`;Ua9{WIeezq}4asV-W9p}G!#lR?7u6Fm6qyc8U-tuAEZghvht#&t(0 zNWFMY^O{_8X(onc#Bb?lHrW$tZLcj3b$D&ZJZ6HiITErI(GJg<=zLK)b;-^l(6y0m zAHPmY+X-@VL0$~(BMOA$nui?ntg2B9tqD?YR|ej>>&M}Z?|$;_3qqCD{?jMgM$ErZ z88Gv7B_+Qf?FW)D6n3gVan1u8htmf*@!t#5yL25c@55w;2^}>2a0VY6i9We33;k2$ zmx-*r&HPt!T=Q45yHWS}rE|mUUVEpb21T`C>_~O+$)~CPPB?{>=rNKjIa!qK5lVE} z8lUdkH$(`YDk4WjG*KjA8dV1h^#dE1MYb$?E4=Bww+TG$KkmV~C(Wx4m^o7$dg?p^ ztF(Ue2Z&OsjX+)e`$>CpL$UNT26GI8d=*uC$&Rlg+dq3Ryz#Bq^u1rL>+Wcp7Gf_Y zKV2O-YqmD%M0)1YQ)O>3{@{(s zH(x9>1GU`}cCHkR8|pgyo(GkJ2`5-`FW5ObtSHvnp@a05{Un2L4lR4)IVmyIYa4au zLT%*y^OdZjQ)vx*8#@K!+ecdJN!C3zYt4py;Yi`SW#QG&KNMR1;tMoaT3A#iSCW&B z!?v-DFQ)lBL-fb;j(5F3?TnvZxNfOYymgH>=Ik3q`Kb;#Hh7q~&9>5(ZdYhCjUh+*qgvHMr)bP9I`+~UY)pD%3I!i#0D1}v%a?i(uLz((jogx;49h~C5f~CAorOC>*X~n*~fn(rO=s}3P(aV z0(HeA1YUT_d0b?p-Y^jJtXt{pQNv0jkNUChS%2Wm8hpMt*d=yprC{tp$IR<~rVcsz zd=6D)qlsWP4^-p$Xr1)@n=ucbrm|Na~)NDup8`Nb_}Cqe;jlP@{XIse!H zkeuFBtBji2wddkZJ=EiD>P+J`b=5czu6wgWFyP0%t~k;uVBp3#%kkPp8FA+t-~N6j zzT6**-=oifIuz;rd|@SsS)V1@qYXRld?5?`m0et4?1ACy2E`t&+#yJ3TWH>jWE*$xJloXEZzV8z0&g5-rCl?&42W`O^n zcPsH#ak%62hx60@)s_1G4eP!Y6eZ=R(Ab=>jaqoAl09Uc07Sx|NJr3j$PBtxNUwFD zn1UuHWaMedd5byv$l(N{(ysAD^ame5st; zYp9%D(91I71O@);wlyr$2ZEL}&Uz+|=Eiij&y?x*nb+MOc=r!K4}JOc%N8bc*=#3V zb-8`o&fu#VX{^qmi_Zs*E%dmg{>^0eVI79^Z-$)&n@A!tGf$Dzz@IWbfxl(YUy zVD&thdpBBOolAA=v{}FQD}=VZ1=~qKBd|9O23u#U5VPNLO$`_Z>uF74_@u#|hkrgeRS&L3n$zpYbcWXI@Ji z9)WZ_0egoArY~4**KwPp7xxJ1E|5`yk#aTu=&<8KB;fu)3T*sL2trBe zCCbzJK6_kv)r~*^`nIP~Ht9FG_m%CqY(^a>jm}0`*cdn}Koxb)>j->v=zD%vFZ9dn z4@Hr!fs`yT8)3G4e*o2W7D*nn!bilRi(Gv6s`JlG9Jgn037&kj5Uckk!fsPUWPy_E zjiwctBJ|y4*8OHo@0OA#!>bbD-?tUPiv1RmoT&dqK)?44>U6N>JCBZ?C#8UZdTEp% z-e{Okf;`Qv2j#J#{p^O-2_qZ}{_oFf-zl?% z7v)fbzoWQu$oktm0=W34QarpcmFB~@&mZ>U-1=?>9$Z};*Zi^g4YqDF%6AvFxeikb z(rCA$bQ*(q(_eL%UX>xnisy#p z%^Bpn@V=MS!LuI=uY2u3j#GYer;V-;_WCEg z1A@S|(?(%5uz(4$&X6v+;kD1IeT8P?r1LJdva*{J%(0@PNemQeu-xfTFM0~W=dJ*D ztb*bYxQ{?Eow#i&LOaifHgE>iaTmetGaaTUJ-TM1b&eU_#Y%T^dWy%!u?iMw=g&x^ zyyxajYwVHbFha!+g}}5_yBGd%-a%;7(@-jltcVGY@S=6;_awr(@NPKAEV4j4lhP3o zWt+e-)x?jTW%Q(#@R@Q`jVyW}gYFxozA6OwZ*bJ2Fe2k60_!f0RS1UQntTcTYo4dc z?GvdP{%tS9IdBo`l1Jh1@9x0nUE8r>W){-Zk`N4=qRzS&QG_?#9}EhHcn0ZG^oTWP z3ul5m2KWrtBYY4@=YMnPe~=WUPgWhkOP|%D#GeA2jZ^$M*FVXMW{7#Qy>5%?-7uSg zbS9CrA%a9XjDtHqZ^%#Q5dL0cA*Btn#;Qe5JA`M);Yx&NPoh3mS>ZEgQ*S!Z0MzS2 zdn;i5SOMwG1pN7)03Kddi+4zYV~`$iIR;j&l>E^X5^nlnxspF-B5&x&kN5o0Z`i!S z$jNy_JXbyciT|ZrFAje3ujks`kkk8Tx-Wm~btP-?cx!Vy_H@b@Hu&(Pw<sr5c2bTVp%J({m=^JB)pit*c7Ud$il zYLkU~Wnl=v`mj=fGk(@%nq`9(Hh(31*Qa@|eSL-h#UEcDTJ_vZj=4Yosr{rI{!dcv zjvl#W&7T)G`LVUE7{8mHB)lta>150H2JuUpKU`ig?)jtAPQ7={vR2u=Rfpo3dF|Eq znb-U;GwNGL-KwMSWidb$Mo!unGy0Eno%gpFZIdtgH1Nh9w?wvoy7E|?8%oxYK8|_6 z`U8R1v#ng~qtKugtrMz^C;t{kCeCw$4(XZF|VZR$B(S!Q)n2%au*3dKU-B{U6z zch~J&^L2RNS8L^h38T%3zX700mZv#vs#Xa!w!9={!FKWU@PF_-L{>ZoTS&JGuGlOg z5Zd?=!ka#VoSF@}&j|vsOF5$#(9B_P0g6h;VY=1{mMT!Olf z?zeK)BN5cB_ybZ-e-wIFKHk_?g0(yMVea@cOd6Gr)Z|2j*gz4n>bJ_w+$}yOG^X4) zqoutVq#IG-D@g|Yem}n6R))8hS7H4=yQsWlSE+YSI~2OMsFfZIJx_E2E?Wzbj%d_C zlH`Z%D?`<`PeqD~_0ZIdK?`82^e};73y>cBnRCn??lja?R?yfqfb?jvy9La-44u>z zpf@L!>xf64C;LMyYdV#WdMF!5lyL|xFV=4=A}FfWg;%lD;qH2n!`&CM8rS1NKSbLf zD<+C&b1eM*V|vMsU6E}cuW0Q&Npnb~Og?Ub^ka8};;ICtbvk^J&Tl3$S;f9F-S7!n zmf?~ytB(WMO-v9WVTYp4rt3eou50N74Dz>?N3i($QjE>AVRl~!Mr3HBbXy>75(o?9 zqg_FKMnH?B4-)Ot@v~OgQ>18K=h=UF)IRgNpEHv&1CB%E&HrvTogpAJ4A6i>mKWdSiuH=sy;yml_2i3llrysQdy)^(5 z1&3<>=;@xTUs@Xc;*om-Z~pcU($PZS`3b=x(I;O2L&vEL(dMD=^#>_jwKc2%`)YFEDWml;T9j+Ea*nMqZDEO1G`Q#AgV2aY zkeB`)=9c$Gm?_^uiuTW_D1uS)Jj@l(Te;Fn`H<53i$hKA1t~EbCV@WL=4J&MCSB7c z@Msfd~h?&;&lj@Y(=ED&We;*qW6keDbVIlOen=}IJ$4_> zoRU=9c<_r_NJpWPENBvBD-_0K>uUd`XxLLvJJd=EDHKlU z+4nwJ`}fmkm|TaoS#!+&`7hM|)8?@9ax6F5;u910%P!B|MxQkVQvUO`4=--=;j+;l z+*LFCVW?AR5Z;(wa>Wr7o3CYd;aFj^u22~eP?B9O0Nv(*?+j7K<*-8IQcHF zm#8OI8+pd}l>E_C{V)CO^6-YYKW_7x)B0w+7XR@gD_K~cD& zEB9&cQRkQ{)}q+2s#SjV#@k7!+;jsRNy$yhwV91{u~24q(%5>C4V zmH+;JwA>s}yY_x4$phi+zW}yGQubWA*k4tL7rv~-+p9{Dm%JZ+vJ~WIIFOd)fZJt* zrYV*!K{w$GL{MHG#{QB3c98TSN}n*$eM-h&uG(JpLHT9%}~)E|`hV zC}3_5(jmh6Q&0!H;YZ=>7aPuDoox7Nkdk`?!J4+$D_@F9_2gJB>!_F9Y+760tS1ue zTI1)H9a5)5TzgtiYcZ9>ekhp(N7Lqex9_Q|uWd5lhR&Huitw)wdoI>7)HwKsy@w2< znOJdiX&5h_myQ%y_ks0ZNh&hj3ij9PT>|Q{EsX)Yqea4dkIadYK=ri4Jb$bj$Y$W3 zJ8vfdBpAVDZ%(Rn@gM)84L|)n0S3S8(G9UQi=5$;JlDRqJn;6NHwQny?~(5sIM7C) zHOG18@Bb+$X61kPy{&?2TX@&qm;L*Lz(@c1P4Jz&enWd^6Do6U%%XX&v+n+<z z7Qm~B5|$L3W6rJjsC_2S@;(2fD~ysITow$r2^TK1O}y|%QGU9o9UI$P2SiM}AX|~J zbZ@Y}dU^B4WOI<)-!);~e$Ix#|piZNZA7UB2~izvY^C*@XsM1fc~@Sa{?rH5l6XBUt(_ zqzXF}4*}rhL?~_oxkepy|K|vozmH&1U)VC{(lH3K>_MQa5Jfcvkd1_BZFoi0g|!bn z8SYs>LG3&Dh!A)Nt^QAMBVbS0%$-5!*1(>cAOLj8mx`^mer(?0gR(vdO{yj^%A`o9 z@a*WOg0P_=WN0)X4kq~(x$Jg3Q%n$;chc_&q)Rq6I&x7jHl1T85pZ|g+wi1Yo+G;% zLZ&T@n(bepX6Fjao6g~@ngn&^MUdF|(h4|l{3&cSdUP-#H?_K%W<$Dq{jbaxpT|o* z^`3T=3Tgu4wsGfO6WR93lF*8$MCmpuAtT9o=3V#G#8r>>n$F*a#sJ#ul=0E70Iqqx z9M7Jc)@|43@bpZNj6Ky6;q~rmJ?+?9JS2ju_HT=9{aAQ3wV`uPaGrhd6LNB1pJOfb zR_Kqinm}OpVYUDClYGzLbe&mUeDpu0YL}ezfBk><=~v&*PNici>V&=PlB_sRzWLV# zT&MW{eZ|E_#oiK0b1IHAe*0Vdw9Eg8d3DU-G4#x)Rl=6C2)36;FrZnP zPOh=erQb9Q{3eg|89T&326ejYHoX=c((_L#|l%^t0~q=bmpRJsV8{dULQ| zkEl&6WSUF0XbuDh&WAks3@Cw0y5KHEiZ((o`Wi;*R_IlGVff0#B9|f&0*99KwLVij z2IkotZu7u&CW)MQB=?4#J`i%|U?^$*nSl|oyQ7KeAwlZa3dK1AUl}gC)c?!>3@0UR zK&|9~Ek6zRK2{Au;T;wx3z zi-_n1&JG)NDwMqOmSqvGzQ!ijAe|Xy`MpDJbfVefXR}AR^|YgNR~BWZ9CLpD+wjJB z-!f}UY8|Ki^v7~~zac#w0o~gY2~@wZ(TA7lV8-_DYAH^+MM;#N*3*s+O*0HRwf8{V z)XOe5>&h!#i|%=nerr2sQxFV`;aVF$_o9T1H%8PwarxPL;kxZdYj-72s>gNVgHLEf z=bR-BC&!{;mm?k+xb~Sa$9?t7@B3f=+4t=;uKA@lY|h!%GasA6SA_7}+*z&*?tj^= zE!_=gV$Pu}Dc92u$@(O?^U@|CE*j--@wa!k`?04=hqH}zHaS|tb!|}?`QD}={2K!1 zyDB1ZC=x3C20q&zAfWDPat_x|KTxX+Qt86#2)2}jF)F)huKL%-VHDT3U$v&WN8M-! z*0tJQYt{s|e)OSz*l8yl9A4ENptt+8RTmIOodxkZ?mc}NLEv2y&S+7Oovi{gpQj4c%EWCZXDcc;*s@G0$u%$p(AF?dT8X7qU*c8& zB)H+X9-hIot|Q^}-xCNXpugr7i(D>Lhv2(6!8Yr5NP{khSzBk-Eu?!g@Ky+5M-%_i z#0@P)XIlM%hVu-g0iYA`H#ryG6(wwH6QuK>B&4DmUYm^lA3cfMJsT{hcRo#(picZ@ z^fqSe;Jk6@JKJQ$yfDx-KeflRbz~r?RVaZibZqZ2+6bs&qB<4~oG;0r(s$_jxbki& z(opiR@iW;(iLg#Q4{g43O8!7?@T^lqYhHRu8#ecQoh`S*yq7`dz-UEzQKNaP%5l0p zV&d#yt82Rzs3(#v>keI!4d+}NHPQ;|=RJ$ZPL;d=y%^E^hMV2DEAxe~#JsNT4KSL$ z9DWuqBcsWOZ|wQe`1vf)0$Qx!2Ia`=7t5ya+B#`>{_t2Totr=GX?D!I>267NI7~fk zYnA!E8~V;;!+kfR#E|VZ9w#0jo}>Is-5ty#s&l0F9_hK}m5=M5ykbFQ%ZICvw(*ve z^OM~_c={D3XT%KCSJCa)=Mm7OW5Q!&sdZ*M@>LQls2CTXYu!C2fm+%p^G15Ecy>7{ z-u6Smi(r_sxoAdbMUAK~+KxP7SrQw+?$$?{Q|9$;e*Em63fwx~ zi&U2^^y9a-1@N?m~aR@(ox5Dzww=)>u2GrTd8mai? zUytPsIr(HG7DC<@K#x6HixBx}oI876nLV97?NL*Qq^eM~bk2jZoc2<4kQeP5Tl8Wi zWn4on6eHV;vWBx~m%1wpSZy@BKTQ^s|Dxbm*{dN#Ae zuqGnD&v})0<>-A*W+vxn7@lFn#2g#?r>gaJi)(2u@1SS-a(@WxNciza?~0f7ix#!o zcgjqoe9v~-o83E}vM5p%p!-M|_oDYcDc3GopVK^w*m!u8-e0X_?ST-!EDQ+&&je`4 zW281KCadW^@cYO~?4Ak7o2}W!HB=ii#b$g`FFQtM*^o`^h}R8oSqE!%QHEtXjom)# zH_t5wlilG*;`{RTPVD8tq&ypP6ICJFnT3Bl9^dBg8K%OhiUZwE$ZX=48HyyVi&#XNsVF7Z2O z*~=9{;(8v7EjOt}snjm^IT$q#vC^JQ^Mm`GmtgH1ycT%xaMDB<#s$ez-~1%#%4l4Q zX&&)f*juHes5XM?pat-G&G0_bE#QMg;cf05_a%?LRrmNMr$x3bIcmVVF|* z-BqU0Y-H$VVB@BDpGLqUCps=!bfh^Iv6lHg$H)rV7{_Ix4$_$L{Ngd;eVxZC6dhlC zcNvJ8=vI>K-8B!*MnIMua}ec5pEsBG2bL3QE=9;cLBtqUbJrDvHtMuWLZ+`vnnR-Cb_@6lB*^ev}YL6eMv%hKm>li|3^UjnGHU% zmUz$QJ%&NF?OXP7?!)$qFiv^$Ao{1M0#NhVRg%uhMgTK<&gQZRPWV?bdei&oF7Kh| zVQ;)MN;1m2`4{_wnELPm^i9#k9R8*}EcVCPIqd;;p!M+g`dszu%^!c3vh~wXwZSJ% z7c~*v0_d%Q_r_p71}+G|B1TnniU6b_$<(ETDkDC`&;-} zq6w*?kFpErIX}Q(Y8JyIMH+RC^T=tFn}07t-dq?T{RuL^1A60;FJFYQ>kFtS{S?yB zvtby7l&h;C1w+Z+5jhJkdinkP3%5Qs8+gokv*-yc&AWDY-V> zaZ(aa?Bi&&&NVLq4ng|gB~|!jcQCHH;H(78*~7+YBj(Ss=BwG^4Vi^)5-Cr2&Q8L` zqufYxw*CHh(+2tHWi@zURgJK2tMc(RZ+YxERE#&f?gHu}$E&m7HLNkbby^~>pO}DL zZ`*xh#h0T2?*6<=SjZh+Fc6r+z+_?`t=r$s^0o+xtDi6Qp6>dz8jq~0ZCBamUk7x{ z19k3DmnexhDc|1a{HhL^`0r*P?)ki00Qc@JITwg3-mGjd>TSoI{!UEHvkT%sTL*@m zw@OytR*+)zD#@jHcKC$?$BNO>v|gmBV#DBeGvJ$?YZm}w5{=D}bd~zvvGHkQK&9(3Fl0jn8z3T-QmUU29O>zZ1Wlzn5toFzV*x_vup%* zlzJn4JjPZA?c2*NgZ-zp|9@E+6ov~{OI_;WGmP_Xcz{|KBx6^ z+Xt1Rza7bf(^m9juTKU~?E4B2#=Lo#6ED8yRDQ6cdns9$u zz_5d2-asc#>F31AObyA-j*nv{=>NT)^X!DY_>8UymyrQEn}7}HAG&T z9gvxJ#UjMz5}Z8s*q1g@=fEIp7NMKR}rquDvESF`bkWhJj?O>TNlTV058t;dR! zM>*65fagPt9ue=5lV;~!`P7q<=B%$$J3zYKze#NZap_yYdE?(lsLR=M75>NdA_gei zQEDdQ&Cq1L5R#u&$b+?4h)#<{n_uh^hDTqr6F;P>}`f(c`K;RoNF0Yg$n zI6LR0L$SipLkHf4?klGK(c+V0FFMcT)mwuotr>zh`-Jv@-wZ>0cqiVun#{6O*WoZKstkQUu6Ycnt|$| zjLPEGP;3@cKc^%hdidzQEgI&goJ)tP#lk2a?j*fzN&TT#K`O@Q_^*!eO zODBPR;RrV_ALGG@EUoLxH3^y5Nh$slDUr)aKsNRoviF4r%8DzqgyPWI#z1G>gGIuM z+EIm@LHch98MZEor`rp*3+MjItf z;%%q@`yk%`CJ?t*g6B0W08h}|I%9ChL-CjI4dU$QN@(LZI}Jp5Uf)2#?$4(scj)~4 zR@C6;w=0Cg*VOT9?yL3!$mKY#%0`NIl~It(`Tn) zP8{$2lU)IvOM4lQ+2Ke(h$;45B5q2a4d)DV3BzvhF39rs-pN{0{5da_kF5lpIJ%>& z#$UWbwyuVLvnSafHE6NHZZVC^6auX7L!jfZ z!SBtjelgFN6M*G$a@(ZCp7v(R2tybo77lWejBsImuC2p+dpxbA&cKJ?SkJtK)*SDf zT?Ks|GG5V`_NTS=$^{uM2*z5U2PUqh{rBJNeC^7gShN)Hb7v43zH+<=(+V72GG4M# zhv&tepH^Wh>3yC!-w(@sz6Ki#ZkUun0Nv4TW4VUp2pcw^`MM5OQK!^#*vexdy*Z?A ze%OMgyLNecj~S_D4e87E6&sk|;sxj(2kadI?E%w{o1CvdG8jdhAR_9i zJ9_y+MAp9vY3r-7`AeaAQeb+sVY(9OW?C%q#yXAHqKAI+CKb?Sga&Qh6CwCHtZ3)u;=Ep-0L^4nG?>ICUWQ z88#IR&2(Vluml*AB0zd$aNhXn2vFZx5*A?Hew-%w#yq#&t{`y!_@Y#tM?gK((>-2E z4(S=1q2c?Z-AH#S_?*B98wA(_Z$$sj%6B{#(iR&SDT@!0!p)ZSj(}64^i!W+AQ0@b zb^N}3?Nj?ZX_F3MPqp50HgLt}qP3FMQIKxYNl5tjqBKk`u*dZ-*!s=(xOaC1;@;R; z*_lYn&1nO>2k5Rj5E7nC`(cWtU5PJWer?J~rEiH!e!YxZL>W zAz$mvAuf@3#~zH%&H+|}Ijr!mlauhbc`4lrIM};3v$q514RZ^x+3KQjeVual4h=}v zaKQ+7m+tZP!LT4XjOY1Tj{Rv)ijc$cG>$A_;~oQ9RXKEEDW=%-96g7|_#ZSbx1Hz} zb1BJrXejm@4)9Xsiex)MReqclZ;(@r9jDo>D-H{Jd7PyT`js|7dUL?e zL#9V63X8ns7M){7P@5eG>)!_6;|1)EenG>AIrc9xMBN3y=|F@4VFVh|l?se>?IM7F zkU)lxFoAStbmwq%W_OqAGd(pCimF&nX~`m`kfK1>jMPD|-5%A%rTVhq{K+1T4Ld_f z^D5|f_2i3HT;CP2M4!2WIRcn9jdxeOse$ljalNJ#U>dng)j8XS7Z;Z$4$a&L_l zE_Y;rI&jaa$rv9e_~6Ey9fu4)zrojH<7;>Oi6g|60oOv>Nd9Mrw^Q$f!TQUaeZn)V z#PM3c%RoI=N%99{Jza{S^z&R3PSh|M$NXgJTAybBAX!v4JFzPXk zBgMkB$a5ZAkSYLMyz_-+AREwP&&q3w<-+S1We5X8XBz|I*SGpaUU)ppR>ZI(d@dT{ z!gJ@Oi`0}urFe7IfU}0W1juCrSBzlmNC0(Kn%Ow=x6_l`Ebr4^nA4&=HkP-domc}l#WZrxCN+KdmxOWT3x*3PW2-af?6bZPV=Xs7)p8fve%57L>a zj{tYDu8wY5j$p(`zwwDEh5FKV48Hj@YDnNPd0Cde6_EFoZfhUdaJ|R#hC1=d<(ZgC z8~fpCtVq7|{R~XYvkB|};cjfzWnwnYZ|!V5xvxWbEkgRC>nDdRcDAw6V{SjEQ2LLX z`D|LAj=XNlPv#~9gD1C zg~dxsKYLiZn(xnZk@MO^k@&zM_vCM)6;uuG85bvrO3#hyvXo}_v4>P6`ywD?FiHuPRjz-8H$S-56gf>82#?sSGe zi>q-sPP^^TO5VtUhZm(Qa4ov$?^0rBf#C6pv+*=#z`9_76JK1BC5*d?jw6dUP9j*r9U+5DyKyFaQ7Z^xwb)i4Q(VhPfo-i=Op8Bza|c=f8qQL%z2_1TgoDbwT>Gr!t5zbb#;Ct z;E-7+H`!Jm>GqI9!?eN)$7I{PbRA~;mcBfG<}{D%z!Xg|pLR!M>wjlzsH@S)k*>7y zIX0nq8gY2@8JIB>duP`&dpsUlW2NY_H~sgsy%?L*JwS}}mNVQ{sHN++w_IYxbxf%9 zIDx_WgPezb9-SsaK+~}BKL?>3hZn4yQSdn_w`=of0s-h4<8ODBXkvoU)A~E{z!|A1 z@E%=dJlJ?}A1U`I_jBO-H_B1M)eN*a2^sYWBzr=t>+C#Bf>iwX2Uv@o?> znc2T}Un9BnILX$to-L{8apA_`m^nF~T$FZ1WIi_zg=fR`1uvF0>D#dk1LS7l9BA9C z&USVsP_lDN#m5gmsMwrsfVmEM*IWBtdtUZ-JnejFW<&tv_rhcGH{Y4Kvho((S-J=* zX=(WLWqok!00l2E*^1jAT7zru{uK8``aWI(yQ?F^_s3Ox;AR zBAjV7eKTyuH;ktJ@R>HuQ9s0e&O33T`X0v1n=w;fg-ey!aJ}{nCdnJ+$}0_EI?Adfo-Qfh(7r8i^V4W&`kyB>zbwcM+UAeHX|%60UZQMzhuY zQ0VczNhCWYLF(6)#?NR!MCGxL#>U=)g@aw)61v9u%J1&*x5=p6o{@zWpZqR*p*b9p zJ=*ciFRlul--UV2edhc@PP>>+%JsDqyHD}YPgKQv34e>1n)6!OtMSa@)FY;_abq&V z-<*^r!c7mW<`gaenA^qq!#S7?5V}J?@io|}`y&EHuU?pO)PeNIjU!P$yfhQT(=|a7 z74O!@&IqOVq*?Y;e*BZe(O)Hh^bq^3n|^CH=J4qtVD*u_OSDON@!Yhd4x~43oci+a z_cJj#RTYN1&Z--+XHKSh&0g!H5v0djI_Wmg(zq~B0L#;^2Ip{ulc;Rb1yIdZd$_Tu z|MD?zJVv0{aRjRHurckn>0Z=@jHnU9%3J5u%OffCExGT)9W%Xxf8#i4rrHX8ZVc8% zxjQtKswHxJrFa-7r^0= z5eS8&HOvjdu5}{pJ(icwW#nRDU5*i=h_@nHKwhz!)AfjqzS4I5Sly1WsR=K-DshE& zoxr;rHwJ!zwZ=fg(4hvv&hL;f|YDLa23pwjkI$25J0a( zeHA#Vjk5ENZ6>BQa+1phqxX17!_I|m;OPXkT`+^~v%6bn{;0Q}>(oaiR2FY1&>f(i z%h>?Zg;%|C_`6b{FE7RN(aqKgW{mKBsOb z@WUmE4(IaWdvR`SSMzN7`y4uNhRiN?KE~?)+mpQb#Z2#aLKX}rkp9la894X3Qhc%} z2(LXpFD{e0*{A>T_VD^QUeouk*?8!BO5;55*T0u+uEcnNdJM2;xD>p2UYaORc(gZW zC}*bf)1Ewt-PMt}nfhbTob6Wd5`pyYiu5^@jb$klp)sG$t?yR~16*f4>%0!Tn$D2o zR7f5eIBSF(4=zYOqQq&pOijS+TYRDl5a+NzyfC%fcyYSgeoTAc2Rj3Jj}DJ^Y%5N! z0d)y2Q^I56@1lg89u8C=eB<|bEJwDN7JL6pC*VQh7giZVTG#B1Fl|0j@3v}(oHGVW-Xy48Z$4B5qxK-o%DpfvcEPCH4YRrka$PB; z;QwduI^f%=um8K#XoOoF3l~NC(Icc6XDtl7V~%%sY2&p-6Bi zi6%3D9}d(FQVL*K!~Ptw%W9rF&rz3!q*iQY>096_oHNcs_n%%@GWT>5@~(x1Z;r3gRGUFhLF&P^hgKGUE(JXnkoL;c3aJIGel>_ddR(9f0O-E@R6Bjx9ORMb zto6PeMK>F}^|af5=K1IO7Z&OsO|#BDU7B{xS9!`}E_*bp7L9xEg24gO<1(dA;;m56 zc%m(5YB6$}!MqzRAUzfMAtHY3LPt{j$6^cW1WXxWXj-xnOM?BZ;UiaQRuEh^OQZ@Iw%c22i z@;fBGV*)DA1lTiyb|Hhs-XCy}y=D@9=QN*yR|b+tGD`T#YP`(-07#*?l5_LQ3mQ2 zo*M^%?q|l!jPW+Q;@En!3jqqt2HxY{C`35L9uKiuog`dw~A} zyAv{0jb>nb0@38Td=Qj)0XP(?LpVP^4m^@=RNJH>vW;APP~0Pdy2_G|z}WNf)?Ffx5a{KR|LyxuTHh7s)bn8{Oh;Tk%dY#|!a>;Pjb=2?QGFQ2 zux_1GT7Xa-#<~eP={Fu;MYj(!kRBJXAwWMq<5W0 z=P%Oz=9ryhKK^^RsD*a3cO6F+)dlk(2DT0#XC8EOa`bpJ-8#FPgVt=>O1u&`GZG&8 zYW<)C>2dk-oGRXx;Ll53MJB{JF7{$srn*3_uFoB-70V4YWiZ=3(e`>fOE9Bmk}*EA*UPlowv>F^l< zdpdBQ4Uo?S+S*n6qn5$1s0U{GoA0J6OQDf+mw8~Xa32D<9lYKjOI^n~kZ zT0#d=h)h&VF0zxKd}N_j@>FV5YRO2E%m7_U^NkX-%%U={9KT1ObPj^WE~*%)mTb zz>d60nHeQ6W#Bg?TqjruW`m%6n+R0Iz3ccI+Ha(h%2Jl%tmpJ)LUMkeScwuCZP>4H zWY*gZ^o@gTJlZ$0M$+YeUs~g%2R?OErD^zqbVR(z)=In>lHRhpJ3_nM(X{Q=FsF@H zk^Xo}ZP{s80)i<(b$1kw`(p{DM`;n{>Z3r^DUY>r>a;QIZLONCrlYR-ZXtlWaoz z0=Y3fbduBdvXxYUGyq@}8!T0wf7#3mdSQ)kNM{a8R5zJu za?d#WW!Gi&r8I*KqCz4YGP$Q=IdOn4Q6%$ulNO-&2d)ze_@!FRnZ~D2z|QWQ0q*Wy zEfn%@VwhZ@kY_XdYGS}V2GS9!k4M!LDeoMl$12|O=z83NpieX%^s)atuOWv+ya0d( zMFZI(ywe?_H60OJx;w-TTjVvxvLiGJ4!haoP#~(3%2JkM32!mRbX~xZ-wNgpDPpxd zaIiNra6Y}kNOLEcIiQ?aE9rKxpYIIOwXb%?3RMojxdJs3E!ye}5OH~Jy^j|$N*6`* zhGn|rm|EJqq3l2`1wjSou?*n;?JIR;)R`i?sVhQDb_8ifYlyZxqr6@UbOapJO_k`R zVd7C&w35=xQH?0?tasYQ1teK8McBIj)SS~2*~7#twXR~5%DfW6csfi z{(43o9s5uVIf6>j?afl`4_?ZS*<&VJXzzL>ZRiej{WJtck$45PBd=Fz?W+O>-Kp>` zHLAV`1>Up%gLfTo-~YGTQ-AWkDB4!^myg~TV9yq`_Xphf_*;=|<_NvwJcQ15yiZ>} zEJE+Ew9?ug{yhMA1=C1twz+xq+{|{UF@q-&Ro{_&edC#<=!^rbw9Gl0Zfw7aTFp&l zHw5|y${AnJ0-$I0eHI`+1LzkS!1lZR21()V-+F<$N^$Q6>Bf}G?}=64#aOXB zL8ZXUy$+Fl1^uw69AYo29n|KD(&H<<^oI{!{2+<9+R1A-#+LC<=2R6VHwkpSZQT*t z&>7+MRuuL^weiLZ15K@yc)KiV7_x}VLYzJ}|MI51=O2LC!Vbv_rcaT!foi&@0vwtE z>E}JuPF-xT*(8CKVK`T)nNo;odW$9&S`u9=~eaiM3<^ha6LxMw0iJc>g z;$izwqytA9>B@ubyncyQhk{O59Biirn*u%Uva&lkWfCmaR^tI@oyUOsU3!hLp=tU= zY4TC0DItGOV~8#we>l0OFwPlvX2XdB=1T`V!;vP3AOToQlWGloE$FFtp=Ux4 z+`|~QKYw>pjqW;O;pPCnvB6KvT0+#~QEe80cAQgHW|4QOIBJ}U&f42Xvvj1}qp04` z=GM@4uXT~pT&53|v_pxl|Jf7F^ksXP+p|MaB=p^;rUQs(UQG1y-xKjdB2dp%1)hWT zwgvb8)iU9bgDiU=KU$^PwRtHTwV9_oUS5>ZdzGkvh$X6D_(M;V8QG=rRw_<5|l9Paubk;t$vNMrXYV{e@ ztaQmteTqB50rsN>-SpnJAg}HWhqKD6$h6MX{r5SWzmHz-q<^qEL<>c*ZHG3)bq&T>7Sib@J0WHMEz`tdlQW!}Ksa z!{6K#plxiA_O=pJJMv)8klR10Mxs;Mx`6WpMd7pxm{8N|jr8%(V8#mYNY%Uf_$u94 zQ!t+&{erEhkKDAXBh1ZO^m<1+PNKQ!2t>KV0_{2f@S&SdoNS>xkF939LLb0>)gg9H z{YOWFiV~|TjxqnFIY>*IL$s+Y%$;f&AG8ZSu*pcrv$4>lwQa6~CApRX=0!}8eAyP} z0U

ntKoV|(IQX5WH2qc;=o=y7JQgNCZ8GZ_i8C%sXjWlzMT>ZwppPJqXWQFW+M zQIR9T-Ot{9`}ps?@L#cd)F>#;{v+yXz@m^C2^KPg@@#;6>hCh}Xf=juzH=6xQ@Mx^ zo3xHDI<|oxoZm(jmh4vzKstb#sOQ|5;m;lm^DHY#i#pGhG+0@k%&!MM1DDOk5nB0M*OmyFA zb#%eA?fK`*us{6vq54Lw{=3pkw=Z6h<1c}_ao*bQfp4w+i7uK~858UEjWy_;U$;7<$EL+qrV#*F?8 z_t#G!pt#_jZ#(E;OFaybfr%t?P_8;4k{#!uUBA8|K(DS3&~X#ZT+i-5jO%y6#K0c7 z{TO|y)eo^bxM^ND2Yjb?Af8e-rf?RUofz)N8vMoNfgao{A63nli=>s|E}!Az=+bYa;dRBBrnJm|I*uqv%Q>@0AeE=XvQZ zyU6ca!|-`(9(oE$7mdkn+2U2+W0l@{0lA(l4%CM}edw&|Ryv9)pFkvc7=c56f2M3s zo2Fkh{r0yUbkYAhXcs&Dkk4h6GUxQ-b!#l|tKBElw_fa^A2H*tEM*xe>0$u=@1MBo zh<~-veIL8I;fBbHQXZPD1r9h+NRiu#%gZijK&BneD802QKsUY7O^37beJuk>hxpl> zoIk@xwN`x$zFn>;o&I<$-TRS?g9udZHyP3!!gwuS_W&UB-EBcS?%`H?ZJmGE&MD^e zoPBJ%wEX%j+gDdHV1y$}3rhnLN6h8*uXoeki(H!T>zYF=IY11{S^fd&@1_c~G~tj# zbuorPB3wKaLsx1Pi_V#s#TMWcMA2!I3 z=6BOIFL&}ZPAvj3oJr?~ndyA}VU@b1Jv2KbOfR%?kd9}tWLb_s&}#um19`#;@LWM>OO~Xcv|SNM_rjjlZ7q zOMMlO%Lw8X?t-%#g7ltyA9~(;9DSqa4Gy~Tqxnl6JmQ!xCms3d0d``Ht2fg%r;Mb- zrrH^@^3q$bL+D}G86;b+YW_~Hk@HNiE7|;xmMD4(NN1qi)zM9^_T>zR3p_798Kg@Y zKzh8wdjjn}2GF57mAD4wzBMJOBE?Vz?&xj&?zTWinpoyTUNycfl0M^d$3h2hUscJJ zW3C=X7|lk5NcSvO4e7yNQMfFFPj)gecf)I4^wMgznyW33bv#@JApE&iK6;<&q3z80 z1x->(0q^dR%$W-D9M?=B4TevZNz|=pIzIE*qwcj zFazs`Nk`0~PoI2}f%d#w9%eHqq_R-`TL^1W*CyTcSc`6-hanvx~ zr{pmgRcwF#>vIoJSGniZ{Lk=qUo@@mMKpJMgGA@+pc|0NanW-f^m$7-ujlP~Zg!tl z?C^=Ee5J*&)e#ak~9QszxOIL zP<(2}63zXwLN9+e9b`^z)s_g>EUSan<4k7vD!$-%&4L> z52>RDI|HWy554I(nOceEYsl2Qapj7|J3;nw2B!T&#dy&vkX*harSmsC`)=ha_?dn{efMe zkRnaMXi(jxlza@T(Kj}h{b?L9eZUf$IZB_r&l_LwqK}({c}E>_q9A<-x$IZJ+)3|U z(M02_hfh5XM9NN_WT7K8_U1;>z8mLt^J81joPPu?5P|){{BAmQj9F8f#>M+r&_5W^ z%$CjyP;H!X(j`^5es-KDOr3kos4r+o_>K`&!(>=H}x6bx?OuCc82J zG#?BAz|(z8+%&Vvlvh0ihhL_342-3#yMsLlkgf*+yklWEeXuRaop)M;qPSB#yQg2h z@1i4^?mA8*5IlK`g|i)3W!a`qZ-LVlpcXmkwj7uX7)M04k<0!EW)J@A1bvJBq1zFh zNvk_@cdj59tsvY?w5UD>3Wk%4ormfZvIUNZ!bgJdllWQytF%ZZjgO4R&me6CYr zbf$ducywKAedXuBm8wTK*$+JHWDeF7flD?$)N?8vr=(HILI&W99%&LukqCLBX1b%} zGWt#ZKj<*aN;>Vw>P;+OHyaAcaZ1Ie#V~5Qs3)R~tQX*lJ0|9!$b1ePY zbs+@|HZp>Xq{#jAF|!5Y`2zI5Kzf=edK{$tJwfW+v6M}bTP+@!R4gtI*iF5K;|!T9 zyr+V6Az>=ii287#tmXrb;U%5L4$=dfv>U_i-YDI+(7}x_tr19W%(H{(j<+4$>k05w zma-H}u=WlfW8&A3XIJxT)X0HD!Ny8cIlP{#`>$ih+&@3_kc}CsdeLv8n@-XxY7GbC z6YQ$e;ogv=y~PowpE6zd$hq~y#~H&+4Mdu?3hDziGef(^tbe@+m_#jJnSTC`gC74{ zL*DO$x-W;a3&p&$11LcBQiWiv+gtm7lJ^Y0WW@DgrHHyjmbo+Qjc(fJjB*;YX3)xp z4JkuEe$zpRk2U37>pSddc;#cJWH< z`RWkt>7^}U`rm3Fee*!=>&Rvry0vSPr(R)r+r*U3$-hpQ>705c=Bq~%zA8#I65jpv zjX(Bp_~28~QmJaPbU?Gu9Q7<-&v=JQ!e^#j*k>jqS%eUEMC|m#_V3VRj#J3(Q>eih zpu;B`=^O^yFP>db=N(>0hflFly*Wxk&`WIrJN>ciV)~uqQVNO|GD5K^N@mcU?!I$< z#?-OvFSk8oE_y0R7b)lqQ^&S1*lV367_AB5+|&cs(-w|P0_kcrJsG6;o)UXTbB4Bo zjXDNOj@kk=pgH5sx=?$ObGWffKhG~bpP|I-5wh%&wv(S2yu~z3AH; zEhnq@2+~{t(m{9Ci*dkH4kVF|o2VVAqpj5MKXh^jqM*~gp;N^(tG(RN9}a?)g;C7V zK6#2Z=GBJ`_&&Ertw~UbEyU-Bz4r@i{hU3aMNXM&rEo5Zr#O7ka#-u7WS`g#*2%t& zM$RD6Do?KP(yQzJJQAwc+`w_t>Wk9#pibvdKc~wl(_M?4Y1^^|W5I>}o3s~oynC^W zy`TO?z~Ee1vNJ?auk>ktFSIYMG!;Jw`u4XSeC{k7@HNhZo$e^7@9QOxFZa@m>wKD> zNmyF|>bf{*L}ADlu-WrS4|<69I+^IOYx;toa+)iWa0$_X+qv`cZ{HZ)v3#{?wxLQzQDqo_bO`c8qd6jVC@VeM+Mo>^s>51!<_4oT_LJy7-mizRSCz6Pg_NuTxq!8Uz>I@al*m$)>s6ndOUY;B=MC!9iM$-ITrClG~$ zL?_&-(1ry9b#LjxSqb}|D7kH044ozAteYb4_ST(`Tyg!_D<1!sY1H(oa?sNYLVNxy z15G`bKI(m~Vj%+vmY6oQT1X0pNQwq%O?V=$2u-C5(N9fc7gdSsy}IQJYK_*BN3oDe zh?2!5^N2jZ?@Ssm9~yk>xb*eAS+#FVU&u}c>0xT$x{Tz=ZW4@^7_~h$FWuBjgOBB= z??HEu<)tUn-4noi;xq`ugR1&bb1~^^$^uih+ z-EeqiS#6eOz~#mxE2+sY(v>fF@krxv?ydb7X56ENS+&l^f7_y( z0VrOE>h-8>Jh@I9(({b|^2cceN9e)5pn$+AQP6S^eZSFVAm3Ds>1_RtsWkA2V5!!o zK<@Bd9atyxHU#L4-JyimYx)YJpAUZF}TCyJ^j4_qzAkqHIg1} zNuj%^7LSVq^LTal^dMc>Ba)tJB8I-K?+DXdOo`>9zz`K2TP5j||NZhhU%{dzMs_g2 zvd&)y>SZYzL0@mQ&AH}PHHU9FR)q)4<+Tj}Uiurl&`ta45KTv)_9e|hT@1TaK~SgN zAEo&l{krzAE;&n0AwI`PXl%*0U}Jz+MlKXEN(BcyToGEvz|Gt|9Si{YlWQf~%GQvv z1UERGgpD?l4%DH(%(JV!1*cZSiH}x{DBO1BI5X|nD6!W>a)lJy+#Tku7v!Ylyw8*x zfr4F4b}(&Bn#b;~&3;}SvQUC|_Jw7xAG82<2nsmD;PnoURr$Zy-PXcT~?sp#1Ay*K6_Mc4fFtue{VpKg6 z`)UezZQtJf;5V-ubJ@dxHIF@DZ#m#j53I8R?fHQ6On(>uJOFTJX_2-b&fI9w z)mvRNThN{fxMu^J`&(Ptv_Q++(oyno7*PMw^Be#=yl4Ug)sD7ya<(jEpxe(dw>8!e z-MB|YUCl!`rfI<@_5spqPmo@qC_4IfqR7cW9@m&wD9{dHl-9JXRCiRNQ2>snY0SY#v9li>RW<0Iz1}L8?4E|BeOkSC(2Cr2R8qGL0!JhC`;=OJ zY!grP9^CF&Yu{HF7WWEzSdasUF7g`p!tfl_%~Mp6Rj- zJwfJ=!1k3s9{k?-0L5}GTbn38^WYaA+JA(ResE+JU3_4Lu2G4z_p#CJ@n%|-bj?EM5(iRHHEyJ7$#>{xWSS_ZHy}3G%eT?DDORO*fO+WD=eWs@G-h$K|q_c6x7^^wfszbVta^^r2LM zv;ss5!G_T4^yuO1a-Tv~V^YDnlIHtF;GP;~ zhb84@8`LVVdt*5*eR{DW8jZF1%J9ya+ydG5QcwLurJpO;H&*hv=l-5GsSmo69Y{yz zV+OiC4iB|%`j~k*ri8X^`GWM6XnKKxB8+~p@TCE~aF~iZrr#sd zqz6NwqX@<@-XBJHC|W+L%95Xe+KD{dXIJ~^{HNP>Eh2O3R11w|MssACv}E1oigLPa zA+#=zK}0gOIwPSkd=aH6vBEa*&;;swf}_DG?vO&I7+=I5L8_TnXCuy2w5S>sKwVJ- z6k3@!5%$bT7Zi*5%&2;$*I`J0@J%3fYn77aeH0AHW zu7ItwcJIc0Pd(2*^~96Jx@i-micyHPw-Z%WGAqu~s|_-d?1er~v%Vx>OF=2X-(~eP zC8v8p6kU!A)Y-g^+#O#s1sGr;-O^8Gcd4fp8`{qGv||&J^U|}6q?frc`K%EPn^t2O zR4iW+@`ezx_rxgwCPR6?%aXqUtfON2ZEtnc{b$ta@}48?20DC0djqVN%Q4fux&P6d=s+FSb_C!k(8u5aQl8|?8nz*24 zmOCUDoDrv&7-H4owK*r$LW9M6V(16xBCTRImF=Fglrm6<1bu4Dw)cKV)VVPe#7q|- z_DhmfIriZ5ZmOPj$(0fNgvxM)Dc@+A1Vs(H3l1ldEli5NLIsIQRo}A!xjE6<3!t%e z`FZZe?9_sB5(PXy>e{i2LcT3zFsW2`wQ756HTQHNUD~rxdcPpOc#-rWjMLTj2paP@ zkvHUzP*M6w!|0Bb+3#i1K`I$oe`uMPQ`Qe2qfc(}QRB_@99mEfgK{@0I8?A>O(9*P zU5KW`k!Um&b}VoNg(5>U(uJo&wACUF&vO=?Mx+w#p{~RnC|WzMppSGYGI%r=_L@Nl zn+0H9D5C8c&_O?x;yNr#8K@_V%yyQohG^_zaiFfGptf{7!E3K>oI2^$+yAbNJKy$hI)QWkhyc_ilBctSoXuZS*uS0OZzNG$Vqn~mkZ&&a7K%&BN8ckS zy{82m>W`K|dQo%A;`2`H2wZV!?y>l496@AfLQ$gBJg z^>rEu7Zw6XbwIurgG!YxG+2iomCA}~NC~>D-2Rq>w`8p-Rm!mr^=f2AAE#I`Z5FM% z0ZarG8C8ndg3PLevnN`vBv+OJkUYzXX0_nM7OSmh%9+3VPoU<&iP4}ZyT6M65~AzD zph|`3x$8n^I((r4xn=;b=yRW-xw9+ic2W2CRTOY-X2xxh;q6!yodavNoth8>>%8xI z4=_)8Jr2&3K)OL~g;ECTMLFc5_=6fLS;+rHi?~9cA=rK}yiHPh?#rT&z+l_qitq}+ zqpP&@qtSD@)*_PE9Ub~Wy?`kw7&;WW0&QJOB)7sOYK}N&d+6GSa9ciEp`x^f8fd{Y zqUhI><{;g(*iDOf1WOmB$Ie7q(GFUT@pzOlIM$-pG!xhm7PeoNq7ea^e$b)DgX$bD zOIZd3P#45(5PV?boU4Bp9&zLWY9u{(P>L{%;B>KfVu0OdW4qhfs~r_VgAbulfV>X` zu4RA6L2)EPfSfVu4+v^8B}C2i0O|mSRc3)?r&64v4Ff1> zNmi&Q#L%Jm5~|AEG>jvvLxZ*q&|k=71FEmVHZ-~6LJYwAHG%{m`}?b3>f{y1r4k$} zM9>`pnLF)TyivXeOBtlA^P=$k)*^7SgIS~mOCJQrYeBd}+F5{bs1~b%4Cbm)2mRm( zDrz9BEM+NqpdNH5uK!ddhp+yIvHQ%n%sBrFZ_rPgNV(7q!646FC$m`v>_({lX(GFz)?^!T~d*0PiW;cj-I#iQv$EVtZ{1lHqG_BcpS z`dMOiciye94AP4!Y6L+$P#;?*6+GgCLv=)jp}YiA41n@*XjAWSRt0n_1cvBug;Av8 z(4no6(J0>Gff?hTpiDLmmEamGLNkP$JbI}18IOS@tyS%Dx_`PeL>s!o z1+T)dW&fgQe8nJOM?iN$Z+SzQm;Cn#oDoRZ+2x6r{Am&oE_C^|(|JZ!GMhyS7H3_t z$r`JJegNB}Tu-hnr4Q6$9C%uVettt~Jm~!I1jK4lhT1h66+Fvwl+)cuj5?Is+Lke}?qG_@)bsP+f^b65 zS0Sn0njzKtNJPxqzb< zx3+TvRO6;fk+!*nGAl|qpsun2vTJ9kUp)Tu)Vfvnt9Smr$i&6{52p0qY6N|kS3Z7!0vF6 z;B@jRbMMcDAbcQ*+x_I#mGT9B*&tcyl!Y@A6ZQyo)AaxcJ+ zjfId1ff((H<#sp)xS!P;}E1QmO1-w%@~9u8nOvti}DAUN96vQR6vB zRv7r&*CJp~V6F}2^S&%44b-uzqG2NE&c1$2@_D*jcddTwU!r7`Mai7Ig`g-TySg(w z+TxoVlz0Z#d6jsdkKJ1|38yh7?RR0in<2a#-AwsdPh^bQzlq>*+*!RYUBe1nd7&?wWO z8{^6X8Nq$g5E1yTTNyA za7>k9$j%1<&DxHz=J%P!^tW8DT&*JrR2XR04%81GZ7!P4is^R+6*3zHI&8Fw&YxkU zi}ttCDU&T+7X!GXP-UjOL0ZhlF70dafF@H>^3>r>nbBzE^>wsJ8w2TW-e{RYSC*nn z9xf)7x$JY3igGv@YJ2k+KlW_@_}#{%zk8RpcG7-I#7|1JpUsWPt{f$~yF>lfZ0VcB z7zdD16j@`MB@`e9ba*2J6OyFnVJF`AfCBRr)Dvd+3`#p9=7^%pa_{fu0E}e@)=fq$ z)mBZTPS3`KaY+T_lnm0-Iy2I|UIys}6;ylO$_{!I3bJa*%L6_25O(Okyv|Sd0svDO z!+SGhc*Y=%s5e#^NGy;Mbo6+0c@b+6P)83RYt}7i7W>E*lDRQi7VWa8UAsX(o9z)4 za`F|ZWgZOi*+YCEqD%mKiig>=YS}AuCRoU35_>Y~21=A(i(`f~Esrq-I2iY{=W@B#s5w{w9*+vtd-BgyA1+I<&YszBsUe%WsW(qK z6`04~FKOI`em=s<$o!#k<=t3nscOP59D!+sFb>d{ppgg3I3ul(}b=83)IJU|_ z$4|DD7qJFo9l6Db=IABeewpWtmRoA;p__=lY|{=xCe}*aq2(_?Ya_g)g-!P9)2u@q zsIzloD?1}Lb!j^%;LM#l(#QZ?@dFn)n?SDy7(`1_06j!+@%><>;{)`r(E+GWtC#5D zQ6^4BFO*=;Ys~_^^z}yi-AT1+Q$^4*D=kowAI~Vvut-p`K47(n`+VA z>aD*uS7R3Gl&RYF!?KnT?}AZ2TFO$|K%HVOZ%nq-voiiQ^{P+;&WQ8lfBtjZlixUX z`SAqfOE?JPGg3(5Tv4RB2N{Y|RK{|yQn6+1vV9FwzE~>fJO1ye``~sg? zj1{9p^dDed24F|NHQ1b!Iak1=WkaqE-80|CPP1G>sj;A)SpdSy3x# zU$}ooQOAbwU>zQ1?*=2M^yz5~`a&|N434xL%8NM9xpgr>ecnDcI%cAN&JOfscLo%G z43tG92w?ztU1wOAt`y%ourRs<;2!{Is54t|PB_@Q{@a8%sA4giXC zFsZgq-W1>pc@XgQ#Auqo>1YP2TJTbQ*_)T8#*Jp%wrAm`yBz_%I98U*Be4bW0O=naiXEJ zX$%RX*#_j1ALrMRz`#0mO!4#6gF1NI zQD|xoJFFjF;U%M4`?w%?cU+Z3-#@adym<2z^rJm+q>1i1rB>JXUDX!mhGkVbq^?;I zQQzf`(u&p)9XCmvGv&)^3>{r60`eqW`V&Gmxn7J@KMxVI|h3 zL*OhP0N1$l04Zn2JRN(83AK8ow0w7nnl!RH&fl+s?p@;M&M}LQ%rzzE(E8IEwKO+} zeT=qoch0S*v;W(^hk=iAdv9xi18pq=C;FMpw!qn3rSrVU@A=yY+cm!zoXVfGIX0Eg zm9h)~P|r_2+3GXxi_}YwU2%6Kw1i3VwmZYkpRNe3d1XOh^-Hfgmp<|s`CE39se;7n z`WQ%5`T*%-GDuIl#Gaq`elH|P+YRx53$Y7UiIQ-!TQ;&=me^&8u#0^a*;f%!&)9|N zyc|*^_Hsm}*8@=V2*1$#Ir)}|l#HaHpq?Df8Z;xSZZlP~UpLVn`RPREsCkJBXxSg` z2y!Z*R=Mu5N}APV;+|x^j2s&?8h$*dy6EGAJY%h`Z{l*D$ts?>K3m#}?Q_A%-N3`t$r3LA6fi8XK z!bZA+>1nr)k#)Qmx}kvmgh>9vOGnU$S2odmmye`pFKD2f4zHv!c7sa4SMu8<$SYr{ z!yW-JzKxx;=#Zf3xQAUqnJ(VnM&CZPGUvZPmH~SdVoPP|!De}XTTmBA`VWt)qG|@x z^)7@9hQq#cZO)2Gs5%p%Tku2+roKi->NZv{WKAzr-JoJ?5iC6Y((2F z;b6ew*|}(*v0)Sgwo>M3dQWt`FOc3Jcvo}T738(Y{~ZJUJ^vOHer8Cd(~CVh@yV}= zdwxc0o_bDWtnf%WA3PM+V+Vnd#e49mx@cs#Q<2aQy=UMC{bJ<=1z9!rOYMTe6U~!S zXW|so2rb>Eol1to{@zn-`FrYNgn1ZH{{9h_bokifN7J#D(6>|%fx!V|4W99QcLL_u z%?!FbkEy1M53HcFWOrO(9fFnNWMf}v5$V?_)X;opFe7(aPXTcIs5!(VW@XVwP#OBI zO#xlN^@&p~^u5FFart?3#s)?RDzkx14$WBL&H**^FL8DD{ z&OSE!(`mKz*|kk{*9p}e(BpH3Jod=K%>i9n$7udMTPCSBPF zT$TaR{kdCSYzI`0>d!Vy1nY5>7^OZEyt~&gc(MAB%f3d&n(B;H?-)4eJb)ycyO{ia z>Q^E5H!-j)$L@|(W6+*Vj1^fEdY?d%)v|2(WkrtPsGwF87L?v6?fELGkE`_hKoH>; z5>aL@dYpZZXsaaI*+J3nb`onENHiEY9lk%$i&3;tfc?k&s3%pN7cx2q_H55qdVeZ{zo~X2s$V-FGzOkkc@yJT@vvcRC?>IT| zGU>D}{k*!rKz}*4mTovAwo_V2U%`qm4bnm{_(X@6q+{(D(`ewA6|j4`BleB-$e zYIa9Ci!57B2r#>;*S$u6L2cTQ`FH zA4U35&eprk6TpAKf45{w-_az#ss=4}jcIvl`z zHhF*m^)IdS(XH&jLLnEea`hpqA$QZfZhmOxk{61=fHxr1*Y>s1L+3OMSi}m|Wn0;J zg6gS9^c5}aUif+=UGjVYPja@@U;TO@948UORmdz>s1V?}`q|nnVeYya36yJLE+y*im zI_aq|y}VUeF8RS|@rGZ&pBdp-9bzAL^MQQo#XEw$h1RJ$RJ#AkG1XkR{&0RbuSZ~K zXHULqxL`S;$mYHyO!QYaKgZ@-*8p_o(Uk`3WB^IZz1%U+$G+#}>_B>=9LCo7|1NB# z(;sgmCtLH`u1ijTkE#w7J%Bn`anD@PKv%!qNzbhEspnLVoft?K}-IU$D;ETWk&fY;HAu=dem$_T0;BecZXI zckP6-l%=phy=t@?Rqx)GfKVwFw99GqStJdZkBgyg=~Iu{_dfkJ!9H%Z5)CH*WxRM? zDj*lrMAJnT%yZ5?(#;tlx7VAgie0uUiHr=Ki-z8tNREsryAlK;4u2K?=wW8L2i#%u zbcM*<5u~6iL`pOc+J)rDhKE2@qf0{k4RhcS;ysnh26Fq?Qz+6(E$u<7ubV+;a~+SY zXNs zVTXcWH(E8oI{K8t2>WDbh$MrWpP0@N!>SBL)ksyHRiN8XtfiZ0R}CnwG+teHb$eJh znl#>L{v{*mFH2nX@1-8v;*9bwX^5$f_!dP}28J4{=wEVR6kWl66+tpeltghAYD zZcSU5US;6LR*t3@1ROrkjMX2{snUfF0U+}D*Ba=sF(&%mhc51nv#`wu{hn@zVLt|9 z?Y!az2v3+YJli71EsXmfM`n&P@z!NmzSK#^9GH7H z_Pd}*ukQ%cUJcqSj90Pod+Pi~nmfVG_s9-sgh%dSCuDM@#OtSkf{!{i59q)+fs<~F zBa+r>f!DUXqTE68qocJKR&A^>(90K%ple_0@E+;%EUSq4aCDX*1lt!2AvpEyvbG%z>uH95`iq=IxFRS)@`J32mk;QkS({^71j zG@+nejFzq>Rd7$!uRIRs2?c8uvQ(R>Zj6jgUl#`xqK1D(N)zi%^8I<;OZ zi7`Y~=f&HDboyTUMY3U3A(C|MVU_gWmLM%@4$|iC2p<=W3G%2>jTU1E1Gd6c-Y=yt z_kQG}E(S2F%25y91qS&xXOtfK!b`Wz(Wlb^j_R8js6#3QDv%>Ghdt;ZUBi7p0*rvI^~{%Ex?n$joVw#{B>Kl$bsTWvedliq(E83W*NLGh zCD|8h+(h6`-$t8A`;Rcu8B9N;diw|+m@~Yf5$g2hIL*;m&+OZd(UzKY>C6gxbeV_V zXXj3~jz65;9sVdi@QH`+JH1x7J@TEyE9ty_ZS*)hyI)-Eqct57UK}nW?>QgH$v(JA z-6!Y_pht?}mu(^1>WK2fgK3?3%uM(v+rO8y&#Sj-pZhxY9{;_dkxu=>Lx23x#q;3t zY;YRECQ7Y5k8uF&4S@dCDHi(W@in^8-Q)7V)jnVn`6_jV9yvMF+EP~!N*-mw%tt6R5 zPGgsKDD=VeF9C33QE?~`dxM248!Z%=R!QC4Jk+(tLlIwCjn2iDn<8*0gCHnbQ{WLz z53&=|>E1*lD$$E35b(F!bPz>a&v;i>%v?qe~ z9O>|7$;+tv^J%p-_n}tu^4z_?e;38DkoWa<9eb9;pn~y%wmjRIF^m>g+no_!><2#^ zVHatydLvD5G?rXM5|p@iw+0H5iGg-@XYXU>S6K$Hyvsn#6DxfsS-WDW2vQpU@wuCK zPZ*(NjR63}U!71xx6iGnwe4YA+Y#mwc7Q`rO~+PAoE0>wRwA)Hy}b?$c9j3(T_>G5 z*~-CXw6Ed&UFKDx@l_sP^cqi#-q$ctA*Lo0qm)uTuJl0{QKSS-u>%|jr+_HYNkw7qW)MkJq=h-iLOVZ zVC7qB^z>K68*K?UCIGKdlf?B1x0yo!&+sF}UYF8;biQBh{N+{i8! z*e6lo6RXe*l>G0q6h!uB2k4o5Tj@W`y!=q@b3?Le`rRTIk5K55tDd^1LH*Xd+IArY zp7iDHkp66EkPaPdE-$9CBnhhc|7d#H5k~xLqPH7_SDy6+~N+nI4RZC{J zfdSB!ej?ZW29;RbuMAhVad<@8@tG)4H~!ED8h2PD8JKm$qwhV`eIXefX9QFdb-BAJ z6y8aqktseDhcg&?0Y5$-5_=86oB?=|eJ@C8B_~rvjIt}tFulMosR!5ttP4UKz}}lV zp8?is2Znm}^B(MS?8NMHDq(;vZw=8O7+5b=QHnUF*xo3H_rwZcNzbobRxRio69EL{k6nGdF#_BUrNcs0^bmfhgy{mU`&1W!@q6Tu*=L<%Q{T+0mGG z(4VL4kRJ{iQ)Qr0b_1tY=ekEwE8}k;y9fO|{NE>T+T`fJcev`Hkm(2Wy7%a}uBT&a ze2sy#CBRky`wvXOLV@%pOvl~*k*mzoDoaTmYx#%lg6wdZ^8=!zzDsEUdMa4&3#6xB z0P9B2t}j1oS#al1L{W)ykQ%3wrvdB$>GhNBG-jVF{t0rle}Enb;!#Qu(D4>B_5M3s z^}}iQ?3AgSSV7cheeID}oH!~0}azIX!k%4g&zf{0(1`zjh@zY~kDBN8tNQZfxbZHGKc{)| zYJ$`fv{ovnK@2+nGpoF`r8`oRbBk1hhnT@!Oo2LS_YLp8b;m*nJ-pmoj(8MFpwH2I zi+7R;l^!DA*cqYsN>FDOO0eotVC<%OUA&IRP>|1dhUob4q}I{%JaMNx=yKuVMnO(zb5 zZS`gvHNA@eJL@QVB0#5Q;N%_0qHKEpSnF8 z8LnnSB3U^2768@_34okm#$M3Qf5*tLUXZRv(}fsKUTtY7_O`dNl07EcyyS$P%UlZl2#=a`*Po7arQs6&Y6Z zfwo;>99{HW2d!)k59((Dz4_(^-MqC}u8~q+pGQ_5NqPvX*dscek9Lt_bAn#*Te}C} zdPMc~8(!-oXE3++cwl(^X^ETu@#)}Y6JXA-e5s4)#8;F%h?J#7L|YQ9%s@ogPju7` zMAv_!(BapxlcS4qk@ZXwc1zcnuRXQ<)mwfj$l-uswDw?165`-e;FNa*LpO?? zeI$Jku&$(d5YmBm$`P!GWvXbf(8&Gk)jsY#RejIMIsmgMNaXN(smrs0;p>nJ(j^s` zBce_*a4y6Fd+g#sz6Z2Ry^(YP_c&k|5_8oPdeQe(fiE1G*vWwUhR*P?-)JyGqB#^q zvq=K2XGSLu`%;Qtfs&5{yy%V&2FM=z!b=M`mrleCI^^0{y69tePsOe_jw-yU#J#zD zcmWd>jJoFKF8byBE^bI^br_Xhh`9?4^1pxXp}RjU9mg5kSAmva)auNNJ_|_E__s*= z*yV}R*-y3cNa$dd?=o=s?zUiF011B)U)-&!w{H2h{nB zVyipgCaRl6bk5%uy8bhTPW(C1$bGW~?3w8B;n-KJbM^e^o1ebsD%rhjw`i^G0h>H8 zsnSUHIuprJIV+H^Bmi+mNe1sdl=loEUC9Hig9cwS(N2~cQx8~Av@S&kn9+)^&DF|) z`g(?|BMf+3dnxTbx#=;`o(`akiP3d6vMz{*gdBB40!UW@x^a7xDoN=CzOba&p zhy6x_!y*{T-b0TihG^kiTLN_H^Bo+Z478xI%!{jhJYOtdLED{t^0~2=P%!L!uXj;P zi5NaGEFW3!CBY){C`8`ill?7Ej}dYk540m&xM}!MeOI)E=)^}_>7PqI+>p|mpNJzP z5Z2~&!k!LCa@U@|kalMmsF?#%KMx-XKz!Rm2mSq%(ukhj_LhUXHL{PQIj~a%Qd>g> zG)8c-{vuIr^N2eDsKOa@`V(#Jyd7LR0ek3b29W;!g|;*njKlle^r4%7zAHp646Nr{ zK|OwcFJ(IGE04F)rq0rLs6roJ!$3MZXyiK&lAv}&x{|%mzd!d3nl*@E$Ty$spvRW` zG_65_pXWO0cAbMW&@W)$1tQw+4R$E>p1#M9qRaEbjvA`g;rodbh4c@!$(?#1JzW5v7b#K3KuvT%93YxpM%E+*(*e|6x z5tOH;zNafDmjLdS1h5|eKC30jei8R)t+%MO{MbqodCv#rqkE~vv4Jhr?F?^=Bp59* zKpq3#iFxQTaGp$ik4Mkd2zpNxJ%RpCNrmK6+q5NUm;!)xNIyz^<1LzoXs z8HdL6YyEWo)9utffcgGkwub5Z^Sb#-+@T>i+7(dp1{jD^tYrqzr7v`90>)Ye^f(xn zfBTdHMvDp(=TbcMHI1$;_HkUI10cbzo%;Wqk&8PM1hS~Zmz z%eUUC5!|7b7z!!n;xu3yn6^8$JDZReV;G>;K}gR*M~3e)op8?pN7nCK?4~CfxF80M zc586rwfmw8-NO4fe4)p7yS1+$H`8TWr%{RN$8M%y&-rgVpOe8*SPv2KGoEPI4ALQR zAkW+A*Ts?h)JiYq=sQh2Csk}su51s}iI29@+nY<*fdbp&!e?XipfS(ih|)@IgCNiQ zwl^IVkxPFKp7vN9J-yne`PsoD)q_E?%@H9%M|&Ll1vXQwN84oJ*$UwxM!R4w0%xBV z$J+1#>WP5e?^Z$Iq&Y-q{YeGwQ;tv6Uz7mSGlBIe^+wh4)f9H_Zf<_^nrm8KzT-D? zz~vAvRU}y%K&345(i6ctWdYVHB|kj{q|1~&Jq2r8LM1WwFAmTJ19|)b2GF-sw|5=M zf}3G&i(1h=DPo>Tb5F=Y@1eQJqURi}CxUY+If^d!0(2pp}M?77c*N;PNz(uEjcUd@cLe7(Y-?+)h0GQfKJbZ2NtR2a?#(2?(W z_&;~k9q&50CtuIJLA>9myR_}6FLsB?onuZdswgjO3GpJR`3f8i8@nSs1!ABCMiCsb zH#1}W`d7Mij{;>Q4=?r5tqZ$(;V*y#EqU5Fr-UpmQ2Z8pI-~fR7WsU4NH@bbUiloy z{g2q3eC3HY-kZJ@1<^fJ6+imH7J7GUK$n7$0EkEj`m08k$D(aPeqP&j&^4G7)Ti0a zK*X6(w$rcPb#hQqN`j(y$34_a&#&?8R+tlj72|i;A}0gEt+b{@*WptuymZWeT4-@| zP@gquP*WZNw6(~xmT^$2%7I}Q&)t8{ee6W3n+5o z{14!HhkQgnrZj6O5ncSOLL>J}1?x#Tnv(O^BeW+KUPNBJD*Vg>kY^eu2Q(^>|0fAE`oJYH&P-%K6O z)fAT78P=BAWlg5F$8yqpL3;{F7mcwZa|t==VjQd|viA}g37dECQo+`uVTJ1{T-PJOJ67ip^C1@Tm`>IZpJ z4By-o;2w4@OAcc(Z)1Q?ezc8NwiM3*0HySp|FqH@n*vEuT^!Ds-w*SsybS6r#>AXw zYg_=7pE2X_#WlVmvtL%Tb&g_jhx}tVUHe)$ZDGcDwOQ1?0xzmWzqa15iIMQ)T3^mi zCpa%xvS<9bIe(h&ybXTZ?TO}8?5QANT|mEMfgbqW!*o-trf14k{x)y{)O2%J4cGFvVrUb$H`~7)c6p|I)T7O}ASPTL;%kBg- zh@ByCmOy#}p7qu@9dr^qN7r=f-!B~FS8WmLovlHd&F1^p?>WgCD2;UphTwVsZKrR( z&`DhZ{njA%UK`tMZ*0gv-SbnXL(!twtn+~fJ@eAq{OttjxmVWtxZcxKptr%4)8fo| zh3R2OKp}C6Qr`_^tsy$(3U=yP3)h4+$|eAxQ$3z&`BT{rWnaH%k^^q1Z{5O$U7s)b zP!=qfim{W%T59V}q5&1w<(_9rjix7l9|!A1dp>#`$MzI!Pt(FZW4ARFhXXigAY5QT z+1(MKZJ%$Ywr%Ul>)XK=yodeVp!PsFB+}gD(eZ>_bN+qr#p&&al>Bp1OsVW1kDv=` z6g?H7CxLWf&*9dY*CND<=)J@?c_>13=x8%Kvu5y2nL@20gM7g+x72QF@e=b|#>v}v@iyl}sYoIlsW{tg`>9K0&?z|XaiupggT;p6nm z{YRLn%2Jq#Lz_mVp4|V5hZnDkuMaGHe0HNvq@%{0b9&E5*gkxetv_oH`w(LfcF~kt zi4JJWef_|>cK2cze}+QLBF+owhPT*WLVHUmGh`>Rd#$k)-@Ahp0qDB#F>sEyUv0i9 zci`)-s<0i9B0PVipN<$~rtvwPj{vUUc&>v!+!5MC$Ln=(e4ntfcygtev!O=V3^akw zNinxEYMcCn*(Be7xr-N0gDqw%;F*Ey3*=(^LT*<)?&igMka&$<4Cc@AE6-mJ5YEX4u}`;Rd4KJ>W?&gZ|ebz?K?@6d5F zTN(N9XHB=|{P$p&-SB!B1tT<6sqbCI0qWekXJCEg40e*P7N~7?CNQ4M3c!>Yqwe;$ zwhvx@d)w>Jz2n@zqm7KV3Ugg!ovEtYU@)6FKuwLJCxZ1Jke(1J?)V3!mu4B>Z05Zl5fY%scdUd^@KmTNA^jLH{NI?1j!-p>3s^-1z zYBl0aAQ)o=`a3|woC(>D$8iRHOkztF8N?)6 zTjAc1T=e}ny6L~GynO9pE{fqKh_6G`Pk>q24?xSn33OT_TA5kIFNM#mFw&`0t#r~93(agYQA0)c2fiyH)AH6Zr)z=A2?`SC zqOXGtpN*W)gqUCrjMrVnEok#OWS{_GtmwX?aiX_z}4LD;_+>}#Vt*?Q?O$^l~umDXWsm3sep ztZ_UWifJ7&)=a0f{Wy1`nf79ODq9Bw#uWwgKH3rF4k)CEwEFtqkMa4$@BHexYP#$o zdqzEmdwhlgh99$ii257(?8A6lFaW}z9#chE%(C~%B*5B#Y?+6C@t%`2mGs>ES)El% ztXly4_t+`}*O9Zwo7q=0O{~e=Pn6ff!8*hlj=XB53Bg%|{Z=gY0-R$OBYj_e&oKoQ1kaUX`A$fm)`cetv8uio!+Q|*YVR;s6VrB?o=yS^)Av>PRh%_11hMnPo% z#SprRSvjDWl~6FE1pUFF!{Ht)w$VvV9itn= zEGjM-dJ4P=J%!$+UeL~S&ZXX;C;UwkKu_0VEnW5YBno>vFfR1Hjf>od76&GZI>qz+ z24nqdA;D`5XAX?WVyX=#b}&Q9nb>E;Lyg04Dl@z$FvA4jLy-X#VTT9U0RqDmm8Um! zg=s@)gqmFu4t8PGW}Byp&joF{kr^1rG9&!ZF=iT5rFzFhJjE~1dk^o z?D%XP$|G$Cno=jxGfS)~T8#a>)Q(jccmPooYYa4p z0T(#CU?gLXB2nZWMrlQBh!(N6ypHV`i;i>WiRJ0SSUsHWA<&cK#uFGi>)Gcm-VtC1 zXPD2YZ4gBc;>H*DCFsO(=uN9L@_h-Q*kCn~)g<(^J41v71sg#r$8&FF`U!xFS2fQP z>{$26m2Px@ms~fa+on7*L$obcA^%928Tn`;dR0qB<_Y=)w9qFt&aGvf#u; zsu0!>m?WT|T4P{oAh#yK66OYL9|m~6O{6jGp2x9y8B+x&gvh~TrAg#E9s3sZi6VMf zm+fp%AaaP*Aat&1iFH5#KsLq-4VFR{P9UN(QNX~6vk0)K;Uwi9Oa#@jBb0y+3dZ&d z#t-XtG@Fm{Y%a#KeS>qP0rO!Nc?437F{!|8!@lY8sdIpH9mUKrH#o~MXQtS>UTT^{ zy?^RybBIVXoXgM+&=q4UB_4FBW9K&J4UupmrdROXaQ=3%{oLk>avNqlTZgEjgRy|a zPKvF=fy%Um-6OGc@8D5JI*RG{z3PorZ58=5KwoTO^YqEiAk*(5o>o^3z==-?#r8gI zBRJ{~7-@Gv^hM!>EJ1mic`3_~5Ex)#S>az1wG=3Y{>;-r)Yoy4!3fjhT!_XZ z7l=rR@ehi9255ekB6_it#vyi?XB-Do+b2TFgKmvO3iqqWy+&d{K~5Nxc&ZI(>1L_C zPD@e3F#{%X-s0;7de>|y3`+)vC)NwVs+iy~jjtIar)rj-p`DLW4&4;xIh(x7a&I9LaBzBHRvz(9kbH(Rlkd-UxnWOk~$Is_vA|;?d)_7Mf{yz)LV5vo%Gz#VKW-1cl#{lL*G^Q+ZAGjMp~o18as*6UQnG# zT~BD8);CCxMb?Gn-19x6=!yB|nR3nh8?rJsACeM3tomLP`b|EJ0X3&eDA;G@H4Zqq zrQ(f4>Ks&>1S)T`!6h(Cj03Qi#aL8tD6f}zE5qKJ7lq%G$)7iL*N+}^lYDOUch7@w zo$`o{IC$bS4e0`RHqojAFJnZRtNZ?$9dX5=-v>;WRXrpuRE;gYz)geNlXo zBWx#Hh%S6wp%ME~3P4v<{@quv^+?K<`g;6(@99U5JmkPh)l+@$2oF%3?ILvr!`;EK z?EQcC&MwA{tBT|2&iB|}uXnwh-K?`|(rro_qNos15Fcp}QGgd7kZ7t(w1^i3FCbMF zeE|jWgm|e+5rPI@pa}7RpnybC=mSM<1(84?Xr(r76S`l?y7Ah(w&(M5?|8-@kL`^h zQrO1-pK{{y%+7c;wk7}Oo_h}U7lhBAOR`SBw!3%QDjup77Jac=wHavzMn*~eD9`i0 z5%EOG2PJ*T$okOj{jJubB5~b{?x|!0mc1{Le9zbo0v~<=00000004lfr}5gtZs&;} zdWO^NVHzRGJR|ADA{Zj?Sz!;)o~oQtEQ;h><{5H_XnD1DRcvcfuTOgtvKg$K3MY={ zkpqQ=@}yDlgD^@DiB3<>-H21%y8^EE|VM@xDjrld;Jv*B~l z`$pRV000000000$)c+gYCeic~(Zj#V%K9i_zmd2HL*(7rJ8jJzKQwu)Sr3Q@oD`Fh zQDn5nzx$^42 zx3B!;QvJ32?k%5CWmQF6crowv7~ne5a<#P<%f3&8BlX#e|Dk0l=HWwygJeIqKYKgptkb3G}KjkIrc-OX95`JG3Pe(!-Zl?S69pF#f~ zjvG>~;cc6`YHV%$ozni&uf-p?y)ay@Mycs5JoX~xHJ5DFC!Z@+b!>XMK0_C--bv3_@1Q_PyQT6}F}G2&o;2VXRoOlL_QB8r z00000007`NgYT|xzRniW;t8UI_YqzCLt2uv%b}{U@TspI`@#KZ7S7h{Uet#+QTSAi zH<~DD`A}?>eL*9)=AEo_u}@?DZD%9i%g=~}H%NZmc000000001P zZ#I?Pbw060&%WzMf7pKXb4y=7`$-|`+g>E$K}*>7wh(f+qu6q~x6C3Bg)sBf^lv#$ zTr(JLY`N9z4exqN)U)%{{mi4YIA`rKEO8LElZ%i{H&>QTrMJ1sTFEe4-Ik^ zjXtsOb^7&3o~BRl`zLMr*5EvImJ#rQ6!&*lPgVc`000000093p&uP2zw2FKA4mR3; z&*9>|U;onG=cI^R!j#<>C(j8;n_#4vJ?HN}X1cTMLey8^Zm)WND2vb;@z!*u_>czs zs=Et&tXWl$<$M@oFD^qIA@q3kD20C0G^l7h^urUsAp5VJo__27G+_ioTB)(#|2w%j zJRJZ4000000B%R#6!GNl6!pg1PAaN69(SJj$?H!}=JblqRlAVW@~2PEoK`K;d?CnT zl>W~9k{6&&(Rg@YOSe%4<@|EVD9F)xS+A2Be$x z3ds$__}8VzrNWzxiGm zTwZTApMB}tpJ;G?`c9%Au2$R2wJp!n4W?^Cyp@bgrQJe$mRcnG)*lb8{rR%BVe6d9 zzU#IT^3BFFDVsVERmPd3@wm6TcvN^?6`psC%Mpv0V^Nnw_Oj?+ezvoGizK}u&V65z z4fSwEe12-R8m+Fq5iQ@Op%TlL;V2DIQ=Cwp&4az3Nn}HCJ8$jr#ks?bg?QSxUY*lwV(a&`HkO;(=a>7XMy+^kmAR4;^p(` zW9TL`oI^7PM;%k8n@&v;U3Y+C6#{unH)JjAJFHCi3vJ?{wezE zBVQq=TQ@K2`KfUib@9n?iMMJrPV*di7!p$y`pd ## Sponsors -

- - - Writing essays service Edubirdie - -

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Support Laradock with your [organization](https://opencollective.com/laradock/contribute/).
- - - - - - - - - - - -For basic sponsorships go to [Open Collective](https://opencollective.com/laradock#sponsor), for golden sponsorships contact support@laradock.io. +Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page.
-*Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page.* +For more info contact support@laradock.io. + +--- ## Quick Overview @@ -233,7 +271,7 @@ You can choose, which tools to install in your workspace container and other con *If you can't find your Software in the list, build it yourself and submit it. Contributions are welcomed :)* - +--- ## What is Docker? @@ -286,24 +324,146 @@ You are welcome to join our chat room on Gitter. [![Gitter](https://badges.gitter.im/Laradock/laradock.svg)](https://gitter.im/Laradock/laradock?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +## Awesome People +Laradock exists thanks to all the people who contribute. +### Project Maintainers + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Mahmoud Zalt +
+ @mahmoudz +
+ +
+ Bo-Yi Wu +
+ @appleboy +
+ +
+ Philippe Trépanier +
+ @philtrep +
+ +
+ Mike Erickson +
+ @mikeerickson +
+ +
+ Dwi Fahni Denni +
+ @zeroc0d3 +
+ +
+ Thor Erik +
+ @thorerik +
+ +
+ Winfried van Loon +
+ @winfried-van-loon +
+ +
+ TJ Miller +
+ @sixlive +
+ +
+ Yu-Lung Shao (Allen) +
+ @bestlong +
+ +
+ Milan Urukalo +
+ @urukalo +
+ +
+ Vince Chu +
+ @vwchu +
+ +
+ Huadong Zuo +
+ @zuohuadong +
+ +
+ Lan Phan +
+ @lanphan +
+ +
+ Ahkui +
+ @ahkui +
+ +
+ < Join Us > +
+ @laradock +
+### Code Contributors + + + +--- -## Donations +## Financial Contributors -> Help keeping the project development going, by [contributing](http://laradock.io/contributing) or donating a little. -> Thanks in advance. +Contribute and help us sustain the project. -Donate directly via [Paypal](https://paypal.me/mzmmzz) +Option 1: Donate directly to [Paypal](https://paypal.me/mzmmzz). -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) -or show your support via [Beerpay](https://beerpay.io/laradock/laradock) +Option 2: Support us via [BeerPay](https://beerpay.io/laradock/laradock). [![Beerpay](https://beerpay.io/laradock/laradock/badge.svg?style=flat)](https://beerpay.io/laradock/laradock) -or become a backer on [Open Collective](https://opencollective.com/laradock#backer) +Option 3: Become a backer on [Open Collective](https://opencollective.com/laradock/contribute). - + diff --git a/.github/README-zh.md b/README-zh.md similarity index 100% rename from .github/README-zh.md rename to README-zh.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d01fad5 --- /dev/null +++ b/README.md @@ -0,0 +1,249 @@ +

+ Laradock Logo +

+ +--- + +

PHP development environment that runs on Docker

+ + +

+ contributions welcome + GitHub forks + GitHub issues + GitHub stars + Build status + GitHub license +

+ +

+ forthebadge +

+ + + +

Use Docker First - Then Learn About It Later

+ +

+ + Laradock Documentation + +

+ +--- + +## Awesome People +Laradock exists thanks to all the people who contribute. + +### Project Maintainers + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Mahmoud Zalt +
+ @mahmoudz +
+ +
+ Bo-Yi Wu +
+ @appleboy +
+ +
+ Philippe Trépanier +
+ @philtrep +
+ +
+ Mike Erickson +
+ @mikeerickson +
+ +
+ Dwi Fahni Denni +
+ @zeroc0d3 +
+ +
+ Thor Erik +
+ @thorerik +
+ +
+ Winfried van Loon +
+ @winfried-van-loon +
+ +
+ TJ Miller +
+ @sixlive +
+ +
+ Yu-Lung Shao (Allen) +
+ @bestlong +
+ +
+ Milan Urukalo +
+ @urukalo +
+ +
+ Vince Chu +
+ @vwchu +
+ +
+ Huadong Zuo +
+ @zuohuadong +
+ +
+ Lan Phan +
+ @lanphan +
+ +
+ Ahkui +
+ @ahkui +
+ +
+ < Join Us > +
+ @laradock +
+ +### Code Contributors + + + +### Financial Contributors + +Contribute and help us sustain the project. + +Option 1: Donate directly to [Paypal](https://paypal.me/mzmmzz). + +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mzmmzz) + +Option 2: Support us via [BeerPay](https://beerpay.io/laradock/laradock). + +[![Beerpay](https://beerpay.io/laradock/laradock/badge.svg?style=flat)](https://beerpay.io/laradock/laradock) + +Option 3: Become a backer on [Open Collective](https://opencollective.com/laradock/contribute). + + + + + + + + + +## Sponsors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Support Laradock with your [organization](https://opencollective.com/laradock/contribute/). +
+Your logo will show up on the [github repository](https://github.com/laradock/laradock/) index page and the [documentation](http://laradock.io/) main page. +
+For more info contact support@laradock.io. + +## License + +[MIT License](https://github.com/laradock/laradock/blob/master/LICENSE) From 308f813e452ba143084470da32940784f6411e00 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 13 Sep 2019 18:17:09 +0200 Subject: [PATCH 213/589] Enhance the design and readability of the docs --- DOCUMENTATION/content/introduction/index.md | 98 +++++-------------- DOCUMENTATION/static/custom-style.css | 17 ++++ .../hugo-material-docs/layouts/index.html | 48 +++++---- README.md | 14 +-- 4 files changed, 73 insertions(+), 104 deletions(-) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 25555ff..8493fed 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -4,19 +4,34 @@ type: index weight: 1 --- -![](https://raw.githubusercontent.com/laradock/laradock/master/.github/home-page-images/laradock-logo.jpg) +Laradock is a full PHP development environment based on Docker. -## Use Docker First - Then Learn About It Later - -Laradock is a PHP development environment that runs on Docker. - -Supports a variety of useful Docker Images, pre-configured to provide a wonderful PHP development environment. +Supporting a variety of common services, all pre-configured to provide a full PHP development environment. + +## Features +- Easy switch between PHP versions: 7.3, 7.2, 7.1, 5.6... +- Choose your favorite database engine: MySQL, Postgres, MariaDB... +- Run your own stack: Memcached, HHVM, RabbitMQ... +- Each software runs on its own container: PHP-FPM, NGINX, PHP-CLI... +- Easy to customize any container, with simple edit to the `Dockerfile`. +- All Images extends from an official base Image. (Trusted base Images). +- Pre-configured NGINX to host any code at your root directory. +- Can use Laradock per project, or single Laradock for all projects. +- Easy to install/remove software's in Containers using environment variables. +- Clean and well structured Dockerfiles (`Dockerfile`). +- Latest version of the Docker Compose file (`docker-compose`). +- Everything is visible and editable. +- Fast Images Builds. +
--- +### Use Docker First - Then Learn About It Later +--- + ## Sponsors @@ -79,7 +94,8 @@ Your logo will show up on the [github repository](https://github.com/laradock/la
For more info contact support@laradock.io. ---- +
+ ## Quick Overview @@ -120,25 +136,6 @@ That's it! enjoy :) - -## Features - -- Easy switch between PHP versions: 7.3, 7.2, 7.1, 5.6... -- Choose your favorite database engine: MySQL, Postgres, MariaDB... -- Run your own stack: Memcached, HHVM, RabbitMQ... -- Each software runs on its own container: PHP-FPM, NGINX, PHP-CLI... -- Easy to customize any container, with simple edit to the `Dockerfile`. -- All Images extends from an official base Image. (Trusted base Images). -- Pre-configured NGINX to host any code at your root directory. -- Can use Laradock per project, or single Laradock for all projects. -- Easy to install/remove software's in Containers using environment variables. -- Clean and well structured Dockerfiles (`Dockerfile`). -- Latest version of the Docker Compose file (`docker-compose`). -- Everything is visible and editable. -- Fast Images Builds. - - - ## Supported Software (Docker Images) @@ -273,48 +270,6 @@ You can choose, which tools to install in your workspace container and other con --- - -## What is Docker? - -[Docker](https://www.docker.com) is an open platform for developing, shipping, and running applications. -Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. -With Docker, you can manage your infrastructure in the same ways you manage your applications. -By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production. - - - - - - -## Why Docker not Vagrant!? - -[Vagrant](https://www.vagrantup.com) creates Virtual Machines in minutes while Docker creates Virtual Containers in seconds. - -Instead of providing a full Virtual Machines, like you get with Vagrant, Docker provides you **lightweight** Virtual Containers, that share the same kernel and allow to safely execute independent processes. - -In addition to the speed, Docker gives tons of features that cannot be achieved with Vagrant. - -Most importantly Docker can run on Development and on Production (same environment everywhere). While Vagrant is designed for Development only, (so you have to re-provision your server on Production every time). - - - - - - - -## Demo Video - -What's better than a **Demo Video**: - -- Laradock [v4.*](https://www.youtube.com/watch?v=TQii1jDa96Y) -- Laradock [v2.*](https://www.youtube.com/watch?v=-DamFMczwDA) -- Laradock [v0.3](https://www.youtube.com/watch?v=jGkyO6Is_aI) -- Laradock [v0.1](https://www.youtube.com/watch?v=3YQsHe6oF80) - - - - - @@ -324,10 +279,11 @@ You are welcome to join our chat room on Gitter. [![Gitter](https://badges.gitter.im/Laradock/laradock.svg)](https://gitter.im/Laradock/laradock?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -## Awesome People +--- + Laradock exists thanks to all the people who contribute. -### Project Maintainers +## Project Maintainers @@ -445,7 +401,7 @@ Laradock exists thanks to all the people who contribute.
-### Code Contributors +## Code Contributors diff --git a/DOCUMENTATION/static/custom-style.css b/DOCUMENTATION/static/custom-style.css index 0f3957f..d25a5ac 100644 --- a/DOCUMENTATION/static/custom-style.css +++ b/DOCUMENTATION/static/custom-style.css @@ -11,3 +11,20 @@ height: 70px; padding: 25px; } +.palette-primary-deep-purple .article h1{ + color: #7e57c2; + font-size: 35px; +} +.palette-primary-deep-purple .article h2{ + + color: #ce2046; + font-size: 25px; +} +.palette-primary-deep-purple .article h3{ + color: #851d54; + font-size: 18px; +} +.palette-primary-deep-purple .article code{ + color: #851d54; + background: #eeeeeea8; +} diff --git a/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html b/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html index 5ee52d1..502cd68 100644 --- a/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html +++ b/DOCUMENTATION/themes/hugo-material-docs/layouts/index.html @@ -1,8 +1,8 @@ {{ partial "head" . }} {{ if (eq (trim .Site.Params.provider " " | lower) "github") | and (isset .Site.Params "repo_url") }} - {{ $repo_id := replace .Site.Params.repo_url "https://github.com/" ""}} - {{ .Scratch.Set "repo_id" $repo_id }} + {{ $repo_id := replace .Site.Params.repo_url "https://github.com/" ""}} + {{ .Scratch.Set "repo_id" $repo_id }} {{ end }}
@@ -25,26 +25,32 @@
- -
- - - - - - - -
+ +
+ + + + + + + +
+ +


+ laradock logo {{ range where .Site.Pages "Type" "index" }} -

{{ .Title }} {{ if .IsDraft }} (Draft){{ end }}

+





+
+
+

{{ .Title }} {{ if .IsDraft }} (Draft){{ end }}

- {{ .Content }} + {{ .Content }} {{ end }}