striker78
By:
striker78

Is it possible to run a second meteor app (website) on my single droplet?

April 20, 2017 320 views
Applications Nginx Deployment Ubuntu 16.04

I am running a meteor app on Ubuntu 16.04 that serves up a website. Would like to serve another website (different domain) on same droplet. Is this possible?

4 Answers
striker78 April 30, 2017
Accepted Answer

It works now. Missing piece was the server block config for 'root' for each site as explained here
How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 16.04.
I also removed all 'defaultserver' settings for each site. Presume that second site redirected to first one due to it being set as 'defaultserver'.

Thanks to @jtittle for all the help!

When using the Nginx web server, server blocks (similar to the virtual hosts in Apache) can be used to encapsulate configuration details and host more than one domain off of a single server. In this guide, we'll discuss how to configure server blocks in Nginx on an Ubuntu...

@striker78

Using NGINX, yes. You'd simply setup another server block for the second domain and change the port that you're proxying to.

For example, if we have domain01.com and domain02.com, we might have something that looks like the following examples.

domain01.com

upstream @backend {
    server 127.0.0.1:3536;
}

server
{
    listen 80;
    listen [::]:80;
    server_name domain01.com www.domain01.com;

    location /
    {
        proxy_pass http://@backend;
        include /etc/nginx/config/proxy/proxy.conf;
    }
}

domain01.com

upstream @backend {
    server 127.0.0.1:3537;
}

server
{
    listen 80;
    listen [::]:80;
    server_name domain02.com www.domain02.com;

    location /
    {
        proxy_pass http://@backend;
        include /etc/nginx/config/proxy/proxy.conf;
    }
}

The only thing we're really changing in the server block is the port in @backend and the name of the server, i.e server_name.

The reference to proxy.conf is where I store my proxy configuration, which looks like this:

        proxy_buffers 16 32k;
        proxy_buffer_size 64k;
        proxy_busy_buffers_size 128k;
        proxy_cache_bypass $http_pragma $http_authorization;
        proxy_connect_timeout 59s;
        proxy_hide_header X-Powered-By;
        proxy_http_version 1.1;
        proxy_ignore_headers Cache-Control Expires;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
        proxy_no_cache $http_pragma $http_authorization;
        proxy_pass_header Set-Cookie;
        proxy_read_timeout 600;
        proxy_redirect off;
        proxy_send_timeout 600;
        proxy_temp_file_write_size 64k;
        proxy_set_header Accept-Encoding '';
        proxy_set_header Cookie $http_cookie;
        proxy_set_header Host $host;
        proxy_set_header Proxy '';
        proxy_set_header Referer $http_referer;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Original-Request $request_uri;

I prefer to keep the core configuration in another file and include it as it keeps the server blocks clean.

  • @jtittle Thanks for the reply. In your example are you putting the nginx config for both apps in a single config file?

    Also I dont use a proxy.conf file but I am new to nginx.

    In my case, I basically attempted to mimic the first app's config so I have my initial app in its own nginx config file -/etc/nginx/sites-available/mymeteorapp1 - and I copied this to create a 2nd config file/etc/nginx/sites-available/mymeteorapp2.
    I added the sym links to the /etc/nginx/sites-enabled/ dir.
    Then when I ran

    # nginx -t
    

    I got errors, first this one:

    nginx: [emerg] "server_tokens" directive is duplicate in /etc/nginx/sites-enabled/mymeteorapp2:1
    

    So I commented out that line. Then I got this error:

    duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/mymeteorapp2:14
    

    So I commented out that line too. This gave me success for config check.

    oot@ubuntu-512mb-fra1-01:~# nginx -s reload
    nginx: [warn] invalid parameter "spdy": ngx_http_spdy_module was superseded by ngx_http_v2_module in /etc/nginx/sites-enabled/mymeteorapp1:30
    nginx: [warn] invalid parameter "spdy": ngx_http_spdy_module was superseded by ngx_http_v2_module in /etc/nginx/sites-enabled/mymeteorapp2:32
    nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
    nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
    root@ubuntu-512mb-fra1-01:~#
    

    Is this a valid approach?

    • @striker78

      To really comment on what would be best overall, I'd need to see the server block(s). If you'd reply with the configuration, I'd be more than happy to tell you if there's anything that I would change or if I'd leave it as-is.

      ...

      That being said, from what I'm seeing when you're running nginx -s reload, there's two things:

      1). If you're using spdy, it's best to switch over to HTTP/2 if your version of NGINX supports it. If not, I'd consider upgrading to a version that does.

      2). If you have the ssl_stapling directive in any server block that isn't handling SSL, go ahead and remove it. It should only be defined within sever blocks that physically handle SSL.

      • @jtittle will take a look at the spdy and ssl_stapling settings. They are known issues re the config I have. I'll dig up the ref and see if I can apply fixes you suggest.

