Question

Need help deploying meteor app on a DO droplet with ubuntu 16.04 with nginx

My Meteor app is not working in Ubuntu 16.04. I’m stuck and would really appreciate any help.

I created a systemd service config for my Meteor app. My app appears to start but I get a 502 in the browser.

It appears that my service is running

root@ubuntu# journalctl -f -u mymeteorapp
    Nov 06 22:33:52 ubuntu systemd[1]: Started mymeteorapp.service.

root@ubuntu:~# systemctl status mymeteorapp
    Nov 05 12:48:42 ubuntu systemd[1]: Started Meteor.js (NodeJS) mymeteorapp application.
    root@ubuntu:~#

But I get this nginx error

root@ubuntu:/lib/systemd/system# tail -f /var/log/nginx/error.log
    2016/11/06 22:34:29 [error] 13486#13486: *248 connect() failed (111: Connection refused) while connecting to upstream, client: 84.23.134.181, server: 36.102.142.66, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "36.102.142.66"

Running netstat shows this:

root@ubuntu:/lib/systemd/system# netstat -plnt
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 4849/nginx -g daemo
    tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 17393/mongod
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4849/nginx -g daemo
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1467/sshd
    tcp6 0 0 :::80 :::* LISTEN 4849/nginx -g daemo
    tcp6 0 0 :::22 :::* LISTEN 1467/sshd

But I should see something here for 8080?

Nginx config is below:

    root@ubuntu:~# cat /etc/nginx/sites-available/mymeteorapp
    ================
    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 [::]: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 36.102.142.66; # 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 36.102.142.66; # this domain must match Common Name (CN) in the SSL certificate

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

    ssl_certificate /etc/nginx/ssl/mymeteorapp.pem; # full path to SSL certificate and CA certificate concatenated together
    ssl_certificate_key /etc/nginx/ssl/mymeteorapp.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:8080 ;
    #proxy_pass http://0.0.0.0:8080;
    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;
    }
    }
    }
    ================

Below is the script for systemd service:

root@ubuntu:~# cat /lib/systemd/system/mymeteorapp.service

    [Unit]
    Description=Meteor.js (NodeJS) mymeteorapp application
    # start the service after mongodb starts
    Requires=mongodb.service
    After=mongodb.service

    [Service]
    Type=forking
    # Automatically restart process if crashed
    Restart=on-failure
    RestartSec=10 5
    ##Restart=always
    StandardOutput=syslog
    StandardError=syslog
    SyslogIdentifier=mymeteorapp
    # drop root proviliges and switch to mymetorapp user
    User=mymeteorapp
    Group=mymeteorapp
    Environment=PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    Environment=NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
    # set to home directory of the user Meteor will be running as
    Environment=PWD=/home/mymeteorapp
    Environment=HOME=/home/mymeteorapp
    # leave as 127.0.0.1 for security
    Environment=BIND_IP=127.0.0.1
    # the port nginx is proxying requests to
    Environment=PORT=8080
    # this allows Meteor to figure out correct IP address of visitors
    Environment=HTTP_FORWARDED_COUNT=1
    # MongoDB connection string using mymeteorapp as database name
    Environment=MONGO_URL=mongodb://localhost:27017/mymeteorapp
    # The domain name as configured previously as server_name in nginx
    Environment=NODE_ENV=production
    Environment=ROOT_URL=https://36.102.142.66
    # optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
    #Environment=METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
    # this is optional: http://docs.meteor.com/#email
    # commented out will default to no email being sent
    # you must register with MailGun to have a username and password there
    # export MAIL_URL=smtp://postmaster@mymetorapp.net:password123@smtp.mailgun.org
    # alternatively install "apt-get install default-mta" and uncomment:
    # export MAIL_URL=smtp://localhostEnvironment=statedir=/var/cache/foo
    ExecStart=/usr/bin/node /home/mymeteorapp/bundle/main.js

    [Install]
    WantedBy=multi-user.target

Some refs I have used: how-to-deploy-a-meteor-js-application-on-ubuntu-14-04-with-nginx

run-your-meteor-app-on-production.html - purportedly an update for 16.04 on the 14.04 ref above though it still has the Upstart config instead of systemd.

run-meteor-app-as-a-service-on-ubuntu

how-to-deploy-node-js-applications-using-systemd-and-nginx

SystemdForUpstartUsers

