skip to Main Content

I am running a Symfony Project via drud/ddev (nginx) for local development.
I did this many times before and had no issues whatsoever.

In my recent project I have to use the Mercure-Hub to push Notifications from the server to the client.
I required the symfony/mercure-bundle via composer and copied the generated docker-compose content into a docker-compose.mercure.yaml (.ddev/docker-compose.mercure.yaml)
After starting the container the Mercure-Hub works seamlessly but is only reachable over http.

My problem: I only have beginner knowledge in the field of nginx and docker-compose.

I am thankful for every bit of advice! 🙂

Steps to reproduce

  1. Setup basic Symfony Project and run it via DDEV.

  2. Require symfony/mercure-bundle.

  3. Copy docker-compose.yaml and docker-compose.override.yaml content to a docker-compose.mercure.yaml in the .ddev folder (change the port).

  4. Configure Mercure-Hub URL in .env.

  5. Start the container and visit [DDEV-URL]:[MERCURE-PORT] / subscribe a Mercure topic.

My problem

  • Mercure-Hub only reachable via http.

  • HTTPS call gets an 'ERR_SSL_PROTOCOL_ERROR'

My wish

  • Access the Mercure-Hub URL / subscribe to Mercure topics via HTTPS.

What I’ve tried

Files

ddev config.yaml

name: project-name
type: php
docroot: public
php_version: "8.1"
webserver_type: nginx-fpm
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: true
additional_hostnames: []
additional_fqdns: []
database:
  type: mariadb
  version: "10.4"
nfs_mount_enabled: true
mutagen_enabled: false
use_dns_when_possible: true
composer_version: "2"
web_environment: []
nodejs_version: "16"

docker-compose.mercure.yaml

version: '3'

services:
  ###> symfony/mercure-bundle ###
  mercure:
    image: dunglas/mercure
    restart: unless-stopped
    environment:
      SERVER_NAME: ':3000'
      MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      # Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
      MERCURE_EXTRA_DIRECTIVES: |
        cors_origins http://127.0.0.1:8000
    # Comment the following line to disable the development mode
    command: /usr/bin/caddy run -config /etc/caddy/Caddyfile.dev
    volumes:
      - mercure_data:/data
      - mercure_config:/config
    ports:
      - "3000:3000"
###< symfony/mercure-bundle ###

volumes:
  ###> symfony/mercure-bundle ###
  mercure_data:
  mercure_config:
###< symfony/mercure-bundle ###

.env

###> symfony/mercure-bundle ###
# See https://symfony.com/doc/current/mercure.html#configuration

# The URL of the Mercure hub, used by the app to publish updates (can be a local URL)
MERCURE_URL=http://ddev-pnp-master-mercure-1:3000/.well-known/mercure

# The public URL of the Mercure hub, used by the browser to connect
MERCURE_PUBLIC_URL=http://ddev-pnp-master-mercure-1:3000/.well-known/mercure

# The secret used to sign the JWTs
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"

###< symfony/mercure-bundle ###

Edit 1

I changed my docker-compose thanks to the advice from rfay.
(only showing the relevant part below)

[...]
services:
  mercure:
    image: dunglas/mercure
    restart: unless-stopped
    expose:
      - "3000"
    environment:
      - SERVER_NAME=":3000"
      - HTTP_EXPOSE=9998:3000
      - HTTPS_EXPOSE=9999:3000
[...]
  • replaced ports with expose
  • added HTTP_EXPOSE & HTTPS_EXPOSE

Problem with this

Now my problem is that the container doesn’t expose any ports (see docker desktop screenshot below).

docker desktop port screenshot

2

Answers


  1. Chosen as BEST ANSWER

    Solution

    With the help of rfay I found the solution (which consisted of reading the ddev documentation properly lol).

    What I did

    • replacing ports with expose
    • adding VIRTUAL_HOST, HTTP_EXPOSE and HTTPS_EXPOSE under environment
    • adding container_name & labels (see code below)

    My final docker-compose.mercure.yaml

    version: '3'
    
    services:
      mercure:
        image: dunglas/mercure
        restart: unless-stopped
        container_name: "ddev-${DDEV_SITENAME}-mercure-hub"
        labels:
          com.ddev.site-name: ${DDEV_SITENAME}
          com.ddev.approot: ${DDEV_APPROOT}
        expose:
          - "3000"
        environment:
          VIRTUAL_HOST: $DDEV_HOSTNAME
          SERVER_NAME: ":3000"
          HTTP_EXPOSE: "9998:3000"
          HTTPS_EXPOSE: "9999:3000"
          MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
          MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
          MERCURE_EXTRA_DIRECTIVES: |
            cors_origins https://project-name.ddev.site
        # Comment the following line to disable the development mode
        command: /usr/bin/caddy run --config /etc/caddy/Caddyfile.dev
        volumes:
          - mercure_data:/data
          - mercure_config:/config
    
    volumes:
      mercure_data:
      mercure_config:
    

    With this docker-compose in place my mercure container is available via HTTPS over the port 9999.

    For further information see the ddev documentation: https://ddev.readthedocs.io/en/latest/users/extend/custom-compose-files/#docker-composeyaml-examples


  2. The solution in https://stackoverflow.com/a/74735903/21252828 does not work until you add a minus before the config option at the command:

    ...
    command: /usr/bin/caddy run --config /etc/caddy/Caddyfile.dev
    ...
    

    Otherwise the container fails (and restarts endless).

    Maybe you can edit your post Christian Neugebauer?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search