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/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.
diff --git a/docker-compose.sync.yml b/docker-compose.sync.yml new file mode 100644 index 0000000..20bb016 --- /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-docker-sync" diff --git a/docker-sync.yml b/docker-sync.yml new file mode 100644 index 0000000..bb70a26 --- /dev/null +++ b/docker-sync.yml @@ -0,0 +1,13 @@ +version: "2" + +options: + verbose: true +syncs: + 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 + sync_userid: 1000 # giving permissions to www-data user (as defined in nginx and php-fpm Dockerfiles) + 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 new file mode 100755 index 0000000..6955358 --- /dev/null +++ b/sync.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# 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 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 + +# prints colored text +print_style () { + + if [ "$2" == "info" ] ; then + COLOR="96m" + elif [ "$2" == "success" ] ; then + COLOR="92m" + elif [ "$2" == "warning" ] ; then + COLOR="93m" + elif [ "$2" == "danger" ] ; then + COLOR="91m" + else #default color + COLOR="0m" + fi + + STARTCOLOR="\e[$COLOR" + ENDCOLOR="\e[0m" + + 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 " 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" +} + +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+) on 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 ${@} + +elif [ "$1" == "down" ]; then + print_style "Stopping Docker Compose\n" "info" + docker-compose down + + print_style "Stopping Docker Sync\n" "info" + docker-sync stop + +elif [ "$1" == "bash" ]; then + docker-compose exec workspace bash + +elif [ "$1" == "install" ]; then + print_style "Installing docker-sync\n" "info" + gem install docker-sync + +elif [ "$1" == "sync" ]; 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 \ No newline at end of file