jtittle here are my nginx config files.

The nginx config for mymeteorapp1 - this one is currently live

root@ubuntu:~# cat /etc/nginx/sites-available/mymeteorapp1
server_tokens off; # for security-by-obscurity: stop displaying nginx version

# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP
server {
#    listen 80 default_server; # if this is not a default server, remove "default_server"
     listen 0.0.0.0:80;
     listen [::]:80 default_server ipv6only=on;
#listen 80;

    root /usr/share/nginx/html; # root is irrelevant
    index index.html index.htm; # this is also irrelevant

    server_name mymeteorapp1.com; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.

    # redirect non-SSL to SSL
    location / {
        rewrite     ^ https://$server_name$request_uri? permanent;
    }
}

# HTTPS server
server {
    listen 443 ssl spdy; # we enable SPDY here
    server_name mymeteorapp1.com; # this domain must match Common Name (CN) in the SSL certificate

    root html; # irrelevant
    index index.html; # irrelevant

    ssl_certificate /etc/nginx/ssl/mymeteorapp1.pem; # full path to SSL certificate and CA certificate concatenated together
    ssl_certificate_key /etc/nginx/ssl/mymeteorapp1.key; # full path to SSL key

    # performance enhancement for SSL
    ssl_stapling on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    # safety enhancement to SSL: make sure we actually use a safe cipher
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

    # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
    # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
    add_header Strict-Transport-Security "max-age=31536000;";

    # If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
    # This works because IE 11 does not present itself as MSIE anymore
    if ($http_user_agent ~ "MSIE" ) {
        return 303 https://browser-update.org/update.html;
    }

    # pass all requests to Meteor
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # allow websockets
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

        # this setting allows the browser to cache the application in a way compatible with Meteor
        # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
        # the root path (/) MUST NOT be cached
        if ($uri != '/') {
            expires 30d;
        }
    }
}

This is the nginx config for mymeteorapp2 - this is the meteor app I am currently trying to deploy

root@ubuntu:~# cat /etc/nginx/sites-available/mymeteorapp2
#server_tokens off; # for security-by-obscurity: stop displaying nginx version

# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP
server {
#    listen 80 default_server; # if this is not a default server, remove "default_server"
     listen 0.0.0.0:80;
#     listen [::]:80 default_server ipv6only=on;
#listen 80;

    root /usr/share/nginx/html; # root is irrelevant
    index index.html index.htm; # this is also irrelevant

    server_name 46.101.1xx.yy; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.

    # redirect non-SSL to SSL
    location / {
        rewrite     ^ https://$server_name$request_uri? permanent;
    }
}

# HTTPS server
server {
    listen 443 ssl spdy; # we enable SPDY here
    certificate
    server_name 46.101.1xx.yy; # this domain must match Common Name (CN) in the SSL certificate

    root html; # irrelevant
    index index.html; # irrelevant

    ssl_certificate /etc/nginx/ssl/mymeteorapp2.pem; # full path to SSL certificate and CA certificate concatenated together
    ssl_certificate_key /etc/nginx/ssl/mymeteorapp2.key; # full path to SSL key

    # performance enhancement for SSL
    ssl_stapling on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    # safety enhancement to SSL: make sure we actually use a safe cipher
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

    # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
    # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
    add_header Strict-Transport-Security "max-age=31536000;";

    # If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
    # This works because IE 11 does not present itself as MSIE anymore
    if ($http_user_agent ~ "MSIE" ) {
        return 303 https://browser-update.org/update.html;
    }

    # pass all requests to Meteor
    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # allow websockets
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

        # this setting allows the browser to cache the application in a way compatible with Meteor
        # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
        # the root path (/) MUST NOT be cached
        if ($uri != '/') {
            expires 30d;
        }
    }
}
Have another answer? Share your knowledge.