94

I'm new to Nginx and I'm trying to get subdomains working.

What I would like to do is take my domain (let's call it example.com) and add:

  • sub1.example.com,
  • sub2.example.com, and also have
  • www.example.com available.

I know how to do this with Apache, but Nginx is being a real head scratcher.

I'm running Debian 6.

My current /etc/nginx/sites-enabled/example.com:

server {
    server_name www.example.com example.com;
    access_log /srv/www/www.example.com/logs/access.log;
    error_log /srv/www/www.example.com/logs/error.log;
    root /srv/www/www.example.com/public_html;

    location / {
        index  index.html index.htm;
    }

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
    }
}

It is working to serve example.com and www.example.com.

I have tried to add a second server block in the same file like:

server {
        server_name www.example.com example.com;
        access_log /srv/www/www.example.com/logs/access.log;
        error_log /srv/www/www.example.com/logs/error.log;
        root /srv/www/www.example.com/public_html;

        server {
            server_name sub1.example.com;
            access_log /srv/www/example.com/logs/sub1-access.log;
            error_log /srv/www/example.com/logs/sub1-error.log;
            root /srv/www/example.com/sub1;
    }
        location / {
            index  index.html index.htm;
        }

        location ~ \.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
        }
}

No luck. Any ideas? I'd super appreciate any feedback.

1
  • 1
    I should have mentioned: The ultimate goal is for sub1.example.com to go to example.com/sub1 and sub2.example.com to go to example.com/sub2. I hope that makes sense. Commented Jul 10, 2013 at 11:09

6 Answers 6

135

The mistake is putting a server block inside a server block, you should close the main server block then open a new one for the sub domains

server {
    server_name example.com;
    # the rest of the config
}
server {
    server_name sub1.example.com;
    # sub1 config
}
server {
    server_name sub2.example.com;
    # sub2 config
}
Sign up to request clarification or add additional context in comments.

5 Comments

when I try this, it cannot find the site, I had it working in different domains, I'm just testing around and this doesn't work: blog.example.com
Maybe that worked 7 years ago. Currently, "server_name example.com;" catches EVERYTHING that ends with "example.com", so you cannot make a distinction between plain domain, or a subdomain. So both "subX.example.com" AND "example.com" get catched and processed by the first server block, so the subsequent blocks will never see the light of day.
@alejandrob that seems contrary to the Nginx docs nginx.org/en/docs/http/… as well as my own experience.
The above config works fine on nginx/1.26.2 (latest as of now).
17
  1. Add A field for each in DNS provider with sub1.example.com and sub2.example.com

  2. Set the servers. Keep example.com at last:
    As below

    server {
        server_name sub1.example.com;
        # sub1 config
    }
    server {
        server_name sub2.example.com;
        # sub2 config
    }
    server {
        server_name example.com;
        # the rest of the config
    }
    
  3. Restart Nginx: sudo systemctl restart nginx

Comments

11

You just need to add the following line in place of your server_name

server_name xyz.com  *.xyz.com;

And restart Nginx. That's it.

Comments

8

You'll have to create another nginx config file with a serverblock for your subdomain. Like so:

/etc/nginx/sites-enabled/subdomain.example.com

Comments

3

There is a very customizable solution, depending on your server implementation:

Two (or more) SUBdomains in a single nginx "sites" file? Good if you own a wildcard TLS certificate, thus want to maintain ONE nginx config file. All using same services BUT different ports? (Think of different app versions running concurrently, each listening locally to differents ports)

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ~^(?<sub>.+).example.com;

    # default app (the "default" ports, good for the "old" app)
    set $app 19069;
    set $app-chat 19072;

    # new app
    # new.example.com
    if ( $sub = "new" ) {
        set $app 18069;
        set $app-chat 18072;
    }
    # upstreaming
    location / {
        proxy_redirect off;
        proxy_pass http://127.0.0.1:$app;
    }

    location /longpolling {
        proxy_pass http://127.0.0.1:$app-chat;
    }

I know the performance will "suck", but then again, since the decision was to go with one server for all it's like complaining that an econobox cannot haul as much people as a bus because the little car has a "heavy" roof rack on top of it.

A regex expert could potentially improve the performance for such a custom solution, specially since it could ommit the CPU expensive "if" conditional statements.

Comments

0

Maybe this could help someone having a challenge with this, this got me grinding the whole day. First, if you have SSL installed, remove it (delete better still), this would help reset the previous configuration that's disrupting the subdomain configuration.

in etc/nginx/.../default file create a new server block

    server {
       listen 80; 
       server_name subdomain.domain.com;

       location /{
         proxy_pass http://localhost:$port;
       }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.