Setting up nginx on Ubuntu for parse-server

Before You Begin

  1. Check for updates
    sudo apt-get update && sudo apt-get upgrade

Install nginx

  1. Install nginx
    sudo apt-get install -y nginx
  2. Decide how you want to access parse:
    a. example.com/parseapp/
    b. parseapp.example.com/ (don’t forget to add an A record for parseapp pointing to the IP address and include subdomain in Let’s Encrypt certificates)

Setup nginx for example.com/parseapp/

  1. Change directory
    cd /etc/nginx/sites-enabled/
  2. Open default
    sudo nano default
  3. Select all
    ctrl+shift+6
    ↓↓↓↓ to the bottom
    ctrl+K
  4. Paste the following in, changing example.com, parseapp, and portnumber
    # HTTP - redirect all requests to HTTPS
    server {
        listen 80;
        listen [::]:80 default_server ipv6only=on;
        return 301 https://\$host\$request_uri;
    }
    
    # HTTPS - serve HTML from /usr/share/nginx/html, proxy requests to /parse/
    # through to Parse Server
    server {
            listen 443;
            server_name example.com;
    
            root /usr/share/nginx/html;
            index index.html index.htm;
    
            ssl on;
            # Use certificate and key provided by Let's Encrypt:
            ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    
            # Pass requests for example.com/parseapp/ to parse-server instance at localhost:portnumber
    
            location /parseapp/ {
                    proxy_set_header X-Real-IP \$remote_addr;
                    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                    proxy_set_header X-NginX-Proxy true;
                    proxy_pass http://localhost:portnumber/parse/;
                    proxy_ssl_session_reuse off;
                    proxy_set_header Host \$http_host;
                    proxy_redirect off;
            }
            location / {
                    try_files \$uri \$uri/ =404;
            }
    }
  5. Save and exit
  6. Restart nginx
    sudo service nginx restart

Setup nginx for parseapp.example.com/

  1. Change directory
    cd /etc/nginx/sites-enabled/
  2. Open default
    sudo nano default
  3. Select all
    ctrl+shift+6
    ↓↓↓↓ to the bottom
    ctrl+K
  4. Paste the following in, changing example.com, parseapp, and portnumber
    # HTTP - redirect all requests to HTTPS
    server {
        listen 80;
        listen [::]:80 default_server ipv6only=on;
        return 301 https://\$host\$request_uri;
    }
    
    # HTTPS - serve HTML from /usr/share/nginx/html, proxy requests to /parse/
    # through to Parse Server
    server {
            listen 443;
            server_name example.com;
    
            root /usr/share/nginx/html;
            index index.html index.htm;
    
            ssl on;
            # Use certificate and key provided by Let's Encrypt:
            ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    
            location / {
                    try_files \$uri \$uri/ =404;
            }
    }
    
    server {
            listen 443;
            server_name parseapp.example.com;
    
            root /usr/share/nginx/html;
            index index.html index.htm;
    
            ssl on;
            # Use certificate and key provided by Let's Encrypt:
            ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    
            # Pass requests for parseapp.example.com/ to Parse Server instance at localhost:portnumber/parse/
    
            location / {
                    proxy_set_header X-Real-IP \$remote_addr;
                    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                    proxy_set_header X-NginX-Proxy true;
                    proxy_pass http://localhost:portnumber/parse/;
                    proxy_ssl_session_reuse off;
                    proxy_set_header Host \$http_host;
                    proxy_redirect off;
            }
    }
  5. Save and exit
  6. Restart nginx
    sudo service nginx restart

Mini series

  1. Setting up a server at Linode
  2. Install Let’s Encrypt to Create SSL Certificates on Ubuntu
  3. Setting up MongoDB on Ubuntu
  4. Setting up nginx on Ubuntu for parse-server
  5. Setting up parse-server on Ubuntu

Setting up parse-server on Ubuntu

(Digital Ocean: How To Run Parse Server on Ubuntu 14.04)
(Digital Ocean: How To Migrate a Parse App to Parse Server on Ubuntu 14.04)
(GitHub: NodeSource Node.js and io.js Binary Distributions)

Before You Begin

  1. Check for updates
    sudo apt-get update && sudo apt-get upgrade

