0

I was running Apache before using an htaccess rule but switched to nginx running a docker instance of the Discourse forum software. I am running nginx outside of the docker instance and then using proxypass so that it is located in domain.com/forum. Before I had it setup as seen below in order to take whatever subdomain is input minus www. and append it to the end of the url. If no subdomain is provided, it would just end up working as normal.

RewriteEngine on
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteCond %{HTTP_HOST} .example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/forum/t/%1$1 [L,NC,QSA]

I used a converter from htaccess to nginx which gave me this:

location / {
  if ($http_host !~ "^www\."){
   rewrite ^(.*)$ http://example.com/forum/t/%1$1 redirect;
  }
}

My current location setup looks like this:

location /forum {
    proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
   }
    fastcgi_read_timeout 60;
 }

So my question is, how can I merge my converted code in the if statement with my current code that contains the proxy_pass stuff? I tried to just put it in there but that just ended up with a loop.

Any insight would be appreciated, Thanks!

MostHated
  • 11
  • 3
  • You should avoid using IF with Nginx if at all possible. What you want is probably pretty simple but your question is difficult to understand. Can you please edit it to more clearly state your desired end state. – Tim Feb 16 '18 at 22:09
  • Hmm... well. I am trying to think of how to even word it differently. The block of code just above us, and the one above that, I need them both to be in the same location block and to work, if I try to put the if statement and its associated code into the location block along with the proxy_pass it will just loop. Right now my site works just fine using the bottom section of code, the middle section of code is what I need to add in there as well. – MostHated Feb 16 '18 at 23:14
  • As far as the IF statement goes, I put the original htaccess code in to an nginx converter and that is what it gave me, so I am not sure what else I could do with it or how to change it. – MostHated Feb 16 '18 at 23:18
  • Could your question be something like this: "how do I configure Nginx to listen for requests on any subdomain other than www, forwarding those requests to a URL on the root domain such as http://example.com/forum/t/(subdomain)"? – Tim Feb 16 '18 at 23:32
  • Yes, that would be correct for the first part, but the second part is doing that while still utilizing the proxy_pass and all that which is in the 3rd portion of code that I am already using to allow my forum to work. – MostHated Feb 16 '18 at 23:59

2 Answers2

1

This is what I ended up with that worked. I added some additional things after the fact for specific subdomains, but this was what got that actually working.

 server {
    server_name example.com www.example.com;
    listen ipaddress;

    root /home/me/public_html;
    index index.html index.htm index.php;
    access_log /var/log/virtualmin/example.com_access_log;
    error_log /var/log/virtualmin/example.com_error_log;
    fastcgi_param GATEWAY_INTERFACE CGI/1.1;
    fastcgi_param SERVER_SOFTWARE nginx;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_param REQUEST_METHOD $request_method;
    fastcgi_param CONTENT_TYPE $content_type;
    fastcgi_param CONTENT_LENGTH $content_length;
    fastcgi_param SCRIPT_FILENAME /home/me/public_html$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_param REQUEST_URI $request_uri;
    fastcgi_param DOCUMENT_URI $document_uri;
    fastcgi_param DOCUMENT_ROOT /home/me/public_html;
    fastcgi_param SERVER_PROTOCOL $server_protocol;
    fastcgi_param REMOTE_ADDR $remote_addr;
    fastcgi_param REMOTE_PORT $remote_port;
    fastcgi_param SERVER_ADDR $server_addr;
    fastcgi_param SERVER_PORT $server_port;
    fastcgi_param SERVER_NAME $server_name;
    fastcgi_param HTTPS $https;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/php-nginx/15187383894597.sock/socket;
    }
    listen 443 ssl http2;  listen [::]:443 ssl http2;
    ssl_certificate /home/me/ssl.combined;
    ssl_certificate_key /home/me/ssl.key;
        http2_idle_timeout 5m; # up from 3m default

    location /forum {

        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
    fastcgi_read_timeout 60;
}

 # This server forwards requests from subdomains
 server {
  server_name ~^(.*)\.example\.com$;
   listen   ipaddress default_server;

  location / {
    return 301 https://example.com/forum/c/$1;
  }
}

Then I added a few of these to test the random specific ones, they worked just fine.

 # Test for specificsub
 server {
  server_name specificsub.example.com;
   listen   ipaddress;

  location / {
    return 301 https://example.com/forum/c/assets/specificsub;
  }
}

 # Test for specificsub2
 server {
  server_name specificsub2.example.com;
   listen   ipaddress;

  location / {
    return 301 https://example.com/forum/c/assets/specificsub2;
  }
}
MostHated
  • 11
  • 3
0

Something like this should do the job. This probably won't work exactly as is, but should give you a general strategy to develop yourself. If you want someone to do all this for you and test it you should hire yourself a consultant.

I assume you have an unlimited set of subdomains.

// This server serves only forum traffic on the main domain
server {
  server_name example.com;

  location /forum {
      proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
      proxy_set_header Host $http_host;
      // etc
   }

   // This should forward all requests to the forum subfolder
   location / {
     return 301 http://example.com/forum/;
   }

   // Insert any other required locations
 }

 // This server forwards requests from subdomains
 server {
  server_name ~^(.*)\.example\.com$;
  // If the line above doesn't work uncomment these two and try them instead. They basically listen to everything not specified explicitly.
  // listen       80  default_server;
  // server_name  _;

  location / {
    return 301 http://example.com/forum/t/$1;
  }
}
Tim
  • 31,888
  • 7
  • 52
  • 78
  • Hey there, thanks for the reply. I will give this a go. My domain has *.domain.com pointed to the server, so whatever the person types in ends up becoming the category in which they hit on the forum, if it doesn't exist it just takes them to the forums main page so that I don't have to setup and subdomains. If there is a forum category named abc, you just have to type abc.domain.com and it takes you directly to that category. – MostHated Feb 17 '18 at 01:11
  • Unfortunately I have yet to be able to get this to work : ( The first one you have, when I put in a subdomain (abc.example.com) it just takes me back to example.com each time. The second one made it so nginx would not restart, so I am trying to debug that so I can try it. – MostHated Feb 17 '18 at 03:01
  • I got it mostly working. Just trying to work out a bug, but so far its mostly good. Thanks. : D – MostHated Feb 17 '18 at 05:58
  • After a bit of tweaking, I got it all working, double thanks! – MostHated Feb 17 '18 at 06:13
  • Happy to have helped. Please post your own answer to the question that shows your configuration. It might help others in future., – Tim Feb 17 '18 at 07:37