Search code examples
dockernginxnginx-reverse-proxymercure

Unable to setup Mercure with docker and Nginx (502 Bad Gateway)


I'm currently trying to set up a project with Mercure. My initial project has been setup by someone else, so I have very few knowledge of either Nginx or Docker.

We've tried some solutions found when looking through it but it's too different from our config to be able to apply any of them... And we don't want to break anything of course.

That said here is the issue : We have integrated Mercure to our Symfony project and it's working fine in a local environment. However, we can't make it work in a production environment (meaning HTTPS in enabled). At first, we had issues with cors_policy, but now we just run through a 502 error.

Here is our configuration : docker-compose.yml (mercure part) :

  dj_mercure:
    image: dunglas/mercure
    container_name: dj_mercure
    restart: unless-stopped
    ports:
      - "3000:3000"
    networks:
      - core
    environment:
      SERVER_NAME: ':3000'
      MERCURE_PUBLISHER_JWT_KEY: '${MERCURE_SECRET}'
      MERCURE_SUBSCRIBER_JWT_KEY: '${MERCURE_SECRET}'
      # Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
      MERCURE_EXTRA_DIRECTIVES: |
        cors_origins https://${HOST}
        use_forwarded_headers "1"
    # Comment the following line to disable the development mode
    #command: /usr/bin/caddy run -config /etc/caddy/Caddyfile.dev
    volumes:
      - caddy_data:/data
      - caddy_config:/config

networks:
  core:
    driver: bridge

volumes:
  caddy_data:
  caddy_config:

I'd like to point that our env variable HOST contains dev.mysite.fr And here is the default.conf file of Nginx :

server {
    listen 80 default_server;

    server_name localhost;
    root /var/www/html/public;
    index index.php index.html index.htm;

    location /.well-known/mercure {
        proxy_pass http://127.0.0.1:3000;
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        ## Be sure to set USE_FORWARDED_HEADERS=1 to allow the hub to use those headers ##
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

    # Dev
    location ~ ^/(index_dev|config)\.php(/|$) {
        fastcgi_pass dj_php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }

    # Prod
    location ~ ^/index\.php(/|$) {
        fastcgi_pass dj_php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        internal;
    }

    # return 404 for all other php files not matching the front controller
    # this prevents access to other php files you don't want to be accessible.
    location ~ \.php$ {
        return 404;
    }

   # return 404 for all other php files not matching the front controller
   # this prevents access to other php files you don't want to be accessible.
   location ~ \.php$ {
     return 404;
   }

}

I only added the location /.well-known/mercure part to the file. Everything else was already set up, so I' not sure if I should modify it or not.

Finally, we have this code in our Javascript :

const url = new URL('https://dev.mysite.fr/.well-known/mercure');
url.searchParams.append('topic', "http://somesite.local/xyz");
eventSource = new EventSource(url);
eventSource.onmessage = event => { // ...
}

But I keep getting a 502 Bad Gateway error basically saying :

2022/07/25 13:46:59 [error] 44#44: *24 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.5, server: localhost, request: "GET /.well-known/mercure?topic=http%3A%2F%2Fsomesite.local%2Fxyz HTTP/1.1", upstream: "http://127.0.0.1:3000/.well-known/mercure?topic=http%3A%2F%2Fsomesite.local%2Fxyz", host: "dev.mysite.fr", referrer: "https://dev.mysite.fr/fr/admin/dashboard"

We feel like we're really close to the answer, but our lack of knowledge is getting in the way. We have not a complete idea of that we're doing, so is there anyone here who could help us understand and fix this ?

Thanks!


Solution

  • Well, it turns out the answer was given on the Docker forums, so I'll share the solution just in case someone is interested :

    As stated by meyay, we changed this line

    - proxy_pass http://127.0.0.1:3000;
    + proxy_pass http://dj_mercure:3000;
    

    And now the request is properly redirected to the Mercure Hub. We still have an issue to fix, but at least this is working correctly for now!