Home Ask Login Register

Developers Planet

Your answer is one click away!

cellulosa February 2016

Meteor on httpd (Apache/2.4.6 CentOS) proxy and WebSockets

I can't workout how to get WebSockets to work when I deploy my meteor app online. I keep getting this error:

WebSocket connection to 'ws://website.com/sockjs/***/********/websocket' failed: Unexpected response code: 400

I think this is due to the fact that apache sits in front of my meteor app. I know Apache 2.4 had a bug to make ws:// working, but I think this should be resolved by modules/mod_proxy_wstunnel.so, which I have enabled (of course I have enabled also modules/mod_proxy.so)

Here's my config. I'm running Meteor 1.2.1 as a systemd service (/etc/systemd/system/meteor.service) like so:

Description=meteor nodejs daemon
After=network.target remote-fs.target

ExecStart=/usr/bin/node /home/root/www/main.js


This is the output of httpd -v

Server version: Apache/2.4.6 (CentOS)
Server built:   Aug 28 2015 22:11:18

And this is the relevant part in my vhost config (/etc/httpd/conf/httpd.conf) for website.com:

<VirtualHost my.ser.ver.ip:8080>
    ServerName website.com
    ServerAlias www.website.com
    ProxyRequests Off
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    <Proxy *>
        Allow from all

I've already tried to add the RewriteCond as suggested here but no success...

Any idea? I'm also having issue getting oauth to work with th


cellulosa February 2016

Solved the mystery. Of course it was my bad: I forgot all about Varnish.

I had Varnish set on port 80 forwarding the request to Apache, which was in turn proxying the request to node.js. I resolved by removing apache and thus configuring Varnish to serve straight to node.js for that specific domain.

This is what I did:

  1. Implemented this default.vcl in /etc/varnish/
  2. Removed import directors and all the content inside sub vcl_init {} (as I only have a single server)
  3. Replaced set req.backend_hint = vdir.backend(); in sub vcl_recv {} with:

if (req.http.Host ~ "^(www\.)?website.com") {
    set req.backend_hint = nodejs;
} else {
    set req.backend_hint = apache;
  1. Created the two backends like so:

backend apache {
    .host = "";
    .port = "8080";
    .max_connections = 300;
    .probe = {
        .request =
            "HEAD / HTTP/1.1"
            "Host: localhost"
            "Connection: close";
        .interval = 5s;
        .timeout = 1s;
        .window = 5;
        .threshold = 3;
    .first_byte_timeout = 300s;
    .connect_timeout = 5s;
    .between_bytes_timeout = 2s;

backend nodejs {
    .host = "";
    .port = "3000";
    .connect_timeout = 1s;
    .first_byte_timeout = 2s;
    .between_bytes_timeout = 60s;
    .max_connections = 800;

Post Status

Asked in February 2016
Viewed 3,296 times
Voted 6
Answered 1 times


Leave an answer

Quote of the day: live life