dunglas / mercure

🪽 An open, easy, fast, reliable and battery-efficient solution for real-time communications
https://mercure.rocks
GNU Affero General Public License v3.0
3.97k stars 296 forks source link

How to run Mercure in production with apache, symfony and docker? #157

Closed undersound closed 4 years ago

undersound commented 5 years ago

I am trying to run a symfony application together with mercure hub under https. Symfony, the mysql db and the mercure hub are all docker containers. I am using mod_proxy in apache on the host to proxy traffic to the symfony container.

I have the following docker compose settings for the mercure hub:

mercure-hub:
    build:
      context: .
      dockerfile: build//hub/Dockerfile
    restart: always
    container_name: mercure-hub
    image: myimage-mercure-hub
    ports:
      - 3030:80
    environment:
      JWT_KEY: aVerySecretKey
      ALLOW_ANONYMOUS: 1
      PUBLISH_ALLOWED_ORIGINS: '*'
      CORS_ALLOWED_ORIGINS: '*'
    expose:
      - 3030

The following vhost conf for the proxypass to the symfony container

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ProtocolsHonorOrder On
        Protocols h2 http/1.1

        ServerName http://example.com

        ProxyPreserveHost On
        ProxyPass / http://localhost:8099/
        ProxyPassReverse / http://localhost:8099/

        ServerAlias example.com

        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    </VirtualHost>
</IfModule>

And the vhost for port 80

<VirtualHost *:80>
    ProtocolsHonorOrder On
    Protocols h2 http/1.1

    ServerName http://example.com

    ProxyPreserveHost On
    ProxyPass / http://localhost:8099/
    ProxyPassReverse / http://localhost:8099/
</VirtualHost>

Now when I browser to https://example.com I get the following error https://example.com:3030/hub?topic=my.topic net::ERR_SSL_PROTOCOL_ERROR

This is caused by the call in my app.js file from symfony.

What am I doing wrong here?

Thanks in advance for any help

7system7 commented 5 years ago

Almost the same problem here but simplier. I would like to proxy the mercure (from binary) through Apache w/o certs. The mercure is running w/ the default config on localhost:3000.

The apache config:

ProxyRequests off

<LocationMatch /hub>
      ProxyPass http://localhost:3000
      ProxyPassReverse http://localhost:3000

      Header set Content-Type "text/event-stream"
      Header set Cache-Control "no-cache, no-store, must-revalidate"
      Header set X-Accel-Buffering "no"

      Header set Connection "keep-alive"
      Header set Expire "0"
      Header set Pragma "no-cache"
      Header set Transfer-Encoding "chunked"
</LocationMatch>

Javascript:

const url = new URL('http://example.local/hub');
url.searchParams.append('topic', encodeURIComponent('ycNotification'));
const eventSource = new EventSource(url);

eventSource.onmessage = event => {
     // do sg
};

With these config the connection was built but the mercure logged only a user agent string. After that, the connection is closing. This was what I expected:

$ JWT_KEY='aVerySecretKey' ADDR='localhost:3000' ALLOW_ANONYMOUS=1 CORS_ALLOWED_ORIGINS=* bin/mercure
INFO[0000] Mercure started                               addr="localhost:3000" protocol=http
INFO[0001] New subscriber                                remote_addr="127.0.0.1:53262" subscriber_topics="[ycNotification]"

But sadly, I got this:

JWT_KEY='aVerySecretKey' ADDR='localhost:3000' ALLOW_ANONYMOUS=1 CORS_ALLOWED_ORIGINS=* bin/mercure
INFO[0000] Mercure started                               addr="localhost:3000" protocol=http
127.0.0.1 - - [05/Nov/2019:21:09:16 +0100] "GET /hub?topic=ycNotification HTTP/1.1" 200 1679 "http://exmaple.local/example" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
127.0.0.1 - - [05/Nov/2019:22:00:56 +0100] "GET /?topic=ycNotification HTTP/1.1" 200 117 "http://http://exmaple.local/example" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

My question is how should I configure the apache to proxy an url to mercure correctly? I tried a lot of way but I was failed.

7system7 commented 5 years ago

OMG! Finally I found the solution. It was too simple.

The correct apache config is simplier:

ProxyRequests off

<LocationMatch /hub>
      ProxyPass http://localhost:3000
      ProxyPassReverse http://localhost:3000
</LocationMatch>

In this case, the correct request url for Javascript is http://example.local/hub/hub because the apache proxy LocationMatch. So the correct code:

const url = new URL('http://example.local/__hub/hub');

So, it works. Thank you for your cooperation. :smile:

Tubusy commented 4 years ago

Seems like people here are sorted, but here's some alternate details for newcomers:

I managed to get things working on a live Apache server like this. In Apache domain conf:

ProxyPass /hub/ http://localhost:9090/
ProxyPassReverse /hub/ http://localhost:9090/

In Javascript: new URL('https://www.example.com/hub/.well-known/mercure'); In Symfony: MERCURE_PUBLISH_URL=https://www.example.com/hub/.well-known/mercure From root, running Mercure server like this for testing: docker run -e JWT_KEY='!ChangeMe!' -e DEMO=1 -e ALLOW_ANONYMOUS=1 -e CORS_ALLOWED_ORIGINS='*' -e PUBLISH_ALLOWED_ORIGINS='*' -p 9090:80 dunglas/mercure So now everything is working, without https / 443 problems.

ljfreelancer88 commented 4 years ago

I have a couple of questions since I'm not using Docker and I'm confused too.

Should I run this ./mercure --jwt-key='secretKeyGoesHere' --addr=':3000' --cors-allowed-origins='http://mydomain.io' --publish-allowed-origins='http://localhost:3000' in the (hosting)terminal manually for background process? and then use the following in Apache config?

#http://localhost/publisher/.well-known/mercure
<VirtualHost *:80>
      ProxyRequests off
      ProxyPreserveHost On
      ProxyPass /publisher/ http://127.0.0.1:3000/
      ProxyPassReverse /publisher/ http://127.0.0.1:3000/   
      ErrorLog "logs/publisher.com-error.log"
</VirtualHost>

Thank you in advance. :)

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

disco07 commented 3 years ago

how to put mercury in production with apache in ubuntu. Can you help me please ? Urgent

FPDK commented 1 year ago

There's a nice guide here: https://www.ismailzai.com/blog/symfony-mercure-apache