How to install discourse forum along with multiple sites via varnish & hitch proxy

174 Views Asked by At

I'm using virtualmin with apache for my other sites.

apache listening one port 8080 varnish port 80 hitch port 443 discourse port 8081

With below default.vcl file, there isn't any problem with my other apache sites. Although discourse site opens, but with lot of problems.

  • logo not appearing, attachments not working.

I tried to turn on force https option in admin panel of discourse, but with this, no user can login to site.

My varnish config:

vcl 4.1;
import std;
# Default backend definition. Set this to point to your content server.
backend default {
    .host = "192.168.1.103";
    .port = "8080";
}
backend discourse {
    .host = "192.168.1.103";
    .port = "8081";
}

sub vcl_recv {
    if (req.http.host == "discourse.example.com") {
        set req.backend_hint = discourse;
        return (pipe);
    } else {
        set req.backend_hint = default;

    }

    if (std.port(server.ip) != 443) {
set req.http.location = "https://" + req.http.host + req.url;
return(synth(301));
}

    if (!req.http.X-Forwarded-Proto) {
        if(std.port(server.ip) == 443) {
            set req.http.X-Forwarded-Proto = "https";
        } else {
            set req.http.X-Forwarded-Proto = "https";
        }
    }
}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
}

sub vcl_synth {

    if (resp.status == 301 || resp.status == 302) {
        set resp.http.location = req.http.location;
        return (deliver);
    }
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}

My changes in discourse app.yml:

expose: 
- "8081:80" # http
# - "443:443" # https

## Uncomment these two lines if you wish to add Lets Encrypt (https)
# - "templates/web.ssl.template.yml"
# - "templates/web.letsencrypt.ssl.template.yml"
## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
# LETSENCRYPT_ACCOUNT_EMAIL: [email protected]

My hitch config changes:

pem-file = "/home/discourse/ssl.everything"

Help me in resolving this issue.

1

There are 1 best solutions below

0
PajE On

hum...

My first guess would be on your discourse configuration. I don't know that software, but if your errors are something like HTTP 404 on logo and attachment, could be a wrong discourse configuration. Could be resolved either

some things about your vcl.. it's really confused

  • the return(pipe) call makes your whole website not cacheable.. if you don't need cache, why are you using varnish (and not something easier to handle like a nginx or an apache httpd configuration)

  • your vcl_backend_response, vcl_synth and vcl_deliver declaration are unnecessary

  • you're using return(pipe) before redirecting to the https in case of http.. so the redirect won't work for your discourse website.

  • But theoretically the second proto might be http in your case ..

     if(std.port(server.ip) == 443) {
         set req.http.X-Forwarded-Proto = "https";
     } else {
         set req.http.X-Forwarded-Proto = "http";
     }
    

At the end, the following code should probably be a enought and sufficient working configuration for you

vcl 4.1;
import std;
# Default backend definition. Set this to point to your content server.
backend default {
    .host = "192.168.1.103";
    .port = "8080";
}
# Discours backend declaration
backend discourse {
    .host = "192.168.1.103";
    .port = "8081";
}

sub vcl_recv {


    if (std.port(server.ip) != 443) {
         set req.http.location = "https://" + req.http.host + req.url;
         return(synth(301));
    }

    if (!req.http.X-Forwarded-Proto) {
        if(std.port(server.ip) == 443) {
            set req.http.X-Forwarded-Proto = "https";
        } else {
            set req.http.X-Forwarded-Proto = "http";
        }
    }
    if (req.http.host == "discourse.example.com") {
        # Telling discourse the website is discourse.example.com
        # might be sufficient (if not, hardcode your website hostname into discourse
        set req.http.x-forwarded-host = req.http.host;
        set req.backend_hint = discourse;
        # Do you really want a pipe
        # (i.e. pathing the request to discourse without any transformation/cache? )
        return (pipe);
    } else {
        set req.backend_hint = default;
    }
}