Setup with Docker and Browser-Sync

Hello Grav users,

I wanted to set up a docker development environment for Grav CMS with auto-reload.
My requirements are:

  1. user/pages and user/themes shall live in separate directories on the host and should be mounted into the respective path in the docker container.

  2. The theme directory should be watched via npm nodemon or similar to automatically compile scss files etc.

  3. browser-sync should run with the --proxy option and reload the browser whenever a change is made on the site. The proxy option should allow other people to access the site via the internet.

For a short example, I show you the respective parts of my configuration files:
The script section of my package.json:

"scripts": {
    "scss": "node-sass --include-path scss -o www/user/themes/quark/css/ www/user/themes/quark/scss/",
    "watch:scss": "nodemon -e scss,less -x 'npm run scss'",
    "watch:browser": "npx browser-sync start --proxy grav --files '**/*' --tunnel",
    "watch": "npm-run-all --parallel watch:*"

My docker-compose.yaml:

version: "2.1"

    image: dsavell/grav
      - 8888:80
      - 443:443
      - ./user/themes/quark:/var/www/user/themes/quark
      - ./user/pages:/var/www/user/pages

    build: ./nodejs/
      - 3000:3000
      - 3001:3001
      - grav
    command: run watch

My ./nodejs/Dockerfile:

FROM node:latest


ADD package*.json /var/

RUN npm install


So far everything is working:
The scss files get compiled on changes and also the local browser-sync reloads on every change.
Not working, however, is the tunneled instance of the page. When checking the browser-sync UI on localhost:3001, I can see the address of the tunnel. But when I follow the link, I get a 404.

My assumption is, that there is something wrong with the permissions. All my research, however, was unsuccessful so far. Anyone here who had the same problem and/or knows how to solve this?

And just to state in advance: I want to stick to pure npm – no Gulp or something similar :wink:

Thanks a lot in advance,


I know this is old, but I had the same issue today and found a fix for it.

Problem: Browser sync won’t proxy the built in PHP server correctly.

I’m assuming you’re probably using PHP’s built in server as a temporary development server.
Starting it like:

php -S localhost:8080 system/router.php

Solution: Start the PHP server using instead of localhost

So your command to start the server would look like this instead:

php -S system/router.php

I think the problem arrises in that starting the php server with localhost instead of may start the server in ipv6 instead of ipv4.

Check out this browser-sync issue discussion:
Browser-sync issue
And check out the notes below the PHP server documentation:
PHP server discussion

Hope that helps anyone running into the same issue!

1 Like