{"id":1895,"date":"2015-06-28T12:49:56","date_gmt":"2015-06-28T12:49:56","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=1895"},"modified":"2015-08-01T08:21:09","modified_gmt":"2015-08-01T08:21:09","slug":"how-to-get-your-mean-stack-up-and-running-in-less-than-a-minute","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/codeproject\/how-to-get-your-mean-stack-up-and-running-in-less-than-a-minute\/","title":{"rendered":"How to get your MEAN stack up and running in less than a minute"},"content":{"rendered":"<p>Over the past year I&#8217;ve tried lots of options for hosting my MEAN applications, and finally I&#8217;ve settled for <a href=\"https:\/\/www.digitalocean.com\/?refcode=974c9bc93d77\">DigitalOcean<\/a>. It&#8217;s true what they advertise &#8211; that you can have a SSD cloud server up and running in less than 55 seconds. However, you don&#8217;t have to go spending your hard earned cash just yet &#8211; I have a special deal with <a href=\"https:\/\/www.digitalocean.com\/?refcode=974c9bc93d77\">DigitalOcean<\/a> and you can signup via <a href=\"https:\/\/www.digitalocean.com\/?refcode=974c9bc93d77\">this link<\/a> and get 10$ immediately, which will be enough for 2 full months of non stop server running. They even provide you with API\u00a0so that you can control your\u00a0server, and <a href=\"http:\/\/code.tutsplus.com\/tutorials\/using-the-digital-ocean-api-to-manage-cloud-instances--cms-22864\">this tutorial<\/a> shows you how.<\/p>\n<p><em>I don\u2019t want to make it look like I\u2019m pushing you on\u00a0DigitalOcean\u00a0&#8211; you can sign up with someone else if you like, I just recommend them because I had a good experience with them in the past and because it&#8217;s so easy to get a MEAN stack all pre-installed (more on this in a bit) and ready for use.<\/em><\/p>\n<h4>Create a droplet<\/h4>\n<p>Once you complete the sign up on\u00a0<a href=\"https:\/\/www.digitalocean.com\/?refcode=974c9bc93d77\">DigitalOcean<\/a>\u00a0\u00a0you will be presented with a similar screen, as show on the image below, where you have to click on the <strong>Create Droplet<\/strong> button:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_1_createDroplet.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1761\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_1_createDroplet.jpg\" alt=\"DO_1_createDroplet\" width=\"999\" height=\"555\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_1_createDroplet.jpg 999w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_1_createDroplet-300x167.jpg 300w\" sizes=\"auto, (max-width: 999px) 100vw, 999px\" \/><\/a><\/p>\n<p>Next, you have to\u00a0name your <strong>droplet<\/strong> (cool name the folks at DigitalOcean chose to call their server instances) and select the size (the smallest one will be just fine here), just as it&#8217;s shown on the image below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_2_nameAndSize.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1762\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_2_nameAndSize.jpg\" alt=\"DO_2_nameAndSize\" width=\"998\" height=\"659\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_2_nameAndSize.jpg 998w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_2_nameAndSize-300x198.jpg 300w\" sizes=\"auto, (max-width: 998px) 100vw, 998px\" \/><\/a><\/p>\n<p>After this, you have to choose a region, as shown on the image below. Naturally, you&#8217;ll want to choose some location which is closer to your targeted audience.<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_3_region.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1763\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_3_region.jpg\" alt=\"DO_3_region\" width=\"809\" height=\"367\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_3_region.jpg 809w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_3_region-300x136.jpg 300w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/a><\/p>\n<p>Now comes the most awesome part. In <strong>Select Image<\/strong> section you have tons of options ranging from the barebones distributions (Centos, Ubuntu, Debian, etc.), to the pre-built stacks (LAMP, LEMP, WordPress, ROR, MEAN, etc.) like shown on the image below. Here you have to choose the MEAN on 14.04 option (<a href=\"http:\/\/www.urbandictionary.com\/define.php?term=ymmv\">YMMV<\/a> on the exact number), and this is awesome because with this droplet you won&#8217;t have to go through the hassle of installing Node.js, Express and MongoDB as we did in the <a href=\"https:\/\/hackhands.com\/how-to-get-started-on-the-mean-stack\/\">first tutorial<\/a> &#8211; it will be already done and waiting for you! <a href=\"https:\/\/www.youtube.com\/watch?v=UPphDSc6ZEE\">B-E-A-utiful<\/a>!<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_4_image.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1764\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_4_image.jpg\" alt=\"DO_4_image\" width=\"810\" height=\"707\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_4_image.jpg 810w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_4_image-300x262.jpg 300w\" sizes=\"auto, (max-width: 810px) 100vw, 810px\" \/><\/a><\/p>\n<p>Then, just wait a few seconds and your droplet will be ready:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_5_waiting.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1765\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_5_waiting.jpg\" alt=\"DO_5_waiting\" width=\"999\" height=\"279\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_5_waiting.jpg 999w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_5_waiting-300x84.jpg 300w\" sizes=\"auto, (max-width: 999px) 100vw, 999px\" \/><\/a><\/p>\n<p>You&#8217;ll be redirected to the dashboard (once the droplet is created) which will look something like the image below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_6_created.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1766\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_6_created.jpg\" alt=\"DO_6_created\" width=\"1002\" height=\"960\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_6_created.jpg 1002w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_6_created-300x287.jpg 300w\" sizes=\"auto, (max-width: 1002px) 100vw, 1002px\" \/><\/a><\/p>\n<h4>Connect to the droplet<\/h4>\n<p>On your email address you will receive instructions which will look something like on the image below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_7_email.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1767\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_7_email-1024x301.jpg\" alt=\"DO_7_email\" width=\"604\" height=\"178\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_7_email-1024x301.jpg 1024w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_7_email-300x88.jpg 300w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_7_email.jpg 1235w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><\/p>\n<p>Now, using\u00a0a SSH client of your choice (I&#8217;m currently on Windows so not much leeway here :)) connect to the droplet. The image below shows the setting from the <a href=\"http:\/\/www.chiark.greenend.org.uk\/~sgtatham\/putty\/download.html\">Putty<\/a> SSH client on Windows:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_8_putty_2.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1776\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_8_putty_2.jpg\" alt=\"DO_8_putty_2\" width=\"458\" height=\"436\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_8_putty_2.jpg 458w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_8_putty_2-300x286.jpg 300w\" sizes=\"auto, (max-width: 458px) 100vw, 458px\" \/><\/a><\/p>\n<p>You have to connect with the <strong>root<\/strong> user and the password that was emailed to you. However, immediately upon logging in you will get a notification that you have to change the root&#8217;s password, as shown on the image below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_9_rootLogin.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1769\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_9_rootLogin.jpg\" alt=\"DO_9_rootLogin\" width=\"660\" height=\"431\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_9_rootLogin.jpg 660w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_9_rootLogin-300x196.jpg 300w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/a><\/p>\n<h4>Create a new user<\/h4>\n<p>Using root user\u00a0in linux is bad practice, so now you&#8217;re going to create a new user with the following command:<\/p>\n<pre class=\"lang:default decode:true\">useradd nikola<\/pre>\n<p>Of course, you can use any username you want. After this add the\u00a0user to the <strong>sudo<\/strong> group by executing the following command:<\/p>\n<pre class=\"lang:default decode:true\">gpasswd -a nikola sudo<\/pre>\n<p>The sudo group enables the user nikola to use\u00a0the\u00a0sudo command when using some commands that are restricted to root user. You can learn more about sudo <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-add-delete-and-grant-sudo-privileges-to-users-on-a-debian-vps\">here<\/a>. The image below shows the example of the commands I just listed:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_10_userAdd.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1770\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_10_userAdd.jpg\" alt=\"DO_10_userAdd\" width=\"453\" height=\"334\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_10_userAdd.jpg 453w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_10_userAdd-300x221.jpg 300w\" sizes=\"auto, (max-width: 453px) 100vw, 453px\" \/><\/a><\/p>\n<h3>Run<\/h3>\n<p>Now just run<\/p>\n<pre class=\"lang:default decode:true \">grunt<\/pre>\n<p>and if you visit your ip address on port <strong>3000<\/strong> you should see:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.32.35.png\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1908\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.32.35-1024x702.png\" alt=\"Screen Shot 2015-06-28 at 14.32.35\" width=\"604\" height=\"414\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.32.35-1024x702.png 1024w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.32.35-300x206.png 300w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.32.35.png 1148w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><\/p>\n<p><em>What you now have running is a well known <a href=\"http:\/\/meanjs.org\/\">MEAN.js<\/a> framework. You may have also heard about <a href=\"http:\/\/mean.io\/\">MEAN.io<\/a> and you can learn about the difference in my post about <a href=\"https:\/\/hackhands.com\/mean-io-vs-mean-js-deploying-latter-digitalocean\/\">MEAN.io vs MEAN.js<\/a>.<\/em><\/p>\n<h4>Use your own domain<\/h4>\n<p>In case you bought (or have somewhere hanging in the closet from the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Dot-com_bubble\">90&#8217;s .com boom<\/a>) a domain that you would like to use to point to your droplet you have to go to the <strong>DNS<\/strong>\u00a0settings and add a domain like shown on the image below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_11_DNS.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1771\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_11_DNS.jpg\" alt=\"DO_11_DNS\" width=\"1000\" height=\"472\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_11_DNS.jpg 1000w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/DO_11_DNS-300x142.jpg 300w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a><\/p>\n<p>Also, in your <a href=\"http:\/\/en.wikipedia.org\/wiki\/Domain_name_registrar\">domain registrar<\/a> (where you bought your domain &#8211; think Godaddy, Namecheap, Hostgator, etc.)\u00a0you have to set the corresponding nameservers to:<\/p>\n<ul>\n<li>ns1.digitalocean.com<\/li>\n<li>ns2.digitalocean.com<\/li>\n<li>ns3.digitalocean.com<\/li>\n<\/ul>\n<p>You can learn more about this on the <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-set-up-a-host-name-with-digitalocean\">official Digital Ocean guide<\/a>.<\/p>\n<h3>Using PM2<\/h3>\n<p>Running your Node.js application by hand is, well, not the way we roll. Imagine restarting the app every time something happens, or god forbid application crashes in the middle of the night and you find about it only in the morning &#8211; ah the horror. <a href=\"https:\/\/github.com\/Unitech\/pm2\">PM2<\/a> solves this by:<\/p>\n<ul>\n<li>allowing you to keep applications alive forever<\/li>\n<li>reloading applications without downtime<\/li>\n<li>facilitating common system admin tasks<\/li>\n<\/ul>\n<p>To install PM2, run the following command:<\/p>\n<pre class=\"code-pre \"><code langs=\"\">sudo npm install pm2 -g<\/code><\/pre>\n<p>To start your process with PM2, run the following command (once in the root of your application):<\/p>\n<pre class=\"lang:default decode:true\">pm2 start server.js<\/pre>\n<p>As you can see from the output shown on the image\u00a0below, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/PM2.jpg\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1777\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/PM2.jpg\" alt=\"PM2\" width=\"677\" height=\"109\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/PM2.jpg 677w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/PM2-300x48.jpg 300w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/a><\/p>\n<p>As I mentioned before, the application running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot).\u00a0The command to do that is the following:<\/p>\n<pre class=\"lang:default decode:true \">pm2 startup ubuntu<\/pre>\n<p>The output of this command will instruct you to execute an additional command which will enable the actual startup on boot or reboot. In my case the note for the additional command was:<\/p>\n<pre class=\"lang:default decode:true \">sudo env PATH=$PATH:\/usr\/local\/bin pm2 startup ubuntu -u nikola<\/pre>\n<p>If you want to learn more about the additional PM2 options you can take a look at <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-set-up-a-node-js-application-for-production-on-ubuntu-14-04#other-pm2-usage-(optional)?refcode=974c9bc93d77\">this post<\/a>.<\/p>\n<h3><strong>Using NGINX as a\u00a0Reverse proxy in front of your Node.js application<\/strong><\/h3>\n<p>Though this step is not mandatory, there are several benefits of doing so, as answered in <a href=\"http:\/\/stackoverflow.com\/questions\/16770673\/using-node-js-only-vs-using-node-js-with-apache-nginx\">this Stack Overflow question<\/a>:<\/p>\n<ul>\n<li>Not having to worry about privileges\/setuid for the Node.js process. Only root can bind to port 80 typically. If you let nginx\/Apache worry about starting as root, binding to port 80, and then relinquishing its root privileges, it means your Node app doesn&#8217;t have to worry about it.<\/li>\n<li>Serving static files like images, CSS, js, and HTML. Node may be less efficient compared to using a proper static file web server (Node may also be faster in select scenarios, but this is unlikely to be the norm). On top of files serving more efficiently, you won&#8217;t have to worry about handling eTags or cache control headers the way you would if you were servings things out of Node. Some frameworks may handle this for you, but you would want to be sure. Regardless, still probably slower.<\/li>\n<li>More easily display meaningful error pages or fall back onto a static site if your node service crashes. Otherwise users may just get a timed out connection.<\/li>\n<li>Running another web server in front of Node may help to mitigate security flaws and DoS attacks against Node. For a real-world example, <a href=\"http:\/\/web.nvd.nist.gov\/view\/vuln\/detail?vulnId=CVE-2013-4450\">CVE-2013-4450<\/a> is <a href=\"http:\/\/blog.nodejs.org\/2013\/10\/22\/cve-2013-4450-http-server-pipeline-flood-dos\/\">prevented by running something like Nginx in front of Node<\/a>.<\/li>\n<\/ul>\n<p>So, with being convinced that having NGINX in front of Node.js application is a good thing, following are the steps on how to install and configure it.<\/p>\n<p>First,\u00a0update the apt-get package lists with the following\u00a0command:<\/p>\n<pre class=\"lang:default decode:true\">sudo apt-get update<\/pre>\n<p>Then install NGINX using apt-get:<\/p>\n<pre class=\"lang:default decode:true\">sudo apt-get install nginx<\/pre>\n<p>Now open the default server block configuration file for editing:<\/p>\n<pre class=\"lang:default decode:true\">sudo vi \/etc\/nginx\/sites-available\/default<\/pre>\n<p>and add this to it:<\/p>\n<pre class=\"lang:default decode:true\">server {\r\n    listen 80;\r\n\r\n    server_name meantodo.com;\r\n\r\n    location \/ {\r\n        proxy_pass http:\/\/127.0.0.1:3000;\r\n        proxy_http_version 1.1;\r\n        proxy_set_header Upgrade $http_upgrade;\r\n        proxy_set_header Connection 'upgrade';\r\n        proxy_set_header Host $host;\r\n        proxy_cache_bypass $http_upgrade;\r\n    }\r\n}\r\n<\/pre>\n<p>This configures the <strong>web<\/strong> server to respond to requests at its root. Assuming our server is available at <a href=\"http:\/\/meantodo.com\/\">http:\/\/meantodo.com<\/a>, accessing it via a web browser would send the request to the application server&#8217;s private IP address on port 3000, which would be received and replied to by the Node.js application.<\/p>\n<p>Once you&#8217;re done with the setting you have to run the following command which will restart NGINX:<\/p>\n<pre class=\"lang:default decode:true\">sudo service nginx restart<\/pre>\n<p>You can learn more about additional NGINX setting\u00a0from quite a <a href=\"https:\/\/www.digitalocean.com\/community\/tags\/nginx?type=tutorials&amp;refcode=974c9bc93d77\">load of tutorials<\/a>.<\/p>\n<h3>Faking RAM with swap<\/h3>\n<p>Since we chose the smallest droplet version of 512 MB we can use <strong><a href=\"https:\/\/www.linux.com\/news\/software\/applications\/8208-all-about-linux-swap-space\">swap<\/a><\/strong>\u00a0to make this droplet perform better.\u00a0Swap is an area on a hard drive that has been designated as a place where the operating system can temporarily store data that it can no longer hold in RAM.\u00a0For a more indepth tutorial on this you may want to check out\u00a0<a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-add-swap-on-ubuntu-14-04\/?refcode=974c9bc93d77\">official DigitalOcean guide<\/a>.<\/p>\n<p>In order to allocate\u00a0a swap file space execute the following command:<\/p>\n<pre class=\"lang:default decode:true\">sudo fallocate -l 1G \/swapfile<\/pre>\n<p>Then restrict it to only root user by executing:<\/p>\n<pre class=\"lang:default decode:true\">sudo chown 600 \/swapfile<\/pre>\n<p>With the next two commands you actually setup\u00a0the swap space and enable it:<\/p>\n<pre class=\"lang:default decode:true \">sudo mkswap \/swapfile\r\nsudo swapon \/swapfile<\/pre>\n<p>To view the swap space information you can execute:<\/p>\n<pre class=\"lang:default decode:true\">sudo swapon -s<\/pre>\n<p>To enable swap automatically when the server restarts you have to add the following content to\u00a0the <strong>\/etc\/fstab<\/strong> file:<\/p>\n<pre class=\"code-pre \"><code langs=\"\">\/swapfile   none    swap    sw    0   0<\/code><\/pre>\n<p>Additionally, there are two more settings worth\u00a0changing:<\/p>\n<ul>\n<li>swappiness \u00a0<em>&#8211; parameter which determines how often your system swaps data out of RAM to the swap space. The value is between 0 and 100 and\u00a0represents a percentage (60 is the default, but we&#8217;ll use 10 since we&#8217;re on a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Virtual_private_server\">VPS<\/a>)<\/em><\/li>\n<li>vfs_cache_pressure &#8211; <em>parameter which determines\u00a0how much the system will choose to cache inode and dentry information over other data (default value is 100, but we&#8217;ll use 50)<\/em><\/li>\n<\/ul>\n<p>In order to make this change append the <strong>\/etc\/sysctl.conf<\/strong>\u00a0file with the following content:<\/p>\n<pre class=\"lang:default decode:true\">vm.swappiness=10\r\nvm.vfs_cache_pressure = 50<\/pre>\n<h3>Other security concerns<\/h3>\n<p>If you want to learn more on how to secure your droplet I advise you to go over the steps in the initial server setup with Ubuntu on <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/initial-server-setup-with-ubuntu-14-04\/?refcode=974c9bc93d77\">official DigitalOcean tutorial<\/a>.<\/p>\n<h3>A freakin&#8217; 150+ page MEAN tutorial PDF<\/h3>\n<p>This is actually an excerpt from the <a href=\"https:\/\/hackhands.com\/how-to-get-started-on-the-mean-stack\/\">4 part tutorial<\/a> series I wrote for <a href=\"https:\/\/hackhands.com\/\">HackHands<\/a>. If you like you can also take a look at all those posts combined into one big PDF file via <a href=\"https:\/\/leanpub.com\/meantodo\">LeanPub<\/a>:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.45.42.png\" rel=\"lightbox[1895]\" target=\"_blank\" rel=\"https:\/\/leanpub.com\/meantodo\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1910 size-full\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.45.42.png\" alt=\"Screen Shot 2015-06-28 at 14.45.42\" width=\"310\" height=\"397\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.45.42.png 310w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-28-at-14.45.42-234x300.png 234w\" sizes=\"auto, (max-width: 310px) 100vw, 310px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>P.S. It&#8217;s an intentional typo, since if you&#8217;re proud of getting something in production then it&#8217;s called a prouduction \ud83d\ude09<\/p>\n<p>P.P.S. You can enter any amount (yes, even 0$) and I won&#8217;t take it against you ;), though a coffee would be nice\u00a0<a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/smileyGlasses.png\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1759\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/smileyGlasses.png\" alt=\"smileyGlasses\" width=\"32\" height=\"32\" \/><\/a><\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/hand_rock_n_roll.png\" rel=\"lightbox[1895]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1736\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2015\/06\/hand_rock_n_roll.png\" alt=\"hand_rock_n_roll\" width=\"32\" height=\"32\" \/><\/a>\u00a0on!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Over the past year I&#8217;ve tried lots of options for hosting my MEAN applications, and finally I&#8217;ve settled for DigitalOcean. It&#8217;s true what they advertise &#8211; that you&hellip;<\/p>\n","protected":false},"author":1,"featured_media":1907,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,39],"tags":[],"class_list":["post-1895","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codeproject","category-mean"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/1895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=1895"}],"version-history":[{"count":6,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/1895\/revisions"}],"predecessor-version":[{"id":1931,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/1895\/revisions\/1931"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/1907"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=1895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=1895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=1895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}