Install Node.js, Development Tools, other stuff, and parse-server

  1. Go to user’s home directory
    cd ~
  2. See NodeSource page for up-to-date installation instructions
    curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
  3. Install nodejs, build-essential and git
    sudo apt-get install -y nodejs build-essential git
  4. Install htop
    sudo apt-get install htop
  5. Install bcrypt
    sudo apt-get install bcrypt
  6. Install tmux to allow processes to run without ssh connection
    sudo apt install tmux
  7. Install parse-server and mongodb-runner (I haven’t figured out what the runner does)
    sudo npm install -g parse-server mongodb-runner

Setup Parse Cloud Code

  1. Go to user’s home directory
    cd ~
  2. Make a cloud directory
    mkdir -p ~/cloud
  3. Make a main.js file
    nano ~/cloud/main.js
  4. Paste
    Parse.Cloud.define('hello', function(req, res) {
      res.success('Hi');
    });
  5. Save and exit

Setup a new parse-server app

  1. Things you need
    • App name (long) ${newAppLong}
    • App name (short) ${newApp}
    • Password (no funny characters) ${password}
    • Parse port number ${port}
    • Parse appId ${appId}
    • Parse masterKey ${masterKey}
  2. Open port in ufw
    sudo ufw allow ${port}
  3. Add a new user to mongoDB
    mongo --port 27017
    use ${newApp}
    db.createUser({user: "${newApp}", pwd: "${password}", roles: [ { role: "dbOwner", db: "${newApp}"} ]})
    exit
  4. Restart MongoDB
    sudo service mongod restart
  5. Configure nginx for ${newApp} (parseapp) as per Setting up nginx on Ubuntu for parse-server
  6. Start parse-server on boot
    crontab -e
    If first run, select nano, 2
    At the bottom of the file add either:

    • for https://example.com/${newApp}/
      @reboot tmux new-session -s test -d parse-server --port ${port} --appId ${appId} --masterKey ${masterKey} --databaseURI mongodb://${newApp}:${password}@localhost:27017/${newApp} --cloud /home/parse/cloud/main.js --serverURL https://example.com/${newApp}/ --appName "${newAppLong}"
    • or for https://${newApp}.example.com/
      @reboot tmux new-session -s test -d parse-server --port ${port} --appId ${appId} --masterKey ${masterKey} --databaseURI mongodb://${newApp}:${password}@localhost:27017/${newApp} --cloud /home/${currentUser}/cloud/main.js --serverURL https://${newApp}.example.com/ --appName "${newAppLong}"

    Save & exit

  7. Open a new terminal window
  8. Check if npm and node are installed locally
    npm -v
    node -v
  9. If not, download and install fromhttps://nodejs.org/

  10. Install parse-dashboard locally
    sudo npm install -g parse-dashboard
  11. Run parse-dashboard locally
    parse-dashboard --appId ${appId} --masterKey ${masterKey} --serverURL https://example.com/${newApp}/ --appName "${newAppLong}"
    or
    parse-dashboard --appId ${appId} --masterKey ${masterKey} --serverURL https://${newApp}.example.com/ --appName "${newAppLong}"

Mini series

  1. Setting up a server at Linode
  2. Install Let’s Encrypt to Create SSL Certificates on Ubuntu
  3. Setting up MongoDB on Ubuntu
  4. Setting up nginx on Ubuntu for parse-server
  5. Setting up parse-server on Ubuntu

Install Let’s Encrypt to Create SSL Certificates on Ubuntu

(Linode: Install Let’s Encrypt to Create SSL Certificates)
[Update 2018 03 06: You might want to look at Certbot]

Before You Begin

  1. Check for updates
    sudo apt-get update && sudo apt-get upgrade
  2. Check if git is installed
    which git
    If not install git
    sudo apt-get install git
    Password
    y
  3. Open a port for Let’s Encrypt
    sudo ufw allow 443
    [Update 2018 03 06: (you might need to allow port 80 as well for some reason)]

Install Let’s Encrypt

  1. Download and install Let’s Encrypt
    sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
  2. Navigate to the new /opt/letsencrypt directory:
    cd /opt/letsencrypt

