Mercure responds with a 400 error in production

154 Views Asked by At

I'm trying to put Mercure hub into production in a Symfony project, but without success.

I downloaded Mercure on the releases page and unzipped it in a mercure folder at the root of my Symfony project in /var/www/locfac/public_html/mercure. I've configured everything locally and it works fine. But, in production on my Nginx server, it returns an 400 error.

I manage to start the hub in the terminal, but it's not accessible on the link via the browser and requests never come to it. The hub link should be https://locfac.com/hub.

I'd appreciate it if someone could help me. Here is my code:

#serveur configuration

server {
    server_name locfac.com www.locfac.com;
    root /var/www/locfac/public_html/public;
    
    location /hub {
        proxy_pass http://localhost:8500;
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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;
    }

    # optionally disable falling back to PHP script for the asset directories;
    # nginx will return a 404 error when files are not found instead of passing the
    # request to Symfony (improves performance but Symfony's 404 page is not displayed)
    # location /bundles {
    #     try_files $uri =404;
    # }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # optionally set the value of the environment variables used in the application
        # fastcgi_param APP_ENV prod;
        # fastcgi_param APP_SECRET <app-secret-id>;
        # fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";

        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        # Caveat: When PHP-FPM is hosted on a different machine from nginx
        #         $realpath_root may not resolve as you expect! In this case try using
        #         $document_root instead.
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
#   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/index.php/some-path
        # Remove the internal directive to allow URIs like this
        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$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # return 404;
    }

    error_log /var/log/nginx/locfac.log;
    access_log /var/log/nginx/locfac.log;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/locfac.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/locfac.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = www.locfac.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = locfac.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;
    server_name locfac.com www.locfac.com;
    return 404; # managed by Certbot

}

#Caddyfile

{
    {$DEBUG:debug}
    https_port 8500
    auto_https off
}

{$SERVER_NAME:localhost}

# tls internal
tls /etc/letsencrypt/live/locfac.com/fullchain.pem /etc/letsencrypt/live/locfac.com/privkey.pem

route {
    encode zstd gzip

    mercure {
        # Transport to use (default to Bolt)
        transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db}
        # Publisher JWT key
        publisher_jwt "{$MERCURE_PUBLISHER_JWT_KEY}" {$MERCURE_PUBLISHER_JWT_ALG}
        # Subscriber JWT key
        subscriber_jwt "{$MERCURE_SUBSCRIBER_JWT_KEY}" {$MERCURE_SUBSCRIBER_JWT_ALG}
        # Permissive configuration for the development environment
        cors_origins *
        publish_origins *
        ui
        anonymous
        subscriptions
        # Extra directives
        {$MERCURE_EXTRA_DIRECTIVES}
    }

    header / Content-Type "text/html; charset=utf-8"
    respond / `<!DOCTYPE html>
    <html lang=en>
    <meta charset="utf-8">
    <meta name="robots" content="noindex">
    <title>Welcome to Mercure</title>
    <h1>Welcome to Mercure</h1>
    <p>The URL of your hub is <code>/.well-known/mercure</code>.
    Read the documentation on <a href="https://mercure.rocks">Mercure.rocks, real-time apps made easy</a>.`

    respond /healthz 200
    respond "Not Found" 404
}

log {
    output file /var/log/mercure/mercure.log {
            roll_local_time
            roll_keep 7
    }
}

I've written a hub start file whose contents are as follows :

#!/bin/bash
SYMFONY_ROOT="/var/www/locfac/public_html"
MERCURE_PATH="$SYMFONY_ROOT/mercure/mercure"

MERCURE_PUBLISHER_JWT_KEY="$(cat $SYMFONY_ROOT/config/jwt/public.pem)" \
MERCURE_PUBLISHER_JWT_ALG="RS256" \
MERCURE_SUBSCRIBER_JWT_KEY="$(cat $SYMFONY_ROOT/config/jwt/public.pem)" \
MERCURE_SUBSCRIBER_JWT_ALG="RS256" \
$MERCURE_PATH run
0

There are 0 best solutions below