Search code examples
phpdockersymfonydocker-composemercure

Symfony + Mercure connection problems. Use HTTPS instead of HTTP


I was trying to establish a connection between two docker containers. One as nginx server + Symfony application, and the second with Mercure.

My application is working fine, docker-compose build also works without any problems. The problem is when I try to test it, and try to publish something to Mercure from Symfony App I got 500 internal server error with "Failed to send an update." message.

In the stack trace I can see that I got TransportException Error, with different env variable than I have in .env file. Application is trying to use HTTPS instead of HTTP that was defined in .env file.

Symfony\Component\HttpClient\Exception\TransportException: SSL connect error for "https://mercure/.well-known/mercure". at vendor/symfony/http-client/Chunk/ErrorChunk.php:65

###> 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://mercure/.well-known/mercure

# The public URL of the Mercure hub, used by the browser to connect
MERCURE_PUBLIC_URL=http://localhost:9090/.well-known/mercure

MERCURE_PUBLISH_URL=http://mercure/.well-known/mercure

# The secret used to sign the JWTs
MERCURE_JWT_SECRET=<Proper JWT Token is here>
###< symfony/mercure-bundle ###

In Mercure container I get:

mercure_1   | {"level":"debug","ts":1619097073.714639,"logger":"http.stdlib","msg":"http: TLS handshake error from 172.21.0.5:57420: no certificate available for 'mercure'"}

My docker-compose configuration

services:

    api:
        build:
            context: ./api
            dockerfile: Dockerfile
        volumes:
            - ./api:/app
            - ./api/storage/logs/php-fpm:/var/log/php-fpm
        networks:
            - redio_network
        ports:
            - "7000:80"
        environment:
            <<: *common-variables

    mercure:
        image: dunglas/mercure
        environment:
            MERCURE_PUBLISHER_JWT_KEY: '!ChangeMe!'
            MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeMe!'
        ports:
            - "9090:80"
        networks:
            - redio_network
        volumes:
            - ./_data/caddy_data:/data
            - ./_data/caddy_config:/config
        command: /usr/bin/caddy run -config /etc/caddy/Caddyfile.dev

Here is my Controller, when I publish to a Mercure topic:

class ChatController extends AbstractController
{
    /**
     * @Route("/push", name="push")
     * @param Request $request
     * @param HubInterface $publisher
     * @return Response
     */
    public function push(Request $request, HubInterface $publisher): Response
    {
        $publisher->publish(new Update(
            '/chat',
            json_encode(['message' => 'hello!'])
        ));

        return $this->json('Done');
    }
}

Solution

  • Okey I found it. If anyone has the same problem add SERVER_NAME variable to your docker-compose configuration. Mercure use Caddy server which is set by default to force HTTPS.

    mercure:
        image: dunglas/mercure
        environment:
            MERCURE_PUBLISHER_JWT_KEY: '!ChangeMe!'
            MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeMe!'
            SERVER_NAME: ":80"