Hello everyone,
I’m facing an issue with establishing WebSocket (wss://
) connections for Phoenix LiveView in a deployed application on Clever Cloud. The application works perfectly in HTTP, but as soon as I switch to HTTPS (which Clever Cloud handles with Let’s Encrypt), the WebSocket connection fails.
Environment:
- Elixir version: 1.14
- Phoenix version: 1.7.10
- Phoenix LiveView version: 1.0
- Clever Cloud: Hosting the application
- LiveView version: 0.18.18
- WebSocket protocol: WSS
- Frontend: JavaScript (Phoenix LiveSocket)
- Backend: Phoenix framework with LiveView and PubSub
Steps Taken:
- I’ve configured Phoenix to handle both HTTP and WebSocket connections using the correct URL and port configurations.
- The application works perfectly over HTTP (i.e., it uses
ws://
for WebSockets), but as soon as I enable HTTPS on Clever Cloud (which uses Let’s Encrypt), the WebSocket connection switches towss://
, and it fails to connect. - I’ve already checked that the domain and DNS configuration on Clever Cloud are correct. The application is accessible via
https://www.felicien.cool
and the certificate is valid.
Problem:
- The WebSocket (
wss://
) connection repeatedly fails to connect. - I can see that the connection is being established in the server logs (Phoenix is logging “CONNECTED TO Phoenix.LiveView.Socket”).
- On the frontend, I see an error in the browser’s developer console that says
WebSocket connection to 'wss://www.felicien.cool/live/websocket' failed
. - The app works as expected over HTTP (i.e., using
ws://
for WebSocket).
Current Configuration:
config.exs
:
elixir
Copy
config :wordly, WordlyWeb.Endpoint,
# Port 80 pour HTTP
url: [host: "www.felicien.cool", port: 443],
render_errors: [
formats: [html: WordlyWeb.ErrorHTML, json: WordlyWeb.ErrorJSON],
layout: false
],
pubsub_server: Wordly.PubSub,
check_origin: ["https://felicien.cool", "https://www.felicien.cool"],
live_view: [signing_salt: "xxxx"]
runtime.exs
:
host = System.get_env("PHX_HOST") || "www.felicien.cool"
port = String.to_integer(System.get_env("PORT") || "4000")
config :wordly, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
config :wordly, WordlyWeb.Endpoint,
url: [host: host, port: 443, scheme: "https"],
http: [
# Enable IPv6 and bind on all interfaces.
# Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
# See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html
# for details about using IPv6 vs IPv4 and loopback vs public addresses.
ip: {0, 0, 0, 0, 0, 0, 0, 0},
port: port
],
secret_key_base: secret_key_base
JavaScript (LiveSocket)
:
js
import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
import topbar from "../vendor/topbar";
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken } });
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
window.addEventListener("phx:page-loading-start", () => topbar.show(300));
window.addEventListener("phx:page-loading-stop", () => topbar.hide());
liveSocket.connect();
window.liveSocket = liveSocket;
Troubleshooting Done:
- Verified that the WebSocket URL (
wss://www.felicien.cool/live/websocket
) is correct and accessible. - Ensured the certificate is valid and the domain is correctly configured for SSL in Clever Cloud.
- Checked browser logs and network activity, where I see that the connection to the WebSocket URL fails.
- Confirmed that the issue only happens when switching to HTTPS; everything works in HTTP.
Questions:
- Could there be a misconfiguration on my end that’s causing the WebSocket connection to fail when using
wss://
? - Is there anything specific in Clever Cloud’s configuration that I may need to check for WebSocket connections (like reverse proxy settings)?
- Should I disable the
https:
configuration in Phoenix and let Clever Cloud handle everything, or is there a specific setting I need to adjust? - Could this be related to Clever Cloud’s load balancer, and if so, how can I ensure WebSocket connections are passed through correctly?
Any advice or insights on how to resolve this would be greatly appreciated!
Thank you in advance!