Sage 9 on Docker: https://localhost:3000 not working

I guys I’m trying to setup Sage on Docker

I can run yarn with this command
docker container exec my-wpcli yarn --cwd web/app/themes/sage start

I can access Browsersync UI at http://localhost:3001/
But I can’t access the dev site at https://localhost:3000/

This is my docker-compose.yml

version: '3.6'
    image: nginx:latest
    container_name: my-nginx
      - '80:80'
      - '443:443'
      - ./nginx:/etc/nginx/conf.d
      - ./src:/var/www/html:rw,cached
      - ./certs:/etc/certs
      - wordpress
    restart: always

    image: mariadb
    container_name: my-mysql
      - MYSQL_ROOT_PASSWORD=password
    restart: always
      - '3306:3306'

      context: .
      dockerfile: Dockerfile
    container_name: my-wordpress
      - ./src:/var/www/html:rw,cached
      - ./config/php.ini:/usr/local/etc/php/conf.d/php.ini
      - mysql
    restart: always

    container_name: my-wpcli
    image: bitroniq/docker-wordpress-cli-sage
    restart: always
      - wordpress
      - ./src:/var/www/html:rw,cached
      - '3000:3000'
      - '3001:3001'

    image: composer/composer
    container_name: amodioceramiche-composer
    working_dir: /var/www/html
    restart: 'no'
      - ./src:/var/www/html:rw,cached

any clues?

Can you share your resources/assets/config.json? The devUrl key is what is being proxied by webpack/Browsersync in Sage. You should be setting that to whatever the address for the Nginx container is. Looks like just http://localhost.

This is the config.json

  "entry": {
    "main": [
    "customizer": [
  "publicPath": "/app/themes/sage",
  "devUrl": "https://mysite.local",
  "proxyUrl": "https://localhost:3000",
  "cacheBusting": "[name]_[hash:8]",
  "watch": [

This is the webpack output

[BS] [HTML Injector] Running...
[Browsersync] Proxying: https://mysite.local
[Browsersync] Access URLs:
       Local: https://localhost:3000
          UI: http://localhost:3001
 UI External:

The Browsersync UI is visible at localhost:3001

But https://localhost:3000 return first a warning about unsecure https (NET::ERR_CERT_AUTHORITY_INVALID) and forcing to browse localhost anyway result in an endless wait for a reply from localhost

I also changed the proxyUrl to not use https but Browsersync keep using https to access localhost:3000

PS: when yarn start is running, on https:mysite.local there are two errors showing in console

  • GET app/themes/sage/dist/styles/main.css net::ERR_ABORTED 404
  • GET __webpack_hmr net::ERR_ABORTED 404

the first should be normal as per docs, what about the second? could be related to my problem?

This might seem basic, but can you confirm you are able to access the WordPress install through https://mysite.local (with or without SSL)? If you can’t do this, then Sage definitely will not work since it needs a working WordPress install to proxy.

Yes it’s a working WordPress install.

Accessing https://mysite.local is fine.
Sage works and yarn build compiles properly.

When running yarn start via docker, looking at https://mysite.local there are those two errors in the console, so both Wordpress and Yarn are running.

That it still uses HTTPS could be caused by agressive caching of redirects by Chrome.
By my experience only clearing the cache and restarting Chrome helped getting rid of the redirect (even in an Incognito mode window that I prefer for the development site tabs).

What’s the url where is supposed to see the live preview?
The one defined in proxyUrl?

Now is http://localhost:3000
But yarn start shows https instead and this is not related to chrome.

I also cleared and restarted chrome but still no good.

Maybe HSTS is enabled in nginx development container?
When you visit the URL with http:// that is proxied by browsersync
manually in your browser, would it redirect to https://?

There is no http:// proxied, every thing (except the Browsersync UI) is on https.

http://localhost:3000 it says ERR_EMPTY_RESPONSE
http://localhost redirects to https://mysite.local/wp-signup.php?new=localhost (returning 404) is it HSTS enabled?

But doing curl -s -D- https://mysite.local/ | grep -i Strict does not return the header, that make me think there is no HSTS enabled.

Looking better at nginx config there is Strict-Transport-Security active on https even if curl does not grep it:

server {
    listen      80;
    listen [::]:80;
    server_name mysite.local;

    location / {
        rewrite ^ https://$host$request_uri? permanent;

    rewrite ^/(wp-.*.php)$ /wp/$1 last;
    rewrite ^/(wp-(content|admin|includes).*) /wp/$1 last;

server {
    listen      443           ssl http2;
    listen [::]:443           ssl http2;
    server_name               mysite.local www.mysite.local;

    add_header                Strict-Transport-Security "max-age=31536000" always;

    ssl_session_cache         shared:SSL:20m;
    ssl_session_timeout       10m;

    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers               "ECDH+AESGCM:ECDH+AES256:ECDH+AES128:!ADH:!AECDH:!MD5;";

    root /var/www/html/web;