Question

Nginx not redirecting to www

I’ve read the similar posts here but still not having any luck. I want to redirect any non-www traffic to www (example.com -> www.example.com), and keep the domain name in the address bar, not the IP address…

The DNS is on dreamhost, pointed to my DO droplet running Ubuntu 14.04.4. Right now both www.example.com and example.com go to my site, and keep the domain in the address bar. But it’s not inserting ‘www’.

It’s a node app running on port 3000. I have an A record (@ droplet.ip.add.ress) and a CNAME (www “example.com.”). I’ve also tried that with two A records doing (@ droplet.ip.add.ress) & (www my.ip.address).

My Nginx sites-available default looks like this:

server {
        listen                  80;
        server_name     example.com;
        return                 301 $scheme://www.example.com$request_uri;
}

server {
        listen                  80;
        server_name     $scheme://www.example.com;

        location / {
                proxy_pass                      http://localhost:3000;
                proxy_http_version         1.1;
                proxy_set_header           Upgrade $http_upgrade;
                proxy_set_header           Connection 'upgrade';
                proxy_set_header           Host $host;
                proxy_cache_bypass      $http_upgrade;
        }
}

Running “nginx -t” says my syntax and is fine and .conf test is successful. Oddly, trying to ping them or curl -I tells me it can’t resolve the host… But the site works on my phone, on different browsers, on incognito etc.

Pretty stuck but seemingly really close so any help is really appreciated!

Subscribe
Share

Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

I had a similar problem. I wanted to redirect all traffic to only the https://www version of my website. I had this kind of config in my site-available/example.com :

server {
  listen [::]:80;
  listen 80;
  server_name example.com www.example.com;
  return 301 https://www.example.com$request_uri;
}

server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;
  server_name example.com;
  return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    root /var/www/example.com/html;

    index index.html;
    
    server_name www.example.com;

    ---------------
    various SSL configs

}

But it wouldn’t redirect example.com to https://www.example.com, it would redirect to https://example.com. I also tried to use $scheme but it didn’t fix it.

What fixed it was to change the order of the servers, starting with my https://www like this:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    root /var/www/example.com/html;

    index index.html;
    
    server_name www.example.com;

    ---------------
    various SSL configs

}

server {
  listen [::]:80;
  listen 80;
  server_name example.com www.example.com;
  return 301 https://www.example.com$request_uri;
}

server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;
  server_name example.com;
  return 301 https://www.example.com$request_uri;
}

I am still new to linux and server management so I don’t know much why it is working with this config and not with the config I found everywhere on the web, but at least it is working.

Hi!

You need to replace server_name $scheme://www.example.com; with server_name www.example.com;. server_name takes only the hostname, not the actual URL. Your DNS records look correct.

Also—please add proxy_set_header Proxy ""; after the other proxy_set_header lines in order to protect your server against the HTTPoxy Vulnerability.

Make sure you reload/restart nginx so that the changes take effect.

Your config looks fine assuming you changed example.com to your actual domain. But if your app is running on port 3000, you need to change listen 80 to listen 3000.