Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
While deploying an app recently, I experienced many frustrations with the various nuances that accompany deployment, most of which were made even more difficult by the lack of centralized information about it online. Of course, this is a result of the many ways that deployment can be done (meaning that this guide is only one way to do things).
This guide is designed to be a start to finish guide for someone creating a React single page application using DigitalOcean, with every important detail. Weâll serve it with NGINX as a reverse proxy (and explain why you want to do this), PM2 as a process manager, and Serve to actually handle the serving of the app. Most of the concepts here with regards to setting up your DigitalOcean server are transferrable to the AWS EC2 platform once you have shell access to your server. The concepts here can also be utilized for other SPAs, an Express.js based server, etc.
This guide will assume you already have a DigitalOcean account and have pointed your domain name registrarâs name servers to DigitalOcean. For info on changing your name servers, check out this article from DigitalOcean: How to Point to DigitalOcean Nameservers From Common Domain Registrars
If you donât already have an account, hereâs a mutually beneficial referral link to get you started with a $10 credit (enough for about 2 months of server time for their cheapest server).
Step 1: Create a Droplet
Droplets are DigitalOceanâs cleverly named servers. Weâre going to create one. Click the big green create button at the top of the screen.
Distributions
DigitalOcean is known for having âOne-click appsâ that come shipped with everything you need, but for the sake of explicitly adding what we need, weâll start with an empty distribution.
There are multiple options as far as distributions. Ubuntu is pretty common, and I like it, so weâll go with that! Currently, there is a new LTS version on the horizonâââ17.10âââbut weâre going to stick with 16.04 since thatâs what Iâm used to working with.
Size, Location, Options
You donât need much power for a simple React app thatâs meant to serve as a portfolio or starting point for your deployment endeavors. For our purposes, Iâll select the $5 1GB / 1 vCPU / 25GB SSD / 1TB transfer option.
For location, pick whatever is closest to you or wherever you expect your users to be.
There are some really awesome options you have available, such as private networking (e.g. a server that can only communicate with your other DO servers) and weekly backups, but we donât need that for now.
SSH Keys
This one is really important! SSH (or Secure SHell) is essential for direct networking with your server in a safe way. Other articles cover this, but thereâs room for confusion that we should avoid.
First, check if you have existing SSH keys. If you are a programmer, youâve probably encountered this or at the very least already have one. To do this, open up Command Prompt / Terminal and enter ls -al ~/.ssh . This command is listing everything in the .ssh directory within your home directory (which you may not see, since itâs hidden by default), with the -a flag showing all files (meaning, the hidden ones with your normal not-hidden ones) and -l displaying more information about each subdirectory within it. If you have a pair of keys already, theyâll likely be called id_rsa and id_rsa.pub. If so, you can skip down a paragraph.
Youâll get some fancy art when you make your key.
If you donât have an SSH key, weâll need to create a new one. Create it using the command ssh-keygen -t rsa. Follow the promptsâââyouâll need to specify the file (leave it as the default id_rsa option by leaving your response blank) and a passphrase (leave it blank again if youâd like). For more details on this process, check out this other handy DigitalOcean article.
Now that you have your SSH key, cd ~/.ssh and open up id_rsa.pub. This is your public key, meaning the key that services can use to verify you are you when connecting. id_rsa is a PRIVATE keyâââdonât pass this one out. Copy the contents of the entire id_rsa.pub file, go back to your DigitalOcean âCreate Dropletâ tab in your browser, click âNew SSH Keyâ under âAdd Your SSH Keysâ, and paste it in there. Name the key something related to your computer, so you can identify where the key is held if needed.
You can now name your droplet! Itâs probably best to name them after what you plan on calling the website, since if you deploy more it could start to get confusing. Hit the big green âCREATEâ button again!
Step 2: Setting up the Droplet
After a minute from hitting âCREATEâ, your droplet should be ready. Head over to the droplets section of DigitalOcean, where youâll find a list of your droplets. Copy the IP address next to your dropletâs name on the list. Since you included an SSH key, we wonât need a password from your email or anything to login!
Connecting Via SSH
Back to your command prompt / terminal. To connect to the server over SSH, weâll use the ssh command (duh!), and specify the user on the account at IP address provided. Since weâre starting out as root, the command will look like this: ssh root@[YOUR IP HERE]. There will likely be a security prompt to ensure you want to continue (yes, you do), and a password if you specified one when creating the SSH key, but thatâs it. And like that, youâre in! Youâll know it when your prompt changes to reflect the user and server that youâre on, e.g. root@[SERVER NAME].
Changing the Default User
A major point of security when setting up a server is to change the user with which youâre connecting. In the same way that one should be explicit in their code to minimize erratic outcomes, one should be explicit in user privleges granted. The account youâre logged in as will be the account that your applications use, meaning if anything were compormised, your entire system would be in jeopardy as a result. It doesnât take much more than a `rm -rf` with too large of a scope to destroy your server.
In our SSH connection to our server, lets create a new user now: adduser [USERNAME]. Youâll be prompted for a password and some other information that isnât really necessary. We also want to make sure this user has access to the sudo groupâââmeaning the powers of rootâââwhen necessary. To do this, weâll do the following: usermod -aG sudo [USERNAME].
- usermod here is the command used to modify user accounts and privileges
- The -a flag means append / add, meaning. This can only be used with -G, whichâŠ
- -G enables you to select which group youâre adding the user to.
- sudo is the group AND level of privleges! (Fun factâââsudo comes from âsuper user doâ)
If you did it correctly, you should be able to prepend sudo to any command to run it with root privleges! Letâs test it quickly. Switch over to your new user using su [USERNAME] and try sudo echo âHello!'. You donât need root powers to do this, but itâll prompt you for your password, which is an indication that you did it correctly. If youâre not able to access it, try this process again.
Setting Up SSH For the New User
We also want to be able to SSH into this user, instead of having to go through root. Letâs set this user up for that. Logged in as the new user, enter the following commands:
- cd ~âââto get back to your home directory.
- mkdir .sshâââMaking the directory for SSH, hidden as a result of the `.` prefix
- touch .ssh/authorized_keysâââCreating the file with which your public key will be stored, so the user can recognize you.
- chmod 700 .sshâââChanging permissions of the directory; itâs hidden from others, but you still have access.
- chmod 644 .ssh/authorized_keysâââChanging permissions of the file; it can be read by all, but only changed by the current user.
That was a lot! But we still have the most important step left: adding your public SSH key. Hopefully you still have your `id_rsa.pub` fileâs contents still copied into your clipboard, but if not, go back to your computer and copy it. Now, weâll edit the file the file with VIM! VIM is intimidating to me as a new programmer, but once you know a few of the basic commands, itâs actually quite convenient. Letâs use the following command to edit your authorized keys from your home directory on your server: vim .ssh/authorized_keys.
WARNING: Iâm no VIM expert, so Iâm probably using it inefficiently. Donât hate me! It works.
Currently, we are just viewing the .ssh/authorized_keys file. To edit it, weâll press i. Now, paste in your key. Next, we can use [CTRL]+ [ to exit insert mode. Next, enter :w to write / save your file, and :x to exit it. SSH is all set! This user will recognize you when you use your private key to SSH into it.
Now that we have our new user setup, thereâs no reason for us to be working with root! Enter exit into your terminal to exit the SSH prompt. Now, letâs log in with your new username to your server via SSH! Itâs similar to before, but instead of root, weâll use your new username: ssh [USERNAME]@[IP ADDRESS].
Installing Environment Dependencies
Weâll need to install node to get working with our React app. The following will do the job to get the latest version of Node at the time of writing, 9.10, running. This is the latest version, not the LTS release, so make sure this is OK for you before proceeding. This article goes more in depth about install options via package managers and other versions.
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -sudo apt-get install -y nodejssudo apt-get install -y build-essential
This installs Node, npm, and the build tools that come in handy for npm.
Now would be a good time to install any other dependencies you may need for your app, but for a vanilla React app, youâre probably fine with this.
Once Node & npm are installed, weâre going to need to install two tools:
- npm i -g pm2âââinstalls PM2, aka Process Manager. If the name didnât tip you off, itâs going to help us handle running our app in the background of your server.
- npm i -g serveâââinstalls Serve, a very handy app that serves up a single page on a server. Since single page apps are only on one page and modify that page, this works for React.
Step 3: Setting Up Your React App On Your Server
From here on, it should be smooth sailing since the rest is stuff youâve probably already encountered in your day to day! Youâre going to need to clone your React app to the server from Github. If you used create-react-app to bootstrap this project, you can run npm run build to package your assets into a minified version that will be more efficient for production. This will create a build folder in the root directory of your project.
Now, for the main event! Run pm2 serve build. Here, PM2 will use Serve to display your webpage. I believe the default port that Serve uses is 5000, so you should be able to see your project running at [YOUR PUBLIC IP ADDRESS]:5000. If itâs not working, check pm2 listâââit will let you know what the status of all of your processes are, how many restarts each process has had, etc. While youâre at it, get familiar with the PM2 command line argumentsâââitâll come in handy when it comes to managing your app.
If it is working, great! We have just a little more work to do.
Step 4: Setting Up A Reverse Proxy with NGINX
Before we get started with the how, hereâs the why:
A reverse proxy is a buffer between your server and the rest of the internet, in addition to your standard firewall. Think of it like thisâââinstead of talking to various resources around your server, there is an intermediary that checks every request, gets the information requested from the server, and sends it back out. In our case, we have PM2/Serve putting up your webpage on port 5000 (or whatever it is on your computer). Instead of exposing that port, your app stays guarded and unexposed behind this buffer.
Letâs make sure you have NGINX installed: sudo apt-get install nginx.
NGINX is a service that works in tandem with the default Ubuntu firewall, which can be accessed with ufw. It should show up if you type ufw app list. There should be 3Â options:
- Nginx-FullâââEnables both ports 22 and 88 for HTTP and HTTPS access, respectively.
- Nginx-HTTPâââEnables port 22 for HTTPÂ only.
- Nginx-HTTPSâââEnables port 80 & HTTPSÂ only.
Installing an SSL certificate and setting up HTTPS is out of the scope of this post, but feel free to check out this solid DigitalOcean post on it. Anyway, enable whichever one is appropriate for you. Weâll assume you just want to get going, so use sudo ufw allow 'Nginx HTTPâ to allow as few ports as necessary.
Next, we need to setup the configuration of your NGINX service. Using cd /etc/nginx/sites-enabled should get you to a directory with a default file in it. vim default to open this file in VIM. Donât forget: i to insert, [CTRL] + [ to get out of insert mode, :w to write/save your file, and :x to exit.
Youâre going to want to ALMOST copy and paste everything Iâve listed in the block below to your default file, but thereâs a couple of things we need to personalize.
- server_nameâââCall it whatever you want to refer to your whole server as.
- upstreamâââThis can be named whatever as well, but itâs probably best to name it after the app youâre pointing it to. Make sure that the port address is correctâââyou want to point to your local port that your app is running on. The upstream itself is exactly as it soundsâââone of your apps that live âupstreamâ from your proxy, and is guarded as a result.
- proxy_passâââYouâre going to pass in the name of your upstream here, since itâs essentially forwarding all requests here at the moment.
upstream my_nodejs_upstream { server 127.0.0.1:5000; keepalive 64;}server { listen 80; server_name my_nodejs_server; root project_root; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection âupgradeâ; proxy_max_temp_file_size 0; proxy_pass http://my_nodejs_upstream/; proxy_redirect off; proxy_read_timeout 240s; }}
Once youâve updated this /etc/nginx/sites-enabled/default file, youâre at the finish line! Now cross it.
Enter sudo ufw enable to make sure the default firewall is enabled. Then, sudo service nginx start to get NGINX running. Once more, your app should be accessible from your IP address, except you wonât need to specify a port. Specifying a port shouldnât get you anything.
Congratulations, and thanks for sticking through this tutorial! Your app is now fully functional once more. It should be accessible via the IP address, as well as through your domain name if you setup your name servers correctly!
If you see any errors or typos, leave a comment and let me know! Iâd like to keep this up to date as fresh programmers continue to deploy their websites.
Start to Finish: Deploying a React App on DigitalOcean was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.