├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── docker-compose.yml └── sandbox ├── fsevents.js ├── index.html ├── index.js ├── polling.js ├── proxy_fsevents.js ├── proxy_polling.js └── simple.css /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:6-slim 2 | MAINTAINER Arnau Siches 3 | 4 | RUN npm -g install browser-sync 5 | 6 | WORKDIR /source 7 | 8 | ENTRYPOINT ["browser-sync"] 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Ustwo Fampany Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | name := browser-sync 2 | image_name := ustwo/$(name) 3 | FLAGS = -v $(PWD)/sandbox:/source \ 4 | --name $(name) 5 | 6 | DOCKER := docker 7 | DOCKER_TASK := $(DOCKER) run --rm -it 8 | DOCKER_PROC := $(DOCKER) run -d -it 9 | 10 | build: 11 | @$(DOCKER) build -t $(image_name) . 12 | .PHONY: build 13 | 14 | push: 15 | @$(DOCKER) push $(image_name) 16 | .PHONY: push 17 | 18 | shell: 19 | @$(call task,--entrypoint=sh,) 20 | .PHONY: shell 21 | 22 | 23 | ############################################################################### 24 | # Test # 25 | ############################################################################### 26 | test-clean: 27 | $(DOCKER) rm -vf $(name) testapp 28 | $(DOCKER) network rm bs 29 | .PHONY: clean 30 | 31 | test-proxy: test-app 32 | $(call proc,start --proxy=testapp:8000 --files="*.css") 33 | .PHONY: test-proxy 34 | 35 | test-server: 36 | $(DOCKER_PROC) $(FLAGS) \ 37 | -p 3000:3000 \ 38 | -p 3001:3001 \ 39 | $(image_name) \ 40 | $1 start --server --files "*.css" 41 | .PHONY: test-server 42 | 43 | 44 | test-proxy-polling: test-app 45 | @$(call proc,start --config proxy_polling.js) 46 | .PHONY: test-proxy-polling 47 | 48 | test-proxy-fsevents: test-app 49 | @$(call proc,start --config proxy_fsevents.js) 50 | .PHONY: test-proxy-fsevents 51 | 52 | test-polling: 53 | @$(call proc,start --config polling.js) 54 | .PHONY: test-polling 55 | 56 | test-fsevents: 57 | @$(call proc,start --config fsevents.js) 58 | .PHONY: test-fsevents 59 | 60 | 61 | test-app: 62 | $(DOCKER) network create bs 63 | $(DOCKER_PROC) -p 8000:8000 \ 64 | --name testapp \ 65 | --net bs \ 66 | -v $(PWD)/sandbox:/sandbox \ 67 | -w /sandbox \ 68 | python:2 python -m SimpleHTTPServer 69 | .PHONY: test-app 70 | 71 | ############################################################################### 72 | # Helpers # 73 | ############################################################################### 74 | 75 | define task 76 | $(DOCKER_TASK) $(FLAGS) \ 77 | $1 \ 78 | $(image_name) \ 79 | $2 80 | endef 81 | 82 | define proc 83 | $(DOCKER_PROC) $(FLAGS) \ 84 | --net bs \ 85 | -p 3000:3000 \ 86 | -p 3001:3001 \ 87 | $(image_name) \ 88 | $1 89 | endef 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker image for browser-sync 2 | 3 | This Docker image wraps [BrowserSync](http://www.browsersync.io/) exposing its 4 | command-line interface as the `ENTRYPOINT`. This means you can use this image 5 | as drop-in replacement for Browser Sync's CLI. 6 | 7 | **Note**: please note this document assumes you're using Docker 1.9 or above. 8 | 9 | It has been tested with Docker for Mac and with Docker Machine on OSX. 10 | 11 | 12 | ## Table of Contents 13 | 14 | * [How to use this image](#how-to-use-this-image). 15 | * [Docker Machine in OSX](#docker-machine-in-osx). 16 | 17 | 18 | ## How to use this image 19 | 20 | The basic Browser Sync examples translated are the exact same commands with 21 | the docker command prefixing it. 22 | 23 | ### Static sites 24 | 25 | The following case publishes port 3000 and port 3001 so you can use the 26 | static server and configure Browser Sync as always. 27 | 28 | ```sh 29 | docker run -dt \ 30 | --name browser-sync \ 31 | -p 3000:3000 \ 32 | -p 3001:3001 \ 33 | -v $(PWD):/source \ 34 | -w /source \ 35 | ustwo/browser-sync \ 36 | start --server --files "css/*.css" 37 | ``` 38 | 39 | ### Dynamic sites 40 | 41 | In this case, you have to let Docker know how to resolve the host you are 42 | proxying to. There are a couple of ways to do this so we'll go one by one. 43 | 44 | #### Link 45 | 46 | A docker link is a one-way connection between two containers. Order matters 47 | so you have to **first** start your app and then link Browser Sync to it: 48 | 49 | ```sh 50 | docker run -dt --name myapp -p 8000:8000 myimage 51 | 52 | docker run -dt \ 53 | --name browser-sync \ 54 | --link myapp \ 55 | -p 3000:3000 \ 56 | -p 3001:3001 \ 57 | ustwo/browser-sync \ 58 | start --proxy "myapp:8000" --files "css/*.css" 59 | ``` 60 | 61 | Notice the name of the app and the link are the same, and the browser sync 62 | proxy flag has the same name as well as the exposed port of your app. There 63 | is no need to use the `-p 8000:8000` flag, it is just to make it more clear. 64 | 65 | 66 | #### Custom network 67 | 68 | A docker network is a connection between multiple containers. Unlike links, 69 | order does not matter so it is a more robust solution, but it requires setting 70 | up the network before running the containers. It is a one-time thing though: 71 | 72 | ```sh 73 | docker network create bs 74 | ``` 75 | 76 | Then you start both services as follows: 77 | 78 | ```sh 79 | docker run -dt --name myapp --net bs myimage 80 | 81 | docker run -dt \ 82 | --name browser-sync \ 83 | --net bs \ 84 | -p 3000:3000 \ 85 | -p 3001:3001 \ 86 | ustwo/browser-sync \ 87 | start --proxy "myapp:8000" --files "css/*.css" 88 | ``` 89 | 90 | 91 | ### Config file 92 | 93 | Given the image exposes Browser Sync's CLI as is, you can use a config file 94 | as well. 95 | 96 | ```sh 97 | docker run -dt \ 98 | --name browser-sync \ 99 | --net bs \ 100 | -p 3000:3000 \ 101 | -p 3001:3001 \ 102 | ustwo/browser-sync \ 103 | -v $(PWD)/config.js:/source/config.js \ 104 | start --config config.js 105 | ``` 106 | 107 | 108 | ## Docker Compose 109 | 110 | Take a look to [docker-compose.yml](./docker-compose.yml) for a simple case. 111 | 112 | 113 | ## Docker Machine in OSX 114 | 115 | Docker Machine with Virtualbox has limited support of filesystem events. 116 | [BrowserSync](http://www.browsersync.io/) uses filesystem events as its main 117 | strategy to watch for changes and falls back to polling otherwise. If you are 118 | in this situation you can only use the polling strategy as shown in `sandbox/polling.js`. 119 | 120 | 121 | ## Contact 122 | 123 | * open.source@ustwo.com 124 | 125 | 126 | ## Maintainers 127 | 128 | * Arnau Siches (@arnau) 129 | 130 | ## License 131 | 132 | There is no guarantee of active maintenance. Licensed under MIT. 133 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | bs: 2 | image: ustwo/browser-sync 3 | command: start --server --files "*.css" 4 | volumes: 5 | - ./sandbox:/source 6 | ports: 7 | - "3000:3000" 8 | - "3001:3001" 9 | -------------------------------------------------------------------------------- /sandbox/fsevents.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Browser-sync config file 4 | |-------------------------------------------------------------------------- 5 | | 6 | | For up-to-date information about the options: 7 | | http://www.browsersync.io/docs/options/ 8 | | 9 | | There are more options than you see here, these are just the ones that are 10 | | set internally. See the website for more info. 11 | | 12 | | 13 | */ 14 | module.exports = { 15 | "ui": { 16 | "port": 3001, 17 | "weinre": { 18 | "port": 8080 19 | } 20 | }, 21 | "files": "*.css", 22 | "watchOptions": { 23 | "usePolling": false 24 | }, 25 | "server": true, 26 | "proxy": false, 27 | "port": 3000, 28 | "middleware": false, 29 | "ghostMode": { 30 | "clicks": true, 31 | "scroll": true, 32 | "forms": { 33 | "submit": true, 34 | "inputs": true, 35 | "toggles": true 36 | } 37 | }, 38 | "logLevel": "info", 39 | "logPrefix": "BS", 40 | "logConnections": false, 41 | "logFileChanges": true, 42 | "logSnippet": true, 43 | "rewriteRules": false, 44 | "open": false, 45 | "browser": "default", 46 | "xip": false, 47 | "hostnameSuffix": false, 48 | "reloadOnRestart": false, 49 | "notify": true, 50 | "scrollProportionally": true, 51 | "scrollThrottle": 0, 52 | "reloadDelay": 0, 53 | "reloadDebounce": 0, 54 | "plugins": [], 55 | "injectChanges": true, 56 | "startPath": null, 57 | "minify": true, 58 | "host": null, 59 | "codeSync": true, 60 | "timestamps": true, 61 | "clientEvents": [ 62 | "scroll", 63 | "input:text", 64 | "input:toggles", 65 | "form:submit", 66 | "form:reset", 67 | "click" 68 | ], 69 | "socket": { 70 | "path": "/browser-sync/socket.io", 71 | "clientPath": "/browser-sync", 72 | "namespace": "/browser-sync", 73 | "clients": { 74 | "heartbeatTimeout": 5000 75 | } 76 | }, 77 | "tagNames": { 78 | "less": "link", 79 | "scss": "link", 80 | "css": "link", 81 | "jpg": "img", 82 | "jpeg": "img", 83 | "png": "img", 84 | "svg": "img", 85 | "gif": "img", 86 | "js": "script" 87 | } 88 | }; 89 | -------------------------------------------------------------------------------- /sandbox/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

