Configuration¶
Caution
When you change anything in your docker-sync.yml be sure to run docker-sync clean and docker-sync start right after it. Just running docker-sync start or stop will not recreate the container and your changes will have no effect!
docker-sync.yml¶
The file docker-sync.yml should be placed in the top-level folder of your project, so docker-sync can find it. The configuration will be searched from the point you run docker-sync from, traversing up the path tree
In there, you usually configure one ( or more ) sync points. Be sure to decide which sync-strategy you want to chose, see Sync strategies.
Below are all the available options, simple examples can be found in the docker-sync-boilerplate.
Important
Be sure to use a sync-name which is unique, since it will be a container name. Do not use your app name, but rather app-sync.
References¶
Caution
This is a configuration reference. Do not use all options at once, they do not make sense! Or copy them as your starting point, rather use the docker-sync-boilerplate and then cherry pick the options you need.
options:
# default: docker-compose.yml if you like, you can set a custom location (path) of your compose file like ~/app/compose.yml
# HINT: you can also use this as an array to define several compose files to include. Order is important!
compose-file-path: 'docker-compose.yml'
# optional, default: docker-compose-dev.yml if you like, you can set a custom location (path) of your compose file. Do not set it, if you do not want to use it at all
# if its there, it gets used, if you name it explicitly, it HAS to exist
# HINT: you can also use this as an array to define several compose files to include. Order is important!
compose-dev-file-path: 'docker-compose-dev.yml'
# optional, activate this if you need to debug something, default is false
# IMPORTANT: do not run stable with this, it creates a memory leak, turn off verbose when you are done testing
verbose: false
# ADVANCED: the image to use for the rsync container. Do not change this until you exactly know, what you are doing
# replace <sync_strategy> with either rsync, unison, native_osx to set a custom image for all sync of this type
# do not do that if you really do not need that!
<sync_strategy>_image: 'yourcustomimage'
# optional, default auto, can be docker-sync, thor or auto and defines how the sync will be invoked on the cli. Mostly depending if your are using docker-sync solo, scaffolded or in development ( thor )
cli_mode: 'auto'
# optional, maximum number of attempts for unison waiting for the success exit status. The default is 5 attempts (1-second sleep for each attempt). Only used in unison.
max_attempt: 5
# optional, default: pwd, root directory to be used when transforming sync src into absolute path, accepted values: pwd (current working directory), config_path (the directory where docker-sync.yml is found)
project_root: 'pwd'
syncs:
default-sync:
# os aware sync strategy, defaults to native_osx under MacOS (except with docker-machine which use unison), and native docker volume under linux
# remove this option to use the default strategy per os or set a specific one
sync_strategy: 'native_osx'
# which folder to watch / sync from - you can use tilde, it will get expanded.
# the contents of this directory will be synchronized to the Docker volume with the name of this sync entry ('default-sync' here)
src: './default-data/'
host_disk_mount_mode: 'cached' # see https://docs.docker.com/docker-for-mac/osxfs-caching/#cached
# other unison options can also be specified here, which will be used when run under osx,
# and ignored when run under linux
# IMPORTANT: this name must be unique and should NOT match your real application container name!
fullexample-sync:
# enable terminal_notifier. On every sync sends a Terminal Notification regarding files being synced. ( Mac Only ).
# good thing in case you are developing and want to know exactly when your changes took effect.
# be aware in case of unison this only gives you a notification on the initial sync, not the syncs after changes.
notify_terminal: true
# which folder to watch / sync from - you can use tilde (~), it will get expanded. Be aware that the trailing slash makes a difference
# if you add them, only the inner parts of the folder gets synced, otherwise the parent folder will be synced as top-level folder
src: './data1'
# when a port of a container is exposed, on which IP does it get exposed. Localhost for docker for mac, something else for docker-machine
# default is 'auto', which means, your docker-machine/docker host ip will be detected automatically. If you set this to a concrete IP, this ip will be enforced
sync_host_ip: 'auto'
# should be a unique port this sync instance uses on the host to offer the rsync service on
# do not use this for unison - not needed there
# sync_host_port: 10871
# optional, a list of excludes. These patterns will not be synced
# see http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#ignore for the possible syntax and see sync_excludes_type below
sync_excludes: ['Gemfile.lock', 'Gemfile', 'config.rb', '.sass-cache', 'sass', 'sass-cache', 'composer.json' , 'bower.json', 'package.json', 'Gruntfile*', 'bower_components', 'node_modules', '.gitignore', '.git', '*.coffee', '*.scss', '*.sass']
# use this to change the exclude syntax.
# Path: you match the exact path ( nesting problem )
# Name: If a file or a folder does match this string ( solves nesting problem )
# Regex: Define a regular expression
# none: You can define a type for each sync exclude, so sync_excludes: ['Name .git', 'Path Gemlock']
#
# for more see http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#pathspec
sync_excludes_type: 'Name'
# optional: use this to switch to rsync verbose mode
sync_args: '-v'
# optional, default can be either rsync or unison See Strategies in the wiki for explanation
sync_strategy: 'unison'
# this does not user groupmap but rather configures the server to map
# optional: usually if you map users you want to set the user id of your application container here
sync_userid: '5000'
# optional: usually if you map groups you want to set the group id of your application container here
# this does not user groupmap but rather configures the server to map
# this is only available for unison/rsync, not for d4m/native (default) strategies
sync_groupid: '6000'
# defines how sync-conflicts should be handled. With default it will prefer the source with --copyonconflict
# so on conflict, pick the one from the host and copy the conflicted file for backup
sync_prefer: 'default'
# optional, a list of regular expressions to exclude from the fswatch - see fswatch docs for details
# IMPORTANT: this is not supported by native_osx
watch_excludes: ['.*/.git', '.*/node_modules', '.*/bower_components', '.*/sass-cache', '.*/.sass-cache', '.*/.sass-cache', '.coffee', '.scss', '.sass', '.gitignore']
# optional: use this to switch to fswatch verbose mode
watch_args: '-v'
# monit can be used to monitor the health of unison in the native_osx strategy and can restart unison if it detects a problem
# optional: use this to switch monit monitoring on
monit_enable: false
# optional: use this to change how many seconds between each monit check (cycle)
monit_interval: 5
# optional: use this to change how many consecutive times high cpu usage must be observed before unison is restarted
monit_high_cpu_cycles: 2
docker-compose.yml¶
You should split your docker-compose configuration for production and development (as usual). The production stack (docker-compose.yml) does not need any changes and would look like this (and is portable, no docker-sync adjustments).
version: "2"
services:
someapp:
image: alpine
container_name: 'fullexample_app'
command: ['watch', '-n1', 'cat /var/www/somefile.txt']
otherapp:
image: alpine
container_name: 'simpleexample_app'
command: ['watch', '-n1', 'cat /app/code/somefile.txt']
docker-compose-dev.yml¶
The docker-compose-dev.yml ( it needs to be called that way, look like this ) will override this and looks like this.
version: "2"
services:
someapp:
volumes:
- fullexample-sync:/var/www:nocopy # nocopy is important
otherapp:
# thats the important thing
volumes:
- simpleexample-sync:/app/code:nocopy # nocopy is important
volumes:
fullexample-sync:
external: true
simpleexample-sync:
external: true
Tip
Do check that you use nocopy, see below for the explanation
So the docker-compose-dev.yml includes the volume mounts and definitions - your production docker-compose.yml will be overlaid by this when starting the stack with
docker-sync-stack start
This effectively does this in docker-compose terms
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up
Portable docker-compose.yml¶
Most of you do not want to inject docker-sync specific things into the production docker-compose.yml
to keep it portable. There is a good way to achieve this very cleanly based on docker-compose overrides.
- Create a
docker-compose.yml
(you might already have that one) - that is your production file. Do not change anything here, just keep it the way you would run your production environment. - Create a
docker-compose-dev.yml
- this is where you put your overrides into. You will add the external volume and the mount here, also adding other development ENV variables you might need anyway
Start your compose using:
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up
If you only have macOS- and Linux-based development environments, create docker-compose-Linux.yml
and docker-compose-Darwin.yml
to put your OS-specific overrides into. Then you may start up your dev environment as:
docker-compose -f docker-compose.yml -f docker-compose-$(uname -s).yml up
You can simplify this command by creating an appropriate shell alias or a Makefile. There is also a feature undergo to let docker-sync-stack
support this out of the box, by simply calling:
docker-sync-stack start
A good example for this is a part of the boilerplate project.
Why :nocopy is important?¶
In case the folder we mount to has been declared as a VOLUME during image build, its content will be merged with the name volume we mount from the host - and thats not what we want. So with nocopy we ignore the contents which have been on the initial volume / image and do enforce the content from our host on the initial wiring
version: "2"
services:
someapp:
volumes:
- fullexample-sync:/var/www
to
version: "2"
services:
someapp:
volumes:
- fullexample-sync:/var/www:nocopy
Environment variables support¶
Docker-sync supports the use of environment variables from version 0.2.0.
The support is added via implementation of https://github.com/bkeepers/dotenv.
You can set your environment variables by creating a .env file at the root of your project (or form where you will be running the docker-sync commands).
The environment variables work the same as they do with docker-compose.
This allows for simplifying your setup, as you are now able to change the project dependent values instead of modifying yaml files for each project.
Tip
You can change the default file using DOCKER_SYNC_ENV_FILE
, e.g. if .env is already used for something else, you could use .docker-sync-env
by setting export DOCKER_SYNC_ENV_FILE=.docker-sync-env
# contents of your .env file
WEB_ROOT=/Users/me/Development/web
API_ROOT=./dir
The environment variables will be picked up by docker-compose
services:
api:
build: ${API_ROOT}
and by docker-sync as well.
# WEB_ROOT is /Users/me/Development/web
syncs:
web-rsync:
src: "${WEB_ROOT}"
For a detailed example take a look at https://github.com/EugenMayer/docker-sync-boilerplate/tree/master/dynamic-configuration-dotnev.