Create an SSL Certificate

  1. Run Let’s Encrypt including each domain to be covered with a -d
    • sudo -H ./letsencrypt-auto certonly --standalone -d example.com -d www.example.com
    • password
    • a good email address
    • Agree
    • Success!
      IMPORTANT NOTES:
      - Congratulations! Your certificate and chain have been saved at/etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2017-xx-xx. To obtain a new or tweaked version of this certificate in the future, simply run letsencrypt-auto again. To non-interactively renew *all* of your certificates, run "letsencrypt-auto renew"
      - If you like Certbot, please consider supporting our work by:
      Donating to ISRG / Let's Encrypt:
      https://letsencrypt.org/donate
      Donating to EFF:
      https://eff.org/donate-le
  2. Setup auto renewals of certificates
    • sudo crontab -e
    • First run select nano as editor
    • Add the line to the bottom of the file to run at 02:30 every Monday, pausing nginx to allow access to port 443 as required.
      30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew --quiet --pre-hook "sudo service nginx stop" --post-hook "sudo service nginx start"
      (I HAVEN’T confirmed this is working yet, but it should be)

Mini series

  1. Setting up a server at Linode
  2. Install Let’s Encrypt to Create SSL Certificates on Ubuntu
  3. Setting up MongoDB on Ubuntu
  4. Setting up nginx on Ubuntu for parse-server
  5. Setting up parse-server on Ubuntu

Setting up MongoDB on Ubuntu

(MongoDB: Install MongoDB Community Edition on Ubuntu)
(Linode: Install MongoDB on Ubuntu 16.04 (Xenial))
(Digital Ocean: How To Install MongoDB on Ubuntu 14.04)

Before You Begin

  1. Check for updates
    sudo apt-get update && sudo apt-get upgrade

Add the MongoDB repository

  1. Import the MongoDB public GPG key for package signing
    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
  2. Add the MongoDB repository to your sources.list.d directory
    echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
  3. Update your repositories. This allows apt to read from the newly added MongoDB repo
    sudo apt-get update
  4. Install MongoDB
    sudo apt-get install mongodb-org
  5. Enable auto-start on reboot
    sudo systemctl enable mongod.service
  6. Open a port in ufw
    sudo ufw allow 27017

Running MongoDB

  1. Start MongoDB
    sudo service mongod start
  2. Verify MongoDB started
    sudo nano /var/log/mongodb/mongod.log
    and look for
    [initandlisten] waiting for connections on port 27017
  3. Stop MongoDB
    sudo service mongod stop
  4. Restart MongoDB
    sudo service mongod restart

Setup MongoDB users

  1. Open MongoDB
    mongo --port 27017
  2. Create an admin database
    use admin
  3. Add a mongodbAdminUsername and mongodbAdminPassword (letters and numbers, no funny characters)
    db.createUser({user: "mongodbAdminUsername", pwd: "mongodbAdminPassword", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]})
  4. Exit
    exit
  5. Restart MongoDB
    sudo service mongod restart

Mini series

  1. Setting up a server at Linode
  2. Install Let’s Encrypt to Create SSL Certificates on Ubuntu
  3. Setting up MongoDB on Ubuntu
  4. Setting up nginx on Ubuntu for parse-server
  5. Setting up parse-server on Ubuntu

Setting up a server at Linode

Getting started

(Linode: Getting Started)
(Digital Ocean: Additional Recommended Steps for New Ubuntu 14.04 Servers)

  1. Sign up
  2. Add a Linode
    • Select
      Linode 2048
    • Select
      Location
    • Click
      Add this Linode!
  3. Click linodexxxxxxx
  4. Click Deploy an Image
  5. Cofigure deployment
    • Image Ubuntu 16.04 LTS
    • Deployment Disk Size max
    • Swap Disk 512MB
    • Root Password ••••••••
    • Click Deploy
  6. Boot
    • Click Boot
    • Confirm boot
  7. SSH
    • Click Remote Access tab
    • Click SSH Access link ssh root@xxx.xxx.xxx.xxx
    • Click Allow to open in Terminal
    • Terminal should open (first run has some additional Allows and yeses)
    • Enter password in Terminal
  8. Update software via ssh apt-get update && apt-get upgrade
  9. Choose a newhostname and set it hostnamectl set-hostname newhostname
  10. Update /etc/hosts
    • nano /etc/hosts
    • Add IP address and newhostname separated by a tab below:
      127.0.0.1 localhost
      127.0.1.1 ubuntu.members.linode.com

      xxx.xxx.xxx.xxx newhostname
    • Exit ^X
    • Save y
    • File Name to Write: /etc/hosts ↩︎
  11. Setup timezone (I like UTC)
    • dpkg-reconfigure tzdata
    • Arrow around, ↩︎, ⎋
  12. Setup NTP network time synchronisation
    • sudo apt-get install ntp