BrowserSync Simple Test

8 | 9 | 10 | -------------------------------------------------------------------------------- /sandbox/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | http.createServer(function (req, res) { 4 | res.writeHead(200, {'Content-Type': 'text/plain'}); 5 | res.end('Hello World\n'); 6 | }).listen(80, "127.0.0.1"); 7 | -------------------------------------------------------------------------------- /sandbox/polling.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Browser-sync config file 4 | |-------------------------------------------------------------------------- 5 | | 6 | | For up-to-date information about the options: 7 | | http://www.browsersync.io/docs/options/ 8 | | 9 | | There are more options than you see here, these are just the ones that are 10 | | set internally. See the website for more info. 11 | | 12 | | 13 | */ 14 | module.exports = { 15 | "ui": { 16 | "port": 3001, 17 | "weinre": { 18 | "port": 8080 19 | } 20 | }, 21 | "files": "*.css", 22 | "watchOptions": { 23 | "usePolling": true, 24 | // "interval": 50 25 | }, 26 | "server": true, 27 | "proxy": false, 28 | "port": 3000, 29 | "middleware": false, 30 | "ghostMode": { 31 | "clicks": true, 32 | "scroll": true, 33 | "forms": { 34 | "submit": true, 35 | "inputs": true, 36 | "toggles": true 37 | } 38 | }, 39 | "logLevel": "info", 40 | "logPrefix": "BS", 41 | "logConnections": false, 42 | "logFileChanges": true, 43 | "logSnippet": true, 44 | "rewriteRules": false, 45 | "open": false, 46 | "browser": "default", 47 | "xip": false, 48 | "hostnameSuffix": false, 49 | "reloadOnRestart": false, 50 | "notify": true, 51 | "scrollProportionally": true, 52 | "scrollThrottle": 0, 53 | "reloadDelay": 0, 54 | "reloadDebounce": 0, 55 | "plugins": [], 56 | "injectChanges": true, 57 | "startPath": null, 58 | "minify": true, 59 | "host": null, 60 | "codeSync": true, 61 | "timestamps": true, 62 | "clientEvents": [ 63 | "scroll", 64 | "input:text", 65 | "input:toggles", 66 | "form:submit", 67 | "form:reset", 68 | "click" 69 | ], 70 | "socket": { 71 | "path": "/browser-sync/socket.io", 72 | "clientPath": "/browser-sync", 73 | "namespace": "/browser-sync", 74 | "clients": { 75 | "heartbeatTimeout": 5000 76 | } 77 | }, 78 | "tagNames": { 79 | "less": "link", 80 | "scss": "link", 81 | "css": "link", 82 | "jpg": "img", 83 | "jpeg": "img", 84 | "png": "img", 85 | "svg": "img", 86 | "gif": "img", 87 | "js": "script" 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /sandbox/proxy_fsevents.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Browser-sync config file 4 | |-------------------------------------------------------------------------- 5 | | 6 | | For up-to-date information about the options: 7 | | http://www.browsersync.io/docs/options/ 8 | | 9 | | There are more options than you see here, these are just the ones that are 10 | | set internally. See the website for more info. 11 | | 12 | | 13 | */ 14 | module.exports = { 15 | "ui": { 16 | "port": 3001, 17 | "weinre": { 18 | "port": 8080 19 | } 20 | }, 21 | "files": "*.css", 22 | "watchOptions": { 23 | "usePolling": false, 24 | }, 25 | "server": false, 26 | "proxy": "testapp:8000", 27 | "port": 3000, 28 | "middleware": false, 29 | "ghostMode": { 30 | "clicks": true, 31 | "scroll": true, 32 | "forms": { 33 | "submit": true, 34 | "inputs": true, 35 | "toggles": true 36 | } 37 | }, 38 | "logLevel": "info", 39 | "logPrefix": "BS", 40 | "logConnections": false, 41 | "logFileChanges": true, 42 | "logSnippet": true, 43 | "rewriteRules": false, 44 | "open": false, 45 | "browser": "default", 46 | "xip": false, 47 | "hostnameSuffix": false, 48 | "reloadOnRestart": false, 49 | "notify": true, 50 | "scrollProportionally": true, 51 | "scrollThrottle": 0, 52 | "reloadDelay": 0, 53 | "reloadDebounce": 0, 54 | "plugins": [], 55 | "injectChanges": true, 56 | "startPath": null, 57 | "minify": true, 58 | "host": null, 59 | "codeSync": true, 60 | "timestamps": true, 61 | "clientEvents": [ 62 | "scroll", 63 | "input:text", 64 | "input:toggles", 65 | "form:submit", 66 | "form:reset", 67 | "click" 68 | ], 69 | "socket": { 70 | "path": "/browser-sync/socket.io", 71 | "clientPath": "/browser-sync", 72 | "namespace": "/browser-sync", 73 | "clients": { 74 | "heartbeatTimeout": 5000 75 | } 76 | }, 77 | "tagNames": { 78 | "less": "link", 79 | "scss": "link", 80 | "css": "link", 81 | "jpg": "img", 82 | "jpeg": "img", 83 | "png": "img", 84 | "svg": "img", 85 | "gif": "img", 86 | "js": "script" 87 | } 88 | }; 89 | -------------------------------------------------------------------------------- /sandbox/proxy_polling.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Browser-sync config file 4 | |-------------------------------------------------------------------------- 5 | | 6 | | For up-to-date information about the options: 7 | | http://www.browsersync.io/docs/options/ 8 | | 9 | | There are more options than you see here, these are just the ones that are 10 | | set internally. See the website for more info. 11 | | 12 | | 13 | */ 14 | module.exports = { 15 | "ui": { 16 | "port": 3001, 17 | "weinre": { 18 | "port": 8080 19 | } 20 | }, 21 | "files": "*.css", 22 | "watchOptions": { 23 | "usePolling": true, 24 | "interval": 20 25 | }, 26 | "server": false, 27 | "proxy": "testapp:8000", 28 | "port": 3000, 29 | "middleware": false, 30 | "ghostMode": { 31 | "clicks": true, 32 | "scroll": true, 33 | "forms": { 34 | "submit": true, 35 | "inputs": true, 36 | "toggles": true 37 | } 38 | }, 39 | "logLevel": "info", 40 | "logPrefix": "BS", 41 | "logConnections": false, 42 | "logFileChanges": true, 43 | "logSnippet": true, 44 | "rewriteRules": false, 45 | "open": false, 46 | "browser": "default", 47 | "xip": false, 48 | "hostnameSuffix": false, 49 | "reloadOnRestart": false, 50 | "notify": true, 51 | "scrollProportionally": true, 52 | "scrollThrottle": 0, 53 | "reloadDelay": 0, 54 | "reloadDebounce": 0, 55 | "plugins": [], 56 | "injectChanges": true, 57 | "startPath": null, 58 | "minify": true, 59 | "host": null, 60 | "codeSync": true, 61 | "timestamps": true, 62 | "clientEvents": [ 63 | "scroll", 64 | "input:text", 65 | "input:toggles", 66 | "form:submit", 67 | "form:reset", 68 | "click" 69 | ], 70 | "socket": { 71 | "path": "/browser-sync/socket.io", 72 | "clientPath": "/browser-sync", 73 | "namespace": "/browser-sync", 74 | "clients": { 75 | "heartbeatTimeout": 5000 76 | } 77 | }, 78 | "tagNames": { 79 | "less": "link", 80 | "scss": "link", 81 | "css": "link", 82 | "jpg": "img", 83 | "jpeg": "img", 84 | "png": "img", 85 | "svg": "img", 86 | "gif": "img", 87 | "js": "script" 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /sandbox/simple.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: pink; 3 | font-size: 2rem; 4 | } 5 | --------------------------------------------------------------------------------