Replies: 12 comments 7 replies
-
|
It's a URL, not a directory in the filesystem. your.domain.com {
mercure {
...
}
}now it's reachable at But it doesn't have a GUI listening there. Please refer to the ui documentation if you need it to test. In case of a Symfony project you'd now only need to set the MERCURE_URL. |
Beta Was this translation helpful? Give feedback.
-
|
I don't have Synfony installed What you mean with |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
Hi @henderkes , The On the beginning of the example it is mentioned, that the In the |
Beta Was this translation helpful? Give feedback.
-
|
means you subscribe to the topic for changes of the
The |
Beta Was this translation helpful? Give feedback.
-
|
I understand. I guess, I should only the transfer the Und hier tdie Zeile 208: |
Beta Was this translation helpful? Give feedback.
-
For some reason the call is hitting your php_server, not mercure.
You can't use the token from the example for obvious reasons, you need to generate your own according to the Mercure documentation. |
Beta Was this translation helpful? Give feedback.
-
|
I was thinking to use the same password and the same JWT value as it is in the example, to get it easier for testing. If it would working, I would change it in the next step. Can I not do it? To find the problem with php_server and mercure, I think, I have to understand what I have to do, to send it to mercure. Thanks for your help Marc. |
Beta Was this translation helpful? Give feedback.
-
No, that won't work. Even if the example token was valid at the time of writing the documentation, it wouldn't be an hour later anymore. JWT's are not passwords or immutable API keys. You need to sign a jwt using the Usually mercure should automatically be handled before php_server, so I'm not sure on that front. @dunglas any idea? |
Beta Was this translation helpful? Give feedback.
-
|
Please see my comment to your previous message. |
Beta Was this translation helpful? Give feedback.
-
|
I just tried your Caddyfile and Mercure settings (adjusted to localhost) and it's working perfectly fine: ❯❯ symfony-demo git:(main) 18:32 cat Caddyfile
localhost {
root ./public
log
encode zstd br gzip
route {
mercure {
publisher_jwt {$MERCURE_PUBLISHER_JWT_KEY:!ChangeThisMercureHubJWTSecretKey!}
subscriber_jwt {$MERCURE_SUBSCRIBER_JWT_KEY:!ChangeThisMercureHubJWTSecretKey!}
}
php_server
}
}
❯❯ symfony-demo git:(main) 18:32 frankenphp start -c Caddyfile
2026/01/31 17:32:09.634 INFO maxprocs: Leaving GOMAXPROCS=32: CPU quota undefined
2026/01/31 17:32:09.634 INFO GOMEMLIMIT is updated {"package": "github.com/KimMachineGun/automemlimit/memlimit", "GOMEMLIMIT": 30248169062, "previous": 9223372036854775807}
2026/01/31 17:32:09.634 INFO using config from file {"file": "Caddyfile"}
2026/01/31 17:32:09.635 INFO adapted config to JSON {"adapter": "caddyfile"}
2026/01/31 17:32:09.635 WARN Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies {"adapter": "caddyfile", "file": "Caddyfile", "line": 2}
2026/01/31 17:32:09.648 INFO admin admin endpoint started {"address": "localhost:2019", "enforce_origin": false, "origins": ["//[::1]:2019", "//127.0.0.1:2019", "//localhost:2019"]}
2026/01/31 17:32:09.648 INFO http.auto_https server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS {"server_name": "srv0", "https_port": 443}
2026/01/31 17:32:09.648 INFO http.auto_https enabling automatic HTTP->HTTPS redirects {"server_name": "srv0"}
2026/01/31 17:32:09.648 INFO tls.cache.maintenance started background certificate maintenance {"cache": "0xc000760680"}
2026/01/31 17:32:09.652 INFO pki.ca.local root certificate is already trusted by system {"path": "storage:pki/authorities/local/root.crt"}
2026/01/31 17:32:09.652 INFO pki intermediate expires soon; renewing {"ca": "local", "time_remaining": -1932344.652885874}
2026/01/31 17:32:09.659 INFO pki renewed intermediate {"ca": "local", "new_expiration": "2026/02/07 17:32:09.000"}
2026/01/31 17:32:09.747 INFO frankenphp FrankenPHP started 🐘 {"php_version": "8.5.1", "num_threads": 64, "max_threads": 64}
2026/01/31 17:32:09.749 WARN http HTTP/2 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2026/01/31 17:32:09.749 WARN http HTTP/3 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2026/01/31 17:32:09.749 INFO http.log server running {"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2026/01/31 17:32:09.760 INFO http enabling HTTP/3 listener {"addr": ":443"}
2026/01/31 17:32:09.771 INFO failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.
2026/01/31 17:32:09.772 INFO http.log server running {"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2026/01/31 17:32:09.772 INFO http enabling automatic TLS certificate management {"domains": ["localhost"]}
2026/01/31 17:32:09.773 INFO autosaved config (load with --resume flag) {"file": "/home/m/.config/caddy/autosave.json"}
2026/01/31 17:32:09.773 INFO serving initial configuration
Successfully started Caddy (pid=4800) - Caddy is running in the background
2026/01/31 17:32:09.776 INFO tls.obtain acquiring lock {"identifier": "localhost"}
2026/01/31 17:32:09.777 INFO tls storage cleaning happened too recently; skipping for now {"storage": "FileStorage:/home/m/.local/share/caddy", "instance": "c8634587-9fb2-421a-bdc9-0abd4a3da1ba", "try_again": "2026/02/01 17:32:09.777", "try_again_in": 86399.99999952}
2026/01/31 17:32:09.777 INFO tls finished cleaning storage units
2026/01/31 17:32:09.778 INFO tls.obtain lock acquired {"identifier": "localhost"}
2026/01/31 17:32:09.778 INFO tls.obtain obtaining certificate {"identifier": "localhost"}
2026/01/31 17:32:09.786 INFO tls.obtain certificate obtained successfully {"identifier": "localhost", "issuer": "local"}
2026/01/31 17:32:09.786 INFO tls.obtain releasing lock {"identifier": "localhost"}
2026/01/31 17:32:09.786 WARN tls stapling OCSP {"identifiers": ["localhost"]}
❯❯ symfony-demo git:(main) 18:32 curl -d 'topic=songs' -d 'data={"foo": "updated Value"}' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM' -X POST https://localhost/.well-known/mercure -k
2026/01/31 17:32:27.255 INFO http.handlers.mercure Update published {"update": {"id": "urn:uuid:019c151c-fcf6-7279-99c0-653bd918d103", "type": "", "retry": 0, "topics": ["songs"], "private": false}}
2026/01/31 17:32:27.255 INFO http.log.access handled request {"request": {"remote_ip": "::1", "remote_port": "47386", "client_ip": "::1", "proto": "HTTP/2.0", "method": "POST", "host": "localhost", "uri": "/.well-known/mercure", "headers": {"User-Agent": ["curl/8.16.0"], "Accept": ["*/*"], "Authorization": ["REDACTED"], "Content-Length": ["41"], "Content-Type": ["application/x-www-form-urlencoded"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "localhost"}}, "bytes_read": 41, "user_id": "", "duration": 0.001802698, "size": 45, "status": 200, "resp_headers": {"Alt-Svc": ["h3=\":443\"; ma=2592000"], "X-Frame-Options": ["DENY"], "X-Content-Type-Options": ["nosniff"], "X-Xss-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'self'"], "Server": ["Caddy"]}}As an example how you can use your own keys in the console: ❯❯ symfony-demo git:(main) 18:44 export MERCURE_PUBLISHER_JWT_KEY="Bsalasfoi231ijsajifijji231joSAFSAASAAsafasFF"
❯❯ symfony-demo git:(main) 18:45 frankenphp start -c Caddyfile
- snip -
Successfully started Caddy (pid=8112) - Caddy is running in the background
❯❯ symfony-demo git:(main) 18:45 HEADER=$(echo -n '{"alg":"HS256","typ":"JWT"}' | openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
❯❯ symfony-demo git:(main) 18:46 EXP=$(($(date +%s) + 86400))
❯❯ symfony-demo git:(main) 18:46 PAYLOAD=$(echo -n "{\"mercure\":{\"publish\":[\"songs\"]},\"exp\":$EXP}" | openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
❯❯ symfony-demo git:(main) 18:46 SIGNATURE=$(echo -n "$HEADER.$PAYLOAD" | openssl dgst -sha256 -hmac "$MERCURE_PUBLISHER_JWT_KEY" -binary | openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
❯❯ symfony-demo git:(main) 18:46 echo "$HEADER.$PAYLOAD.$SIGNATURE"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsic29uZ3MiXX0sImV4cCI6MTc2OTk2Nzk3MH0.15xU6VA_6jn3QcRrt_-MdOIGdxODsOkgeLQxRp-8Nf8
❯❯ symfony-demo git:(main) 18:46 curl -d 'topic=songs' -d 'data={"foo": "updated Value"}' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsic29uZ3MiXX0sImV4cCI6MTc2OTk2Nzk3MH0.15xU6VA_6jn3QcRrt_-MdOIGdxODsOkgeLQxRp-8Nf8' -X POST https://localhost/.well-known/mercure -k
2026/01/31 17:47:03.922 INFO http.handlers.mercure Update published {"update": {"id": "urn:uuid:019c152a-5d71-7b8f-907d-5e8218b61d94", "type": "", "retry": 0, "topics": ["songs"], "private": false}}
2026/01/31 17:47:03.922 INFO http.log.access handled request {"request": {"remote_ip": "::1", "remote_port": "46446", "client_ip": "::1", "proto": "HTTP/2.0", "method": "POST", "host": "localhost", "uri": "/.well-known/mercure", "headers": {"Accept": ["*/*"], "Authorization": ["REDACTED"], "Content-Length": ["41"], "Content-Type": ["application/x-www-form-urlencoded"], "User-Agent": ["curl/8.16.0"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "localhost"}}, "bytes_read": 41, "user_id": "", "duration": 0.001667541, "size": 45, "status": 200, "resp_headers": {"Content-Security-Policy": ["default-src 'self'"], "Server": ["Caddy"], "Alt-Svc": ["h3=\":443\"; ma=2592000"], "X-Frame-Options": ["DENY"], "X-Content-Type-Options": ["nosniff"], "X-Xss-Protection": ["1; mode=block"]}}
urn:uuid:019c152a-5d71-7b8f-907d-curl -d 'topic=songs' -d 'data={"foo": "updated Value"}' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM' -X POST https://localhost/.well-known/mercure -k
2026/01/31 17:47:34.126 INFO http.log.access handled request {"request": {"remote_ip": "::1", "remote_port": "46448", "client_ip": "::1", "proto": "HTTP/2.0", "method": "POST", "host": "localhost", "uri": "/.well-known/mercure", "headers": {"Accept": ["*/*"], "Authorization": ["REDACTED"], "Content-Length": ["41"], "Content-Type": ["application/x-www-form-urlencoded"], "User-Agent": ["curl/8.16.0"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "localhost"}}, "bytes_read": 0, "user_id": "", "duration": 0.000129447, "size": 13, "status": 401, "resp_headers": {"X-Xss-Protection": ["1; mode=block"], "Content-Security-Policy": ["default-src 'self'"], "X-Frame-Options": ["DENY"], "X-Content-Type-Options": ["nosniff"], "Content-Type": ["text/plain; charset=utf-8"], "Server": ["Caddy"], "Alt-Svc": ["h3=\":443\"; ma=2592000"]}}
Unauthorized # confirmation that the old example token doesn't work for this secret |
Beta Was this translation helpful? Give feedback.
-
|
Thank you, but I didn't expect, that there is an problem with the Caddyfile. My current problem is, how send a POST message to the Mercure Hub. I think, if I'm able to create the right POST message, I have solved my implementation of the Mercure HUB, hopefully! |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
I have Frankenphp running and enabled Mercure successful. Now I want to use it, but I'm not able to find the place, where Mercure is stored.
Therefore I'm not able to send the client requests to the Mercure Hub.
I can't find /.well-known/mercure anywhere,
Beta Was this translation helpful? Give feedback.
All reactions