Securing the server

(Linode: Securing Your Server)

  1. Login
    • ssh root@xxx.xxx.xxx.xxx
    • Password
  2. Add a limited user account
    • adduser example_user
    • Password
    • Retype password
    • Enter Full name
    • Room number
    • Work phone number
    • Home phone number
    • Other
    • Is the info correct? Y
  3. Add user to admin group
    • adduser example_user sudo
  4. Logout exit
  5. Login again, but as the new user
    • ssh example_user@xxx.xxx.xxx.xxx
    • Password
  6. Harden SSH access
    • Create an ssh directory on the Linode machine
      mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/
    • (open a new Terminal window)
    • Check if you have an RSA key-pair on your local Mac
      ls ~/.ssh/id_rsa*
      If NOT,
      ssh-keygen -b 4096
    • Copy the public key from your Mac to the Linode machine
      scp ~/.ssh/id_rsa.pub example_user@xxx.xxx.xxx.xxx:~/.ssh/authorized_keys
    • Swap back to linode terminal
    • Set permissions on the Linode machine
      sudo chmod 700 -R ~/.ssh && chmod 600 ~/.ssh/authorized_keys
    • Logout
      exit
    • Login again, as the new user
      ssh example_user@xxx.xxx.xxx.xxx
      (no password required)
  7. Edit SSH Daemon Options
    • sudo nano /etc/ssh/sshd_config
    • Password
    • Disallow root logins over SSH: change PermitRootLogin yes to PermitRootLogin no
    • Maybe disable SSH password authentication: change PasswordAuthentication yes to PasswordAuthentication no
    • Restart SSH Daemon sudo systemctl restart sshd
  8. Automatic updates (Ubuntu: Automatic Updates)
    • Install package sudo apt install unattended-upgrades
    • Make schedule sudo nano /etc/apt/apt.conf.d/10periodic
      Add lines:
      APT::Periodic::Update-Package-Lists "1";
      APT::Periodic::Download-Upgradeable-Packages "1";
      APT::Periodic::AutocleanInterval "7";
      APT::Periodic::Unattended-Upgrade "1";
      Exit ^X
      Save y
      Write ↩︎
    • Setup notifications sudo apt install apticron
  9. Enable firewall
    sudo ufw allow proto tcp from any to any port 22
    sudo ufw enable
  10. Use Fail2Ban to block multiple unsuccessful login attempts
    (Linode: Using Fail2ban to Secure Your Server)
  11. Install Fail2ban
    sudo apt-get install fail2ban
  12. Configure fail2ban
    • cd /etc/fail2ban
    • Copy fail2ban.conf file and # all lines
      sed 's/\(^[[:alpha:]]\)/# \1/' fail2ban.conf | sudo tee fail2ban.local &> /dev/null
    • Copy jail.conf file and # all lines
      sed 's/\(^[a-z tab]\)/# \1/' jail.conf | sudo tee jail.local &> /dev/null

Point a domain name at your new IP

(Linode: DNS Manager Overview)
(Linode: Common DNS Configurations)

  1. Login to your domain registrar and change the zone file (DNS management) to point to Linode’s name servers.
    • ns1.linode.com
    • ns2.linode.com
    • ns3.linode.com
    • ns4.linode.com
    • ns5.linode.com
  2. Create a new domain zone
    • Login to Linode Manager
    • Click on DNS Manager tab
    • Click Add a domain zone
    • Domain your domain
    • SOA Email A good email address
    • Insert Default Records Yes, ...
    • Click Add a Master Zone

Mini series

  1. Setting up a server at Linode
  2. Install Let’s Encrypt to Create SSL Certificates on Ubuntu
  3. Setting up MongoDB on Ubuntu
  4. Setting up nginx on Ubuntu for parse-server
  5. Setting up parse-server on Ubuntu