From 9e81f92d583fb6812d1bae998250fe5ba1081579 Mon Sep 17 00:00:00 2001 From: avenli Date: Wed, 24 May 2017 14:47:12 +0800 Subject: [PATCH 001/126] fix mongodb php extension config --- workspace/Dockerfile-56 | 3 ++- workspace/Dockerfile-70 | 3 ++- workspace/Dockerfile-71 | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index 42d0256..9b2239e 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -186,7 +186,8 @@ ENV INSTALL_MONGO ${INSTALL_MONGO} RUN if [ ${INSTALL_MONGO} = true ]; then \ # Install the mongodb extension pecl install mongodb && \ - echo "extension=mongodb.so" >> /etc/php/5.6/cli/conf.d/30-mongodb.ini \ + echo "extension=mongodb.so" >> /etc/php/5.6/mods-available/mongodb.ini && \ + ln -s /etc/php/5.6/mods-available/mongodb.ini /etc/php/5.6/cli/conf.d/30-mongodb.ini \ ;fi ##################################### diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index 9c7d562..e19c041 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -186,7 +186,8 @@ ENV INSTALL_MONGO ${INSTALL_MONGO} RUN if [ ${INSTALL_MONGO} = true ]; then \ # Install the mongodb extension pecl install mongodb && \ - echo "extension=mongodb.so" >> /etc/php/7.0/cli/conf.d/30-mongodb.ini \ + echo "extension=mongodb.so" >> /etc/php/7.0/mods-available/mongodb.ini && \ + ln -s /etc/php/7.0/mods-available/mongodb.ini /etc/php/7.0/cli/conf.d/30-mongodb.ini \ ;fi ##################################### diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 71d865b..d26c635 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -182,7 +182,8 @@ ENV INSTALL_MONGO ${INSTALL_MONGO} RUN if [ ${INSTALL_MONGO} = true ]; then \ # Install the mongodb extension pecl install mongodb && \ - echo "extension=mongodb.so" >> /etc/php/7.1/cli/conf.d/30-mongodb.ini \ + echo "extension=mongodb.so" >> /etc/php/7.1/mods-available/mongodb.ini && \ + ln -s /etc/php/7.1/mods-available/mongodb.ini /etc/php/7.1/cli/conf.d/30-mongodb.ini \ ;fi ##################################### From fc8ffe573163b6f74894e51449bc474bef471506 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Fri, 19 May 2017 19:47:57 +0800 Subject: [PATCH 002/126] using set -x could produce more debug info. --- travis-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-build.sh b/travis-build.sh index fa7e577..9d47e09 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash #### halt script on error -set -e +set -xe echo '##### Print docker version' docker --version From d4caddcaeda92aa4639d2cc26254d4a9bfab2b36 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 25 May 2017 09:56:14 +0800 Subject: [PATCH 003/126] move default config DATA_SAVE_PATH from /tmp to ~/.laradocc/data avoid lost data and windows no have /tmp folder. --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index 7397b6d..0573155 100644 --- a/env-example +++ b/env-example @@ -10,7 +10,7 @@ APPLICATION=../ ### Data Path: # For all storage systems. -DATA_SAVE_PATH=/tmp +DATA_SAVE_PATH=~/laradock/data ### PHP version # Applies to the Workspace and PHP-FPM containers (Does not apply to HHVM) From c913c429c094f9b1b5dd81205cf931216c3869d7 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 25 May 2017 10:04:41 +0800 Subject: [PATCH 004/126] change DATA_SAVE_PATH --- env-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-example b/env-example index 0573155..a1fa108 100644 --- a/env-example +++ b/env-example @@ -10,7 +10,7 @@ APPLICATION=../ ### Data Path: # For all storage systems. -DATA_SAVE_PATH=~/laradock/data +DATA_SAVE_PATH=~/.laradock/data ### PHP version # Applies to the Workspace and PHP-FPM containers (Does not apply to HHVM) From f3a016aa796f69d70595a8fe5375a30fe5af5ec8 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 25 May 2017 16:44:51 +0800 Subject: [PATCH 005/126] adminer support mssql --- adminer/Dockerfile | 17 +++++++++++++++++ docker-compose.yml | 5 ++++- env-example | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/adminer/Dockerfile b/adminer/Dockerfile index 6117454..818c8e1 100644 --- a/adminer/Dockerfile +++ b/adminer/Dockerfile @@ -8,5 +8,22 @@ MAINTAINER Patrick Artounian # Add volume for sessions to allow session persistence VOLUME /sessions +##################################### +# SQL SERVER: +##################################### +USER root +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 \ +;fi + +USER adminer + # We expose Adminer on port 8080 (Adminer's default) EXPOSE 8080 diff --git a/docker-compose.yml b/docker-compose.yml index c79ba6a..f05663c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -440,7 +440,10 @@ services: ### Adminer Container #################################### adminer: - build: ./adminer + build: + context: ./adminer + args: + - INSTALL_MSSQL=${ADM_INSTALL_MSSQL} ports: - "${ADM_PORT}:8080" depends_on: diff --git a/env-example b/env-example index a1fa108..7ec7e92 100644 --- a/env-example +++ b/env-example @@ -161,6 +161,7 @@ MINIO_PORT=9000 ### ADMINER ############################################################################################################ ADM_PORT=8080 +ADM_INSTALL_MSSQL=false ### PHP MY ADMIN ####################################################################################################### From f04acee6dfc3a8e2dba93f8a76cddcd73c5336ed Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 25 May 2017 20:04:21 +0800 Subject: [PATCH 006/126] fix jenkins permission denied --- jenkins/install-plugins.sh | 0 jenkins/jenkins-support | 0 jenkins/jenkins.sh | 0 jenkins/plugins.sh | 0 jenkins/publish.sh | 0 jenkins/update-official-library.sh | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 jenkins/install-plugins.sh mode change 100644 => 100755 jenkins/jenkins-support mode change 100644 => 100755 jenkins/jenkins.sh mode change 100644 => 100755 jenkins/plugins.sh mode change 100644 => 100755 jenkins/publish.sh mode change 100644 => 100755 jenkins/update-official-library.sh diff --git a/jenkins/install-plugins.sh b/jenkins/install-plugins.sh old mode 100644 new mode 100755 diff --git a/jenkins/jenkins-support b/jenkins/jenkins-support old mode 100644 new mode 100755 diff --git a/jenkins/jenkins.sh b/jenkins/jenkins.sh old mode 100644 new mode 100755 diff --git a/jenkins/plugins.sh b/jenkins/plugins.sh old mode 100644 new mode 100755 diff --git a/jenkins/publish.sh b/jenkins/publish.sh old mode 100644 new mode 100755 diff --git a/jenkins/update-official-library.sh b/jenkins/update-official-library.sh old mode 100644 new mode 100755 From 5a4708085918076837cd0a10200858ce04f64d08 Mon Sep 17 00:00:00 2001 From: Lawrence Eldridge Date: Sat, 27 May 2017 14:07:45 +0100 Subject: [PATCH 007/126] This issue relates to https://github.com/laradock/laradock/issues/563, which also occurs on Mac. This has been one of the solutions proposed. --- workspace/Dockerfile-56 | 8 ++++++-- workspace/Dockerfile-70 | 8 ++++++-- workspace/Dockerfile-71 | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index 42d0256..e50c830 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -117,13 +117,17 @@ COPY ./aliases.sh /home/laradock/aliases.sh RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh USER root RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh ##################################### # xDebug: diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index 9c7d562..7f551d2 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -117,13 +117,17 @@ COPY ./aliases.sh /home/laradock/aliases.sh RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh USER root RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh ##################################### # xDebug: diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 71d865b..786d43c 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -113,13 +113,17 @@ COPY ./aliases.sh /home/laradock/aliases.sh RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh USER root RUN echo "" >> ~/.bashrc && \ echo "# Load Custom Aliases" >> ~/.bashrc && \ echo "source /home/laradock/aliases.sh" >> ~/.bashrc && \ - echo "" >> ~/.bashrc + echo "" >> ~/.bashrc && \ + sed -i 's/\r//' /home/laradock/aliases.sh && \ + sed -i 's/^#! \/bin\/sh/#! \/bin\/bash/' /home/laradock/aliases.sh ##################################### # xDebug: From da60b32a045e72bc9fdd45616ade987806de9c97 Mon Sep 17 00:00:00 2001 From: Mirko Date: Sat, 27 May 2017 15:24:50 +0200 Subject: [PATCH 008/126] add laravel echo server --- docker-compose.yml | 14 ++++++++++++++ env-example | 4 ++++ laravel-echo-server/Dockerfile | 15 +++++++++++++++ laravel-echo-server/laravel-echo-server.json | 19 +++++++++++++++++++ laravel-echo-server/package.json | 12 ++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 laravel-echo-server/Dockerfile create mode 100644 laravel-echo-server/laravel-echo-server.json create mode 100644 laravel-echo-server/package.json diff --git a/docker-compose.yml b/docker-compose.yml index f05663c..698f289 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -566,6 +566,7 @@ services: - proxy2 ### Jenkins ################################################### + jenkins: build: ./jenkins environment: @@ -581,6 +582,19 @@ services: - frontend - backend +### Laravel Echo Server ####################################### + laravel-echo-server: + build: + context: ./laravel-echo-server + volumes: + - ./laravel-echo-server/laravel-echo-server.json:/app/laravel-echo-server.json:ro + ports: + - "${LARAVEL_ECHO_SERVER_PORT}:6001" + links: + - redis + networks: + - frontend + - backend ### Networks Setup ############################################ diff --git a/env-example b/env-example index 7ec7e92..8ff3134 100644 --- a/env-example +++ b/env-example @@ -240,6 +240,10 @@ CADDY_HOST_HTTPS_PORT=443 CADDY_HOST_LOG_PATH=./logs/caddy CADDY_CUSTOM_CADDYFILE=./caddy/Caddyfile +### LARAVEL ECHO SERVER ################################################################################################ + +LARAVEL_ECHO_SERVER_PORT=6001 + ##### TO BE CONTINUE ................................. diff --git a/laravel-echo-server/Dockerfile b/laravel-echo-server/Dockerfile new file mode 100644 index 0000000..5074a1f --- /dev/null +++ b/laravel-echo-server/Dockerfile @@ -0,0 +1,15 @@ +FROM node:argon + +# Create app directory +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +# Install app dependencies +COPY package.json /usr/src/app/ +RUN npm install + +# Bundle app source +COPY laravel-echo-server.json /usr/src/app/laravel-echo-server.json + +EXPOSE 3000 +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/laravel-echo-server/laravel-echo-server.json b/laravel-echo-server/laravel-echo-server.json new file mode 100644 index 0000000..0a98ef9 --- /dev/null +++ b/laravel-echo-server/laravel-echo-server.json @@ -0,0 +1,19 @@ +{ + "authHost": "localhost", + "authEndpoint": "/broadcasting/auth", + "clients": [], + "database": "redis", + "databaseConfig": { + "redis": { + "port": "6379", + "host": "redis" + } + }, + "devMode": true, + "host": null, + "port": "6001", + "protocol": "http", + "socketio": {}, + "sslCertPath": "", + "sslKeyPath": "" +} \ No newline at end of file diff --git a/laravel-echo-server/package.json b/laravel-echo-server/package.json new file mode 100644 index 0000000..2784a03 --- /dev/null +++ b/laravel-echo-server/package.json @@ -0,0 +1,12 @@ +{ + "name": "laravel-echo-server-docker", + "description": "Docker container for running laravel-echo-server", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "laravel-echo-server": "^1.2.8" + }, + "scripts": { + "start": "laravel-echo-server start" + } +} \ No newline at end of file From e23ecb6a116eeec4b35cf6a82b6e54a8edbf7328 Mon Sep 17 00:00:00 2001 From: Diego Vieira Date: Tue, 30 May 2017 15:05:09 +0100 Subject: [PATCH 009/126] fix mssql startup (#985) - Sleep 45s is invalid - /opt/mssql/bin/sqlservr is the correct path for mssql binary --- mssql/create_table.sh | 2 +- mssql/entrypoint.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mssql/create_table.sh b/mssql/create_table.sh index f0c1a7c..9fe5214 100644 --- a/mssql/create_table.sh +++ b/mssql/create_table.sh @@ -1,5 +1,5 @@ #wait for the SQL Server to come up -sleep 45s +sleep 45 #run the setup script to create the DB and the schema in the DB /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i setup.sql \ No newline at end of file diff --git a/mssql/entrypoint.sh b/mssql/entrypoint.sh index e383513..062293b 100644 --- a/mssql/entrypoint.sh +++ b/mssql/entrypoint.sh @@ -1,2 +1,2 @@ #start SQL Server, start the script to create the DB and import the data, start the app -/opt/mssql/bin/sqlservr.sh & /usr/src/app/create_table.sh & tail -f /dev/null \ No newline at end of file +/opt/mssql/bin/sqlservr & /usr/src/app/create_table.sh & tail -f /dev/null From d0c0a8895efcc36d89f03e8869ad971bd2704d4a Mon Sep 17 00:00:00 2001 From: Lawrence Eldridge Date: Tue, 30 May 2017 15:05:30 +0100 Subject: [PATCH 010/126] add global instance of larval installer for fresh projects. (#988) --- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile-56 | 17 +++++++++++++++++ workspace/Dockerfile-70 | 17 +++++++++++++++++ workspace/Dockerfile-71 | 17 +++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index f05663c..93c6663 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,6 +28,7 @@ services: - COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL} - INSTALL_WORKSPACE_SSH=${WORKSPACE_INSTALL_WORKSPACE_SSH} - INSTALL_LARAVEL_ENVOY=${WORKSPACE_INSTALL_LARAVEL_ENVOY} + - INSTALL_LARAVEL_INSTALLER=${WORKSPACE_INSTALL_LARAVEL_INSTALLER} - INSTALL_DEPLOYER=${WORKSPACE_INSTALL_DEPLOYER} - INSTALL_LINUXBREW=${WORKSPACE_INSTALL_LINUXBREW} - INSTALL_MC=${WORKSPACE_INSTALL_MC} diff --git a/env-example b/env-example index 7ec7e92..fc4832d 100644 --- a/env-example +++ b/env-example @@ -41,6 +41,7 @@ WORKSPACE_INSTALL_V8JS=false WORKSPACE_COMPOSER_GLOBAL_INSTALL=false WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_LARAVEL_ENVOY=false +WORKSPACE_INSTALL_LARAVEL_INSTALLER=false WORKSPACE_INSTALL_DEPLOYER=false WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index 42d0256..2ae0a6c 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -333,6 +333,23 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ composer global require "laravel/envoy=~1.0" \ ;fi +##################################### +# Laravel Installer: +##################################### +USER root + +ARG INSTALL_LARAVEL_INSTALLER=true +ENV INSTALL_LARAVEL_INSTALLER ${INSTALL_LARAVEL_INSTALLER} + +RUN if [ ${INSTALL_LARAVEL_INSTALLER} = true ]; then \ + # Install the Laravel Installer + echo "" >> ~/.bashrc && \ + echo 'export PATH="~/.composer/vendor/bin:$PATH"' >> ~/.bashrc \ + && composer global require "laravel/installer" \ +;fi + +USER laradock + ##################################### # Deployer: ##################################### diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index 9c7d562..00747d8 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -350,6 +350,23 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ composer global require "laravel/envoy=~1.0" \ ;fi +##################################### +# Laravel Installer: +##################################### +USER root + +ARG INSTALL_LARAVEL_INSTALLER=true +ENV INSTALL_LARAVEL_INSTALLER ${INSTALL_LARAVEL_INSTALLER} + +RUN if [ ${INSTALL_LARAVEL_INSTALLER} = true ]; then \ + # Install the Laravel Installer + echo "" >> ~/.bashrc && \ + echo 'export PATH="~/.composer/vendor/bin:$PATH"' >> ~/.bashrc \ + && composer global require "laravel/installer" \ +;fi + +USER laradock + ##################################### # Deployer: ##################################### diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 71d865b..151df36 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -350,6 +350,23 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ composer global require "laravel/envoy=~1.0" \ ;fi +##################################### +# Laravel Installer: +##################################### +USER root + +ARG INSTALL_LARAVEL_INSTALLER=true +ENV INSTALL_LARAVEL_INSTALLER ${INSTALL_LARAVEL_INSTALLER} + +RUN if [ ${INSTALL_LARAVEL_INSTALLER} = true ]; then \ + # Install the Laravel Installer + echo "" >> ~/.bashrc && \ + echo 'export PATH="~/.composer/vendor/bin:$PATH"' >> ~/.bashrc \ + && composer global require "laravel/installer" \ +;fi + +USER laradock + ##################################### # Deployer: ##################################### From d0e5d507121209c343e1a50276bfe9435132788d Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 30 May 2017 17:41:11 +0300 Subject: [PATCH 011/126] Update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 269465c..daa9e6f 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ A Docker PHP development environment that facilitates running **PHP** Apps on ** - [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 - Join Us. ## License From 0290142bf442badfcdf67ea3207d7df234077965 Mon Sep 17 00:00:00 2001 From: mycontroller Date: Tue, 23 May 2017 18:58:58 +0800 Subject: [PATCH 012/126] Dockerfile-56 fill missing MSSQL section --- php-fpm/Dockerfile-56 | 12 ++++++++++++ workspace/Dockerfile-56 | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/php-fpm/Dockerfile-56 b/php-fpm/Dockerfile-56 index 1ce3276..cad89a5 100644 --- a/php-fpm/Dockerfile-56 +++ b/php-fpm/Dockerfile-56 @@ -246,6 +246,18 @@ RUN if [ ${INSTALL_LDAP} = true ]; then \ docker-php-ext-install ldap \ ;fi +##################################### +# SQL SERVER: +##################################### +ARG INSTALL_MSSQL=false +ENV INSTALL_MSSQL ${INSTALL_MSSQL} + +RUN if [ ${INSTALL_MSSQL} = true ]; then \ + apt-get -y install php5-sybase freetds-bin && \ + cp /usr/lib/php5/20131226/*.so /usr/local/lib/php/extensions/no-debug-non-zts-20131226/ && \ + docker-php-ext-enable mssql pdo pdo_dblib \ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index 0e7962c..f945358 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -400,6 +400,17 @@ RUN if [ ${INSTALL_LINUXBREW} = true ]; then \ echo 'export LD_LIBRARY_PATH="$LINUXBREWHOME/lib64:$LINUXBREWHOME/lib:$LD_LIBRARY_PATH"' >> ~/.bashrc \ ;fi +##################################### +# SQL SERVER: +##################################### +ARG INSTALL_MSSQL=false +ENV INSTALL_MSSQL ${INSTALL_MSSQL} + +RUN if [ ${INSTALL_MSSQL} = true ]; then \ + apt-get -y install php5.6-sybase freetds-bin freetds-common libsybdb5 \ + && echo "extension=pdo_dblib.so" > /etc/php/5.6/cli/conf.d/20-pdo_dblib.ini \ +;fi + ##################################### # Minio: ##################################### From 430a5f21cfbb1660ba986cec3e5d2469feb11790 Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Fri, 2 Jun 2017 13:53:13 +0800 Subject: [PATCH 013/126] git key to pull code git key to pull code --- caddy/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index b10a9f5..f183fbc 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -8,7 +8,7 @@ LABEL caddy_version="$caddy_version" architecture="amd64" RUN apk update \ && apk upgrade \ - && apk add tar curl git + && apk add tar curl git openssh RUN curl --silent --show-error --fail --location \ --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \ From 0561199914e0653e27ae3e3ecda4c36781d9c4a2 Mon Sep 17 00:00:00 2001 From: Mark Davidson Date: Sat, 3 Jun 2017 05:54:37 +0100 Subject: [PATCH 014/126] Add Kibana Container (#993) * Add Kibana Container * Add Kibana Port to env-example --- docker-compose.yml | 13 +++++++++++++ env-example | 4 ++++ kibana/Dockerfile | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 kibana/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 38603d6..7e3a70f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -481,6 +481,19 @@ services: - frontend - backend + +### Kibana Container ####################################### + + kibana: + build: ./kibana + ports: + - "${KIBANA_HTTP_PORT}:5601" + depends_on: + - elasticsearch + networks: + - frontend + - backend + ### Certbot Container ################################## certbot: diff --git a/env-example b/env-example index 13e495e..f8ca650 100644 --- a/env-example +++ b/env-example @@ -137,6 +137,10 @@ RABBITMQ_DEFAULT_PASS=guest ELASTICSEARCH_HOST_HTTP_PORT=9200 ELASTICSEARCH_HOST_TRANSPORT_PORT=9300 +### KIBANA ############################################################################################################# + +KIBANA_HTTP_PORT=5601 + ### MEMCACHED ########################################################################################################## MEMCACHED_HOST_PORT=11211 diff --git a/kibana/Dockerfile b/kibana/Dockerfile new file mode 100644 index 0000000..f90cebe --- /dev/null +++ b/kibana/Dockerfile @@ -0,0 +1,3 @@ +FROM kibana:latest + +EXPOSE 5601 \ No newline at end of file From 7207ccbbeb7d341037f366fd43600c7d1c078088 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sun, 4 Jun 2017 07:29:13 -0500 Subject: [PATCH 015/126] upgrade caddy to 0.10.3 version (#994) --- caddy/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index b10a9f5..1e669ee 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -2,7 +2,7 @@ FROM alpine:3.4 MAINTAINER Eric Pfeiffer -ENV caddy_version=0.10.0 +ENV caddy_version=0.10.3 LABEL caddy_version="$caddy_version" architecture="amd64" From cbfd160cbfba8f88424594ee14e4def09cb80fbb Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Tue, 6 Jun 2017 18:11:31 +0800 Subject: [PATCH 016/126] Fix --- pgadmin/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pgadmin/Dockerfile b/pgadmin/Dockerfile index 2d34c22..7dd9606 100644 --- a/pgadmin/Dockerfile +++ b/pgadmin/Dockerfile @@ -1,4 +1,4 @@ -FROM fenglc/pgadmin4 +FROM chorss/docker-pgadmin4 MAINTAINER Bo-Yi Wu From 1bdf113767f63f5cc7f832368c187490164f2740 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 9 Jun 2017 17:33:10 +0300 Subject: [PATCH 017/126] update tools list in the docs --- DOCUMENTATION/content/introduction/index.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/DOCUMENTATION/content/introduction/index.md b/DOCUMENTATION/content/introduction/index.md index 120a3e5..115a79c 100644 --- a/DOCUMENTATION/content/introduction/index.md +++ b/DOCUMENTATION/content/introduction/index.md @@ -83,17 +83,21 @@ In adhering to the separation of concerns principle as promoted by Docker, Larad You can turn On/Off as many instances of as any container without worrying about the configurations, everything works like a charm. - **Database Engines:** -MySQL - MariaDB - Percona - MongoDB - Neo4j - RethinkDB - MSSQL - PostgreSQL - Postgres Postgis. +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 Queuing:** -Beanstalkd - Beanstalkd Console - RabbitMQ - RabbitMQ Console - PHP Worker -- **Tools:** -HAProxy - Jenkins - ElasticSearch - Selenium - Certbot - Mailhog - Minio - Varnish - PhpMyAdmin - Adminer - PgAdmin - MailHog - [Blackfire](https://blackfire.io)... +- **Message Queueing:** +Beanstalkd - RabbitMQ - PHP Worker +- **Queueing Management:** +Beanstalkd Console - RabbitMQ Console +- **Random Tools:** +HAProxy - Certbot - Blackfire - Selenium - Jenkins - ElasticSearch - Kibana - Mailhog - Minio - Varnish - Swoole - 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. @@ -148,7 +152,7 @@ Most importantly Docker can run on Development and on Production (same environme What's better than a **Demo Video**: -- Laradock v5.* (soon or never) +- 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) From 05f8166bef6c3bdf769a71e3fd83368bd68722c3 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 9 Jun 2017 17:46:26 +0300 Subject: [PATCH 018/126] add PR template --- .github/PULL_REQUEST_TEMPLATE.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..567ed50 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +### Thank you for contributing to Laradock. + +##### Make sure you completed the basic 3 steps below: + +- [] I've read the simple [Contribution Guide](http://laradock.io/contributing). +- [] I've updated the **documentation**. (refer to [this](http://laradock.io/contributing/#update-the-documentation-site) for how to do so). +- [] I enjoyed my time contributing and making developer's life easier :) From 262b9f20a36adf0da547984fa799141f5606f2d2 Mon Sep 17 00:00:00 2001 From: Edmund Luong Date: Fri, 9 Jun 2017 11:00:42 -0400 Subject: [PATCH 019/126] Set default setting to false for the following options in workspace: - Laravel Envoy - Laravel Installer - LinuxBrew - MS SQL Server --- workspace/Dockerfile-71 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index c6bf635..29f5b62 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -347,7 +347,7 @@ RUN echo "" >> ~/.bashrc && \ ##################################### USER laradock -ARG INSTALL_LARAVEL_ENVOY=true +ARG INSTALL_LARAVEL_ENVOY=false ENV INSTALL_LARAVEL_ENVOY ${INSTALL_LARAVEL_ENVOY} RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ @@ -360,7 +360,7 @@ RUN if [ ${INSTALL_LARAVEL_ENVOY} = true ]; then \ ##################################### USER root -ARG INSTALL_LARAVEL_INSTALLER=true +ARG INSTALL_LARAVEL_INSTALLER=false ENV INSTALL_LARAVEL_INSTALLER ${INSTALL_LARAVEL_INSTALLER} RUN if [ ${INSTALL_LARAVEL_INSTALLER} = true ]; then \ @@ -390,7 +390,7 @@ RUN if [ ${INSTALL_DEPLOYER} = true ]; then \ ##################################### USER root -ARG INSTALL_LINUXBREW=true +ARG INSTALL_LINUXBREW=false ENV INSTALL_LINUXBREW ${INSTALL_LINUXBREW} RUN if [ ${INSTALL_LINUXBREW} = true ]; then \ @@ -420,7 +420,7 @@ RUN if [ ${INSTALL_LINUXBREW} = true ]; then \ ##################################### # SQL SERVER: ##################################### -ARG INSTALL_MSSQL=true +ARG INSTALL_MSSQL=false ENV INSTALL_MSSQL ${INSTALL_MSSQL} RUN if [ ${INSTALL_MSSQL} = true ]; then \ From 30df311ec2df59f454764bcb6eca3a4f8fdade75 Mon Sep 17 00:00:00 2001 From: ItaloBC Date: Mon, 12 Jun 2017 13:02:08 -0400 Subject: [PATCH 020/126] Change to official repository Elastic.co announced they will pull out their official images from the Docker Registry and user their own. There will be no updates starting 6/20/2017. Pulling needs explicit version. Currently 5.4.1 --- kibana/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kibana/Dockerfile b/kibana/Dockerfile index f90cebe..572f15a 100644 --- a/kibana/Dockerfile +++ b/kibana/Dockerfile @@ -1,3 +1,3 @@ -FROM kibana:latest +FROM docker.elastic.co/kibana/kibana:5.4.1 -EXPOSE 5601 \ No newline at end of file +EXPOSE 5601 From 03b551f9d6e622763a09e67c46fa93ce7379f814 Mon Sep 17 00:00:00 2001 From: ItaloBC Date: Mon, 12 Jun 2017 13:06:41 -0400 Subject: [PATCH 021/126] Change to official repository Elastic.co announced they will pull out their official images from the Docker Registry and user their own. There will be no updates starting 6/20/2017. Pulling needs explicit version. Currently 5.4.1 --- elasticsearch/Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/elasticsearch/Dockerfile b/elasticsearch/Dockerfile index 363932e..914761e 100644 --- a/elasticsearch/Dockerfile +++ b/elasticsearch/Dockerfile @@ -1,5 +1,3 @@ -FROM elasticsearch:latest - -MAINTAINER Bo-Yi Wu +FROM docker.elastic.co/elasticsearch/elasticsearch:5.4.1 EXPOSE 9200 9300 From bbea2f0bab4fc208ce7240cd16554ffe2e33812a Mon Sep 17 00:00:00 2001 From: Michal Ardziejewski Date: Tue, 13 Jun 2017 00:55:05 +0200 Subject: [PATCH 022/126] Set Timezone --- mysql/Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql/Dockerfile b/mysql/Dockerfile index e494b65..aada38f 100644 --- a/mysql/Dockerfile +++ b/mysql/Dockerfile @@ -2,6 +2,14 @@ FROM mysql:5.7 MAINTAINER Mahmoud Zalt +##################################### +# Set Timezone +##################################### + +ARG TZ=UTC +ENV TZ ${TZ} +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + RUN chown -R mysql:root /var/lib/mysql/ ADD my.cnf /etc/mysql/conf.d/my.cnf From e56587ec472775780f9572bdd10731f92214fb6c Mon Sep 17 00:00:00 2001 From: Michal Ardziejewski Date: Tue, 13 Jun 2017 01:03:42 +0200 Subject: [PATCH 023/126] Added TZ environment for MySQL Container --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 7e3a70f..ec9af2c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -197,6 +197,7 @@ services: - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - TZ=${WORKSPACE_TIMEZONE} volumes: - ${DATA_SAVE_PATH}/mysql:/var/lib/mysql - ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d From bbbd247653778e982c7f1bacbaa84ca6d0a3ab3e Mon Sep 17 00:00:00 2001 From: ItaloBC Date: Wed, 14 Jun 2017 14:19:47 -0400 Subject: [PATCH 024/126] ElasticSearch instance fails at loading (wrong) ElasticSearch (ES from now onwards) will fail to initialize since the parameters for its environment are not correct or absent. These are: * `cluster.name`: Name of the cluster itself * `bootstrap.memory_lock`: Needed for ES to [lock the JVM into swap instead of memory](https://www.elastic.co/guide/en/elasticsearch/reference/master/_memory_lock_check.html). * `"ES_JAVA_OPTS=-Xms256m -Xmx256m"`: [Initial and maximum HEAP size for JVM](https://www.elastic.co/guide/en/elasticsearch/reference/current/_heap_size_check.html). Since it's locked to disk, should be the same. Half the defaults (512m) for development. * `ulimits: memlock: soft (-1), hard (-1)`: [ES needs to have unlimited access to memory](https://www.elastic.co/guide/en/elasticsearch/reference/current/max-size-virtual-memory-check.html), otherwise it will feel sluggish. * `mem_limit: 512m`: Hard limit the memory available for the container. This can, and should, be changed using `.env` file variables, but it seems that this should suffice for basic ES development. --- docker-compose.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index ec9af2c..ff285fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -473,6 +473,15 @@ services: volumes: - elasticsearch-data:/usr/share/elasticsearch/data - elasticsearch-plugins:/usr/share/elasticsearch/plugins + environment: + - cluster.name=laradock-cluster + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms256m -Xmx256m" + ulimits: + memlock: + soft: -1 + hard: -1 + mem_limit: 512m ports: - "${ELASTICSEARCH_HOST_HTTP_PORT}:9200" - "${ELASTICSEARCH_HOST_TRANSPORT_PORT}:9300" From 4c732aa5d6018e8010a83ee0694113f2ebeefdaa Mon Sep 17 00:00:00 2001 From: LinBo len Date: Mon, 26 Jun 2017 11:11:10 +0800 Subject: [PATCH 025/126] nginx sites-available shoule only use *.conf although most much of use case developer should modify laradock to suit their project. we can use *.conf.example to take effect. but we also need a dummy nginx conf to info other newer to know how to config their nginx conf. the *.conf.example should be. so i think we should only take *.conf to take effect. not * --- nginx/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/nginx.conf b/nginx/nginx.conf index c627c4e..e747e98 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -28,7 +28,7 @@ http { ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-available/*; + include /etc/nginx/sites-available/*.conf; open_file_cache off; # Disabled for issue 619 charset UTF-8; } From 19518341503bb265fce40f5a2aaf4734eacd985e Mon Sep 17 00:00:00 2001 From: Patrick Mac Gregor Date: Wed, 28 Jun 2017 11:28:04 +0200 Subject: [PATCH 026/126] [Fix] Mailhog should be exposed to backend - fixes failing connection to host "mailhog" when sending mail via smtp - mailhog needs to be available for the backend at Port 1025 - i.e. in a Laravel app .env should contain "MAIL_HOST=mailhog --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index ec9af2c..556e3b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -518,6 +518,7 @@ services: - "8025:8025" networks: - frontend + - backend ### Selenium Container ######################################## From 26d7fb01ed503b3a77bfa3928fe11f967569a0ee Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 29 Jun 2017 09:25:24 +0800 Subject: [PATCH 027/126] fixing package docker-engine is not available. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 03e4e58..87a8450 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,8 +41,10 @@ env: # Installing a newer Docker version before_install: + - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" - sudo apt-get update - - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-engine + - sudo apt-get -y install docker-ce script: ./travis-build.sh From 70e01125fd72b47fab49afb95ff47134cd6cc9a4 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 29 Jun 2017 09:30:37 +0800 Subject: [PATCH 028/126] fixing package docker-engine is not available. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 87a8450..f54fc73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,6 +45,7 @@ before_install: - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" - sudo apt-get update - sudo apt-get -y install docker-ce + - docker version script: ./travis-build.sh From 63152e11fa94866de2eeb9d3fc19c3a513e36a87 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 29 Jun 2017 12:47:29 +0800 Subject: [PATCH 029/126] fix caddy build failed --- caddy/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 072a0c7..09d4bbd 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -3,6 +3,7 @@ FROM alpine:3.4 MAINTAINER Eric Pfeiffer ENV caddy_version=0.10.3 +ARG plugins=http.git LABEL caddy_version="$caddy_version" architecture="amd64" @@ -12,7 +13,7 @@ RUN apk update \ RUN curl --silent --show-error --fail --location \ --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \ - "https://caddyserver.com/download/linux/amd64?plugins=http.cgi,http.cors,http.expires,http.filemanager,http.git,http.ipfilter,http.realip,tls.dns.cloudflare,tls.dns.digitalocean,tls.dns.dnspod,tls.dns.dyn,tls.dns.googlecloud,tls.dns.linode,tls.dns.namecheap,tls.dns.ovh,tls.dns.route53,tls.dns.vultr" \ + "https://caddyserver.com/download/linux/amd64?plugins=${plugins}" \ | tar --no-same-owner -C /usr/bin/ -xz caddy \ && mv /usr/bin/caddy /usr/bin/caddy \ && chmod 0755 /usr/bin/caddy From bc1c957f4796d5be26b3067e0468fb09f208ea18 Mon Sep 17 00:00:00 2001 From: Vincent Chu Date: Fri, 30 Jun 2017 06:22:55 -0400 Subject: [PATCH 030/126] add APACHE_SITES_PATH variable --- docker-compose.yml | 2 +- env-example | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 556e3b9..699794b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -149,7 +149,7 @@ services: - applications volumes: - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 - - ./apache2/sites:/etc/apache2/sites-available + - ${APACHE_SITES_PATH}:/etc/apache2/sites-available ports: - "${APACHE_HOST_HTTP_PORT}:80" - "${APACHE_HOST_HTTPS_PORT}:443" diff --git a/env-example b/env-example index f8ca650..f80de1e 100644 --- a/env-example +++ b/env-example @@ -85,6 +85,7 @@ APACHE_HOST_HTTP_PORT=80 APACHE_HOST_HTTPS_PORT=443 APACHE2_PHP_SOCKET=php-fpm:9000 APACHE_HOST_LOG_PATH=./logs/apache2 +APACHE_SITES_PATH=./apache2/sites PHP_SOCKET=php-fpm:9000 ### MYSQL ############################################################################################################## From 19f9b25a4612278f878202683677f928ed7f5c63 Mon Sep 17 00:00:00 2001 From: sakanaproductions Date: Fri, 30 Jun 2017 17:48:24 -0700 Subject: [PATCH 031/126] fixed issue #1017, added ENV variables back to Dockerfile and added startup file back --- mysql/Dockerfile | 18 +++++++++++++++++- mysql/startup | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 mysql/startup diff --git a/mysql/Dockerfile b/mysql/Dockerfile index aada38f..f63e014 100644 --- a/mysql/Dockerfile +++ b/mysql/Dockerfile @@ -12,8 +12,24 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN chown -R mysql:root /var/lib/mysql/ +ADD startup /etc/mysql/startup + +ARG MYSQL_DATABASE=default +ARG MYSQL_USER=default +ARG MYSQL_PASSWORD=secret +ARG MYSQL_ROOT_PASSWORD=root + +ENV MYSQL_DATABASE=$MYSQL_DATABASE +ENV MYSQL_USER=$MYSQL_USER +ENV MYSQL_PASSWORD=$MYSQL_PASSWORD +ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD + +RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/startup && \ + sed -i 's/MYSQL_USER/'$MYSQL_USER'/g' /etc/mysql/startup && \ + sed -i 's/MYSQL_PASSWORD/'$MYSQL_PASSWORD'/g' /etc/mysql/startup + ADD my.cnf /etc/mysql/conf.d/my.cnf -CMD ["mysqld"] +CMD ["mysqld", "--init-file=/etc/mysql/startup"] EXPOSE 3306 diff --git a/mysql/startup b/mysql/startup new file mode 100644 index 0000000..11ced19 --- /dev/null +++ b/mysql/startup @@ -0,0 +1,3 @@ +DROP USER MYSQL_USER; +CREATE DATABASE IF NOT EXISTS MYSQL_DATABASE; +GRANT ALL ON `MYSQL_DATABASE`.* TO 'MYSQL_USER'@'%' IDENTIFIED BY 'MYSQL_PASSWORD'; \ No newline at end of file From 007017a2a74068696dc4a0e435c02788ebf604c5 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 4 Jul 2017 06:00:31 +0300 Subject: [PATCH 032/126] fix mysql error no access --- mysql/Dockerfile | 18 +----------------- mysql/startup | 3 --- 2 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 mysql/startup diff --git a/mysql/Dockerfile b/mysql/Dockerfile index f63e014..aada38f 100644 --- a/mysql/Dockerfile +++ b/mysql/Dockerfile @@ -12,24 +12,8 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN chown -R mysql:root /var/lib/mysql/ -ADD startup /etc/mysql/startup - -ARG MYSQL_DATABASE=default -ARG MYSQL_USER=default -ARG MYSQL_PASSWORD=secret -ARG MYSQL_ROOT_PASSWORD=root - -ENV MYSQL_DATABASE=$MYSQL_DATABASE -ENV MYSQL_USER=$MYSQL_USER -ENV MYSQL_PASSWORD=$MYSQL_PASSWORD -ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD - -RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/startup && \ - sed -i 's/MYSQL_USER/'$MYSQL_USER'/g' /etc/mysql/startup && \ - sed -i 's/MYSQL_PASSWORD/'$MYSQL_PASSWORD'/g' /etc/mysql/startup - ADD my.cnf /etc/mysql/conf.d/my.cnf -CMD ["mysqld", "--init-file=/etc/mysql/startup"] +CMD ["mysqld"] EXPOSE 3306 diff --git a/mysql/startup b/mysql/startup deleted file mode 100644 index 11ced19..0000000 --- a/mysql/startup +++ /dev/null @@ -1,3 +0,0 @@ -DROP USER MYSQL_USER; -CREATE DATABASE IF NOT EXISTS MYSQL_DATABASE; -GRANT ALL ON `MYSQL_DATABASE`.* TO 'MYSQL_USER'@'%' IDENTIFIED BY 'MYSQL_PASSWORD'; \ No newline at end of file From 50834268a76afb0b4685345b03943b2cd80ac6ea Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 4 Jul 2017 06:00:45 +0300 Subject: [PATCH 033/126] upgrade mysql base image to 8.0 --- mysql/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql/Dockerfile b/mysql/Dockerfile index aada38f..2061a0b 100644 --- a/mysql/Dockerfile +++ b/mysql/Dockerfile @@ -1,4 +1,4 @@ -FROM mysql:5.7 +FROM mysql:8.0 MAINTAINER Mahmoud Zalt From 3e59a2a813688a5336c7e06080a905e6cd6776ce Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 4 Jul 2017 06:01:18 +0300 Subject: [PATCH 034/126] add creating multiple databases to the docs --- DOCUMENTATION/content/documentation/index.md | 24 +++++++++++++++---- .../createdb.sql.example | 22 ++++++++--------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index e447225..e4a7ced 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -192,14 +192,17 @@ The NGINX Log file is stored in the `logs/nginx` directory. However to view the logs of all the other containers (MySQL, PHP-FPM,...) you can run this: ```bash -docker logs {container-name} +docker-compose logs {container-name} +``` + +```bash +docker-compose logs -f {container-name} ``` More [options](https://docs.docker.com/compose/reference/logs/) -```bash -docker logs -f {container-name} -``` + + @@ -1057,6 +1060,19 @@ The default username and password for the root MySQL user are `root` and `root ` +
+ +## Create Multiple Databases (MySQL) + +Create `createdb.sql` from `mysql/docker-entrypoint-initdb.d/createdb.sql.example` in `mysql/docker-entrypoint-initdb.d/*` and add your SQL syntax as follow: + +```sql +CREATE DATABASE IF NOT EXISTS `your_db_1` COLLATE 'utf8_general_ci' ; +GRANT ALL ON `your_db_1`.* TO 'mysql_user'@'%' ; +``` + + +
diff --git a/mysql/docker-entrypoint-initdb.d/createdb.sql.example b/mysql/docker-entrypoint-initdb.d/createdb.sql.example index 2b7c515..5567985 100644 --- a/mysql/docker-entrypoint-initdb.d/createdb.sql.example +++ b/mysql/docker-entrypoint-initdb.d/createdb.sql.example @@ -1,20 +1,20 @@ -### -### Copy createdb.sql.example to createdb.sql -### then uncomment then set database name and username to create you need databases +# +# 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 is auto run when mysql container start and $DATA_SAVE_PATH/mysql not exists. -### -### if your $DATA_SAVE_PATH/mysql is 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 -### +# +# this sql script will auto run when the mysql container starts and the $DATA_SAVE_PATH/mysql not found. +# +# if your $DATA_SAVE_PATH/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'@'%' ; From 9d2be424def0200dbcc0fe8bf8024e01c4f68bd5 Mon Sep 17 00:00:00 2001 From: Vincent Chu Date: Thu, 6 Jul 2017 00:31:42 -0400 Subject: [PATCH 035/126] fix #1041 Possible fix described on: https://bugs.mysql.com/bug.php?id=85946 ``` [mysqld] character-set-server=utf8 ``` --- mysql/my.cnf | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql/my.cnf b/mysql/my.cnf index 06595ca..bee678a 100644 --- a/mysql/my.cnf +++ b/mysql/my.cnf @@ -7,3 +7,4 @@ [mysqld] sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" +character-set-server=utf8 From 02e2454c79d499ef9d52c2500b0476c9b7c17cb9 Mon Sep 17 00:00:00 2001 From: Vincent Chu Date: Wed, 5 Jul 2017 17:56:50 -0400 Subject: [PATCH 036/126] add docker-entrypoint-initdb.d variables for MySQL + MariaDB + Percona --- docker-compose.yml | 6 +++--- env-example | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 55d6a18..8f397d6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -200,7 +200,7 @@ services: - TZ=${WORKSPACE_TIMEZONE} volumes: - ${DATA_SAVE_PATH}/mysql:/var/lib/mysql - - ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d ports: - "${MYSQL_PORT}:3306" networks: @@ -218,7 +218,7 @@ services: - MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD} volumes: - ${DATA_SAVE_PATH}/percona:/var/lib/mysql - - ./percona/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ${PERCONA_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d ports: - "${PERCONA_PORT}:3306" networks: @@ -246,7 +246,7 @@ services: build: ./mariadb volumes: - ${DATA_SAVE_PATH}/mariadb:/var/lib/mysql - - ./mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d ports: - "${MARIADB_PORT}:3306" environment: diff --git a/env-example b/env-example index f80de1e..72aa07f 100644 --- a/env-example +++ b/env-example @@ -95,6 +95,7 @@ MYSQL_USER=default MYSQL_PASSWORD=secret MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=root +MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d ### Percona ############################################################################################################ @@ -103,6 +104,7 @@ PERCONA_USER=homestead PERCONA_PASSWORD=secret PERCONA_PORT=3306 PERCONA_ROOT_PASSWORD=root +PERCONA_ENTRYPOINT_INITDB=./percona/docker-entrypoint-initdb.d ### MSSQL ############################################################################################################## @@ -117,6 +119,7 @@ MARIADB_USER=default MARIADB_PASSWORD=secret MARIADB_PORT=3306 MARIADB_ROOT_PASSWORD=root +MARIADB_ENTRYPOINT_INITDB=./mariadb/docker-entrypoint-initdb.d ### POSTGRES ########################################################################################################### From f2f665dc087cb5ceb2e3a9495f2b398db7b3034f Mon Sep 17 00:00:00 2001 From: Rudolf Gitler Date: Fri, 7 Jul 2017 13:21:14 +0200 Subject: [PATCH 037/126] Update Dockerfile-71 php7.1-xdebug instead of php-xdebug instead. apt-get update needed therefore --- workspace/Dockerfile-71 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 29f5b62..14fb295 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -132,8 +132,8 @@ RUN echo "" >> ~/.bashrc && \ ARG INSTALL_XDEBUG=false RUN if [ ${INSTALL_XDEBUG} = true ]; then \ # Load the xdebug extension only with phpunit commands - apt-get install -y --force-yes php-xdebug && \ - sed -i 's/^;//g' /etc/php/7.1/cli/conf.d/20-xdebug.ini && \ + apt-get update && \ + apt-get install -y --force-yes php7.1-xdebug && \ sed -i 's/^;//g' /etc/php/7.1/cli/conf.d/20-xdebug.ini && \ echo "alias phpunit='php -dzend_extension=xdebug.so /var/www/vendor/bin/phpunit'" >> ~/.bashrc \ ;fi # ADD for REMOTE debugging From 7ec8b8846eb5de60141c25a94c3895decfdb1164 Mon Sep 17 00:00:00 2001 From: Ryan Hayle Date: Fri, 7 Jul 2017 16:43:06 -0500 Subject: [PATCH 038/126] Allow specifying the version of MySQL to install in .env file. --- docker-compose.yml | 2 ++ env-example | 1 + mysql/Dockerfile | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 55d6a18..ee0d4b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -192,6 +192,8 @@ services: mysql: build: context: ./mysql + args: + - MYSQL_VERSION=${MYSQL_VERSION} environment: - MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_USER=${MYSQL_USER} diff --git a/env-example b/env-example index f80de1e..0782818 100644 --- a/env-example +++ b/env-example @@ -90,6 +90,7 @@ PHP_SOCKET=php-fpm:9000 ### MYSQL ############################################################################################################## +MYSQL_VERSION=8.0 MYSQL_DATABASE=default MYSQL_USER=default MYSQL_PASSWORD=secret diff --git a/mysql/Dockerfile b/mysql/Dockerfile index 2061a0b..5eb6c40 100644 --- a/mysql/Dockerfile +++ b/mysql/Dockerfile @@ -1,4 +1,5 @@ -FROM mysql:8.0 +ARG MYSQL_VERSION=8.0 +FROM mysql:${MYSQL_VERSION} MAINTAINER Mahmoud Zalt From fe38f0c2ffb1caea43ed66ae8b2c78e92bf928e0 Mon Sep 17 00:00:00 2001 From: Ryan Hayle Date: Fri, 7 Jul 2017 17:02:05 -0500 Subject: [PATCH 039/126] Add documentation on the MYSQL_VERSION variable. --- DOCUMENTATION/content/documentation/index.md | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index e4a7ced..f2d0c63 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -158,7 +158,7 @@ You might use the `--no-cache` option if you want full rebuilding (`docker-compo ## Docker-Sync -Docker on the Mac [is slow](https://github.com/docker/for-mac/issues/77), at the time of writing. Especially for larger projects, this can be a problem. The problem is [older than March 2016](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) - as it's a such a long-running issue, we're including it in the docs here. +Docker on the Mac [is slow](https://github.com/docker/for-mac/issues/77), at the time of writing. Especially for larger projects, this can be a problem. The problem is [older than March 2016](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) - as it's a such a long-running issue, we're including it in the docs here. The problem originates in bind-mount performance on MacOS. Docker for Mac uses osxfs by default. This is not without reason, it has [a lot of advantages](https://docs.docker.com/docker-for-mac/osxfs/). @@ -737,7 +737,7 @@ docker-compose up -d mariadb phpmyadmin 1 - Run the Adminer Container (`adminer`) with the `docker-compose up` command. Example: ```bash -docker-compose up -d adminer +docker-compose up -d adminer ``` 2 - Open your browser and visit the localhost on port **8080**: `http://localhost:8080` @@ -1026,6 +1026,26 @@ To change the default forwarded port for ssh: +
+ +## Change the (MySQL) Version +By default **MySQL 8.0** is running. + +MySQL 8.0 is a development release. You may prefer to use the latest stable version, or an even older release. If you wish, you can change the MySQL image that is used. + +Open up your .env file and set the `MYSQL_VERSION` variable to the version you would like to install. + +``` +MYSQL_VERSION=5.7 +``` + +Available versions are: 5.5, 5.6, 5.7, 8.0, or latest. See https://store.docker.com/images/mysql for more information. + + + + + +
## MySQL access from host From 7765df107610cea6a019419786356dec6d6d7dd6 Mon Sep 17 00:00:00 2001 From: Ujjwal Ojha Date: Sat, 8 Jul 2017 10:00:52 +0545 Subject: [PATCH 040/126] fix php7.1-xdebug because of missing new line --- workspace/Dockerfile-71 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 14fb295..e5525c1 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -133,7 +133,8 @@ ARG INSTALL_XDEBUG=false RUN if [ ${INSTALL_XDEBUG} = true ]; then \ # Load the xdebug extension only with phpunit commands apt-get update && \ - apt-get install -y --force-yes php7.1-xdebug && \ sed -i 's/^;//g' /etc/php/7.1/cli/conf.d/20-xdebug.ini && \ + apt-get install -y --force-yes php7.1-xdebug && \ + sed -i 's/^;//g' /etc/php/7.1/cli/conf.d/20-xdebug.ini && \ echo "alias phpunit='php -dzend_extension=xdebug.so /var/www/vendor/bin/phpunit'" >> ~/.bashrc \ ;fi # ADD for REMOTE debugging From 9dda2f6b9fcd8db07980066e0e8bef3b018cd7f0 Mon Sep 17 00:00:00 2001 From: Ujjwal Ojha Date: Sat, 8 Jul 2017 16:43:05 +0545 Subject: [PATCH 041/126] image optimizers libraries --- docker-compose.yml | 2 ++ env-example | 2 ++ php-fpm/Dockerfile-56 | 11 +++++++++++ php-fpm/Dockerfile-70 | 11 +++++++++++ php-fpm/Dockerfile-71 | 11 +++++++++++ workspace/Dockerfile-56 | 13 +++++++++++++ workspace/Dockerfile-70 | 13 +++++++++++++ workspace/Dockerfile-71 | 13 +++++++++++++ 8 files changed, 76 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 8f397d6..29b0109 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,7 @@ services: - INSTALL_DEPLOYER=${WORKSPACE_INSTALL_DEPLOYER} - INSTALL_LINUXBREW=${WORKSPACE_INSTALL_LINUXBREW} - INSTALL_MC=${WORKSPACE_INSTALL_MC} + - INSTALL_IMAGE_OPTIMIZERS=${WORKSPACE_INSTALL_IMAGE_OPTIMIZERS} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} - NODE_VERSION=${WORKSPACE_NODE_VERSION} @@ -75,6 +76,7 @@ services: - INSTALL_GHOSTSCRIPT=${PHP_FPM_INSTALL_GHOSTSCRIPT} - INSTALL_LDAP=${PHP_FPM_INSTALL_LDAP} - INSTALL_SWOOLE=${PHP_FPM_INSTALL_SWOOLE} + - INSTALL_IMAGE_OPTIMIZERS=${PHP_FPM_INSTALL_IMAGE_OPTIMIZERS} dockerfile: "Dockerfile-${PHP_VERSION}" volumes_from: - applications diff --git a/env-example b/env-example index 72aa07f..23eba15 100644 --- a/env-example +++ b/env-example @@ -45,6 +45,7 @@ WORKSPACE_INSTALL_LARAVEL_INSTALLER=false WORKSPACE_INSTALL_DEPLOYER=false WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false +WORKSPACE_INSTALL_IMAGE_OPTIMIZERS=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_NODE_VERSION=stable @@ -71,6 +72,7 @@ PHP_FPM_INSTALL_INTL=false PHP_FPM_INSTALL_GHOSTSCRIPT=false PHP_FPM_INSTALL_LDAP=false PHP_FPM_INSTALL_SWOOLE=false +PHP_FPM_INSTALL_IMAGE_OPTIMIZERS=false ### NGINX ############################################################################################################## diff --git a/php-fpm/Dockerfile-56 b/php-fpm/Dockerfile-56 index cad89a5..1d8fd97 100644 --- a/php-fpm/Dockerfile-56 +++ b/php-fpm/Dockerfile-56 @@ -258,6 +258,17 @@ RUN if [ ${INSTALL_MSSQL} = true ]; then \ docker-php-ext-enable mssql pdo pdo_dblib \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get update -yqq && \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle \ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/php-fpm/Dockerfile-70 b/php-fpm/Dockerfile-70 index b14adac..b643a38 100644 --- a/php-fpm/Dockerfile-70 +++ b/php-fpm/Dockerfile-70 @@ -282,6 +282,17 @@ RUN if [ ${INSTALL_MSSQL} = true ]; then \ && docker-php-ext-enable pdo_sqlsrv sqlsrv \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get update -yqq && \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle \ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/php-fpm/Dockerfile-71 b/php-fpm/Dockerfile-71 index 3a71dc2..90ea2bd 100644 --- a/php-fpm/Dockerfile-71 +++ b/php-fpm/Dockerfile-71 @@ -289,6 +289,17 @@ RUN if [ ${INSTALL_MSSQL} = true ]; then \ && docker-php-ext-enable pdo_sqlsrv sqlsrv \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get update -yqq && \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle \ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index f945358..076eda3 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -425,6 +425,19 @@ RUN if [ ${INSTALL_MC} = true ]; then\ chmod +x /usr/local/bin/mc \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ + if [ ${INSTALL_NODE} = true ]; then \ + . ~/.bashrc && npm install -g svgo \ + ;fi\ +;fi + USER laradock # diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index 0ee2b70..3751c7a 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -530,6 +530,19 @@ RUN if [ ${INSTALL_SYMFONY} = true ]; then \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ + if [ ${INSTALL_NODE} = true ]; then \ + . ~/.bashrc && npm install -g svgo \ + ;fi\ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index e5525c1..c66befb 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -533,6 +533,19 @@ RUN if [ ${INSTALL_SYMFONY} = true ]; then \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ + if [ ${INSTALL_NODE} = true ]; then \ + . ~/.bashrc && npm install -g svgo \ + ;fi\ +;fi + USER laradock # From 09bf0566afc55b1e7d5774c86277f75511a5becb Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Wed, 12 Jul 2017 18:32:22 +0300 Subject: [PATCH 042/126] Adding Vince Chu to the team Welcome @vwchu :) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index daa9e6f..e7cf945 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ A Docker PHP development environment that facilitates running **PHP** Apps on ** - [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 - Join Us. ## License From f2a9712041d13f966f2582d7daa68317a9981c55 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Thu, 13 Jul 2017 04:08:59 +0300 Subject: [PATCH 043/126] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..8359c58 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mahmoud@zalt.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ From b4ca9c55968217a81973222715d9662d39e2d9f0 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Thu, 13 Jul 2017 04:15:09 +0300 Subject: [PATCH 044/126] Create CONTRIBUTING.md --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7d5865b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +### First off, thanks for taking the time to contribute! + +For the contribution guide [click here](http://laradock.io/contributing/). From fe096ce28256863e0b71c4178591affe4b729dde Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Thu, 13 Jul 2017 20:30:27 +0300 Subject: [PATCH 045/126] move github repository files to the .github directory --- CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 README-zh.md => .github/README-zh.md | 0 README.md => .github/README.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (100%) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) rename README-zh.md => .github/README-zh.md (100%) rename README.md => .github/README.md (100%) diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/README-zh.md b/.github/README-zh.md similarity index 100% rename from README-zh.md rename to .github/README-zh.md diff --git a/README.md b/.github/README.md similarity index 100% rename from README.md rename to .github/README.md From 00a38fe274f2d2275a4c16523261f67abf28e62f Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Fri, 14 Jul 2017 17:03:01 -0400 Subject: [PATCH 046/126] added docker-sync support --- .gitignore | 3 ++- docker-compose.yml | 7 ++++++- docker-sync.yml | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 docker-sync.yml diff --git a/.gitignore b/.gitignore index a6b304c..702790a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /logs /data .env -/.project \ No newline at end of file +/.project +.docker-sync \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 29b0109..17cdde9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,9 @@ services: applications: image: tianon/true volumes: - - ${APPLICATION}:/var/www + #- ${APPLICATION}:/var/www + - applications-sync:/var/www:nocopy # nocopy is required + ### Workspace Utilities Container ########################### @@ -668,3 +670,6 @@ volumes: driver: "local" elasticsearch-plugins: driver: "local" + applications-sync: + external: + name: "applications-sync" diff --git a/docker-sync.yml b/docker-sync.yml new file mode 100644 index 0000000..c68352a --- /dev/null +++ b/docker-sync.yml @@ -0,0 +1,9 @@ +version: "2" + +options: + verbose: true +syncs: + applications-host-sync: # name of the sync volume + src: '${APPLICATION}' # host source directory + # sync_strategy: 'native_osx' # native_osx is the default + # sync_excludes: ['ignored_folder', '.ignored_dot_folder'] # ignored folders form sync \ No newline at end of file From aa22f5d64822f402e7bd82392d7e71a07cf654ed Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Fri, 14 Jul 2017 17:15:45 -0400 Subject: [PATCH 047/126] fixing applications sync volume name --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 17cdde9..3fba283 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -672,4 +672,4 @@ volumes: driver: "local" applications-sync: external: - name: "applications-sync" + name: "applications-host-sync" From 11687ffd364636884380b750e99bd137e092d0ec Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Fri, 14 Jul 2017 19:14:51 -0400 Subject: [PATCH 048/126] disabling docker-sync --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3fba283..66c82d3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,8 +7,8 @@ services: applications: image: tianon/true volumes: - #- ${APPLICATION}:/var/www - - applications-sync:/var/www:nocopy # nocopy is required + - ${APPLICATION}:/var/www +# - applications-sync:/var/www:nocopy # nocopy is required ### Workspace Utilities Container ########################### From 0baf7917282cf92ac69d08b32d163397b9056aaa Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Fri, 14 Jul 2017 19:17:50 -0400 Subject: [PATCH 049/126] enabling sync --- docker-compose.yml | 4 ++-- docker-sync.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 66c82d3..b6ac1b2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,8 +7,8 @@ services: applications: image: tianon/true volumes: - - ${APPLICATION}:/var/www -# - applications-sync:/var/www:nocopy # nocopy is required +# - ${APPLICATION}:/var/www + - applications-sync:/var/www:nocopy # nocopy is required ### Workspace Utilities Container ########################### diff --git a/docker-sync.yml b/docker-sync.yml index c68352a..d602e51 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -5,5 +5,5 @@ options: syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory - # sync_strategy: 'native_osx' # native_osx is the default - # sync_excludes: ['ignored_folder', '.ignored_dot_folder'] # ignored folders form sync \ No newline at end of file + sync_strategy: 'native_osx' # native_osx is the default + sync_excludes: ['laradock', '.ignored_dot_folder'] \ No newline at end of file From 3752f482498951489e16debdc75448640efc1bd8 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Fri, 14 Jul 2017 19:27:16 -0400 Subject: [PATCH 050/126] displaying php errors --- php-fpm/php71.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php-fpm/php71.ini b/php-fpm/php71.ini index c8242dc..2c39db8 100644 --- a/php-fpm/php71.ini +++ b/php-fpm/php71.ini @@ -474,7 +474,7 @@ error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT ; Development Value: On ; Production Value: Off ; http://php.net/display-errors -display_errors = Off +display_errors = On ; 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 @@ -485,7 +485,7 @@ display_errors = Off ; Development Value: On ; Production Value: Off ; http://php.net/display-startup-errors -display_startup_errors = Off +display_startup_errors = On ; 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 From 9970a00533cb551e2a697a61fcc4ec6c03e0b233 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 06:40:06 -0400 Subject: [PATCH 051/126] adding php-fpm user --- docker-sync.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-sync.yml b/docker-sync.yml index d602e51..6df8bd5 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -6,4 +6,6 @@ syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory sync_strategy: 'native_osx' # native_osx is the default - sync_excludes: ['laradock', '.ignored_dot_folder'] \ No newline at end of file + sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories + sync_user: www-data # php-fpm user should have permission to read the files + #sync_userid: 82 \ No newline at end of file From b2c6e53bfae21375a897e0673c55dbad32c62867 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 06:48:23 -0400 Subject: [PATCH 052/126] adding quotes to user --- docker-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-sync.yml b/docker-sync.yml index 6df8bd5..6471720 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -5,7 +5,7 @@ options: syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory + sync_user: 'www-data' # php-fpm user should have permission to read the files sync_strategy: 'native_osx' # native_osx is the default sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories - sync_user: www-data # php-fpm user should have permission to read the files #sync_userid: 82 \ No newline at end of file From f59b9ebda697b86eca60b51d953c6bf20c08fb0e Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 07:01:45 -0400 Subject: [PATCH 053/126] removed user --- docker-sync.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-sync.yml b/docker-sync.yml index 6471720..b8282b4 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -5,7 +5,6 @@ options: syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory - sync_user: 'www-data' # php-fpm user should have permission to read the files sync_strategy: 'native_osx' # native_osx is the default sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories #sync_userid: 82 \ No newline at end of file From 0aa63c40f85cefc5c5362c987eda79582b9150d9 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 07:09:58 -0400 Subject: [PATCH 054/126] defining user id 1000 --- docker-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-sync.yml b/docker-sync.yml index b8282b4..0de3d13 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -5,6 +5,6 @@ options: syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory + sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) sync_strategy: 'native_osx' # native_osx is the default sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories - #sync_userid: 82 \ No newline at end of file From 42fc8b7b577c8e339dbfe37fa78c3f54728f72d3 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 08:19:49 -0400 Subject: [PATCH 055/126] separating syn compose file --- docker-compose.sync.yml | 17 +++++++++++++++++ docker-compose.yml | 7 +------ docker-sync.yml | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 docker-compose.sync.yml diff --git a/docker-compose.sync.yml b/docker-compose.sync.yml new file mode 100644 index 0000000..b4b383a --- /dev/null +++ b/docker-compose.sync.yml @@ -0,0 +1,17 @@ +version: '2' + +services: + +### Applications Code Container ############################# + + applications: + image: tianon/true + volumes: + - applications-sync:/var/www:nocopy # nocopy is required + +### Volumes Setup ############################################# + +volumes: + applications-sync: + external: + name: "applications-host-sync" diff --git a/docker-compose.yml b/docker-compose.yml index b6ac1b2..29b0109 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,9 +7,7 @@ services: applications: image: tianon/true volumes: -# - ${APPLICATION}:/var/www - - applications-sync:/var/www:nocopy # nocopy is required - + - ${APPLICATION}:/var/www ### Workspace Utilities Container ########################### @@ -670,6 +668,3 @@ volumes: driver: "local" elasticsearch-plugins: driver: "local" - applications-sync: - external: - name: "applications-host-sync" diff --git a/docker-sync.yml b/docker-sync.yml index 0de3d13..d497a56 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -6,5 +6,5 @@ syncs: applications-host-sync: # name of the sync volume src: '${APPLICATION}' # host source directory sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) - sync_strategy: 'native_osx' # native_osx is the default + sync_strategy: 'native_osx' # for windows use 'unison' for linux docker-sync is not necessary sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories From 9585a4a7ab82423f1771663f60a9fa2e57176c37 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 08:28:15 -0400 Subject: [PATCH 056/126] changing compose file name for using docker sync stack --- docker-compose.sync.yml => docker-compose-dev.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docker-compose.sync.yml => docker-compose-dev.yml (100%) diff --git a/docker-compose.sync.yml b/docker-compose-dev.yml similarity index 100% rename from docker-compose.sync.yml rename to docker-compose-dev.yml From d83c9be2ea4bdc49c09715b8b81aea6353496bcf Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:05:29 -0400 Subject: [PATCH 057/126] disabling unused services --- docker-compose.yml | 745 +++++++++++++++++++++++---------------------- 1 file changed, 373 insertions(+), 372 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 29b0109..94926dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -130,64 +130,64 @@ services: ### Blackfire Container ################################# - blackfire: - image: blackfire/blackfire - environment: - - BLACKFIRE_SERVER_ID=${BLACKFIRE_SERVER_ID} - - BLACKFIRE_SERVER_TOKEN=${BLACKFIRE_SERVER_TOKEN} - depends_on: - - php-fpm - networks: - - backend +# blackfire: +# image: blackfire/blackfire +# environment: +# - BLACKFIRE_SERVER_ID=${BLACKFIRE_SERVER_ID} +# - BLACKFIRE_SERVER_TOKEN=${BLACKFIRE_SERVER_TOKEN} +# depends_on: +# - php-fpm +# networks: +# - backend ### Apache Server Container ################################# - apache2: - build: - context: ./apache2 - args: - - PHP_SOCKET=${PHP_SOCKET} - volumes_from: - - applications - volumes: - - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 - - ${APACHE_SITES_PATH}:/etc/apache2/sites-available - ports: - - "${APACHE_HOST_HTTP_PORT}:80" - - "${APACHE_HOST_HTTPS_PORT}:443" - depends_on: - - php-fpm - networks: - - frontend - - backend +# apache2: +# build: +# context: ./apache2 +# args: +# - PHP_SOCKET=${PHP_SOCKET} +# volumes_from: +# - applications +# volumes: +# - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 +# - ${APACHE_SITES_PATH}:/etc/apache2/sites-available +# ports: +# - "${APACHE_HOST_HTTP_PORT}:80" +# - "${APACHE_HOST_HTTPS_PORT}:443" +# depends_on: +# - php-fpm +# networks: +# - frontend +# - backend ### HHVM Container ########################################## - hhvm: - build: ./hhvm - volumes_from: - - applications - expose: - - "9000" - depends_on: - - workspace - networks: - - frontend - - backend +# hhvm: +# build: ./hhvm +# volumes_from: +# - applications +# expose: +# - "9000" +# depends_on: +# - workspace +# networks: +# - frontend +# - backend ### Minio Container ######################################### - minio: - build: ./minio - volumes: - - minio:/export - ports: - - "${MINIO_PORT}:9000" - environment: - - MINIO_ACCESS_KEY=access - - MINIO_SECRET_KEY=secretkey - networks: - - frontend +# minio: +# build: ./minio +# volumes: +# - minio:/export +# ports: +# - "${MINIO_PORT}:9000" +# environment: +# - MINIO_ACCESS_KEY=access +# - MINIO_SECRET_KEY=secretkey +# networks: +# - frontend ### MySQL Container ######################################### @@ -210,120 +210,120 @@ services: ### Percona Container ######################################### - percona: - build: - context: ./percona - environment: - - MYSQL_DATABASE=${PERCONA_DATABASE} - - MYSQL_USER=${PERCONA_USER} - - MYSQL_PASSWORD=${PERCONA_PASSWORD} - - MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD} - volumes: - - ${DATA_SAVE_PATH}/percona:/var/lib/mysql - - ${PERCONA_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d - ports: - - "${PERCONA_PORT}:3306" - networks: - - backend +# percona: +# build: +# context: ./percona +# environment: +# - MYSQL_DATABASE=${PERCONA_DATABASE} +# - MYSQL_USER=${PERCONA_USER} +# - MYSQL_PASSWORD=${PERCONA_PASSWORD} +# - MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD} +# volumes: +# - ${DATA_SAVE_PATH}/percona:/var/lib/mysql +# - ${PERCONA_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d +# ports: +# - "${PERCONA_PORT}:3306" +# networks: +# - backend ### MSSQL Container ######################################### - mssql: - build: - context: ./mssql - environment: - - MSSQL_DATABASE=${MSSQL_DATABASE} - - SA_PASSWORD=${MSSQL_PASSWORD} - - ACCEPT_EULA=Y - volumes: - - ${DATA_SAVE_PATH}/mssql:/var/opt/mssql - ports: - - "${MSSQL_PORT}:1433" - networks: - - backend +# mssql: +# build: +# context: ./mssql +# environment: +# - MSSQL_DATABASE=${MSSQL_DATABASE} +# - SA_PASSWORD=${MSSQL_PASSWORD} +# - ACCEPT_EULA=Y +# volumes: +# - ${DATA_SAVE_PATH}/mssql:/var/opt/mssql +# ports: +# - "${MSSQL_PORT}:1433" +# networks: +# - backend ### MariaDB Container ####################################### - mariadb: - build: ./mariadb - volumes: - - ${DATA_SAVE_PATH}/mariadb:/var/lib/mysql - - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d - ports: - - "${MARIADB_PORT}:3306" - environment: - - MYSQL_DATABASE=${MARIADB_DATABASE} - - MYSQL_USER=${MARIADB_USER} - - MYSQL_PASSWORD=${MARIADB_PASSWORD} - - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD} - networks: - - backend +# mariadb: +# build: ./mariadb +# volumes: +# - ${DATA_SAVE_PATH}/mariadb:/var/lib/mysql +# - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d +# ports: +# - "${MARIADB_PORT}:3306" +# environment: +# - MYSQL_DATABASE=${MARIADB_DATABASE} +# - MYSQL_USER=${MARIADB_USER} +# - MYSQL_PASSWORD=${MARIADB_PASSWORD} +# - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD} +# networks: +# - backend ### PostgreSQL Container #################################### - postgres: - build: ./postgres - volumes: - - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data - ports: - - "${POSTGRES_PORT}:5432" - environment: - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - networks: - - backend +# postgres: +# build: ./postgres +# volumes: +# - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data +# ports: +# - "${POSTGRES_PORT}:5432" +# environment: +# - POSTGRES_DB=${POSTGRES_DB} +# - POSTGRES_USER=${POSTGRES_USER} +# - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} +# networks: +# - backend ### PostgreSQL PostGis Container ############################ - postgres-postgis: - build: ./postgres-postgis - volumes: - - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data - ports: - - "${POSTGRES_PORT}:5432" - environment: - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - networks: - - backend +# postgres-postgis: +# build: ./postgres-postgis +# volumes: +# - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data +# ports: +# - "${POSTGRES_PORT}:5432" +# environment: +# - POSTGRES_DB=${POSTGRES_DB} +# - POSTGRES_USER=${POSTGRES_USER} +# - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} +# networks: +# - backend ### Neo4j Container ######################################### - neo4j: - build: ./neo4j - ports: - - "7474:7474" - - "1337:1337" - environment: - - NEO4J_AUTH=default:secret - volumes: - - ${DATA_SAVE_PATH}/neo4j:/var/lib/neo4j/data - networks: - - backend +# neo4j: +# build: ./neo4j +# ports: +# - "7474:7474" +# - "1337:1337" +# environment: +# - NEO4J_AUTH=default:secret +# volumes: +# - ${DATA_SAVE_PATH}/neo4j:/var/lib/neo4j/data +# networks: +# - backend ### MongoDB Container ####################################### - mongo: - build: ./mongo - ports: - - "${MONGODB_PORT}:27017" - volumes: - - ${DATA_SAVE_PATH}/mongo:/data/db - networks: - - backend +# mongo: +# build: ./mongo +# ports: +# - "${MONGODB_PORT}:27017" +# volumes: +# - ${DATA_SAVE_PATH}/mongo:/data/db +# networks: +# - backend ### RethinkDB Container ####################################### - rethinkdb: - build: ./rethinkdb - ports: - - "${RETHINKDB_PORT}:8080" - volumes: - - ${DATA_SAVE_PATH}/rethinkdb:/data/rethinkdb_data - networks: - - backend +# rethinkdb: +# build: ./rethinkdb +# ports: +# - "${RETHINKDB_PORT}:8080" +# volumes: +# - ${DATA_SAVE_PATH}/rethinkdb:/data/rethinkdb_data +# networks: +# - backend ### Redis Container ######################################### @@ -338,290 +338,291 @@ services: ### Aerospike c Container ################################### - aerospike: - build: ./aerospike - volumes_from: - - workspace - volumes: - - ${DATA_SAVE_PATH}/aerospike:/opt/aerospike/data - ports: - - "${AEROSPIKE_SERVICE_PORT}:3000" - - "${AEROSPIKE_FABRIC_PORT}:3001" - - "${AEROSPIKE_HEARTBEAT_PORT}:3002" - - "${AEROSPIKE_INFO_PORT}:3003" - networks: - - backend +# aerospike: +# build: ./aerospike +# volumes_from: +# - workspace +# volumes: +# - ${DATA_SAVE_PATH}/aerospike:/opt/aerospike/data +# ports: +# - "${AEROSPIKE_SERVICE_PORT}:3000" +# - "${AEROSPIKE_FABRIC_PORT}:3001" +# - "${AEROSPIKE_HEARTBEAT_PORT}:3002" +# - "${AEROSPIKE_INFO_PORT}:3003" +# networks: +# - backend ### Memcached Container ##################################### - memcached: - build: ./memcached - volumes: - - ${DATA_SAVE_PATH}/memcached:/var/lib/memcached - ports: - - "${MEMCACHED_HOST_PORT}:11211" - depends_on: - - php-fpm - networks: - - backend +# memcached: +# build: ./memcached +# volumes: +# - ${DATA_SAVE_PATH}/memcached:/var/lib/memcached +# ports: +# - "${MEMCACHED_HOST_PORT}:11211" +# depends_on: +# - php-fpm +# networks: +# - backend ### Beanstalkd Container #################################### - beanstalkd: - build: ./beanstalkd - ports: - - "${BEANSTALKD_HOST_PORT}:11300" - privileged: true - depends_on: - - php-fpm - networks: - - backend +# beanstalkd: +# build: ./beanstalkd +# ports: +# - "${BEANSTALKD_HOST_PORT}:11300" +# privileged: true +# depends_on: +# - php-fpm +# networks: +# - backend ### RabbitMQ Container ###################################### - rabbitmq: - build: ./rabbitmq - ports: - - "${RABBITMQ_NODE_HOST_PORT}:5672" - - "${RABBITMQ_MANAGEMENT_HTTP_HOST_PORT}:15672" - - "${RABBITMQ_MANAGEMENT_HTTPS_HOST_PORT}:15671" - privileged: true - environment: - - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} - - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} - depends_on: - - php-fpm - networks: - - backend +# rabbitmq: +# build: ./rabbitmq +# ports: +# - "${RABBITMQ_NODE_HOST_PORT}:5672" +# - "${RABBITMQ_MANAGEMENT_HTTP_HOST_PORT}:15672" +# - "${RABBITMQ_MANAGEMENT_HTTPS_HOST_PORT}:15671" +# privileged: true +# environment: +# - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} +# - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} +# depends_on: +# - php-fpm +# networks: +# - backend ### Beanstalkd Console Container ############################ - beanstalkd-console: - build: ./beanstalkd-console - ports: - - "2080:2080" - depends_on: - - beanstalkd - networks: - - backend +# beanstalkd-console: +# build: ./beanstalkd-console +# ports: +# - "2080:2080" +# depends_on: +# - beanstalkd +# networks: +# - backend ### Caddy Server Container ################################## - caddy: - build: ./caddy - volumes_from: - - applications - volumes: - - ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile - - ${CADDY_HOST_LOG_PATH}:/var/log/caddy - - ${DATA_SAVE_PATH}:/root/.caddy - ports: - - "${CADDY_HOST_HTTP_PORT}:80" - - "${CADDY_HOST_HTTPS_PORT}:443" - depends_on: - - php-fpm - networks: - - frontend - - backend +# caddy: +# build: ./caddy +# volumes_from: +# - applications +# volumes: +# - ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile +# - ${CADDY_HOST_LOG_PATH}:/var/log/caddy +# - ${DATA_SAVE_PATH}:/root/.caddy +# ports: +# - "${CADDY_HOST_HTTP_PORT}:80" +# - "${CADDY_HOST_HTTPS_PORT}:443" +# depends_on: +# - php-fpm +# networks: +# - frontend +# - backend ### phpMyAdmin Container #################################### - phpmyadmin: - build: ./phpmyadmin - environment: - - PMA_ARBITRARY=1 - - MYSQL_USER=${PMA_USER} - - MYSQL_PASSWORD=${PMA_PASSWORD} - - MYSQL_ROOT_PASSWORD=${PMA_ROOT_PASSWORD} - ports: - - "${PMA_PORT}:80" - depends_on: - - "${PMA_DB_ENGINE}" - networks: - - frontend - - backend +# phpmyadmin: +# build: ./phpmyadmin +# environment: +# - PMA_ARBITRARY=1 +# - MYSQL_USER=${PMA_USER} +# - MYSQL_PASSWORD=${PMA_PASSWORD} +# - MYSQL_ROOT_PASSWORD=${PMA_ROOT_PASSWORD} +# ports: +# - "${PMA_PORT}:80" +# depends_on: +# - "${PMA_DB_ENGINE}" +# networks: +# - frontend +# - backend ### Adminer Container #################################### - adminer: - build: - context: ./adminer - args: - - INSTALL_MSSQL=${ADM_INSTALL_MSSQL} - ports: - - "${ADM_PORT}:8080" - depends_on: - - php-fpm - networks: - - frontend - - backend +# adminer: +# build: +# context: ./adminer +# args: +# - INSTALL_MSSQL=${ADM_INSTALL_MSSQL} +# ports: +# - "${ADM_PORT}:8080" +# depends_on: +# - php-fpm +# networks: +# - frontend +# - backend ### pgAdmin Container ####################################### - pgadmin: - build: ./pgadmin - ports: - - "5050:5050" - depends_on: - - postgres - networks: - - frontend - - backend +# pgadmin: +# build: ./pgadmin +# ports: +# - "5050:5050" +# depends_on: +# - postgres +# networks: +# - frontend +# - backend ### ElasticSearch Container ################################# - elasticsearch: - build: ./elasticsearch - volumes: - - elasticsearch-data:/usr/share/elasticsearch/data - - elasticsearch-plugins:/usr/share/elasticsearch/plugins - environment: - - cluster.name=laradock-cluster - - bootstrap.memory_lock=true - - "ES_JAVA_OPTS=-Xms256m -Xmx256m" - ulimits: - memlock: - soft: -1 - hard: -1 - mem_limit: 512m - ports: - - "${ELASTICSEARCH_HOST_HTTP_PORT}:9200" - - "${ELASTICSEARCH_HOST_TRANSPORT_PORT}:9300" - depends_on: - - php-fpm - networks: - - frontend - - backend +# elasticsearch: +# build: ./elasticsearch +# volumes: +# - elasticsearch-data:/usr/share/elasticsearch/data +# - elasticsearch-plugins:/usr/share/elasticsearch/plugins +# environment: +# - cluster.name=laradock-cluster +# - bootstrap.memory_lock=true +# - "ES_JAVA_OPTS=-Xms256m -Xmx256m" +# ulimits: +# memlock: +# soft: -1 +# hard: -1 +# mem_limit: 512m +# ports: +# - "${ELASTICSEARCH_HOST_HTTP_PORT}:9200" +# - "${ELASTICSEARCH_HOST_TRANSPORT_PORT}:9300" +# depends_on: +# - php-fpm +# networks: +# - frontend +# - backend ### Kibana Container ####################################### - kibana: - build: ./kibana - ports: - - "${KIBANA_HTTP_PORT}:5601" - depends_on: - - elasticsearch - networks: - - frontend - - backend +# kibana: +# build: ./kibana +# ports: +# - "${KIBANA_HTTP_PORT}:5601" +# depends_on: +# - elasticsearch +# networks: +# - frontend +# - backend ### Certbot Container ################################## - certbot: - build: - context: ./certbot - volumes: - - ./data/certbot/certs/:/var/certs - - ./certbot/letsencrypt/:/var/www/letsencrypt - environment: - - CN="fake.domain.com" - - EMAIL="fake.email@gmail.com" - networks: - - frontend +# certbot: +# build: +# context: ./certbot +# volumes: +# - ./data/certbot/certs/:/var/certs +# - ./certbot/letsencrypt/:/var/www/letsencrypt +# environment: +# - CN="fake.domain.com" +# - EMAIL="fake.email@gmail.com" +# networks: +# - frontend ### Mailhog Container ######################################### - mailhog: - build: ./mailhog - ports: - - "1025:1025" - - "8025:8025" - networks: - - frontend - - backend +# mailhog: +# build: ./mailhog +# ports: +# - "1025:1025" +# - "8025:8025" +# networks: +# - frontend +# - backend ### Selenium Container ######################################## - selenium: - build: ./selenium - ports: - - "${SELENIUM_PORT}:4444" - volumes: - - /dev/shm:/dev/shm - networks: - - frontend +# selenium: +# build: ./selenium +# ports: +# - "${SELENIUM_PORT}:4444" +# volumes: +# - /dev/shm:/dev/shm +# networks: +# - frontend ### Varnish Proxy 1 ########################################## - proxy: - build: ./varnish - expose: - - ${VARNISH_PORT} - environment: - - VARNISH_CONFIG=${VARNISH_CONFIG} - - CACHE_SIZE=${VARNISH_PROXY1_CACHE_SIZE} - - VARNISHD_PARAMS=${VARNISHD_PARAMS} - - VARNISH_PORT=${VARNISH_PORT} - - BACKEND_HOST=${VARNISH_PROXY1_BACKEND_HOST} - - BACKEND_PORT=${VARNISH_BACKEND_PORT} - - VARNISH_SERVER=${VARNISH_PROXY1_SERVER} - links: - - workspace - networks: - - frontend +# proxy: +# build: ./varnish +# expose: +# - ${VARNISH_PORT} +# environment: +# - VARNISH_CONFIG=${VARNISH_CONFIG} +# - CACHE_SIZE=${VARNISH_PROXY1_CACHE_SIZE} +# - VARNISHD_PARAMS=${VARNISHD_PARAMS} +# - VARNISH_PORT=${VARNISH_PORT} +# - BACKEND_HOST=${VARNISH_PROXY1_BACKEND_HOST} +# - BACKEND_PORT=${VARNISH_BACKEND_PORT} +# - VARNISH_SERVER=${VARNISH_PROXY1_SERVER} +# links: +# - workspace +# networks: +# - frontend ### Varnish Proxy 2 ########################################## - proxy2: - build: ./varnish - expose: - - ${VARNISH_PORT} - environment: - - VARNISH_CONFIG=${VARNISH_CONFIG} - - CACHE_SIZE=${VARNISH_PROXY2_CACHE_SIZE} - - VARNISHD_PARAMS=${VARNISHD_PARAMS} - - VARNISH_PORT=${VARNISH_PORT} - - BACKEND_HOST=${VARNISH_PROXY2_BACKEND_HOST} - - BACKEND_PORT=${VARNISH_BACKEND_PORT} - - VARNISH_SERVER=${VARNISH_PROXY2_SERVER} - links: - - workspace - networks: - - frontend +# proxy2: +# build: ./varnish +# expose: +# - ${VARNISH_PORT} +# environment: +# - VARNISH_CONFIG=${VARNISH_CONFIG} +# - CACHE_SIZE=${VARNISH_PROXY2_CACHE_SIZE} +# - VARNISHD_PARAMS=${VARNISHD_PARAMS} +# - VARNISH_PORT=${VARNISH_PORT} +# - BACKEND_HOST=${VARNISH_PROXY2_BACKEND_HOST} +# - BACKEND_PORT=${VARNISH_BACKEND_PORT} +# - VARNISH_SERVER=${VARNISH_PROXY2_SERVER} +# links: +# - workspace +# networks: +# - frontend ### Balancer Haproxy ########################################## - balancer: - build: ./haproxy - ports: - - "${HAPROXY_HOST_HTTP_PORT}:8085" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - links: - - proxy - - proxy2 +# balancer: +# build: ./haproxy +# ports: +# - "${HAPROXY_HOST_HTTP_PORT}:8085" +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock +# links: +# - proxy +# - proxy2 ### Jenkins ################################################### - jenkins: - build: ./jenkins - environment: - JAVA_OPTS: "-Djava.awt.headless=true" - ports: - - "${JENKINS_HOST_SLAVE_AGENT_PORT}:50000" - - "${JENKINS_HOST_HTTP_PORT}:8080" - privileged: true - volumes: - - ${JENKINS_HOME}:/var/jenkins_home - - /var/run/docker.sock:/var/run/docker.sock - networks: - - frontend - - backend +# jenkins: +# build: ./jenkins +# environment: +# JAVA_OPTS: "-Djava.awt.headless=true" +# ports: +# - "${JENKINS_HOST_SLAVE_AGENT_PORT}:50000" +# - "${JENKINS_HOST_HTTP_PORT}:8080" +# privileged: true +# volumes: +# - ${JENKINS_HOME}:/var/jenkins_home +# - /var/run/docker.sock:/var/run/docker.sock +# networks: +# - frontend +# - backend ### Laravel Echo Server ####################################### - laravel-echo-server: - build: - context: ./laravel-echo-server - volumes: - - ./laravel-echo-server/laravel-echo-server.json:/app/laravel-echo-server.json:ro - ports: - - "${LARAVEL_ECHO_SERVER_PORT}:6001" - links: - - redis - networks: - - frontend - - backend + +# laravel-echo-server: +# build: +# context: ./laravel-echo-server +# volumes: +# - ./laravel-echo-server/laravel-echo-server.json:/app/laravel-echo-server.json:ro +# ports: +# - "${LARAVEL_ECHO_SERVER_PORT}:6001" +# links: +# - redis +# networks: +# - frontend +# - backend ### Networks Setup ############################################ From 5eae7f30062c3d02398e313ec3321346274a2954 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:23:32 -0400 Subject: [PATCH 058/126] organizing sync file --- docker-compose-dev.yml => docker-compose.sync.yml | 0 docker-sync.yml | 3 +++ 2 files changed, 3 insertions(+) rename docker-compose-dev.yml => docker-compose.sync.yml (100%) diff --git a/docker-compose-dev.yml b/docker-compose.sync.yml similarity index 100% rename from docker-compose-dev.yml rename to docker-compose.sync.yml diff --git a/docker-sync.yml b/docker-sync.yml index d497a56..77a2f62 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -4,7 +4,10 @@ options: verbose: true syncs: applications-host-sync: # name of the sync volume + compose-dev-file-path: 'docker-compose.sync.yml' # compose override file for sync + src: '${APPLICATION}' # host source directory sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) sync_strategy: 'native_osx' # for windows use 'unison' for linux docker-sync is not necessary + sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories From 5ea7b98db86b865a5d0d7ddc1417b78b82a99e33 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:40:05 -0400 Subject: [PATCH 059/126] added bash script --- laradock.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 laradock.sh diff --git a/laradock.sh b/laradock.sh new file mode 100644 index 0000000..e69de29 From e9a01c017414cf2737d44a731d0cacb46a3ff040 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:40:25 -0400 Subject: [PATCH 060/126] modified bash script --- laradock.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) mode change 100644 => 100755 laradock.sh diff --git a/laradock.sh b/laradock.sh old mode 100644 new mode 100755 index e69de29..a14d030 --- a/laradock.sh +++ b/laradock.sh @@ -0,0 +1,17 @@ +#!/bin/bash +if [[ $# -eq 0 ]] ; then + echo "Missing arguments. Please specify 'up' or 'down'."; + exit 1 +fi + +if [[ $1 -eq "up" ]] ; then + echo "Initializing Docker Sync"; + docker-sync start; + echo "Initializing Docker Compose"; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml -d nginx mysql; +else + echo "Stopping Docker Compose"; + docker-compose down; + echo "Stopping Docker Sync"; + docker-sync start; +fi From 0d5080d6bbe419e739ff73b751fb7fadcd6e3cf9 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:41:57 -0400 Subject: [PATCH 061/126] fixed typo --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index a14d030..39eab13 100755 --- a/laradock.sh +++ b/laradock.sh @@ -8,7 +8,7 @@ if [[ $1 -eq "up" ]] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml -d nginx mysql; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d nginx mysql; else echo "Stopping Docker Compose"; docker-compose down; From c17abbea6e74d01f180910abbda55aa490dac542 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:44:09 -0400 Subject: [PATCH 062/126] stopping docker sync --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index 39eab13..2f03b62 100755 --- a/laradock.sh +++ b/laradock.sh @@ -13,5 +13,5 @@ else echo "Stopping Docker Compose"; docker-compose down; echo "Stopping Docker Sync"; - docker-sync start; + docker-sync stop; fi From 56ca814ebb507d79a7f74e50681149bcb82fd9ad Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:46:52 -0400 Subject: [PATCH 063/126] comparing bash strings correctly --- laradock.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/laradock.sh b/laradock.sh index 2f03b62..64f2f3a 100755 --- a/laradock.sh +++ b/laradock.sh @@ -4,14 +4,16 @@ if [[ $# -eq 0 ]] ; then exit 1 fi -if [[ $1 -eq "up" ]] ; then +if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d nginx mysql; -else +elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; echo "Stopping Docker Sync"; docker-sync stop; +else + echo "Invalid arguments. Use 'up' or 'down'"; fi From a38794ebccf23ed6c7fdabfc4465761ab278f93c Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:53:56 -0400 Subject: [PATCH 064/126] passing parameters --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index 64f2f3a..78d141f 100755 --- a/laradock.sh +++ b/laradock.sh @@ -8,7 +8,7 @@ if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d nginx mysql; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml $@; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; From 3e5d1d919a5345ea2c8fe8bfa16533ac1933becb Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 09:56:03 -0400 Subject: [PATCH 065/126] running in daemon mode --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index 78d141f..4517d5b 100755 --- a/laradock.sh +++ b/laradock.sh @@ -8,7 +8,7 @@ if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml $@; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml $@ -d; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; From 3d29c62bfbbac1e143ad6ef4276ecabf0650a75f Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 11:01:52 -0400 Subject: [PATCH 066/126] adding more commands --- laradock.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/laradock.sh b/laradock.sh index 4517d5b..126eab1 100755 --- a/laradock.sh +++ b/laradock.sh @@ -4,6 +4,8 @@ if [[ $# -eq 0 ]] ; then exit 1 fi +echo -e "Default \e[44mBlue"; + if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; @@ -14,6 +16,13 @@ elif [ "$1" == "down" ]; then docker-compose down; echo "Stopping Docker Sync"; docker-sync stop; +elif [ "$1" == "install" ]; then + echo "Installing docker-sync"; + gem install docker-sync; +elif [ "$1" == "sync" ]; then + docker-sync sync; +elif [ "$1" == "clean" ]; then + docker-sync clean; else echo "Invalid arguments. Use 'up' or 'down'"; fi From ef7f2516540a5a84c25fc973ab8ae9603e1c88ca Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 11:04:45 -0400 Subject: [PATCH 067/126] fixed command --- laradock.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/laradock.sh b/laradock.sh index 126eab1..6b2627b 100755 --- a/laradock.sh +++ b/laradock.sh @@ -4,13 +4,14 @@ if [[ $# -eq 0 ]] ; then exit 1 fi -echo -e "Default \e[44mBlue"; +echo -e '\E[37;44m'"\033[1mContact List\033[0m"; + if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml $@ -d; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml -d $@; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; From 988bbf7bdef88cc5f701c753a32da9c1ff99a1cd Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 11:05:16 -0400 Subject: [PATCH 068/126] putting up arg --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index 6b2627b..14f7bdc 100755 --- a/laradock.sh +++ b/laradock.sh @@ -11,7 +11,7 @@ if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml -d $@; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d $@; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; From 855e2a47b53c5bdebf8c187cf72a0c4c5861b9ec Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 11:08:01 -0400 Subject: [PATCH 069/126] passing only the second argument and onward --- laradock.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laradock.sh b/laradock.sh index 14f7bdc..da267a5 100755 --- a/laradock.sh +++ b/laradock.sh @@ -11,7 +11,7 @@ if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d $@; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@:2}; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; From 0c1b6ba9bfe6a8a2a2a3bac82f07c63b6a4a56fc Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 11:13:50 -0400 Subject: [PATCH 070/126] improving script --- laradock.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/laradock.sh b/laradock.sh index da267a5..9c9ea93 100755 --- a/laradock.sh +++ b/laradock.sh @@ -4,14 +4,12 @@ if [[ $# -eq 0 ]] ; then exit 1 fi -echo -e '\E[37;44m'"\033[1mContact List\033[0m"; - - if [ "$1" == "up" ] ; then echo "Initializing Docker Sync"; docker-sync start; echo "Initializing Docker Compose"; - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@:2}; + shift; # removing first argument + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; elif [ "$1" == "down" ]; then echo "Stopping Docker Compose"; docker-compose down; @@ -25,5 +23,5 @@ elif [ "$1" == "sync" ]; then elif [ "$1" == "clean" ]; then docker-sync clean; else - echo "Invalid arguments. Use 'up' or 'down'"; + echo "Invalid argument. Use 'up','down','install','sync' or 'clean' "; fi From 407fb7a395228b78ed51ab7893728cdda20ce83a Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 12:00:35 -0400 Subject: [PATCH 071/126] updaeted commmand --- laradock.sh => sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename laradock.sh => sync.sh (90%) diff --git a/laradock.sh b/sync.sh similarity index 90% rename from laradock.sh rename to sync.sh index 9c9ea93..c88a600 100755 --- a/laradock.sh +++ b/sync.sh @@ -5,7 +5,7 @@ if [[ $# -eq 0 ]] ; then fi if [ "$1" == "up" ] ; then - echo "Initializing Docker Sync"; + echo "Initializing Docker Sync (may take several minutes the first time)"; docker-sync start; echo "Initializing Docker Compose"; shift; # removing first argument From abae2dc09ecfa191a8b13330d3138f95996b6d82 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 12:00:44 -0400 Subject: [PATCH 072/126] updated command --- sync.sh | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/sync.sh b/sync.sh index c88a600..c452eb1 100755 --- a/sync.sh +++ b/sync.sh @@ -1,27 +1,39 @@ #!/bin/bash if [[ $# -eq 0 ]] ; then - echo "Missing arguments. Please specify 'up' or 'down'."; + printf "Available commands:\n"; + printf " install\t\t Installs docker-sync gem on the host machine.\n"; + printf " up \t Starts docker-sync and runs docker compose.\n"; + printf " down \t\t Stops containers and docker-sync.\n"; + printf " trigger \t\t Manually triggers the synchronization of files.\n"; + printf " clean \t\t Removes all synched files from docker-sync container.\n"; exit 1 fi if [ "$1" == "up" ] ; then - echo "Initializing Docker Sync (may take several minutes the first time)"; + printf "Initializing Docker Sync (may take several minutes the first time)"; docker-sync start; - echo "Initializing Docker Compose"; + printf "Initializing Docker Compose"; shift; # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; + elif [ "$1" == "down" ]; then - echo "Stopping Docker Compose"; + printf "Stopping Docker Compose"; docker-compose down; - echo "Stopping Docker Sync"; + printf "Stopping Docker Sync"; docker-sync stop; + elif [ "$1" == "install" ]; then - echo "Installing docker-sync"; + printf "Installing docker-sync"; gem install docker-sync; -elif [ "$1" == "sync" ]; then + +elif [ "$1" == "trigger" ]; then + printf "Manually triggering sync between host and docker-sync container."; docker-sync sync; + elif [ "$1" == "clean" ]; then + printf "Removing and cleaning up files from the docker-sync container."; docker-sync clean; + else - echo "Invalid argument. Use 'up','down','install','sync' or 'clean' "; + printf "Invalid argument. Use 'up','down','install','trigger' or 'clean' "; fi From 2acc9f5d6fe3d4d80d2a3f614df93c13e2028e72 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 12:36:02 -0400 Subject: [PATCH 073/126] cleaning up files --- docker-compose.yml | 744 ++++++++++++++++++++++----------------------- docker-sync.yml | 6 +- 2 files changed, 375 insertions(+), 375 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 94926dd..4dcc108 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -130,64 +130,64 @@ services: ### Blackfire Container ################################# -# blackfire: -# image: blackfire/blackfire -# environment: -# - BLACKFIRE_SERVER_ID=${BLACKFIRE_SERVER_ID} -# - BLACKFIRE_SERVER_TOKEN=${BLACKFIRE_SERVER_TOKEN} -# depends_on: -# - php-fpm -# networks: -# - backend + blackfire: + image: blackfire/blackfire + environment: + - BLACKFIRE_SERVER_ID=${BLACKFIRE_SERVER_ID} + - BLACKFIRE_SERVER_TOKEN=${BLACKFIRE_SERVER_TOKEN} + depends_on: + - php-fpm + networks: + - backend ### Apache Server Container ################################# -# apache2: -# build: -# context: ./apache2 -# args: -# - PHP_SOCKET=${PHP_SOCKET} -# volumes_from: -# - applications -# volumes: -# - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 -# - ${APACHE_SITES_PATH}:/etc/apache2/sites-available -# ports: -# - "${APACHE_HOST_HTTP_PORT}:80" -# - "${APACHE_HOST_HTTPS_PORT}:443" -# depends_on: -# - php-fpm -# networks: -# - frontend -# - backend + apache2: + build: + context: ./apache2 + args: + - PHP_SOCKET=${PHP_SOCKET} + volumes_from: + - applications + volumes: + - ${APACHE_HOST_LOG_PATH}:/var/log/apache2 + - ${APACHE_SITES_PATH}:/etc/apache2/sites-available + ports: + - "${APACHE_HOST_HTTP_PORT}:80" + - "${APACHE_HOST_HTTPS_PORT}:443" + depends_on: + - php-fpm + networks: + - frontend + - backend ### HHVM Container ########################################## -# hhvm: -# build: ./hhvm -# volumes_from: -# - applications -# expose: -# - "9000" -# depends_on: -# - workspace -# networks: -# - frontend -# - backend + hhvm: + build: ./hhvm + volumes_from: + - applications + expose: + - "9000" + depends_on: + - workspace + networks: + - frontend + - backend ### Minio Container ######################################### -# minio: -# build: ./minio -# volumes: -# - minio:/export -# ports: -# - "${MINIO_PORT}:9000" -# environment: -# - MINIO_ACCESS_KEY=access -# - MINIO_SECRET_KEY=secretkey -# networks: -# - frontend + minio: + build: ./minio + volumes: + - minio:/export + ports: + - "${MINIO_PORT}:9000" + environment: + - MINIO_ACCESS_KEY=access + - MINIO_SECRET_KEY=secretkey + networks: + - frontend ### MySQL Container ######################################### @@ -210,120 +210,120 @@ services: ### Percona Container ######################################### -# percona: -# build: -# context: ./percona -# environment: -# - MYSQL_DATABASE=${PERCONA_DATABASE} -# - MYSQL_USER=${PERCONA_USER} -# - MYSQL_PASSWORD=${PERCONA_PASSWORD} -# - MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD} -# volumes: -# - ${DATA_SAVE_PATH}/percona:/var/lib/mysql -# - ${PERCONA_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d -# ports: -# - "${PERCONA_PORT}:3306" -# networks: -# - backend + percona: + build: + context: ./percona + environment: + - MYSQL_DATABASE=${PERCONA_DATABASE} + - MYSQL_USER=${PERCONA_USER} + - MYSQL_PASSWORD=${PERCONA_PASSWORD} + - MYSQL_ROOT_PASSWORD=${PERCONA_ROOT_PASSWORD} + volumes: + - ${DATA_SAVE_PATH}/percona:/var/lib/mysql + - ${PERCONA_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d + ports: + - "${PERCONA_PORT}:3306" + networks: + - backend ### MSSQL Container ######################################### -# mssql: -# build: -# context: ./mssql -# environment: -# - MSSQL_DATABASE=${MSSQL_DATABASE} -# - SA_PASSWORD=${MSSQL_PASSWORD} -# - ACCEPT_EULA=Y -# volumes: -# - ${DATA_SAVE_PATH}/mssql:/var/opt/mssql -# ports: -# - "${MSSQL_PORT}:1433" -# networks: -# - backend + mssql: + build: + context: ./mssql + environment: + - MSSQL_DATABASE=${MSSQL_DATABASE} + - SA_PASSWORD=${MSSQL_PASSWORD} + - ACCEPT_EULA=Y + volumes: + - ${DATA_SAVE_PATH}/mssql:/var/opt/mssql + ports: + - "${MSSQL_PORT}:1433" + networks: + - backend ### MariaDB Container ####################################### -# mariadb: -# build: ./mariadb -# volumes: -# - ${DATA_SAVE_PATH}/mariadb:/var/lib/mysql -# - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d -# ports: -# - "${MARIADB_PORT}:3306" -# environment: -# - MYSQL_DATABASE=${MARIADB_DATABASE} -# - MYSQL_USER=${MARIADB_USER} -# - MYSQL_PASSWORD=${MARIADB_PASSWORD} -# - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD} -# networks: -# - backend + mariadb: + build: ./mariadb + volumes: + - ${DATA_SAVE_PATH}/mariadb:/var/lib/mysql + - ${MARIADB_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d + ports: + - "${MARIADB_PORT}:3306" + environment: + - MYSQL_DATABASE=${MARIADB_DATABASE} + - MYSQL_USER=${MARIADB_USER} + - MYSQL_PASSWORD=${MARIADB_PASSWORD} + - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD} + networks: + - backend ### PostgreSQL Container #################################### -# postgres: -# build: ./postgres -# volumes: -# - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data -# ports: -# - "${POSTGRES_PORT}:5432" -# environment: -# - POSTGRES_DB=${POSTGRES_DB} -# - POSTGRES_USER=${POSTGRES_USER} -# - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -# networks: -# - backend + postgres: + build: ./postgres + volumes: + - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data + ports: + - "${POSTGRES_PORT}:5432" + environment: + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + networks: + - backend ### PostgreSQL PostGis Container ############################ -# postgres-postgis: -# build: ./postgres-postgis -# volumes: -# - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data -# ports: -# - "${POSTGRES_PORT}:5432" -# environment: -# - POSTGRES_DB=${POSTGRES_DB} -# - POSTGRES_USER=${POSTGRES_USER} -# - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -# networks: -# - backend + postgres-postgis: + build: ./postgres-postgis + volumes: + - ${DATA_SAVE_PATH}/postgres:/var/lib/postgresql/data + ports: + - "${POSTGRES_PORT}:5432" + environment: + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + networks: + - backend ### Neo4j Container ######################################### -# neo4j: -# build: ./neo4j -# ports: -# - "7474:7474" -# - "1337:1337" -# environment: -# - NEO4J_AUTH=default:secret -# volumes: -# - ${DATA_SAVE_PATH}/neo4j:/var/lib/neo4j/data -# networks: -# - backend + neo4j: + build: ./neo4j + ports: + - "7474:7474" + - "1337:1337" + environment: + - NEO4J_AUTH=default:secret + volumes: + - ${DATA_SAVE_PATH}/neo4j:/var/lib/neo4j/data + networks: + - backend ### MongoDB Container ####################################### -# mongo: -# build: ./mongo -# ports: -# - "${MONGODB_PORT}:27017" -# volumes: -# - ${DATA_SAVE_PATH}/mongo:/data/db -# networks: -# - backend + mongo: + build: ./mongo + ports: + - "${MONGODB_PORT}:27017" + volumes: + - ${DATA_SAVE_PATH}/mongo:/data/db + networks: + - backend ### RethinkDB Container ####################################### -# rethinkdb: -# build: ./rethinkdb -# ports: -# - "${RETHINKDB_PORT}:8080" -# volumes: -# - ${DATA_SAVE_PATH}/rethinkdb:/data/rethinkdb_data -# networks: -# - backend + rethinkdb: + build: ./rethinkdb + ports: + - "${RETHINKDB_PORT}:8080" + volumes: + - ${DATA_SAVE_PATH}/rethinkdb:/data/rethinkdb_data + networks: + - backend ### Redis Container ######################################### @@ -338,291 +338,291 @@ services: ### Aerospike c Container ################################### -# aerospike: -# build: ./aerospike -# volumes_from: -# - workspace -# volumes: -# - ${DATA_SAVE_PATH}/aerospike:/opt/aerospike/data -# ports: -# - "${AEROSPIKE_SERVICE_PORT}:3000" -# - "${AEROSPIKE_FABRIC_PORT}:3001" -# - "${AEROSPIKE_HEARTBEAT_PORT}:3002" -# - "${AEROSPIKE_INFO_PORT}:3003" -# networks: -# - backend + aerospike: + build: ./aerospike + volumes_from: + - workspace + volumes: + - ${DATA_SAVE_PATH}/aerospike:/opt/aerospike/data + ports: + - "${AEROSPIKE_SERVICE_PORT}:3000" + - "${AEROSPIKE_FABRIC_PORT}:3001" + - "${AEROSPIKE_HEARTBEAT_PORT}:3002" + - "${AEROSPIKE_INFO_PORT}:3003" + networks: + - backend ### Memcached Container ##################################### -# memcached: -# build: ./memcached -# volumes: -# - ${DATA_SAVE_PATH}/memcached:/var/lib/memcached -# ports: -# - "${MEMCACHED_HOST_PORT}:11211" -# depends_on: -# - php-fpm -# networks: -# - backend + memcached: + build: ./memcached + volumes: + - ${DATA_SAVE_PATH}/memcached:/var/lib/memcached + ports: + - "${MEMCACHED_HOST_PORT}:11211" + depends_on: + - php-fpm + networks: + - backend ### Beanstalkd Container #################################### -# beanstalkd: -# build: ./beanstalkd -# ports: -# - "${BEANSTALKD_HOST_PORT}:11300" -# privileged: true -# depends_on: -# - php-fpm -# networks: -# - backend + beanstalkd: + build: ./beanstalkd + ports: + - "${BEANSTALKD_HOST_PORT}:11300" + privileged: true + depends_on: + - php-fpm + networks: + - backend ### RabbitMQ Container ###################################### -# rabbitmq: -# build: ./rabbitmq -# ports: -# - "${RABBITMQ_NODE_HOST_PORT}:5672" -# - "${RABBITMQ_MANAGEMENT_HTTP_HOST_PORT}:15672" -# - "${RABBITMQ_MANAGEMENT_HTTPS_HOST_PORT}:15671" -# privileged: true -# environment: -# - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} -# - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} -# depends_on: -# - php-fpm -# networks: -# - backend + rabbitmq: + build: ./rabbitmq + ports: + - "${RABBITMQ_NODE_HOST_PORT}:5672" + - "${RABBITMQ_MANAGEMENT_HTTP_HOST_PORT}:15672" + - "${RABBITMQ_MANAGEMENT_HTTPS_HOST_PORT}:15671" + privileged: true + environment: + - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} + - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} + depends_on: + - php-fpm + networks: + - backend ### Beanstalkd Console Container ############################ -# beanstalkd-console: -# build: ./beanstalkd-console -# ports: -# - "2080:2080" -# depends_on: -# - beanstalkd -# networks: -# - backend + beanstalkd-console: + build: ./beanstalkd-console + ports: + - "2080:2080" + depends_on: + - beanstalkd + networks: + - backend ### Caddy Server Container ################################## -# caddy: -# build: ./caddy -# volumes_from: -# - applications -# volumes: -# - ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile -# - ${CADDY_HOST_LOG_PATH}:/var/log/caddy -# - ${DATA_SAVE_PATH}:/root/.caddy -# ports: -# - "${CADDY_HOST_HTTP_PORT}:80" -# - "${CADDY_HOST_HTTPS_PORT}:443" -# depends_on: -# - php-fpm -# networks: -# - frontend -# - backend + caddy: + build: ./caddy + volumes_from: + - applications + volumes: + - ${CADDY_CUSTOM_CADDYFILE}:/etc/Caddyfile + - ${CADDY_HOST_LOG_PATH}:/var/log/caddy + - ${DATA_SAVE_PATH}:/root/.caddy + ports: + - "${CADDY_HOST_HTTP_PORT}:80" + - "${CADDY_HOST_HTTPS_PORT}:443" + depends_on: + - php-fpm + networks: + - frontend + - backend ### phpMyAdmin Container #################################### -# phpmyadmin: -# build: ./phpmyadmin -# environment: -# - PMA_ARBITRARY=1 -# - MYSQL_USER=${PMA_USER} -# - MYSQL_PASSWORD=${PMA_PASSWORD} -# - MYSQL_ROOT_PASSWORD=${PMA_ROOT_PASSWORD} -# ports: -# - "${PMA_PORT}:80" -# depends_on: -# - "${PMA_DB_ENGINE}" -# networks: -# - frontend -# - backend + phpmyadmin: + build: ./phpmyadmin + environment: + - PMA_ARBITRARY=1 + - MYSQL_USER=${PMA_USER} + - MYSQL_PASSWORD=${PMA_PASSWORD} + - MYSQL_ROOT_PASSWORD=${PMA_ROOT_PASSWORD} + ports: + - "${PMA_PORT}:80" + depends_on: + - "${PMA_DB_ENGINE}" + networks: + - frontend + - backend ### Adminer Container #################################### -# adminer: -# build: -# context: ./adminer -# args: -# - INSTALL_MSSQL=${ADM_INSTALL_MSSQL} -# ports: -# - "${ADM_PORT}:8080" -# depends_on: -# - php-fpm -# networks: -# - frontend -# - backend + adminer: + build: + context: ./adminer + args: + - INSTALL_MSSQL=${ADM_INSTALL_MSSQL} + ports: + - "${ADM_PORT}:8080" + depends_on: + - php-fpm + networks: + - frontend + - backend ### pgAdmin Container ####################################### -# pgadmin: -# build: ./pgadmin -# ports: -# - "5050:5050" -# depends_on: -# - postgres -# networks: -# - frontend -# - backend + pgadmin: + build: ./pgadmin + ports: + - "5050:5050" + depends_on: + - postgres + networks: + - frontend + - backend ### ElasticSearch Container ################################# -# elasticsearch: -# build: ./elasticsearch -# volumes: -# - elasticsearch-data:/usr/share/elasticsearch/data -# - elasticsearch-plugins:/usr/share/elasticsearch/plugins -# environment: -# - cluster.name=laradock-cluster -# - bootstrap.memory_lock=true -# - "ES_JAVA_OPTS=-Xms256m -Xmx256m" -# ulimits: -# memlock: -# soft: -1 -# hard: -1 -# mem_limit: 512m -# ports: -# - "${ELASTICSEARCH_HOST_HTTP_PORT}:9200" -# - "${ELASTICSEARCH_HOST_TRANSPORT_PORT}:9300" -# depends_on: -# - php-fpm -# networks: -# - frontend -# - backend + elasticsearch: + build: ./elasticsearch + volumes: + - elasticsearch-data:/usr/share/elasticsearch/data + - elasticsearch-plugins:/usr/share/elasticsearch/plugins + environment: + - cluster.name=laradock-cluster + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms256m -Xmx256m" + ulimits: + memlock: + soft: -1 + hard: -1 + mem_limit: 512m + ports: + - "${ELASTICSEARCH_HOST_HTTP_PORT}:9200" + - "${ELASTICSEARCH_HOST_TRANSPORT_PORT}:9300" + depends_on: + - php-fpm + networks: + - frontend + - backend ### Kibana Container ####################################### -# kibana: -# build: ./kibana -# ports: -# - "${KIBANA_HTTP_PORT}:5601" -# depends_on: -# - elasticsearch -# networks: -# - frontend -# - backend + kibana: + build: ./kibana + ports: + - "${KIBANA_HTTP_PORT}:5601" + depends_on: + - elasticsearch + networks: + - frontend + - backend ### Certbot Container ################################## -# certbot: -# build: -# context: ./certbot -# volumes: -# - ./data/certbot/certs/:/var/certs -# - ./certbot/letsencrypt/:/var/www/letsencrypt -# environment: -# - CN="fake.domain.com" -# - EMAIL="fake.email@gmail.com" -# networks: -# - frontend + certbot: + build: + context: ./certbot + volumes: + - ./data/certbot/certs/:/var/certs + - ./certbot/letsencrypt/:/var/www/letsencrypt + environment: + - CN="fake.domain.com" + - EMAIL="fake.email@gmail.com" + networks: + - frontend ### Mailhog Container ######################################### -# mailhog: -# build: ./mailhog -# ports: -# - "1025:1025" -# - "8025:8025" -# networks: -# - frontend -# - backend + mailhog: + build: ./mailhog + ports: + - "1025:1025" + - "8025:8025" + networks: + - frontend + - backend ### Selenium Container ######################################## -# selenium: -# build: ./selenium -# ports: -# - "${SELENIUM_PORT}:4444" -# volumes: -# - /dev/shm:/dev/shm -# networks: -# - frontend + selenium: + build: ./selenium + ports: + - "${SELENIUM_PORT}:4444" + volumes: + - /dev/shm:/dev/shm + networks: + - frontend ### Varnish Proxy 1 ########################################## -# proxy: -# build: ./varnish -# expose: -# - ${VARNISH_PORT} -# environment: -# - VARNISH_CONFIG=${VARNISH_CONFIG} -# - CACHE_SIZE=${VARNISH_PROXY1_CACHE_SIZE} -# - VARNISHD_PARAMS=${VARNISHD_PARAMS} -# - VARNISH_PORT=${VARNISH_PORT} -# - BACKEND_HOST=${VARNISH_PROXY1_BACKEND_HOST} -# - BACKEND_PORT=${VARNISH_BACKEND_PORT} -# - VARNISH_SERVER=${VARNISH_PROXY1_SERVER} -# links: -# - workspace -# networks: -# - frontend + proxy: + build: ./varnish + expose: + - ${VARNISH_PORT} + environment: + - VARNISH_CONFIG=${VARNISH_CONFIG} + - CACHE_SIZE=${VARNISH_PROXY1_CACHE_SIZE} + - VARNISHD_PARAMS=${VARNISHD_PARAMS} + - VARNISH_PORT=${VARNISH_PORT} + - BACKEND_HOST=${VARNISH_PROXY1_BACKEND_HOST} + - BACKEND_PORT=${VARNISH_BACKEND_PORT} + - VARNISH_SERVER=${VARNISH_PROXY1_SERVER} + links: + - workspace + networks: + - frontend ### Varnish Proxy 2 ########################################## -# proxy2: -# build: ./varnish -# expose: -# - ${VARNISH_PORT} -# environment: -# - VARNISH_CONFIG=${VARNISH_CONFIG} -# - CACHE_SIZE=${VARNISH_PROXY2_CACHE_SIZE} -# - VARNISHD_PARAMS=${VARNISHD_PARAMS} -# - VARNISH_PORT=${VARNISH_PORT} -# - BACKEND_HOST=${VARNISH_PROXY2_BACKEND_HOST} -# - BACKEND_PORT=${VARNISH_BACKEND_PORT} -# - VARNISH_SERVER=${VARNISH_PROXY2_SERVER} -# links: -# - workspace -# networks: -# - frontend + proxy2: + build: ./varnish + expose: + - ${VARNISH_PORT} + environment: + - VARNISH_CONFIG=${VARNISH_CONFIG} + - CACHE_SIZE=${VARNISH_PROXY2_CACHE_SIZE} + - VARNISHD_PARAMS=${VARNISHD_PARAMS} + - VARNISH_PORT=${VARNISH_PORT} + - BACKEND_HOST=${VARNISH_PROXY2_BACKEND_HOST} + - BACKEND_PORT=${VARNISH_BACKEND_PORT} + - VARNISH_SERVER=${VARNISH_PROXY2_SERVER} + links: + - workspace + networks: + - frontend ### Balancer Haproxy ########################################## -# balancer: -# build: ./haproxy -# ports: -# - "${HAPROXY_HOST_HTTP_PORT}:8085" -# volumes: -# - /var/run/docker.sock:/var/run/docker.sock -# links: -# - proxy -# - proxy2 + balancer: + build: ./haproxy + ports: + - "${HAPROXY_HOST_HTTP_PORT}:8085" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + links: + - proxy + - proxy2 ### Jenkins ################################################### -# jenkins: -# build: ./jenkins -# environment: -# JAVA_OPTS: "-Djava.awt.headless=true" -# ports: -# - "${JENKINS_HOST_SLAVE_AGENT_PORT}:50000" -# - "${JENKINS_HOST_HTTP_PORT}:8080" -# privileged: true -# volumes: -# - ${JENKINS_HOME}:/var/jenkins_home -# - /var/run/docker.sock:/var/run/docker.sock -# networks: -# - frontend -# - backend + jenkins: + build: ./jenkins + environment: + JAVA_OPTS: "-Djava.awt.headless=true" + ports: + - "${JENKINS_HOST_SLAVE_AGENT_PORT}:50000" + - "${JENKINS_HOST_HTTP_PORT}:8080" + privileged: true + volumes: + - ${JENKINS_HOME}:/var/jenkins_home + - /var/run/docker.sock:/var/run/docker.sock + networks: + - frontend + - backend ### Laravel Echo Server ####################################### -# laravel-echo-server: -# build: -# context: ./laravel-echo-server -# volumes: -# - ./laravel-echo-server/laravel-echo-server.json:/app/laravel-echo-server.json:ro -# ports: -# - "${LARAVEL_ECHO_SERVER_PORT}:6001" -# links: -# - redis -# networks: -# - frontend -# - backend + laravel-echo-server: + build: + context: ./laravel-echo-server + volumes: + - ./laravel-echo-server/laravel-echo-server.json:/app/laravel-echo-server.json:ro + ports: + - "${LARAVEL_ECHO_SERVER_PORT}:6001" + links: + - redis + networks: + - frontend + - backend ### Networks Setup ############################################ diff --git a/docker-sync.yml b/docker-sync.yml index 77a2f62..1da12b7 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -4,10 +4,10 @@ options: verbose: true syncs: applications-host-sync: # name of the sync volume - compose-dev-file-path: 'docker-compose.sync.yml' # compose override file for sync + compose-dev-file-path: 'docker-compose.sync.yml' # docker-compose override file src: '${APPLICATION}' # host source directory sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) - sync_strategy: 'native_osx' # for windows use 'unison' for linux docker-sync is not necessary + sync_strategy: 'native_osx' # for windows use 'unison', for linux docker-sync is not necessary - sync_excludes: ['laradock', '.ignored_dot_folder'] # ignored directories + sync_excludes: ['laradock', 'ignored_folder_example'] # ignored directories From 3bf572b7a4b11b095406befcdf0282427f5e572c Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 13:52:23 -0400 Subject: [PATCH 074/126] added colors --- docker-sync.yml | 2 +- env-example | 10 ++++++++-- sync.sh | 49 +++++++++++++++++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/docker-sync.yml b/docker-sync.yml index 1da12b7..0a3b439 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -8,6 +8,6 @@ syncs: src: '${APPLICATION}' # host source directory sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) - sync_strategy: 'native_osx' # for windows use 'unison', for linux docker-sync is not necessary + sync_strategy: '${DOCKER_SYNC_STRATEGY}' # for osx use 'native_osx', for windows use 'unison' sync_excludes: ['laradock', 'ignored_folder_example'] # ignored directories diff --git a/env-example b/env-example index 23eba15..91d295c 100644 --- a/env-example +++ b/env-example @@ -255,6 +255,13 @@ CADDY_CUSTOM_CADDYFILE=./caddy/Caddyfile LARAVEL_ECHO_SERVER_PORT=6001 +### DOCKER-SYNC ################################################################################################ + +# osx: 'native_osx' (default) +# windows: 'unison' +# linux: docker-sync not required + +DOCKER_SYNC_STRATEGY=native_osx ##### TO BE CONTINUE ................................. @@ -262,8 +269,6 @@ LARAVEL_ECHO_SERVER_PORT=6001 # ......... # ......... - - ############################ # Miscellaneous ############################ @@ -281,3 +286,4 @@ PHP_IDE_CONFIG=serverName=laradock # Fix for windows users to make sure the application path works. COMPOSE_CONVERT_WINDOWS_PATHS=1 + diff --git a/sync.sh b/sync.sh index c452eb1..3cf8bf0 100755 --- a/sync.sh +++ b/sync.sh @@ -1,39 +1,60 @@ #!/bin/bash + +# prints colored text +print_style () { + + if [ "$2" == "info" ] ; then + COLOR="1;96m"; + elif [ "$2" == "success" ] ; then + COLOR="1;92m"; + elif [ "$2" == "warning" ] ; then + COLOR="1;93m"; + elif [ "$2" == "danger" ] ; then + COLOR="1;31m"; + else #white + COLOR="1;97m"; + fi + + printf "\e[$COLOR%-6s\e[m" "$1"; +} + if [[ $# -eq 0 ]] ; then - printf "Available commands:\n"; - printf " install\t\t Installs docker-sync gem on the host machine.\n"; - printf " up \t Starts docker-sync and runs docker compose.\n"; - printf " down \t\t Stops containers and docker-sync.\n"; - printf " trigger \t\t Manually triggers the synchronization of files.\n"; - printf " clean \t\t Removes all synched files from docker-sync container.\n"; + print_style "Invalid argument." 'danger'; printf " Available commands:\n"; + print_style " install" "success"; printf "\t\t Installs docker-sync gem on the host machine.\n"; + print_style " up " "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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; + print_style " clean" "warning"; printf "\t\t Removes all synched files from docker-sync container.\n"; + exit 1 fi if [ "$1" == "up" ] ; then - printf "Initializing Docker Sync (may take several minutes the first time)"; + print_style "Initializing Docker Sync\n" 'info'; + print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" 'warning'; docker-sync start; - printf "Initializing Docker Compose"; + print_style "Initializing Docker Compose\n" 'info'; shift; # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; elif [ "$1" == "down" ]; then - printf "Stopping Docker Compose"; + print_style "Stopping Docker Compose\n" 'info'; docker-compose down; - printf "Stopping Docker Sync"; + print_style "Stopping Docker Sync\n" 'info'; docker-sync stop; elif [ "$1" == "install" ]; then - printf "Installing docker-sync"; + print_style "Installing docker-sync" 'info'; gem install docker-sync; elif [ "$1" == "trigger" ]; then - printf "Manually triggering sync between host and docker-sync container."; + print_style "Manually triggering sync between host and docker-sync container.\n" 'info'; docker-sync sync; elif [ "$1" == "clean" ]; then - printf "Removing and cleaning up files from the docker-sync container."; + print_style "Removing and cleaning up files from the docker-sync container.\n" 'warning'; docker-sync clean; else - printf "Invalid argument. Use 'up','down','install','trigger' or 'clean' "; + print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'\n" 'danger'; fi From a38cecef923c453416b2ed351ea9ed957f15ac44 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:24:01 -0400 Subject: [PATCH 075/126] improving colors --- sync.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sync.sh b/sync.sh index 3cf8bf0..8e8aa69 100755 --- a/sync.sh +++ b/sync.sh @@ -2,20 +2,22 @@ # prints colored text print_style () { - if [ "$2" == "info" ] ; then - COLOR="1;96m"; + COLOR="96m"; elif [ "$2" == "success" ] ; then - COLOR="1;92m"; + COLOR="92m"; elif [ "$2" == "warning" ] ; then - COLOR="1;93m"; + COLOR="93m"; elif [ "$2" == "danger" ] ; then - COLOR="1;31m"; + COLOR="41m"; else #white - COLOR="1;97m"; + COLOR="97m"; fi - printf "\e[$COLOR%-6s\e[m" "$1"; + STARTCOLOR="\e[1;$COLOR"; + ENDCOLOR="\e[m"; + + printf "$STARTCOLOR%b$ENDCOLOR" "$1"; } if [[ $# -eq 0 ]] ; then @@ -30,7 +32,7 @@ if [[ $# -eq 0 ]] ; then fi if [ "$1" == "up" ] ; then - print_style "Initializing Docker Sync\n" 'info'; + print_style "Initializing Docker Sync\n" "info"; print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" 'warning'; docker-sync start; print_style "Initializing Docker Compose\n" 'info'; @@ -44,7 +46,7 @@ elif [ "$1" == "down" ]; then docker-sync stop; elif [ "$1" == "install" ]; then - print_style "Installing docker-sync" 'info'; + print_style "Installing docker-sync\n" 'info'; gem install docker-sync; elif [ "$1" == "trigger" ]; then @@ -56,5 +58,5 @@ elif [ "$1" == "clean" ]; then docker-sync clean; else - print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'\n" 'danger'; + print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'" 'danger'; fi From 8e20ec7617cd381cf762ee4e8938742b5816a768 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:36:15 -0400 Subject: [PATCH 076/126] improved colors --- sync.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sync.sh b/sync.sh index 8e8aa69..46b1586 100755 --- a/sync.sh +++ b/sync.sh @@ -2,6 +2,7 @@ # prints colored text print_style () { + if [ "$2" == "info" ] ; then COLOR="96m"; elif [ "$2" == "success" ] ; then @@ -21,7 +22,7 @@ print_style () { } if [[ $# -eq 0 ]] ; then - print_style "Invalid argument." 'danger'; printf " Available commands:\n"; + print_style "Invalid argument." "danger"; printf " Available commands:\n"; print_style " install" "success"; printf "\t\t Installs docker-sync gem on the host machine.\n"; print_style " up " "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"; @@ -33,30 +34,30 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; - print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" 'warning'; + print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" "warning"; docker-sync start; - print_style "Initializing Docker Compose\n" 'info'; + print_style "Initializing Docker Compose\n" "info"; shift; # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; elif [ "$1" == "down" ]; then - print_style "Stopping Docker Compose\n" 'info'; + print_style "Stopping Docker Compose\n" "info"; docker-compose down; - print_style "Stopping Docker Sync\n" 'info'; + print_style "Stopping Docker Sync\n" "info"; docker-sync stop; elif [ "$1" == "install" ]; then - print_style "Installing docker-sync\n" 'info'; + print_style "Installing docker-sync\n" "info"; gem install docker-sync; elif [ "$1" == "trigger" ]; then - print_style "Manually triggering sync between host and docker-sync container.\n" 'info'; + print_style "Manually triggering sync between host and docker-sync container.\n" "info"; docker-sync sync; elif [ "$1" == "clean" ]; then - print_style "Removing and cleaning up files from the docker-sync container.\n" 'warning'; + print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; docker-sync clean; else - print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'" 'danger'; + print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'" "danger"; fi From b0a6f2d68917f1b55467f3da94d57c75bef7140f Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:39:49 -0400 Subject: [PATCH 077/126] stopping if errors happen --- sync.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sync.sh b/sync.sh index 46b1586..bd320a7 100755 --- a/sync.sh +++ b/sync.sh @@ -35,15 +35,15 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" "warning"; - docker-sync start; - print_style "Initializing Docker Compose\n" "info"; - shift; # removing first argument + docker-sync start && + print_style "Initializing Docker Compose\n" "info" && + shift && # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; elif [ "$1" == "down" ]; then print_style "Stopping Docker Compose\n" "info"; - docker-compose down; - print_style "Stopping Docker Sync\n" "info"; + docker-compose down && + print_style "Stopping Docker Sync\n" "info" && docker-sync stop; elif [ "$1" == "install" ]; then From b7d3691c8d8eddaa5fef611ac577cef16f5249b9 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:41:35 -0400 Subject: [PATCH 078/126] resetting last change --- sync.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sync.sh b/sync.sh index bd320a7..46b1586 100755 --- a/sync.sh +++ b/sync.sh @@ -35,15 +35,15 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" "warning"; - docker-sync start && - print_style "Initializing Docker Compose\n" "info" && - shift && # removing first argument + docker-sync start; + print_style "Initializing Docker Compose\n" "info"; + shift; # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; elif [ "$1" == "down" ]; then print_style "Stopping Docker Compose\n" "info"; - docker-compose down && - print_style "Stopping Docker Sync\n" "info" && + docker-compose down; + print_style "Stopping Docker Sync\n" "info"; docker-sync stop; elif [ "$1" == "install" ]; then From 7fdda613a524d1b36f478d11036883bf5c849f3b Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:43:22 -0400 Subject: [PATCH 079/126] improving messages --- sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sync.sh b/sync.sh index 46b1586..9301041 100755 --- a/sync.sh +++ b/sync.sh @@ -34,7 +34,7 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; - print_style "(May take a long time (15min+) on the 'Looking for changes' step the first time)\n" "warning"; + print_style "May take a long time (15 min+) the first time\n" "info"; docker-sync start; print_style "Initializing Docker Compose\n" "info"; shift; # removing first argument From e26ff8bb1e040d84eeb15b40c2d0aef4342b58ea Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 14:46:00 -0400 Subject: [PATCH 080/126] improving comments --- sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sync.sh b/sync.sh index 9301041..d014e24 100755 --- a/sync.sh +++ b/sync.sh @@ -34,7 +34,7 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; - print_style "May take a long time (15 min+) the first time\n" "info"; + print_style "May take a long time (15min+) the first time\n" "info"; docker-sync start; print_style "Initializing Docker Compose\n" "info"; shift; # removing first argument From 6bed8d14f159f7b11eb084a27c1eadd67e98d8a6 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 15:46:00 -0400 Subject: [PATCH 081/126] improved messages --- sync.sh | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/sync.sh b/sync.sh index d014e24..d48eb18 100755 --- a/sync.sh +++ b/sync.sh @@ -10,32 +10,37 @@ print_style () { elif [ "$2" == "warning" ] ; then COLOR="93m"; elif [ "$2" == "danger" ] ; then - COLOR="41m"; - else #white - COLOR="97m"; + COLOR="91m"; + else #default color + COLOR="0m"; fi - STARTCOLOR="\e[1;$COLOR"; - ENDCOLOR="\e[m"; + STARTCOLOR="\e[$COLOR"; + ENDCOLOR="\e[0m"; printf "$STARTCOLOR%b$ENDCOLOR" "$1"; } -if [[ $# -eq 0 ]] ; then - print_style "Invalid argument." "danger"; printf " Available commands:\n"; +display_options () { + printf "Available options:\n"; print_style " install" "success"; printf "\t\t Installs docker-sync gem on the host machine.\n"; - print_style " up " "success"; printf "\t Starts docker-sync and runs docker compose.\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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; - print_style " clean" "warning"; printf "\t\t Removes all synched files from docker-sync container.\n"; + print_style " clean" "warning"; printf "\t\t Removes all files from the docker-sync container.\n"; +} +if [[ $# -eq 0 ]] ; then + print_style "Missing arguments.\n" "danger"; + display_options; exit 1 fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; - print_style "May take a long time (15min+) the first time\n" "info"; + print_style "May take a long time (15min+) the first run\n" "info"; docker-sync start; + print_style "Initializing Docker Compose\n" "info"; shift; # removing first argument docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; @@ -43,6 +48,7 @@ if [ "$1" == "up" ] ; then elif [ "$1" == "down" ]; then print_style "Stopping Docker Compose\n" "info"; docker-compose down; + print_style "Stopping Docker Sync\n" "info"; docker-sync stop; @@ -59,5 +65,7 @@ elif [ "$1" == "clean" ]; then docker-sync clean; else - print_style "Invalid argument. Use 'up','down','install','trigger' or 'clean'" "danger"; + print_style "Invalid arguments.\n" "danger"; + display_options; + exit 1 fi From a0f1d39ce42e6cb3f1fff618cf1c4552ffdaf3b9 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:03:33 -0400 Subject: [PATCH 082/126] added bash option --- sync.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sync.sh b/sync.sh index d48eb18..4dec67a 100755 --- a/sync.sh +++ b/sync.sh @@ -1,5 +1,19 @@ #!/bin/bash +# This shell script is an optional tool to simplify +# the installation and usage of laradock with docker-sync. + +# To run, make sure to add permissions to this file: +# chmod 755 sync.sh + +# Usage: +# Install docker-sync: ./sync.sh install +# Start workspace with nginx and mysql: ./sync.sh up nginx mysql +# Open bash inside the workspace: ./sync.sh bash +# Stop workspace: ./sync.sh down +# Force sync: ./sync.sh trigger +# Clean synced files: ./sync.sh clean + # prints colored text print_style () { @@ -26,6 +40,7 @@ display_options () { print_style " install" "success"; 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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; print_style " clean" "warning"; printf "\t\t Removes all files from the docker-sync container.\n"; } @@ -56,6 +71,9 @@ elif [ "$1" == "install" ]; then print_style "Installing docker-sync\n" "info"; gem install docker-sync; +elif [ "$1" == "bash" ]; then + docker-compose exec workspace bash; + elif [ "$1" == "trigger" ]; then print_style "Manually triggering sync between host and docker-sync container.\n" "info"; docker-sync sync; @@ -64,6 +82,7 @@ elif [ "$1" == "clean" ]; then print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; docker-sync clean; + else print_style "Invalid arguments.\n" "danger"; display_options; From a670dd91cd58a23bc20f46f24543104c83c9c3d7 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:24:49 -0400 Subject: [PATCH 083/126] adding base functions --- sync.sh => laradock.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename sync.sh => laradock.sh (94%) diff --git a/sync.sh b/laradock.sh similarity index 94% rename from sync.sh rename to laradock.sh index 4dec67a..cd57a30 100755 --- a/sync.sh +++ b/laradock.sh @@ -37,12 +37,12 @@ print_style () { display_options () { printf "Available options:\n"; - print_style " install" "success"; printf "\t\t Installs docker-sync gem on the host machine.\n"; + 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.\n"; print_style " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; - print_style " clean" "warning"; printf "\t\t Removes all files from the docker-sync container.\n"; + print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; } if [[ $# -eq 0 ]] ; then From 7b180524e3d07ea2580082e41df12df4c888a912 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:24:59 -0400 Subject: [PATCH 084/126] adding base functions --- laradock.sh | 79 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/laradock.sh b/laradock.sh index cd57a30..a682e5a 100755 --- a/laradock.sh +++ b/laradock.sh @@ -8,9 +8,9 @@ # Usage: # Install docker-sync: ./sync.sh install -# Start workspace with nginx and mysql: ./sync.sh up nginx mysql +# Start sync and services with nginx and mysql: ./sync.sh up nginx mysql # Open bash inside the workspace: ./sync.sh bash -# Stop workspace: ./sync.sh down +# Stop containers and sync: ./sync.sh down # Force sync: ./sync.sh trigger # Clean synced files: ./sync.sh clean @@ -51,40 +51,61 @@ if [[ $# -eq 0 ]] ; then exit 1 fi -if [ "$1" == "up" ] ; then - print_style "Initializing Docker Sync\n" "info"; - print_style "May take a long time (15min+) the first run\n" "info"; - docker-sync start; - - print_style "Initializing Docker Compose\n" "info"; +if [ "$1" == "sync" ] ; then shift; # removing first argument - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; + print_style "Using Docker Sync\n" "info"; -elif [ "$1" == "down" ]; then - print_style "Stopping Docker Compose\n" "info"; - docker-compose down; + if [ "$1" == "up" ] ; then + print_style "Initializing Docker Sync\n" "info"; + print_style "May take a long time (15min+) the first run\n" "info"; + docker-sync start; - print_style "Stopping Docker Sync\n" "info"; - docker-sync stop; + print_style "Initializing Docker Compose\n" "info"; + shift; # removing first argument + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; -elif [ "$1" == "install" ]; then - print_style "Installing docker-sync\n" "info"; - gem install docker-sync; + elif [ "$1" == "down" ]; then + print_style "Stopping Docker Compose\n" "info"; + docker-compose down; -elif [ "$1" == "bash" ]; then - docker-compose exec workspace bash; + print_style "Stopping Docker Sync\n" "info"; + docker-sync stop; -elif [ "$1" == "trigger" ]; then - print_style "Manually triggering sync between host and docker-sync container.\n" "info"; - docker-sync sync; - -elif [ "$1" == "clean" ]; then - print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; - docker-sync clean; + elif [ "$1" == "install" ]; then + print_style "Installing docker-sync\n" "info"; + gem install docker-sync; + elif [ "$1" == "trigger" ]; then + print_style "Manually triggering sync between host and docker-sync container.\n" "info"; + docker-sync sync; + elif [ "$1" == "clean" ]; then + print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; + docker-sync clean; + else + print_style "Invalid arguments.\n" "danger"; + display_options; + exit 1 + fi else - print_style "Invalid arguments.\n" "danger"; - display_options; - exit 1 + print_style "Not using synced files might be slow on OSX and Windows. Use 'sync' option to speed up.\n"; + + if [ "$1" == "up" ] ; then + print_style "Initializing Docker Compose\n" "info"; + shift; # removing first argument + docker-compose up -d ${@}; + + elif [ "$1" == "down" ]; then + print_style "Stopping Docker Compose\n" "info"; + docker-compose down; + + elif [ "$1" == "bash" ]; then + docker-compose exec workspace bash; + + else + print_style "Invalid arguments.\n" "danger"; + display_options; + exit 1 + fi + fi From 1d2f385586e39a2513b60bf83d7e2245c578bb6d Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:36:25 -0400 Subject: [PATCH 085/126] adding options --- laradock.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/laradock.sh b/laradock.sh index a682e5a..e0a0024 100755 --- a/laradock.sh +++ b/laradock.sh @@ -7,12 +7,12 @@ # chmod 755 sync.sh # Usage: -# Install docker-sync: ./sync.sh install -# Start sync and services with nginx and mysql: ./sync.sh up nginx mysql -# Open bash inside the workspace: ./sync.sh bash -# Stop containers and sync: ./sync.sh down -# Force sync: ./sync.sh trigger -# Clean synced files: ./sync.sh clean +# Install docker-sync: ./laradock.sh sync install +# Start sync and services with nginx and mysql: ./laradock.sh sync up nginx mysql +# Stop containers and sync: ./laradock.sh sync down +# Open bash inside the workspace: ./laradock.sh bash +# Force sync: ./laradock.sh sync trigger +# Clean synced files: ./laradock.sh sync clean # prints colored text print_style () { @@ -53,7 +53,7 @@ fi if [ "$1" == "sync" ] ; then shift; # removing first argument - print_style "Using Docker Sync\n" "info"; + print_style "Using docker-sync to speed up Docker on OSX and Windows.\n" "success"; if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info"; @@ -88,7 +88,7 @@ if [ "$1" == "sync" ] ; then exit 1 fi else - print_style "Not using synced files might be slow on OSX and Windows. Use 'sync' option to speed up.\n"; + print_style "Not using docker-sync might might be slow on OSX and Windows. Use 'sync' option to speed up.\n"; if [ "$1" == "up" ] ; then print_style "Initializing Docker Compose\n" "info"; @@ -99,6 +99,10 @@ else print_style "Stopping Docker Compose\n" "info"; docker-compose down; + elif [ "$1" == "build" ]; then + print_style "Building workspace\n" "info"; + docker-compose build workspace; + elif [ "$1" == "bash" ]; then docker-compose exec workspace bash; From 722e73a3e62bda047a1605fbf8c632f6de303dd8 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:58:07 -0400 Subject: [PATCH 086/126] kept only sync specific functions --- laradock.sh => sync.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) rename laradock.sh => sync.sh (82%) diff --git a/laradock.sh b/sync.sh similarity index 82% rename from laradock.sh rename to sync.sh index e0a0024..871a960 100755 --- a/laradock.sh +++ b/sync.sh @@ -37,12 +37,16 @@ print_style () { display_options () { printf "Available options:\n"; - 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 " up [services]" "success"; printf "\t Starts workspace and services.\n"; + print_style " down" "success"; printf "\t\t\t Stops services.\n"; print_style " bash" "success"; printf "\t\t\t Opens bash on the workspace.\n"; - print_style " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; - print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; + print_style " build" "success"; printf "\t\t\t Builds images.\n"; + + print_style " sync install" "info"; printf "\t\t Installs docker-sync gem on the host machine.\n"; + print_style " sync up [services]" "success"; printf "\t Starts docker-sync and runs docker compose.\n"; + print_style " sync down" "success"; printf "\t\t\t Stops containers and docker-sync.\n"; + print_style " sync trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; + print_style " sync clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; } if [[ $# -eq 0 ]] ; then From 97d198e96777dcd8e3c9ae3b2a17f22fa6f08a13 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 16:58:17 -0400 Subject: [PATCH 087/126] sync functions only --- sync.sh | 105 ++++++++++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 68 deletions(-) diff --git a/sync.sh b/sync.sh index 871a960..a1f8bbb 100755 --- a/sync.sh +++ b/sync.sh @@ -7,12 +7,12 @@ # chmod 755 sync.sh # Usage: -# Install docker-sync: ./laradock.sh sync install -# Start sync and services with nginx and mysql: ./laradock.sh sync up nginx mysql -# Stop containers and sync: ./laradock.sh sync down -# Open bash inside the workspace: ./laradock.sh bash -# Force sync: ./laradock.sh sync trigger -# Clean synced files: ./laradock.sh sync clean +# Install docker-sync: ./sync.sh install +# Start sync and services with nginx and mysql: ./sync.sh up nginx mysql +# Stop containers and sync: ./sync.sh down +# Open bash inside the workspace: ./sync.sh bash +# Force sync: ./sync.sh sync trigger +# Clean synced files: ./sync.sh clean # prints colored text print_style () { @@ -37,16 +37,12 @@ print_style () { display_options () { printf "Available options:\n"; - print_style " up [services]" "success"; printf "\t Starts workspace and services.\n"; - print_style " down" "success"; printf "\t\t\t Stops services.\n"; + 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 " build" "success"; printf "\t\t\t Builds images.\n"; - - print_style " sync install" "info"; printf "\t\t Installs docker-sync gem on the host machine.\n"; - print_style " sync up [services]" "success"; printf "\t Starts docker-sync and runs docker compose.\n"; - print_style " sync down" "success"; printf "\t\t\t Stops containers and docker-sync.\n"; - print_style " sync trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; - print_style " sync clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; + print_style " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; + print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; } if [[ $# -eq 0 ]] ; then @@ -55,65 +51,38 @@ if [[ $# -eq 0 ]] ; then exit 1 fi -if [ "$1" == "sync" ] ; then +if [ "$1" == "up" ] ; then + print_style "Initializing Docker Sync\n" "info"; + print_style "May take a long time (15min+) the first run\n" "info"; + docker-sync start; + + print_style "Initializing Docker Compose\n" "info"; shift; # removing first argument - print_style "Using docker-sync to speed up Docker on OSX and Windows.\n" "success"; + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; - if [ "$1" == "up" ] ; then - print_style "Initializing Docker Sync\n" "info"; - print_style "May take a long time (15min+) the first run\n" "info"; - docker-sync start; +elif [ "$1" == "down" ]; then + print_style "Stopping Docker Compose\n" "info"; + docker-compose down; - print_style "Initializing Docker Compose\n" "info"; - shift; # removing first argument - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d ${@}; + print_style "Stopping Docker Sync\n" "info"; + docker-sync stop; - elif [ "$1" == "down" ]; then - print_style "Stopping Docker Compose\n" "info"; - docker-compose down; +elif [ "$1" == "bash" ]; then + docker-compose exec workspace bash; - print_style "Stopping Docker Sync\n" "info"; - docker-sync stop; +elif [ "$1" == "install" ]; then + print_style "Installing docker-sync\n" "info"; + gem install docker-sync; - elif [ "$1" == "install" ]; then - print_style "Installing docker-sync\n" "info"; - gem install docker-sync; +elif [ "$1" == "trigger" ]; then + print_style "Manually triggering sync between host and docker-sync container.\n" "info"; + docker-sync sync; - elif [ "$1" == "trigger" ]; then - print_style "Manually triggering sync between host and docker-sync container.\n" "info"; - docker-sync sync; - - elif [ "$1" == "clean" ]; then - print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; - docker-sync clean; - else - print_style "Invalid arguments.\n" "danger"; - display_options; - exit 1 - fi +elif [ "$1" == "clean" ]; then + print_style "Removing and cleaning up files from the docker-sync container.\n" "warning"; + docker-sync clean; else - print_style "Not using docker-sync might might be slow on OSX and Windows. Use 'sync' option to speed up.\n"; - - if [ "$1" == "up" ] ; then - print_style "Initializing Docker Compose\n" "info"; - shift; # removing first argument - docker-compose up -d ${@}; - - elif [ "$1" == "down" ]; then - print_style "Stopping Docker Compose\n" "info"; - docker-compose down; - - elif [ "$1" == "build" ]; then - print_style "Building workspace\n" "info"; - docker-compose build workspace; - - elif [ "$1" == "bash" ]; then - docker-compose exec workspace bash; - - else - print_style "Invalid arguments.\n" "danger"; - display_options; - exit 1 - fi - + print_style "Invalid arguments.\n" "danger"; + display_options; + exit 1 fi From a1f8ef9614e4ff6ec737264a3c82d69fca315558 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 17:15:07 -0400 Subject: [PATCH 088/126] adding default services --- config.txt | 1 + sync-services.txt | 1 + sync.sh | 69 ++++++++++++++++++++++++----------------------- 3 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 config.txt create mode 100644 sync-services.txt diff --git a/config.txt b/config.txt new file mode 100644 index 0000000..072cf12 --- /dev/null +++ b/config.txt @@ -0,0 +1 @@ +THIS ARE THE DEFAILTS diff --git a/sync-services.txt b/sync-services.txt new file mode 100644 index 0000000..dbe16dd --- /dev/null +++ b/sync-services.txt @@ -0,0 +1 @@ +nginx mysql \ No newline at end of file diff --git a/sync.sh b/sync.sh index a1f8bbb..9ce4a60 100755 --- a/sync.sh +++ b/sync.sh @@ -18,71 +18,74 @@ print_style () { if [ "$2" == "info" ] ; then - COLOR="96m"; + COLOR="96m" elif [ "$2" == "success" ] ; then - COLOR="92m"; + COLOR="92m" elif [ "$2" == "warning" ] ; then - COLOR="93m"; + COLOR="93m" elif [ "$2" == "danger" ] ; then - COLOR="91m"; + COLOR="91m" else #default color - COLOR="0m"; + COLOR="0m" fi - STARTCOLOR="\e[$COLOR"; - ENDCOLOR="\e[0m"; + STARTCOLOR="\e[$COLOR" + ENDCOLOR="\e[0m" - printf "$STARTCOLOR%b$ENDCOLOR" "$1"; + printf "$STARTCOLOR%b$ENDCOLOR" "$1" } display_options () { printf "Available options:\n"; - 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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n"; - print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n"; + 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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n" + print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n" } if [[ $# -eq 0 ]] ; then - print_style "Missing arguments.\n" "danger"; - display_options; + print_style "Missing arguments.\n" "danger" + display_options exit 1 fi if [ "$1" == "up" ] ; then - print_style "Initializing Docker Sync\n" "info"; - print_style "May take a long time (15min+) the first run\n" "info"; + value=$( Date: Sat, 15 Jul 2017 17:16:30 -0400 Subject: [PATCH 089/126] sdfasdf --- sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sync.sh b/sync.sh index 9ce4a60..f5144a0 100755 --- a/sync.sh +++ b/sync.sh @@ -61,7 +61,7 @@ if [ "$1" == "up" ] ; then print_style "Initializing Docker Compose\n" "info" shift # removing first argument - docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d "$value" + docker-compose -f docker-compose.yml -f docker-compose.sync.yml up -d $value elif [ "$1" == "down" ]; then print_style "Stopping Docker Compose\n" "info" From 8af22b5b376a3a9d8655aa56ad45292c2f4e2314 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 18:32:05 -0400 Subject: [PATCH 090/126] finalizing changes --- sync-services.txt | 1 - sync.sh | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 sync-services.txt diff --git a/sync-services.txt b/sync-services.txt deleted file mode 100644 index dbe16dd..0000000 --- a/sync-services.txt +++ /dev/null @@ -1 +0,0 @@ -nginx mysql \ No newline at end of file diff --git a/sync.sh b/sync.sh index f5144a0..9a7df18 100755 --- a/sync.sh +++ b/sync.sh @@ -3,15 +3,19 @@ # This shell script is an optional tool to simplify # the installation and usage of laradock with docker-sync. +# Make sure that the DOCKER_SYNC_STRATEGY is set in the .env +# DOCKER_SYNC_STRATEGY=native_osx # osx +# DOCKER_SYNC_STRATEGY=unison # windows + # To run, make sure to add permissions to this file: # chmod 755 sync.sh -# Usage: +# USAGE EXAMPLE: # Install docker-sync: ./sync.sh install # Start sync and services with nginx and mysql: ./sync.sh up nginx mysql # Stop containers and sync: ./sync.sh down # Open bash inside the workspace: ./sync.sh bash -# Force sync: ./sync.sh sync trigger +# Force sync: ./sync.sh sync # Clean synced files: ./sync.sh clean # prints colored text @@ -41,8 +45,8 @@ display_options () { 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 " trigger" "success"; printf "\t\t Manually triggers the synchronization of files.\n" - print_style " clean" "warning"; printf "\t\t Removes all files from docker-sync.\n" + print_style " sync" "success"; printf "\t\t Manually triggers the synchronization of files.\n" + print_style " clean" "danger"; printf "\t\t Removes all files from docker-sync.\n" } if [[ $# -eq 0 ]] ; then @@ -52,16 +56,13 @@ if [[ $# -eq 0 ]] ; then fi if [ "$1" == "up" ] ; then - value=$( Date: Sat, 15 Jul 2017 18:47:02 -0400 Subject: [PATCH 091/126] polishing last details --- docker-compose.sync.yml | 2 +- docker-sync.yml | 2 +- sync.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sync.yml b/docker-compose.sync.yml index b4b383a..20bb016 100644 --- a/docker-compose.sync.yml +++ b/docker-compose.sync.yml @@ -14,4 +14,4 @@ services: volumes: applications-sync: external: - name: "applications-host-sync" + name: "applications-docker-sync" diff --git a/docker-sync.yml b/docker-sync.yml index 0a3b439..bb70a26 100644 --- a/docker-sync.yml +++ b/docker-sync.yml @@ -3,7 +3,7 @@ version: "2" options: verbose: true syncs: - applications-host-sync: # name of the sync volume + applications-docker-sync: # name of the intermediary sync volume compose-dev-file-path: 'docker-compose.sync.yml' # docker-compose override file src: '${APPLICATION}' # host source directory diff --git a/sync.sh b/sync.sh index 9a7df18..1a70283 100755 --- a/sync.sh +++ b/sync.sh @@ -57,7 +57,7 @@ fi if [ "$1" == "up" ] ; then print_style "Initializing Docker Sync\n" "info" - print_style "May take a long time (15min+) the first run\n" "info" + print_style "May take a long time (15min+) on the first run\n" "info" docker-sync start; print_style "Initializing Docker Compose\n" "info" From 829a5b5acff3734753d01cd61ea452001a637ed1 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 18:53:01 -0400 Subject: [PATCH 092/126] cleaning up --- config.txt | 1 - php-fpm/php71.ini | 4 ++-- sync.sh | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 config.txt diff --git a/config.txt b/config.txt deleted file mode 100644 index 072cf12..0000000 --- a/config.txt +++ /dev/null @@ -1 +0,0 @@ -THIS ARE THE DEFAILTS diff --git a/php-fpm/php71.ini b/php-fpm/php71.ini index 2c39db8..c8242dc 100644 --- a/php-fpm/php71.ini +++ b/php-fpm/php71.ini @@ -474,7 +474,7 @@ error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT ; Development Value: On ; Production Value: Off ; http://php.net/display-errors -display_errors = On +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 @@ -485,7 +485,7 @@ display_errors = On ; Development Value: On ; Production Value: Off ; http://php.net/display-startup-errors -display_startup_errors = On +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 diff --git a/sync.sh b/sync.sh index 1a70283..2dc1d20 100755 --- a/sync.sh +++ b/sync.sh @@ -14,9 +14,6 @@ # Install docker-sync: ./sync.sh install # Start sync and services with nginx and mysql: ./sync.sh up nginx mysql # Stop containers and sync: ./sync.sh down -# Open bash inside the workspace: ./sync.sh bash -# Force sync: ./sync.sh sync -# Clean synced files: ./sync.sh clean # prints colored text print_style () { From 1e2d368e439523944a6833afd450b3ef159fb146 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sat, 15 Jul 2017 19:28:02 -0400 Subject: [PATCH 093/126] improved docs --- sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sync.sh b/sync.sh index 2dc1d20..6955358 100755 --- a/sync.sh +++ b/sync.sh @@ -42,7 +42,7 @@ display_options () { 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 " sync" "success"; printf "\t\t Manually triggers the synchronization of files.\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" } From 6b0ee109886883ee1fd017dff691cd407387f384 Mon Sep 17 00:00:00 2001 From: Arian Acosta Date: Sun, 16 Jul 2017 10:06:12 -0400 Subject: [PATCH 094/126] added docker sync documentation --- DOCUMENTATION/content/documentation/index.md | 73 ++++++++++++++++++-- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index e4a7ced..0b4a3f0 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -156,21 +156,82 @@ You might use the `--no-cache` option if you want full rebuilding (`docker-compo
-## Docker-Sync +## Speed up with docker-sync -Docker on the Mac [is slow](https://github.com/docker/for-mac/issues/77), at the time of writing. Especially for larger projects, this can be a problem. The problem is [older than March 2016](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) - as it's a such a long-running issue, we're including it in the docs here. +Docker for Mac is [slow](https://github.com/docker/for-mac/issues/77) due to poor performance when the application accesses files shared with the host machine. +One solution is to use [docker-sync](https://github.com/EugenMayer/docker-sync). -The problem originates in bind-mount performance on MacOS. Docker for Mac uses osxfs by default. This is not without reason, it has [a lot of advantages](https://docs.docker.com/docker-for-mac/osxfs/). +In simple terms, docker-sync creates a docker container with a copy of all the application files that can be accessed very quickly from the other containers. +On the other hand, docker-sync runs a process on the host machine that continuously tracks and updates files changes from the host to this intermediate container. -Solutions to resolve this issue are easily installed however, we're hoping it'll be fixed by Docker themselves over time. They are currently [adding "cached and delegated" options](https://github.com/docker/for-mac/issues/77#issuecomment-283996750), which is partly available for Docker Edge. +Out of the box, it comes pre-configured for OS X, but using it on Windows is very easy to set-up by modifying the `DOCKER_SYNC_STRATEGY` on the `.env` -Options are [to switch over to NFS](https://github.com/IFSight/d4m-nfs) which is the simplest. The fastest option is [Docker-Sync "native"](https://github.com/EugenMayer/docker-sync) which is still quite easy to install. +#### Usage -Clone [this repo](https://github.com/EugenMayer/docker-sync-boilerplate) to your machine, copy `default/docker-sync.yml` to your Laradock directory and run `docker-sync-stack start`. Be sure to use `docker-sync-stack clean` to stop and `docker-compose build` to rebuild. More information can be found [in the Docker-sync docs](https://github.com/EugenMayer/docker-sync). +Laradock comes with `sync.sh`, an optional bash script, that automates installing, running and stopping docker-sync. Note that to run the bash script you may need to change the permissions `chmod 755 sync.sh` + +1) Configure your Laradock environment as you would normally do and test your application to make sure that your sites are running correctly. + +2) Make sure to set `DOCKER_SYNC_STRATEGY` on the `.env`. Read the [syncing strategies](https://github.com/EugenMayer/docker-sync/wiki/8.-Strategies) for details. +``` +# osx: 'native_osx' (default) +# windows: 'unison' +# linux: docker-sync not required + +DOCKER_SYNC_STRATEGY=native_osx +``` + +2) Install the docker-sync gem on the host-machine: +```bash +./sync.sh install +``` +3) Start docker-sync and the Laradock environment. +Specify the services you want to run, as you would normally do with `docker-compose up` +```bash +./sync.sh up nginx mysql +``` +Please note that the first time docker-sync runs, it will copy all the files to the intermediate container and that may take a very long time (15min+). +4) To stop the environment and docker-sync do: +```bash +./sync.sh down +``` + +#### Setting up Aliases (optional) + +You may create bash profile aliases to avoid having to remember and type these commands for everyday development. +Add the following lines to your `~/.bash_profile`: + +```bash +alias devup="cd /PATH_TO_LARADOCK/laradock; ./sync.sh up nginx mysql" #add your services +alias devbash="cd /PATH_TO_LARADOCK/laradock; ./sync.sh bash" +alias devdown="cd /PATH_TO_LARADOCK/laradock; ./sync.sh down" +``` + +Now from any location on your machine, you can simply run `devup`, `devbash` and `devdown`. +#### Additional Commands + +Opening bash on the workspace container (to run artisan for example): + ```bash + ./sync.sh bash + ``` +Manually triggering the synchronization of the files: +```bash +./sync.sh sync +``` +Removing and cleaning up the files and the docker-sync container. Use only if you want to rebuild or remove docker-sync completely. The files on the host will be kept untouched. +```bash +./sync.sh clean +``` +**Additional Notes:** +- You may run laradock with or without docker-sync at any time using with the same `.env` and `docker-compose.yml`, because the configuration is overridden automatically when docker-sync is used. +- You may inspect the `sync.sh` script to learn each of the commands and even add custom ones. +- If a container cannot access the files on docker-sync, you may need to set a user on the Dockerfile of that container with an id of 1000 (this is the UID that nginx and php-fpm have configured on laradock). Alternatively, you may change the permissions to 777, but this is **not** recommended. + +Visit the [docker-sync documentation](https://github.com/EugenMayer/docker-sync/wiki) for more details.
From e496a82150e487eddfb823d01c9fe4e68cd01f43 Mon Sep 17 00:00:00 2001 From: stainlessphil Date: Thu, 20 Jul 2017 10:52:13 -0400 Subject: [PATCH 095/126] Xdebug configuration for Linux on PhpStorm Added images and explanations for setting up remote debugging for PhpStorm on Linux Also modified slightly Install Xdebug section to keep reading consistent --- DOCUMENTATION/content/documentation/index.md | 20 ++++++++++++++---- .../configuration/debugConfiguration.png | Bin 0 -> 87122 bytes .../configuration/serverConfiguration.png | Bin 0 -> 65876 bytes 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 DOCUMENTATION/themes/hugo-material-docs/static/images/photos/PHPStorm/linux/configuration/debugConfiguration.png create mode 100644 DOCUMENTATION/themes/hugo-material-docs/static/images/photos/PHPStorm/linux/configuration/serverConfiguration.png diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 0b4a3f0..22f0a85 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -394,9 +394,7 @@ It should be like this: ... ``` -2 - Re-build the containers `docker-compose build workspace php-fpm` - -3 - Open `laradock/workspace/xdebug.ini` and/or `laradock/php-fpm/xdebug.ini` and enable at least the following configurations: +2 - Open `laradock/workspace/xdebug.ini` and `laradock/php-fpm/xdebug.ini` and enable at least the following configurations: ``` xdebug.remote_autostart=1 @@ -404,11 +402,25 @@ xdebug.remote_enable=1 xdebug.remote_connect_back=1 ``` -For information on how to configure xDebug with your IDE and work it out, check this [Repository](https://github.com/LarryEitel/laravel-laradock-phpstorm). +3 - Re-build the containers `docker-compose build workspace php-fpm` + +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. + +## Setup remote debugging for PhpStorm on Linux + - Make sure you have followed the steps above in the [Install Xdebug section](http://laradock.io/documentation/#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/themes/hugo-material-docs/static/images/photos/PHPStorm/linux/configuration/debugConfiguration.png b/DOCUMENTATION/themes/hugo-material-docs/static/images/photos/PHPStorm/linux/configuration/debugConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..e69d539502c859d5c438befc18d2e1041d656095 GIT binary patch literal 87122 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 literal 0 HcmV?d00001 From e671f4c929a96d35fbac09e4766a45ba7d1ee838 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Wed, 26 Jul 2017 02:40:26 +0300 Subject: [PATCH 096/126] Update PULL_REQUEST_TEMPLATE.md context --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 567ed50..9160f01 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,7 @@ -### Thank you for contributing to Laradock. + -##### Make sure you completed the basic 3 steps below: +##### I completed the 3 steps below: -- [] I've read the simple [Contribution Guide](http://laradock.io/contributing). +- [] I've read the [Contribution Guide](http://laradock.io/contributing). - [] I've updated the **documentation**. (refer to [this](http://laradock.io/contributing/#update-the-documentation-site) for how to do so). - [] I enjoyed my time contributing and making developer's life easier :) From d32cfb31b16b419cebfc5f86fa584caf1e4d2efa Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Wed, 26 Jul 2017 02:42:24 +0300 Subject: [PATCH 097/126] update ISSUE_TEMPLATE.md context --- .github/ISSUE_TEMPLATE.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 4cb3eea..eff16ef 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,22 +5,19 @@ - System info disto/version: ### Issue: -##### What seems to be going wrong? - + _____ ### Expected behavior: -##### What should be happening instead? - + _____ ### Reproduce: -##### How might we be able to reproduce the error? - + _____ ### Relevant Code: ``` -// place code here +// place a code sample here ``` From f8527897201b2508e96df5c422192e9b2cbb19b5 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Wed, 26 Jul 2017 03:27:24 +0300 Subject: [PATCH 098/126] update some `guide` format in the documentation --- DOCUMENTATION/content/guides/index.md | 36 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index ffc0c3e..e7de20a 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -326,6 +326,7 @@ Set the following variables: - `laradock/php-fpm/xdebug.ini` Set the following variables: + ``` xdebug.remote_autostart=1 xdebug.remote_enable=1 @@ -336,34 +337,39 @@ 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" ]; thend - docker rm $processes - fi - images=`docker images -q -f dangling=true` - if [ -n "$images" ]; then - docker rmi $images - fi - } - ``` +``` +dclean() { + processes=`docker ps -q -f status=exited` + if [ -n "$processes" ]; thend + 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 @@ -406,14 +412,14 @@ 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 @@ -422,6 +428,7 @@ 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 @@ -430,6 +437,7 @@ If you have enabled `xdebug=true` in `docker-compose.yml/php-fpm`, `xdebug` will ## PHPStorm Settings + - Here are some settings that are known to work: - `Settings/BuildDeploymentConnection` - ![Settings/BuildDeploymentConnection](/images/photos/PHPStorm/Settings/BuildDeploymentConnection.png) From a590ed78ceb98cc32b2a4f89880638ceb844c7a1 Mon Sep 17 00:00:00 2001 From: terry Date: Wed, 26 Jul 2017 13:15:12 +0800 Subject: [PATCH 099/126] fixed #1068 --- workspace/Dockerfile-56 | 2 ++ workspace/Dockerfile-70 | 2 ++ workspace/Dockerfile-71 | 2 ++ 3 files changed, 6 insertions(+) diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index 076eda3..d844b39 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -202,6 +202,8 @@ ENV DRUSH_VERSION 8.1.2 ARG INSTALL_DRUSH=false ENV INSTALL_DRUSH ${INSTALL_DRUSH} RUN if [ ${INSTALL_DRUSH} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ # Install Drush 8 with the phar file. curl -fsSL -o /usr/local/bin/drush https://github.com/drush-ops/drush/releases/download/$DRUSH_VERSION/drush.phar | bash && \ chmod +x /usr/local/bin/drush && \ diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index 3751c7a..c55e297 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -202,6 +202,8 @@ ENV DRUSH_VERSION 8.1.2 ARG INSTALL_DRUSH=false ENV INSTALL_DRUSH ${INSTALL_DRUSH} RUN if [ ${INSTALL_DRUSH} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ # Install Drush 8 with the phar file. curl -fsSL -o /usr/local/bin/drush https://github.com/drush-ops/drush/releases/download/$DRUSH_VERSION/drush.phar | bash && \ chmod +x /usr/local/bin/drush && \ diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index c66befb..350bb62 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -199,6 +199,8 @@ ENV DRUSH_VERSION 8.1.2 ARG INSTALL_DRUSH=false ENV INSTALL_DRUSH ${INSTALL_DRUSH} RUN if [ ${INSTALL_DRUSH} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ # Install Drush 8 with the phar file. curl -fsSL -o /usr/local/bin/drush https://github.com/drush-ops/drush/releases/download/$DRUSH_VERSION/drush.phar | bash && \ chmod +x /usr/local/bin/drush && \ From d6ff224b0d92287b881a8d98da88c2ab385a924d Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Thu, 27 Jul 2017 23:45:18 +0800 Subject: [PATCH 100/126] fix travis ci hugo job get "cannot create directory" error. --- travis-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-build.sh b/travis-build.sh index 9d47e09..c72f51d 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -26,7 +26,7 @@ if [ -n "${HUGO_VERSION}" ]; then # Download hugo binary curl -L https://github.com/spf13/hugo/releases/download/v$HUGO_VERSION/$HUGO_PACKAGE.tar.gz | tar xz - mkdir $HOME/bin + mkdir -p $HOME/bin mv ./${HUGO_BIN}/${HUGO_BIN} $HOME/bin/hugo # Remove existing docs From 318ca3f81c07d6fc57b210383be5e5d3d3098537 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Sat, 29 Jul 2017 10:03:50 +0300 Subject: [PATCH 101/126] format the readme.md file --- .github/README.md | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/README.md b/.github/README.md index e7cf945..29ab074 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,12 +1,26 @@ -![](https://s19.postimg.org/jblfytw9f/laradock-logo.jpg) +