initial-server-setup-with-ubuntu-16-04

how-to-install-node-js-on-ubuntu-16-04

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

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

Sign In or Sign Up to Answer

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.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

My Meteor app now runs ok in my DO Droplet running on Ubuntu 16.04 with ningx. Thought I would share the detailed config in case it helps anyone.

root@ubuntu:~# journalctl -f -u mymeteorapp
-- Logs begin at Sat 2016-10-29 23:05:30 UTC. --
Nov 11 01:16:30 ubuntu systemd[1]: Started mymeteorapp.service.
Nov 11 01:16:32 ubuntu mymeteorapp[11060]: colections.js - category count:  7
Nov 11 01:20:06 ubuntu systemd[1]: Stopping mymeteorapp.service...
Nov 11 01:20:06 ubuntu systemd[1]: Stopped mymeteorapp.service.
Nov 11 01:20:18 ubuntu systemd[1]: Started mymeteorapp.service.
Nov 11 01:20:19 ubuntu mymeteorapp[11196]: colections.js - category count:  7
Nov 11 01:30:21 ubuntu systemd[1]: Stopping mymeteorapp.service...
Nov 11 01:30:21 ubuntu systemd[1]: Stopped mymeteorapp.service.
Nov 11 01:30:34 ubuntu systemd[1]: Started mymeteorapp.service.
Nov 11 01:30:35 ubuntu mymeteorapp[11307]: colections.js - category count:  7
root@ubuntu:~# systemctl status mymeteorapp
● mymeteorapp.service
   Loaded: loaded (/lib/systemd/system/mymeteorapp.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2016-11-11 01:30:34 UTC; 4 days ago
 Main PID: 11307 (node)
    Tasks: 9
   Memory: 58.8M
      CPU: 2min 51.174s
   CGroup: /system.slice/mymeteorapp.service
           └─11307 /usr/local/bin/node /home/mymeteorapp/bundle/main.js

Nov 11 01:30:34 ubuntu systemd[1]: Started mymeteorapp.service.
Nov 11 01:30:35 ubuntu mymeteorapp[11307]: colections.js - category count:  7
root@ubuntu:~#

root@ubuntu:~# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      11307/node
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      14308/nginx: worker
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      916/mongod
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14308/nginx: worker
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1356/sshd
tcp6       0      0 :::80                   :::*                    LISTEN      14308/nginx: worker
tcp6       0      0 :::22                   :::*                    LISTEN      1356/sshd
root@ubuntu:~#

Note that mymeteorapp now runs on port 3000. Initially had it configured to 8080. Presumably I could switch back to 8080 without too much hassle but know of no reason not to run it on 3000.

Nginx config is below:


root@ubuntu:~# cat /etc/nginx/sites-available/mymeteorapp
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 todos.net; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.
    server_name 36.102.142.66; # 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 todos.net; # this domain must match Common Name (CN) in the SSL certificate
    server_name 36.102.142.66; # this domain must match Common Name (CN) in the SSL certificate

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

    ssl_certificate /etc/nginx/ssl/mymeteorapp.pem; # full path to SSL certificate and CA certificate concatenated together
    ssl_certificate_key /etc/nginx/ssl/mymeteorapp.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_pass http://0.0.0.0:8080;
        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;
        }
    }
}
root@ubuntu:~#

Below is the script for systemd service:

root@ubuntu:~# cat /lib/systemd/system/mymeteorapp.service
[Service]
Type=simple
ExecStart=/usr/local/bin/node /home/mymeteorapp/bundle/main.js
Restart=no
#RestartSec=10 5
#Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=mymeteorapp
User=root
Group=root
Environment=NODE_ENV=production
Environment=PWD=/home/mymeteorapp/
Environment=PORT=3000
Environment=HTTP_FORWARDED_COUNT=1
Environment=MONGO_URL=mongodb://localhost:27017/mymeteorapp
#Environment=MONGO_OPLOG_URL=mongodb://127.0.0.1:27017/local
Environment=ROOT_URL=https://36.102.142.66
Environment='METEOR_SETTINGS={"someSetting": "someValue"}'

[Install]
WantedBy=default.target
root@ubuntu:~#

Hi, You can get more info on why you process is dead by doing so : in a first terminal :

journalctl -f -u mymeteorapp

and then in another window

systemctl start mymeteorapp

Perhaps giving us the output of the first window will help…