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:

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

[Service]
User=root
ExecStart=/usr/bin/node /home/root/www/main.js
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=meteor
Environment=ROOT_URL=http://website.com
Environment=PORT=3000
Environment=NODE_ENV=production
Environment=MONGO_URL=mongodb://127.0.0.1:27017/meteor

[Install]
WantedBy=multi-user.target

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
    </Proxy>
</VirtualHost>

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

Answers


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 = "127.0.0.1";
    .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 = "127.0.0.1";
    .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

Search




Leave an answer