+ Laradock Logo +

-[![Build Status](https://travis-ci.org/laradock/laradock.svg?branch=master)](https://travis-ci.org/laradock/laradock) [![GitHub issues](https://img.shields.io/github/issues/laradock/laradock.svg)](https://github.com/laradock/laradock/issues) [![GitHub forks](https://img.shields.io/github/forks/laradock/laradock.svg)](https://github.com/laradock/laradock/network) [![GitHub stars](https://img.shields.io/github/stars/laradock/laradock.svg)](https://github.com/laradock/laradock/stargazers) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/laradock/laradock/master/LICENSE) +

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

-> Use Docker first and learn about it later. +

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

-A Docker PHP development environment that facilitates running **PHP** Apps on **Docker**. +

Use Docker First And Learn About It Later

-[![forthebadge](http://forthebadge.com/images/badges/built-by-developers.svg)](http://zalt.me) +

+ forthebadge +

+ + +--- ## Documentation @@ -14,8 +28,6 @@ A Docker PHP development environment that facilitates running **PHP** Apps on ** ## Credits -**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 @@ -31,4 +43,4 @@ A Docker PHP development environment that facilitates running **PHP** Apps on ** ## License -[MIT License](https://github.com/laradock/laradock/blob/master/LICENSE) (MIT) +[MIT License](https://github.com/laradock/laradock/blob/master/LICENSE) From c836500488000236fcb70eb59b522e06fa282873 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 1 Aug 2017 22:12:43 +0300 Subject: [PATCH 102/126] add symfony, laravel and app nginx sites sampels --- DOCUMENTATION/content/documentation/index.md | 7 +++++ .../content/getting-started/index.md | 5 ++-- ...roject-1.conf.example => app.conf.example} | 7 +++-- ...ct-2.conf.example => laravel.conf.example} | 7 +++-- nginx/sites/symfony.conf.example | 28 +++++++++++++++++++ 5 files changed, 48 insertions(+), 6 deletions(-) rename nginx/sites/{project-1.conf.example => app.conf.example} (82%) rename nginx/sites/{project-2.conf.example => laravel.conf.example} (79%) create mode 100644 nginx/sites/symfony.conf.example diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 9867fa4..c51bfe9 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1021,9 +1021,16 @@ To install CodeIgniter 3 on Laradock all you have to do is the following simple 3 - Re-build your PHP-FPM Container `docker-compose build php-fpm`. + +## Install Symfony +The installation is very simple, nothing special. +The NGINX sites include a default config file for your Symfony project `symfony.conf.example`, so edit it and make sure the `root` is pointing to your project web directory. +You mihgt to run `docker-compose restart` if the container are already running. + +Visit `symfony.dev`
diff --git a/DOCUMENTATION/content/getting-started/index.md b/DOCUMENTATION/content/getting-started/index.md index 0aba2e0..cbbdfb6 100644 --- a/DOCUMENTATION/content/getting-started/index.md +++ b/DOCUMENTATION/content/getting-started/index.md @@ -112,9 +112,9 @@ Your folder structure should look like this: 2 - Go to `nginx/sites` and create config files to point to different project directory when visiting different domains. -Laradock by default includes `project-1.conf` and `project-2.conf` as working samples. +Laradock by default includes `app.conf.example`, `laravel.conf.example` and `symfony.conf.example` as working samples. -3 - change the default names `project-n`: +3 - change the default names `*.conf`: You can rename the config files, project folders and domains as you like, just make sure the `root` in the config files, is pointing to the correct project folder name. @@ -123,6 +123,7 @@ You can rename the config files, project folders and domains as you like, just m ``` 127.0.0.1 project-1.dev 127.0.0.1 project-2.dev +... ``` > **Now jump to the [Usage](#Usage) section.** diff --git a/nginx/sites/project-1.conf.example b/nginx/sites/app.conf.example similarity index 82% rename from nginx/sites/project-1.conf.example rename to nginx/sites/app.conf.example index cf8872b..c28eec3 100644 --- a/nginx/sites/project-1.conf.example +++ b/nginx/sites/app.conf.example @@ -3,8 +3,8 @@ server { listen 80; listen [::]:80; - server_name project-1.dev; - root /var/www/project-1/public; + server_name app.dev; + root /var/www/app; index index.php index.html index.htm; location / { @@ -29,4 +29,7 @@ server { root /var/www/letsencrypt/; log_not_found off; } + + error_log /var/log/nginx/app_error.log; + access_log /var/log/nginx/app_access.log; } diff --git a/nginx/sites/project-2.conf.example b/nginx/sites/laravel.conf.example similarity index 79% rename from nginx/sites/project-2.conf.example rename to nginx/sites/laravel.conf.example index cf495fe..dd9a2ae 100644 --- a/nginx/sites/project-2.conf.example +++ b/nginx/sites/laravel.conf.example @@ -3,8 +3,8 @@ server { listen 80; listen [::]:80; - server_name project-2.dev; - root /var/www/project-2/public; + server_name laravel.dev; + root /var/www/laravel/public; index index.php index.html index.htm; location / { @@ -29,4 +29,7 @@ server { root /var/www/letsencrypt/; log_not_found off; } + + error_log /var/log/nginx/laravel_error.log; + access_log /var/log/nginx/laravel_access.log; } diff --git a/nginx/sites/symfony.conf.example b/nginx/sites/symfony.conf.example new file mode 100644 index 0000000..8d518fe --- /dev/null +++ b/nginx/sites/symfony.conf.example @@ -0,0 +1,28 @@ +server { + + listen 80; + listen [::]:80; + + server_name symfony.dev; + root /var/www/projects/symfony/web; + index index.php index.html index.htm; + + location / { + try_files $uri @rewriteapp; + } + + location @rewriteapp { + rewrite ^(.*)$ /app.php/$1 last; + } + + location ~ ^/(app|app_dev|config)\.php(/|$) { + fastcgi_pass php-upstream; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTPS off; + } + + error_log /var/log/nginx/symfony_error.log; + access_log /var/log/nginx/symfony_access.log; +} From d99cf73bf0a7da2f8584edaecfbf16a4a995d966 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Thu, 3 Aug 2017 07:31:41 +0300 Subject: [PATCH 103/126] edit alias, use the phpunit of the project --- workspace/aliases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index f3e2a2c..376980c 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -34,7 +34,7 @@ alias composer:dump="composer dump-autoload -o" alias db:reset="php artisan migrate:reset && php artisan migrate --seed" alias migrate="php artisan migrate" alias seed="php artisan:seed" -alias phpunit="./vendor/bin/phpunit" +alias phpunit="vendor/bin/phpunit" # requires installation of 'https://www.npmjs.com/package/npms-cli' From 004e4354aa5b84aa16c13fa1a5ac0a1002648500 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Thu, 3 Aug 2017 08:06:48 +0300 Subject: [PATCH 104/126] add more aliases and functions for better development in the workspace --- workspace/aliases.sh | 91 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 13 deletions(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 376980c..6ef6bd1 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -10,23 +10,54 @@ COL_BLUE=$ESC_SEQ"34;01m" COL_MAGENTA=$ESC_SEQ"35;01m" COL_CYAN=$ESC_SEQ"36;01m" +# Detect which `ls` flavor is in use +if ls --color > /dev/null 2>&1; then # GNU `ls` + colorflag="--color" + export LS_COLORS='no=00:fi=00:di=01;31:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:' +else # macOS `ls` + colorflag="-G" + export LSCOLORS='BxBxhxDxfxhxhxhxhxcxcx' +fi + +# List all files colorized in long format +#alias l="ls -lF ${colorflag}" +### MEGA: I want l and la ti return hisdden files +alias l="ls -laF ${colorflag}" + +# List all files colorized in long format, including dot files +alias la="ls -laF ${colorflag}" + +# List only directories +alias lsd="ls -lF ${colorflag} | grep --color=never '^d'" + +# Always use color output for `ls` +alias ls="command ls ${colorflag}" + # Commonly Used Aliases alias ..="cd .." +alias ...="cd ../.." +alias ....="cd ../../.." +alias .....="cd ../../../.." +alias ~="cd ~" # `cd` is probably faster to type though +alias -- -="cd -" +alias home="cd ~" + +alias h="history" +alias j="jobs" +alias e='exit' alias c="clear" alias cla="clear && ls -l" alias cll="clear && ls -la" alias cls="clear && ls" alias code="cd /var/www" alias ea="vi ~/aliases" -alias g="gulp" -alias home="cd ~" -alias npm-global="npm list -g --depth 0" -alias ra="reload" -alias reload="source ~/.aliases && echo \"$COL_GREEN ==> Aliases Reloaded... $COL_RESET \n \"" -alias run="npm run" -alias tree="xtree" -# Laravel / PHP Alisases +# Always enable colored `grep` output +# Note: `GREP_OPTIONS="--color=auto"` is deprecated, hence the alias usage. +alias grep='grep --color=auto' +alias fgrep='fgrep --color=auto' +alias egrep='egrep --color=auto' + alias art="php artisan" alias artisan="php artisan" alias cdump="composer dump-autoload -o" @@ -34,18 +65,31 @@ alias composer:dump="composer dump-autoload -o" alias db:reset="php artisan migrate:reset && php artisan migrate --seed" alias migrate="php artisan migrate" alias seed="php artisan:seed" -alias phpunit="vendor/bin/phpunit" +alias phpunit="vendor/bin/phpunit" +alias pu="phpunit" +alias puf="phpunit --filter" +alias pud='phpunit --debug' + +alias cc='codecept' +alias ccb='codecept build' +alias ccr='codecept run' +alias ccu='codecept run unit' +alias ccf='codecept run functional' + +alias g="gulp" +alias npm-global="npm list -g --depth 0" +alias ra="reload" +alias reload="source ~/.aliases && echo \"$COL_GREEN ==> Aliases Reloaded... $COL_RESET \n \"" +alias run="npm run" +alias tree="xtree" # requires installation of 'https://www.npmjs.com/package/npms-cli' alias npms="npms search" - # requires installation of 'https://www.npmjs.com/package/package-menu-cli' alias pm="package-menu" - # requires installation of 'https://www.npmjs.com/package/pkg-version-cli' alias pv="package-version" - # requires installation of 'https://github.com/sindresorhus/latest-version-cli' alias lv="latest-version" @@ -56,7 +100,6 @@ alias git-revert="git reset --hard && git clean -df" alias gs="git status" alias whoops="git reset --hard && git clean -df" - # Create a new directory and enter it function mkd() { mkdir -p "$@" && cd "$@" @@ -69,3 +112,25 @@ function md() { function xtree { find ${1:-.} -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' } + +# `tre` is a shorthand for `tree` with hidden files and color enabled, ignoring +# the `.git` directory, listing directories first. The output gets piped into +# `less` with options to preserve color and line numbers, unless the output is +# small enough for one screen. +function tre() { + tree -aC -I '.git|node_modules|bower_components' --dirsfirst "$@" | less -FRNX; +} + +# Determine size of a file or total size of a directory +function fs() { + if du -b /dev/null > /dev/null 2>&1; then + local arg=-sbh; + else + local arg=-sh; + fi + if [[ -n "$@" ]]; then + du $arg -- "$@"; + else + du $arg .[^.]* ./*; + fi; +} From 5c0b8316b1765a4104a5d81226b538b9732d50dc Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 4 Aug 2017 00:50:20 +0300 Subject: [PATCH 105/126] make the PHP_UPSTREAM config for NGINX and Apache identical --- apache2/Dockerfile | 5 +++-- docker-compose.yml | 8 +++++--- env-example | 6 ++++-- nginx/Dockerfile | 11 +++++++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apache2/Dockerfile b/apache2/Dockerfile index 9d4d9a9..afbb7c2 100644 --- a/apache2/Dockerfile +++ b/apache2/Dockerfile @@ -2,9 +2,10 @@ FROM webdevops/apache:ubuntu-16.04 MAINTAINER Eric Pfeiffer -ARG PHP_SOCKET=php-fpm:9000 +ARG PHP_UPSTREAM_CONTAINER=php-fpm +ARG PHP_UPSTREAM_PORT=9000 -ENV WEB_PHP_SOCKET=$PHP_SOCKET +ENV WEB_PHP_SOCKET=${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT} ENV WEB_DOCUMENT_ROOT=/var/www/public/ diff --git a/docker-compose.yml b/docker-compose.yml index 4504995..b0c9cb4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,13 +107,14 @@ services: networks: - backend -### Nginx Server Container ################################## +### NGINX Server Container ################################## nginx: build: context: ./nginx args: - - PHP_UPSTREAM=php-fpm + - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER} + - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT} volumes_from: - applications volumes: @@ -146,7 +147,8 @@ services: build: context: ./apache2 args: - - PHP_SOCKET=${PHP_SOCKET} + - PHP_UPSTREAM_CONTAINER=${APACHE_PHP_UPSTREAM_CONTAINER} + - PHP_UPSTREAM_PORT=${APACHE_PHP_UPSTREAM_PORT} volumes_from: - applications volumes: diff --git a/env-example b/env-example index 184b34f..a749ca4 100644 --- a/env-example +++ b/env-example @@ -80,15 +80,17 @@ NGINX_HOST_HTTP_PORT=80 NGINX_HOST_HTTPS_PORT=443 NGINX_HOST_LOG_PATH=./logs/nginx/ NGINX_SITES_PATH=./nginx/sites/ +NGINX_PHP_UPSTREAM_CONTAINER=php-fpm +NGINX_PHP_UPSTREAM_PORT=9000 ### APACHE ############################################################################################################# APACHE_HOST_HTTP_PORT=80 APACHE_HOST_HTTPS_PORT=443 -APACHE2_PHP_SOCKET=php-fpm:9000 APACHE_HOST_LOG_PATH=./logs/apache2 APACHE_SITES_PATH=./apache2/sites -PHP_SOCKET=php-fpm:9000 +APACHE_PHP_UPSTREAM_CONTAINER=php-fpm +APACHE_PHP_UPSTREAM_PORT=9000 ### MYSQL ############################################################################################################## diff --git a/nginx/Dockerfile b/nginx/Dockerfile index e23be3d..77f4abd 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -4,7 +4,8 @@ MAINTAINER Mahmoud Zalt ADD nginx.conf /etc/nginx/ -ARG PHP_UPSTREAM=php-fpm +ARG PHP_UPSTREAM_CONTAINER=php-fpm +ARG PHP_UPSTREAM_PORT=9000 # fix a problem--#397, change application source from dl-cdn.alpinelinux.org to aliyun source. RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories @@ -12,9 +13,11 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories RUN apk update \ && apk upgrade \ && apk add --no-cache bash \ - && adduser -D -H -u 1000 -s /bin/bash www-data \ - && rm /etc/nginx/conf.d/default.conf \ - && echo "upstream php-upstream { server ${PHP_UPSTREAM}:9000; }" > /etc/nginx/conf.d/upstream.conf + && adduser -D -H -u 1000 -s /bin/bash www-data + +# 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 CMD ["nginx"] From 2af40b0ba107a86b57710226fb3b2c29b309f164 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Fri, 4 Aug 2017 00:51:20 +0300 Subject: [PATCH 106/126] fix #970. remove the required public directory in the /var/www --- apache2/Dockerfile | 4 ++-- apache2/sites/default.apache.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apache2/Dockerfile b/apache2/Dockerfile index afbb7c2..bc152dd 100644 --- a/apache2/Dockerfile +++ b/apache2/Dockerfile @@ -7,11 +7,11 @@ ARG PHP_UPSTREAM_PORT=9000 ENV WEB_PHP_SOCKET=${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT} -ENV WEB_DOCUMENT_ROOT=/var/www/public/ +ENV WEB_DOCUMENT_ROOT=/var/www/ EXPOSE 80 443 -WORKDIR /var/www/public/ +WORKDIR /var/www/ COPY vhost.conf /etc/apache2/sites-enabled/vhost.conf diff --git a/apache2/sites/default.apache.conf b/apache2/sites/default.apache.conf index 5cedafb..18ee6de 100644 --- a/apache2/sites/default.apache.conf +++ b/apache2/sites/default.apache.conf @@ -1,9 +1,9 @@ ServerName laradock.dev - DocumentRoot /var/www/public/ + DocumentRoot /var/www/ Options Indexes FollowSymLinks - + AllowOverride All Allow from all From 972bdd90a3eb6266f84fc58d680fbbe9ca002671 Mon Sep 17 00:00:00 2001 From: Shao Yu Lung Date: Fri, 4 Aug 2017 15:11:10 +0800 Subject: [PATCH 107/126] fix rm error ERROR INFO: Step 4/5 : RUN rm -r /var/lib/apt/lists/* ---> Running in 4a3aa49e0e6e rm: can't remove '/var/lib/apt/lists/*': No such file or directory ERROR: Service 'php-worker' failed to build: The command '/bin/sh -c rm -r /var/lib/apt/lists/*' returned a non-zero code: 1 --- php-worker/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 58de7d5..2eb3f92 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -37,5 +37,4 @@ COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf #-------------------------------------------------------------------------- # -RUN rm -r /var/lib/apt/lists/* WORKDIR /etc/supervisor/conf.d/ From 6d89424e91a41693aaa7e2d87926c1681fe01944 Mon Sep 17 00:00:00 2001 From: James Whiteman Date: Mon, 7 Aug 2017 08:42:55 +1200 Subject: [PATCH 108/126] Update Dockerfile-70 Add python option to workspace --- workspace/Dockerfile-70 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index c55e297..d368563 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -545,6 +545,19 @@ RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ ;fi\ ;fi +##################################### +# PYTHON: +##################################### + +ARG INSTALL_PYTHON=false +ENV INSTALL_PYTHON ${INSTALL_PYTHON} +RUN if [ ${INSTALL_PYTHON} = true ]; then \ + apt-get update \ + && apt-get -y install python python-pip python-dev build-essential \ + && pip install --upgrade pip \ + && pip install --upgrade virtualenv \ +;fi + # #-------------------------------------------------------------------------- # Final Touch From 3801973b15dd1f125aafeaf6a4698b8f21447845 Mon Sep 17 00:00:00 2001 From: James Whiteman Date: Mon, 7 Aug 2017 08:45:25 +1200 Subject: [PATCH 109/126] Update env-example Added missing symfony install variable and added new python install variable --- env-example | 2 ++ 1 file changed, 2 insertions(+) diff --git a/env-example b/env-example index a749ca4..be8b520 100644 --- a/env-example +++ b/env-example @@ -45,6 +45,8 @@ WORKSPACE_INSTALL_LARAVEL_INSTALLER=false WORKSPACE_INSTALL_DEPLOYER=false WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false +WORKSPACE_INSTALL_SYMFONY=false +WORKSPACE_INSTALL_PYTHON=false WORKSPACE_INSTALL_IMAGE_OPTIMIZERS=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 From 05c7f9186aca312aeab3b7d67152ef0ab6024a95 Mon Sep 17 00:00:00 2001 From: James Whiteman Date: Mon, 7 Aug 2017 08:47:53 +1200 Subject: [PATCH 110/126] Update docker-compose.yml Added missing symfony and python options to workspace --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index b0c9cb4..16a1aea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,8 @@ services: - INSTALL_DEPLOYER=${WORKSPACE_INSTALL_DEPLOYER} - INSTALL_LINUXBREW=${WORKSPACE_INSTALL_LINUXBREW} - INSTALL_MC=${WORKSPACE_INSTALL_MC} + - INSTALL_SYMFONY=${WORKSPACE_INSTALL_SYMFONY} + - INSTALL_PYTHON=${WORKSPACE_INSTALL_PYTHON} - INSTALL_IMAGE_OPTIMIZERS=${WORKSPACE_INSTALL_IMAGE_OPTIMIZERS} - PUID=${WORKSPACE_PUID} - PGID=${WORKSPACE_PGID} From 2082659fb1da4ab95b6bd9ef16927bc15c94c820 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 7 Aug 2017 05:57:45 +0300 Subject: [PATCH 111/126] update Install Symfony steps in the docs --- DOCUMENTATION/content/documentation/index.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index c51bfe9..8dd89fa 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -1024,13 +1024,15 @@ To install CodeIgniter 3 on Laradock all you have to do is the following simple ## Install Symfony -The installation is very simple, nothing special. +1 - Open the `.env` file and set `WORKSPACE_INSTALL_SYMFONY` to `true`. -The NGINX sites include a default config file for your Symfony project `symfony.conf.example`, so edit it and make sure the `root` is pointing to your project web directory. +2 - Run `docker-compose build workspace`, after the step above. -You mihgt to run `docker-compose restart` if the container are already running. +3 - The NGINX sites include a default config file for your Symfony project `symfony.conf.example`, so edit it and make sure the `root` is pointing to your project `web` directory. -Visit `symfony.dev` +4 - Run `docker-compose restart` if the container was already running, before the step above. + +5 - Visit `symfony.dev`
From 4977b0f92fc53949677790946a44348b2c544d6a Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 7 Aug 2017 12:06:11 +0300 Subject: [PATCH 112/126] fix alias for phpunit to load from current directory --- workspace/aliases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/aliases.sh b/workspace/aliases.sh index 6ef6bd1..1bf21c6 100644 --- a/workspace/aliases.sh +++ b/workspace/aliases.sh @@ -66,7 +66,7 @@ alias db:reset="php artisan migrate:reset && php artisan migrate --seed" alias migrate="php artisan migrate" alias seed="php artisan:seed" -alias phpunit="vendor/bin/phpunit" +alias phpunit="./vendor/bin/phpunit" alias pu="phpunit" alias puf="phpunit --filter" alias pud='phpunit --debug' From 8e84fbbec2bb18980758bdd435175512e2e127a3 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Mon, 7 Aug 2017 12:36:02 +0300 Subject: [PATCH 113/126] add missing symfony and python to workspace and remove useless alias --- workspace/Dockerfile-56 | 43 +++++++++++++++++++++++++++++++++-------- workspace/Dockerfile-70 | 34 +++++++++++++------------------- workspace/Dockerfile-71 | 42 +++++++++++++++++++++++----------------- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index d844b39..a3292e9 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -319,14 +319,6 @@ USER laradock RUN echo "" >> ~/.bashrc && \ echo 'export PATH="/var/www/vendor/bin:$PATH"' >> ~/.bashrc -##################################### -# Laravel Artisan Alias -##################################### -USER root - -RUN echo "" >> ~/.bashrc && \ - echo 'alias art="php artisan"' >> ~/.bashrc - ##################################### # Laravel Envoy: ##################################### @@ -442,6 +434,41 @@ RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ USER laradock +##################################### +# Symfony: +##################################### +USER root +ARG INSTALL_SYMFONY=false +ENV INSTALL_SYMFONY ${INSTALL_SYMFONY} +RUN if [ ${INSTALL_SYMFONY} = true ]; then \ + + mkdir -p /usr/local/bin \ + && curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony \ + && chmod a+x /usr/local/bin/symfony \ + + # Symfony 3 alias + && echo 'alias dev="php bin/console -e=dev"' >> ~/.bashrc \ + && echo 'alias prod="php bin/console -e=prod"' >> ~/.bashrc \ + + # Symfony 2 alias + # && echo 'alias dev="php app/console -e=dev"' >> ~/.bashrc \ + # && echo 'alias prod="php app/console -e=prod"' >> ~/.bashrc \ + +;fi + +##################################### +# PYTHON: +##################################### + +ARG INSTALL_PYTHON=false +ENV INSTALL_PYTHON ${INSTALL_PYTHON} +RUN if [ ${INSTALL_PYTHON} = true ]; then \ + apt-get update \ + && apt-get -y install python python-pip python-dev build-essential \ + && pip install --upgrade pip \ + && pip install --upgrade virtualenv \ +;fi + # #-------------------------------------------------------------------------- # Final Touch diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index d368563..c6c4e38 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -336,14 +336,6 @@ USER laradock RUN echo "" >> ~/.bashrc && \ echo 'export PATH="/var/www/vendor/bin:$PATH"' >> ~/.bashrc -##################################### -# Laravel Artisan Alias -##################################### -USER root - -RUN echo "" >> ~/.bashrc && \ - echo 'alias art="php artisan"' >> ~/.bashrc - ##################################### # Laravel Envoy: ##################################### @@ -510,6 +502,19 @@ RUN if [ ${INSTALL_MC} = true ]; then\ chmod +x /usr/local/bin/mc \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ + if [ ${INSTALL_NODE} = true ]; then \ + . ~/.bashrc && npm install -g svgo \ + ;fi\ +;fi + ##################################### # Symfony: ##################################### @@ -532,19 +537,6 @@ RUN if [ ${INSTALL_SYMFONY} = true ]; then \ ;fi -##################################### -# Image optimizers: -##################################### -USER root -ARG INSTALL_IMAGE_OPTIMIZERS=false -ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} -RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ - apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ - if [ ${INSTALL_NODE} = true ]; then \ - . ~/.bashrc && npm install -g svgo \ - ;fi\ -;fi - ##################################### # PYTHON: ##################################### diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 350bb62..5a39096 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -337,14 +337,6 @@ USER laradock RUN echo "" >> ~/.bashrc && \ echo 'export PATH="/var/www/vendor/bin:$PATH"' >> ~/.bashrc -##################################### -# Laravel Artisan Alias -##################################### -USER root - -RUN echo "" >> ~/.bashrc && \ - echo 'alias art="php artisan"' >> ~/.bashrc - ##################################### # Laravel Envoy: ##################################### @@ -513,6 +505,21 @@ RUN if [ ${INSTALL_MC} = true ]; then\ chmod +x /usr/local/bin/mc \ ;fi +##################################### +# Image optimizers: +##################################### +USER root +ARG INSTALL_IMAGE_OPTIMIZERS=false +ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} +RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ + apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ + if [ ${INSTALL_NODE} = true ]; then \ + . ~/.bashrc && npm install -g svgo \ + ;fi\ +;fi + +USER laradock + ##################################### # Symfony: ##################################### @@ -536,19 +543,18 @@ RUN if [ ${INSTALL_SYMFONY} = true ]; then \ ;fi ##################################### -# Image optimizers: +# PYTHON: ##################################### -USER root -ARG INSTALL_IMAGE_OPTIMIZERS=false -ENV INSTALL_IMAGE_OPTIMIZERS ${INSTALL_IMAGE_OPTIMIZERS} -RUN if [ ${INSTALL_IMAGE_OPTIMIZERS} = true ]; then \ - apt-get install -y --force-yes jpegoptim optipng pngquant gifsicle && \ - if [ ${INSTALL_NODE} = true ]; then \ - . ~/.bashrc && npm install -g svgo \ - ;fi\ + +ARG INSTALL_PYTHON=false +ENV INSTALL_PYTHON ${INSTALL_PYTHON} +RUN if [ ${INSTALL_PYTHON} = true ]; then \ + apt-get update \ + && apt-get -y install python python-pip python-dev build-essential \ + && pip install --upgrade pip \ + && pip install --upgrade virtualenv \ ;fi -USER laradock # #-------------------------------------------------------------------------- From b25215684b4b564564c20706aab3432fbbee1d9b Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Tue, 8 Aug 2017 11:33:42 +0800 Subject: [PATCH 114/126] add demo and use caddy example for laravel https://github.com/caddyserver/examples/blob/master/laravel/Caddyfile --- caddy/Caddyfile | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/caddy/Caddyfile b/caddy/Caddyfile index 269b62a..288d9d3 100644 --- a/caddy/Caddyfile +++ b/caddy/Caddyfile @@ -1,28 +1,30 @@ # Docs: https://caddyserver.com/docs/caddyfile -0.0.0.0:80 -root /var/www/public -fastcgi / php-fpm:9000 php { - index index.php +0.0.0.0:80 { + root /var/www/public + fastcgi / php-fpm:9000 php { + index index.php + } + + # To handle .html extensions with laravel change ext to + # ext / .html + + rewrite { + to {path} {path}/ /index.php?{query} + } + gzip + browse + log /var/log/caddy/access.log + errors /var/log/caddy/error.log + # Uncomment to enable TLS (HTTPS) + # Change the first list to listen on port 443 when enabling TLS + #tls self_signed + + # To use Lets encrpt tls with a DNS provider uncomment these + # lines and change the provider as required + #tls { + # dns cloudflare + #} } - -# To handle .html extensions with laravel change ext to -# ext / .html - -rewrite { - r .* - ext / - to /index.php?{query} +laradock.demo { + root /var/www/public } -gzip -browse -log /var/log/caddy/access.log -errors /var/log/caddy/error.log -# Uncomment to enable TLS (HTTPS) -# Change the first list to listen on port 443 when enabling TLS -#tls self_signed - -# To use Lets encrpt tls with a DNS provider uncomment these -# lines and change the provider as required -#tls { -# dns cloudflare -#} From 668acd66c176f97b8c99dd110e898a2cdf248384 Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Tue, 8 Aug 2017 11:36:16 +0800 Subject: [PATCH 115/126] use openssh-client not openssh* https://hub.docker.com/r/abiosoft/caddy/~/dockerfile/ --- caddy/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 09d4bbd..d88fe39 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -1,15 +1,15 @@ -FROM alpine:3.4 +FROM alpine:3.5 MAINTAINER Eric Pfeiffer -ENV caddy_version=0.10.3 +ENV caddy_version=0.10.5 ARG plugins=http.git LABEL caddy_version="$caddy_version" architecture="amd64" RUN apk update \ && apk upgrade \ - && apk add tar curl git openssh + && apk add --no-cache openssh-client git tar curl RUN curl --silent --show-error --fail --location \ --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \ From 69ccd74d2e52a8a0dac88963f87b5c19e1e12a04 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Tue, 8 Aug 2017 15:01:41 +0300 Subject: [PATCH 116/126] Update Improve MAC speed docs --- DOCUMENTATION/content/documentation/index.md | 187 ++++++++++--------- 1 file changed, 98 insertions(+), 89 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index 8dd89fa..bcda764 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -5,6 +5,8 @@ weight: 3 --- + + ## List current running Containers ```bash @@ -153,88 +155,8 @@ You might use the `--no-cache` option if you want full rebuilding (`docker-compo -
- - -## Speed up with docker-sync - -Docker on the Mac [is slow](https://github.com/docker/for-mac/issues/77), at the time of writing. Especially for larger projects, this can be a problem. The problem is [older than March 2016](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) - as it's a such a long-running issue, we're including it in the docs here. - -In simple terms, docker-sync creates a docker container with a copy of all the application files that can be accessed very quickly from the other containers. -On the other hand, docker-sync runs a process on the host machine that continuously tracks and updates files changes from the host to this intermediate container. - -Out of the box, it comes pre-configured for OS X, but using it on Windows is very easy to set-up by modifying the `DOCKER_SYNC_STRATEGY` on the `.env` - -#### Usage - -Laradock comes with `sync.sh`, an optional bash script, that automates installing, running and stopping docker-sync. Note that to run the bash script you may need to change the permissions `chmod 755 sync.sh` - -1) Configure your Laradock environment as you would normally do and test your application to make sure that your sites are running correctly. - -2) Make sure to set `DOCKER_SYNC_STRATEGY` on the `.env`. Read the [syncing strategies](https://github.com/EugenMayer/docker-sync/wiki/8.-Strategies) for details. -``` -# osx: 'native_osx' (default) -# windows: 'unison' -# linux: docker-sync not required - -DOCKER_SYNC_STRATEGY=native_osx -``` - -2) Install the docker-sync gem on the host-machine: -```bash -./sync.sh install -``` -3) Start docker-sync and the Laradock environment. -Specify the services you want to run, as you would normally do with `docker-compose up` -```bash -./sync.sh up nginx mysql -``` -Please note that the first time docker-sync runs, it will copy all the files to the intermediate container and that may take a very long time (15min+). -4) To stop the environment and docker-sync do: -```bash -./sync.sh down -``` - -#### Setting up Aliases (optional) - -You may create bash profile aliases to avoid having to remember and type these commands for everyday development. -Add the following lines to your `~/.bash_profile`: - -```bash -alias devup="cd /PATH_TO_LARADOCK/laradock; ./sync.sh up nginx mysql" #add your services -alias devbash="cd /PATH_TO_LARADOCK/laradock; ./sync.sh bash" -alias devdown="cd /PATH_TO_LARADOCK/laradock; ./sync.sh down" -``` - -Now from any location on your machine, you can simply run `devup`, `devbash` and `devdown`. - - -#### Additional Commands - -Opening bash on the workspace container (to run artisan for example): - ```bash - ./sync.sh bash - ``` -Manually triggering the synchronization of the files: -```bash -./sync.sh sync -``` -Removing and cleaning up the files and the docker-sync container. Use only if you want to rebuild or remove docker-sync completely. The files on the host will be kept untouched. -```bash -./sync.sh clean -``` - -**Additional Notes:** - -- You may run laradock with or without docker-sync at any time using with the same `.env` and `docker-compose.yml`, because the configuration is overridden automatically when docker-sync is used. -- You may inspect the `sync.sh` script to learn each of the commands and even add custom ones. -- If a container cannot access the files on docker-sync, you may need to set a user on the Dockerfile of that container with an id of 1000 (this is the UID that nginx and php-fpm have configured on laradock). Alternatively, you may change the permissions to 777, but this is **not** recommended. - -Visit the [docker-sync documentation](https://github.com/EugenMayer/docker-sync/wiki) for more details. -
- ## Add more Software (Docker Images) To add an image (software), just edit the `docker-compose.yml` and add your container details, to do so you need to be familiar with the [docker compose file syntax](https://docs.docker.com/compose/compose-file/). @@ -1494,7 +1416,11 @@ Moving from Docker Toolbox (VirtualBox) to Docker Native (for Mac/Windows). Requ ## Improve speed on MacOS -Sharing code into Docker containers with osxfs have very poor performance compared to Linux. Likely there are some workarounds: +Docker on the Mac [is slow](https://github.com/docker/for-mac/issues/77), at the time of writing. Especially for larger projects, this can be a problem. The problem is [older than March 2016](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) - as it's a such a long-running issue, we're including it in the docs here. + +So since sharing code into Docker containers with osxfs have very poor performance compared to Linux. Likely there are some workarounds: + + ### Workaround A: using dinghy @@ -1514,9 +1440,99 @@ Quick Setup giude, (we recommend you check their docs) - +
+ ### Workaround B: using d4m-nfs +You can use the d4m-nfs solution in 2 ways, one is using the Laradock built it integration, and the other is using the tool separatly. Below is show case of both methods: + + +#### B.1: using the built in d4m-nfs integration + +In simple terms, docker-sync creates a docker container with a copy of all the application files that can be accessed very quickly from the other containers. +On the other hand, docker-sync runs a process on the host machine that continuously tracks and updates files changes from the host to this intermediate container. + +Out of the box, it comes pre-configured for OS X, but using it on Windows is very easy to set-up by modifying the `DOCKER_SYNC_STRATEGY` on the `.env` + +##### Usage + +Laradock comes with `sync.sh`, an optional bash script, that automates installing, running and stopping docker-sync. Note that to run the bash script you may need to change the permissions `chmod 755 sync.sh` + +1) Configure your Laradock environment as you would normally do and test your application to make sure that your sites are running correctly. + +2) Make sure to set `DOCKER_SYNC_STRATEGY` on the `.env`. Read the [syncing strategies](https://github.com/EugenMayer/docker-sync/wiki/8.-Strategies) for details. +``` +# osx: 'native_osx' (default) +# windows: 'unison' +# linux: docker-sync not required + +DOCKER_SYNC_STRATEGY=native_osx +``` + +2) Install the docker-sync gem on the host-machine: +```bash +./sync.sh install +``` +3) Start docker-sync and the Laradock environment. +Specify the services you want to run, as you would normally do with `docker-compose up` +```bash +./sync.sh up nginx mysql +``` +Please note that the first time docker-sync runs, it will copy all the files to the intermediate container and that may take a very long time (15min+). +4) To stop the environment and docker-sync do: +```bash +./sync.sh down +``` + +##### Setting up Aliases (optional) + +You may create bash profile aliases to avoid having to remember and type these commands for everyday development. +Add the following lines to your `~/.bash_profile`: + +```bash +alias devup="cd /PATH_TO_LARADOCK/laradock; ./sync.sh up nginx mysql" #add your services +alias devbash="cd /PATH_TO_LARADOCK/laradock; ./sync.sh bash" +alias devdown="cd /PATH_TO_LARADOCK/laradock; ./sync.sh down" +``` + +Now from any location on your machine, you can simply run `devup`, `devbash` and `devdown`. + + +##### Additional Commands + +Opening bash on the workspace container (to run artisan for example): + ```bash + ./sync.sh bash + ``` +Manually triggering the synchronization of the files: +```bash +./sync.sh sync +``` +Removing and cleaning up the files and the docker-sync container. Use only if you want to rebuild or remove docker-sync completely. The files on the host will be kept untouched. +```bash +./sync.sh clean +``` + + +##### Additional Notes + +- You may run laradock with or without docker-sync at any time using with the same `.env` and `docker-compose.yml`, because the configuration is overridden automatically when docker-sync is used. +- You may inspect the `sync.sh` script to learn each of the commands and even add custom ones. +- If a container cannot access the files on docker-sync, you may need to set a user on the Dockerfile of that container with an id of 1000 (this is the UID that nginx and php-fpm have configured on laradock). Alternatively, you may change the permissions to 777, but this is **not** recommended. + +Visit the [docker-sync documentation](https://github.com/EugenMayer/docker-sync/wiki) for more details. + + + + + + + + +
+ +#### B.2: using the d4m-nfs tool + [D4m-nfs](https://github.com/IFSight/d4m-nfs) automatically mount NFS volume instead of osxfs one. 1) Update the Docker [File Sharing] preferences: @@ -1556,17 +1572,10 @@ docker-compose up ... -### Other good workarounds: - -- [docker-sync](https://github.com/EugenMayer/docker-sync) -- Add more here.. -More details about this issue [here](https://github.com/docker/for-mac/issues/77). - - From e4f4de47e7b96fb5de4c2d7d656f3a033beabc1d Mon Sep 17 00:00:00 2001 From: Ary Widiantara Date: Wed, 9 Aug 2017 10:17:53 +0700 Subject: [PATCH 117/126] [UPDATE] change config redis from docker compose to env --- docker-compose.yml | 2 +- env-example | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 16a1aea..ba38624 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -338,7 +338,7 @@ services: volumes: - ${DATA_SAVE_PATH}/redis:/data ports: - - "6379:6379" + - "${REDIS_PORT}:6379" networks: - backend diff --git a/env-example b/env-example index be8b520..423e1ae 100644 --- a/env-example +++ b/env-example @@ -104,6 +104,10 @@ MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=root MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d +### REDIS ############################################################################################################## + +REDIS_PORT=6379 + ### Percona ############################################################################################################ PERCONA_DATABASE=homestead From 245ddf3441dd1b05b5a6081b9c6244aa368220a9 Mon Sep 17 00:00:00 2001 From: Mahmoud Zalt Date: Wed, 9 Aug 2017 16:18:29 +0300 Subject: [PATCH 118/126] update documentation link in the readme --- .github/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/README.md b/.github/README.md index 29ab074..7bc43ac 100644 --- a/.github/README.md +++ b/.github/README.md @@ -22,9 +22,12 @@ --- -## Documentation +

+ + Laradock Docs + +

-[**Full Documentation Here**](http://laradock.io) ## Credits From c099a51d520290b7b7569ac652631d8d5a4c8e91 Mon Sep 17 00:00:00 2001 From: Eric Dattore Date: Thu, 10 Aug 2017 21:07:59 -0600 Subject: [PATCH 119/126] add docs on running Laravel Dusk tests --- DOCUMENTATION/content/guides/index.md | 146 ++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/DOCUMENTATION/content/guides/index.md b/DOCUMENTATION/content/guides/index.md index e7de20a..d166604 100644 --- a/DOCUMENTATION/content/guides/index.md +++ b/DOCUMENTATION/content/guides/index.md @@ -8,6 +8,7 @@ weight: 4 * [Production Setup on Digital Ocean](#Digital-Ocean) * [PHPStorm XDebug Setup](#PHPStorm-Debugging) +* [Running Laravel Dusk Test](#Laravel-Dusk) @@ -555,4 +556,149 @@ Assuming that you are in laradock folder, type: - ![ConnectionSSHAuth](/images/photos/KiTTY/ConnectionSSHAuth.png) - ![TerminalShell](/images/photos/KiTTY/TerminalShell.png) +
+
+
+
+
+ +# Running Laravel Dusk Tests + +- [Intro](#dusk-intro) +- [DNS Setup](#dns-setup) +- [Docker Compose Setup](#docker-compose) +- [Laravel Dusk Setup](#laravel-dusk-setup) +- [Running Laravel Dusk Tests](#running-tests) + + +## 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, +it's only been tested on macOS. Feel free to create pull requests to update the guide +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 +According to RFC-2606, only four TLDs are reserved for local testing[^1]: + +- `.test` +- `.example` +- `.invalid` +- `.localhost` + +A common TLD used for local development is `.dev`, but newer versions of Google +Chrome (such as the one bundled with the Selenium Docker image), will fail to +resolve that DNS as there will appear to be a name collision. + +The recommended extension is `.test` for your Laravel web apps because you're +running tests. Using a DNS forwarder such as `dnsmasq` or by editing the `/etc/hosts` +file, configure the host to point to `localhost`. + +For example, in your `/etc/hosts` file: +``` +## +# Host Database +# +# localhost is used to configure the loopback interface +# when the system is booting. Do not change this entry. +## +127.0.0.1 localhost +255.255.255.255 broadcasthost +::1 localhost +127.0.0.1 myapp.test +``` + +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 +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: + +```yaml +... +selenium: + ... + depends_on: + - nginx + links: + - nginx: +``` + +This allows network communication between the Nginx and Selenium containers +and it also ensures that when starting the Selenium container, the Nginx +container starts up first unless it's already running. This allows +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 + +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 +installation of Laravel Dusk. The change you have to make deals with the URL the +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 +``` +... +USE_SELENIUM=true +``` + +### DuskTestCase.php +```php +abstract class DuskTestCase extends BaseTestCase +{ +... + protected function driver() + { + if (env('USE_SELENIUM', 'false') == 'true') { + return RemoteWebDriver::create( + 'http://selenium:4444/wd/hub', DesiredCapabilities::chrome() + ); + } else { + return RemoteWebDriver::create( + 'http://localhost:9515', DesiredCapabilities::chrome() + ); + } + } +} +``` + + +## 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: +```docker-compose exec --user=laradock workspace bash``` + +Once inside, you can change directory to your application and run: + +```php artisan dusk``` + +One way to make this easier from your project is to create a helper script. Here's one such example: +```bash +#!/usr/bin/env sh + +LARADOCK_HOME="path/to/laradock" + +pushd ${LARADOCK_HOME} + +docker-compose exec --user=laradock workspace bash -c "cd my-project && php artisan dusk && exit" +``` + +This invokes the Dusk command from inside the workspace container but when the script completes +execution, it returns your session to your project directory. + +[^1]: [Don't Use .dev for Development](https://iyware.com/dont-use-dev-for-development/) From 30b626d43ed2adddfbe9eebdb3d3450afb17c088 Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Mon, 14 Aug 2017 10:04:11 +0800 Subject: [PATCH 120/126] fix to backup and fix max client in this version, you can backup postgresql --- pgadmin/Dockerfile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pgadmin/Dockerfile b/pgadmin/Dockerfile index 7dd9606..5836801 100644 --- a/pgadmin/Dockerfile +++ b/pgadmin/Dockerfile @@ -1,5 +1,10 @@ -FROM chorss/docker-pgadmin4 +FROM fenglc/pgadmin4 -MAINTAINER Bo-Yi Wu +MAINTAINER Huadong Zuo + +# user: pgadmin4@pgadmin.org +# password: admin +# pg_dump in "/usr/bin" +# backup in "/var/lib/pgadmin4/data/storage/pgadmin4/" EXPOSE 5050 From 76001daf71e21971a89ed4096f9b84e42244a805 Mon Sep 17 00:00:00 2001 From: zuohuadong Date: Mon, 14 Aug 2017 10:09:17 +0800 Subject: [PATCH 121/126] add pgadmin backup volumes you can use backup files in ${DATA_SAVE_PATH}/pgadmin-backup --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index ba38624..e5b875e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -468,11 +468,14 @@ services: build: ./pgadmin ports: - "5050:5050" + volumes: + - ${DATA_SAVE_PATH}/pgadmin-backup:/var/lib/pgadmin4/data/storage/pgadmin4 depends_on: - postgres networks: - frontend - backend + ### ElasticSearch Container ################################# From 08896f9fb60d47d406f0764e49bf6e235bfed704 Mon Sep 17 00:00:00 2001 From: Vladislav Otchenashev Date: Wed, 16 Aug 2017 00:33:51 +0300 Subject: [PATCH 122/126] Fix supervisord.conf file path otherwise image ignores the supplied supervisord.conf --- php-worker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile index 2eb3f92..687cec5 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile @@ -19,7 +19,7 @@ MAINTAINER Mahmoud Zalt # Modify the ./supervisor.conf file to match your App's requirements. # Make sure you rebuild your container with every change. # -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY supervisord.conf /etc/supervisord.conf # #-------------------------------------------------------------------------- From 9ce470e14ebb4cef1ece05043ec8fd876fc46e33 Mon Sep 17 00:00:00 2001 From: Patrick Mac Gregor Date: Wed, 16 Aug 2017 11:21:04 +0200 Subject: [PATCH 123/126] [php-worker] dedicated dockerfile for php 7.0/7.1 fixes #927: PHP-Worker container uses PHP-CLI 7.0.9 despite workspace using 7.1.4 --- docker-compose.yml | 1 + php-worker/{Dockerfile => Dockerfile-70} | 27 +++++++++-- php-worker/Dockerfile-71 | 59 ++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) rename php-worker/{Dockerfile => Dockerfile-70} (67%) create mode 100644 php-worker/Dockerfile-71 diff --git a/docker-compose.yml b/docker-compose.yml index e5b875e..d1b4227 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -100,6 +100,7 @@ services: php-worker: build: context: ./php-worker + dockerfile: "Dockerfile-${PHP_VERSION}" volumes_from: - applications depends_on: diff --git a/php-worker/Dockerfile b/php-worker/Dockerfile-70 similarity index 67% rename from php-worker/Dockerfile rename to php-worker/Dockerfile-70 index 687cec5..8b7dd60 100644 --- a/php-worker/Dockerfile +++ b/php-worker/Dockerfile-70 @@ -3,14 +3,30 @@ # Image Setup #-------------------------------------------------------------------------- # -# To take a look at the'php-worker' base Image, visit its DockerHub page -# https://hub.docker.com/r/nielsvdoorn/laravel-supervisor/ -# -FROM nielsvdoorn/laravel-supervisor +FROM php:7.0-alpine 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 mcrypt tokenizer xml +RUN pecl channel-update pecl.php.net && pecl install memcached && docker-php-ext-enable memcached + +RUN rm /var/cache/apk/* \ + && mkdir -p /var/www + # #-------------------------------------------------------------------------- # Optional Supervisord Configuration @@ -19,8 +35,11 @@ MAINTAINER Mahmoud Zalt # 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 diff --git a/php-worker/Dockerfile-71 b/php-worker/Dockerfile-71 new file mode 100644 index 0000000..697efb6 --- /dev/null +++ b/php-worker/Dockerfile-71 @@ -0,0 +1,59 @@ +# +#-------------------------------------------------------------------------- +# Image Setup +#-------------------------------------------------------------------------- +# + +FROM php:7.1-alpine + +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 mcrypt tokenizer xml +RUN pecl channel-update pecl.php.net && pecl install memcached && docker-php-ext-enable memcached + +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 -- # + + +# +#-------------------------------------------------------------------------- +# Final Touch +#-------------------------------------------------------------------------- +# + +WORKDIR /etc/supervisor/conf.d/ From 93d5b318fe2cbea88f4bd47de0b3d91183ded495 Mon Sep 17 00:00:00 2001 From: terry Date: Sat, 19 Aug 2017 22:58:40 +0800 Subject: [PATCH 124/126] add drupal console to workspace --- docker-compose.yml | 1 + env-example | 1 + workspace/Dockerfile-56 | 14 ++++++++++++++ workspace/Dockerfile-70 | 14 ++++++++++++++ workspace/Dockerfile-71 | 14 ++++++++++++++ 5 files changed, 44 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index e5b875e..976e370 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,7 @@ services: - INSTALL_NODE=${WORKSPACE_INSTALL_NODE} - INSTALL_YARN=${WORKSPACE_INSTALL_YARN} - INSTALL_DRUSH=${WORKSPACE_INSTALL_DRUSH} + - INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE} - INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE} - INSTALL_V8JS=${WORKSPACE_INSTALL_V8JS} - COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL} diff --git a/env-example b/env-example index 423e1ae..15beb1a 100644 --- a/env-example +++ b/env-example @@ -36,6 +36,7 @@ WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_NODE=false WORKSPACE_INSTALL_YARN=false WORKSPACE_INSTALL_DRUSH=false +WORKSPACE_INSTALL_DRUPAL_CONSOLE=false WORKSPACE_INSTALL_AEROSPIKE=false WORKSPACE_INSTALL_V8JS=false WORKSPACE_COMPOSER_GLOBAL_INSTALL=false diff --git a/workspace/Dockerfile-56 b/workspace/Dockerfile-56 index a3292e9..a5ba788 100644 --- a/workspace/Dockerfile-56 +++ b/workspace/Dockerfile-56 @@ -210,6 +210,20 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ drush core-status \ ;fi +##################################### +# Drupal Console: +##################################### +USER root +ARG INSTALL_DRUPAL_CONSOLE=false +ENV INSTALL_DRUPAL_CONSOLE ${INSTALL_DRUPAL_CONSOLE} +RUN if [ ${INSTALL_DRUPAL_CONSOLE} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ + curl https://drupalconsole.com/installer -L -o drupal.phar && \ + mv drupal.phar /usr/local/bin/drupal && \ + chmod +x /usr/local/bin/drupal \ +;fi + USER laradock ##################################### diff --git a/workspace/Dockerfile-70 b/workspace/Dockerfile-70 index c6c4e38..3d1cde5 100644 --- a/workspace/Dockerfile-70 +++ b/workspace/Dockerfile-70 @@ -210,6 +210,20 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ drush core-status \ ;fi +##################################### +# Drupal Console: +##################################### +USER root +ARG INSTALL_DRUPAL_CONSOLE=false +ENV INSTALL_DRUPAL_CONSOLE ${INSTALL_DRUPAL_CONSOLE} +RUN if [ ${INSTALL_DRUPAL_CONSOLE} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ + curl https://drupalconsole.com/installer -L -o drupal.phar && \ + mv drupal.phar /usr/local/bin/drupal && \ + chmod +x /usr/local/bin/drupal \ +;fi + USER laradock ##################################### diff --git a/workspace/Dockerfile-71 b/workspace/Dockerfile-71 index 5a39096..b0320e6 100644 --- a/workspace/Dockerfile-71 +++ b/workspace/Dockerfile-71 @@ -207,6 +207,20 @@ RUN if [ ${INSTALL_DRUSH} = true ]; then \ drush core-status \ ;fi +##################################### +# Drupal Console: +##################################### +USER root +ARG INSTALL_DRUPAL_CONSOLE=false +ENV INSTALL_DRUPAL_CONSOLE ${INSTALL_DRUPAL_CONSOLE} +RUN if [ ${INSTALL_DRUPAL_CONSOLE} = true ]; then \ + apt-get update -yqq && \ + apt-get -y install mysql-client && \ + curl https://drupalconsole.com/installer -L -o drupal.phar && \ + mv drupal.phar /usr/local/bin/drupal && \ + chmod +x /usr/local/bin/drupal \ +;fi + USER laradock ##################################### From 2af5b2ff499682ad7c99372c483a8f0de179c370 Mon Sep 17 00:00:00 2001 From: Osama Date: Tue, 22 Aug 2017 12:12:56 +0300 Subject: [PATCH 125/126] fix mysql can't write to file --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index e5b875e..21114b6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -211,6 +211,7 @@ services: - ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d ports: - "${MYSQL_PORT}:3306" + user: "1000:50" networks: - backend @@ -475,7 +476,7 @@ services: networks: - frontend - backend - + ### ElasticSearch Container ################################# From f800a3221a08f329672a724ccb4e9c7b91a6cab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Roberto=20P=2E=20Borges?= Date: Tue, 29 Aug 2017 12:54:01 -0300 Subject: [PATCH 126/126] Changes to correct version of dockerfile - Removes extra spaces --- DOCUMENTATION/content/documentation/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DOCUMENTATION/content/documentation/index.md b/DOCUMENTATION/content/documentation/index.md index bcda764..f3a7780 100644 --- a/DOCUMENTATION/content/documentation/index.md +++ b/DOCUMENTATION/content/documentation/index.md @@ -232,7 +232,7 @@ By default **PHP-FPM 7.0** is running. php-fpm: build: context: ./php-fpm - dockerfile: Dockerfile-70 + dockerfile: Dockerfile-56 ... ``` @@ -331,7 +331,7 @@ For information on how to configure xDebug with your IDE and work it out, check ## Setup remote debugging for PhpStorm on Linux - - Make sure you have followed the steps above in the [Install Xdebug section](http://laradock.io/documentation/#install-xdebug). + - Make sure you have followed the steps above in the [Install Xdebug section](http://laradock.io/documentation/#install-xdebug). - Make sure Xdebug accepts connections and listens on port 9000. (Should be default configuration). @@ -946,7 +946,7 @@ To install CodeIgniter 3 on Laradock all you have to do is the following simple ## Install Symfony -1 - Open the `.env` file and set `WORKSPACE_INSTALL_SYMFONY` to `true`. +1 - Open the `.env` file and set `WORKSPACE_INSTALL_SYMFONY` to `true`. 2 - Run `docker-compose build workspace`, after the step above. @@ -1449,7 +1449,7 @@ You can use the d4m-nfs solution in 2 ways, one is using the Laradock built it i #### B.1: using the built in d4m-nfs integration -In simple terms, docker-sync creates a docker container with a copy of all the application files that can be accessed very quickly from the other containers. +In simple terms, docker-sync creates a docker container with a copy of all the application files that can be accessed very quickly from the other containers. On the other hand, docker-sync runs a process on the host machine that continuously tracks and updates files changes from the host to this intermediate container. Out of the box, it comes pre-configured for OS X, but using it on Windows is very easy to set-up by modifying the `DOCKER_SYNC_STRATEGY` on the `.env` @@ -1473,7 +1473,7 @@ DOCKER_SYNC_STRATEGY=native_osx ```bash ./sync.sh install ``` -3) Start docker-sync and the Laradock environment. +3) Start docker-sync and the Laradock environment. Specify the services you want to run, as you would normally do with `docker-compose up` ```bash ./sync.sh up nginx mysql @@ -1486,7 +1486,7 @@ Please note that the first time docker-sync runs, it will copy all the files to ##### Setting up Aliases (optional) -You may create bash profile aliases to avoid having to remember and type these commands for everyday development. +You may create bash profile aliases to avoid having to remember and type these commands for everyday development. Add the following lines to your `~/.bash_profile`: ```bash @@ -1495,11 +1495,11 @@ alias devbash="cd /PATH_TO_LARADOCK/laradock; ./sync.sh bash" alias devdown="cd /PATH_TO_LARADOCK/laradock; ./sync.sh down" ``` -Now from any location on your machine, you can simply run `devup`, `devbash` and `devdown`. +Now from any location on your machine, you can simply run `devup`, `devbash` and `devdown`. ##### Additional Commands - + Opening bash on the workspace container (to run artisan for example): ```bash ./sync.sh bash @@ -1516,7 +1516,7 @@ Removing and cleaning up the files and the docker-sync container. Use only if yo ##### Additional Notes -- You may run laradock with or without docker-sync at any time using with the same `.env` and `docker-compose.yml`, because the configuration is overridden automatically when docker-sync is used. +- You may run laradock with or without docker-sync at any time using with the same `.env` and `docker-compose.yml`, because the configuration is overridden automatically when docker-sync is used. - You may inspect the `sync.sh` script to learn each of the commands and even add custom ones. - If a container cannot access the files on docker-sync, you may need to set a user on the Dockerfile of that container with an id of 1000 (this is the UID that nginx and php-fpm have configured on laradock). Alternatively, you may change the permissions to 777, but this is **not** recommended.