Stuck on 92% Chunk Optimization on Angular Production Builds?

The purpose of this article is to show you how I overcame an out-of-memory issue while building the production version of my Angular web application on my Ubuntu server by adding swap space.

Please keep in mind that building the Angular production bundle using another cloud providers resources (like building Angular on an AWS EC2) can get expensive fast. In light of that I figured out a way to automatically build and deploy Angular production builds essentially for free on GitLab.

The Problem

While Angular CLI was building the production build on the server, the machine returned a process out of memory error message. Here is what the stack trace looked like on the terminal:


FATAL ERROR: Committing semi space failed. 
Allocation failed - process out of memory 
1: node::Abort() [ng build --prod --aot]

At the time of writing this post this was my technology stack:

• Ubuntu 16.04.5 LTS (xenial)
• Node 8.12.0
• Angular CLI 6.1.3
• Angular 6.1.2

The Solution

After some doing some online research I found that a solution to this problem was to add additional swap space on my server. In this post, I will show you how I added swap space to my Ubuntu 16.04.5 LTS.

What is Swap Space?

Swap space is essentially emergency RAM that that sits on your hard drive and is utilized whenever you’re running your RAM close to max capacity. Sometimes large programs make the entire system need extra memory. Swap space can be a dedicated partition of your hard drive, a swap file, or a combination of both. The steps below will show you how to add more swap space to your machine.

Click here for the Official Ubuntu Swap Faq

Checking System Swap Information

First, we will check out our system to see if there are any existing swap configurations with the following:

$ sudo swapon --show

If the machine does not return an output then your system does not swap space available.

You can verify that there is no active swap using the free utility:

$ free -h

If you see a row of 0B‘s in the Swap row, no swap is active on the system.

Check Available Hard Drive Space

The most common way of allocating space for swap is to use a separate partition devoted to the task. However, altering the partitioning scheme is not always possible. We can just as easily create a swap file that resides on an existing partition.

Before we do this, we should check the current disk usage by typing:

$ df -h

The device under /dev in the output is our disk in this case.

For machines with less than 1 GB, it is highly recommended that the swap space should be at bare minimum equal to the amount of RAM. On top of that, it’s also recommended that swap space is at maximum, twice the amount of RAM depending on the currently available disk space. If need more swap space than twice your RAM then you should upgrade your server or add more RAM.

Create a Swap File

Let’s create a file of the swap size that we want to be called swapfile in our root directory.

My server had 512MB of RAM so for this example I will create a 1GB file with fallocate. Please adjust the file size to meet the needs of your own server.

More information on fallocate

$ sudo fallocate -l 1G /swapfile

Once the swap file is created we can verify that the correct amount of space was allocated with the following command:

$ ls -lh /swapfile

output:

$ -rw-r--r-- 1 root root 1.0G Oct 02 12:15 /swapfile

Enabling the Swap File

With the swap file available we need to tell the machine to leverage the extra space available in the swap file. First, we need to set the swap file permissions to 600 to prevent other users from being from being able to access or modify the file.

$ sudo chmod 600 /swapfile

Format the file as swap with mkswap:

$ sudo mkswap /swapfile

More information on mkswap

output:

Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=41e86209-3802-424b-9a9d-d7683142dab7

After marking the file as swap space, we can enable the swap file allowing our system to start utilizing it:

sudo swapon /swapfile

We can verify that the swap space is available by typing:

$ sudo swapon --show

The terminal should return an output like the following:


NAME      TYPE  SIZE USED PRIO
/swapfile file 1024M   0B   -1

Enable the Swap File Permanently

If we reboot our server at the current moment, the machine won’t keep any of the changes we’ve made to the hard drive partition. To make the changes permanent we will have to copy our swap to the /etc/fstab.

$ sudo cp /etc/fstab /etc/fstab.bak

Last we must add the swap file details to /etc/fstab to make it available at boot up permanently.

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Final Notes


Aside from this one case, there are many other reasons that one would need swap space which is included but not limited to memory consuming programs, hibernation (suspend-to-ask), unforeseeable circumstances, or optimizing memory usage. Please let me know if I could improve this post by making anything more clear!

Dockerized Flask App with Nginx & PostgreSQL

The purpose of the article is to share my Github project dockerized-nginx-flask-postgres , a dockerized Flask application that starts 3 docker container setup. This article assumes that you have docker and docker-compose installed on your local as you will need these tools to run this project. To run my project $ git clone my repository and then run the following command in the root directory of the project:

$ docker_init.sh

When this command is run a few things will happen:

  1. docker-compose will build the 3 container setup
  2. docker-compose will spin up the cluster on one network
  3. Flask-Migrate will initialize the PostgreSQL database with basic user authentication tables

When Docker finishes initializing the application you will see the following output in of your terminal:

$ ------------------------------------ 
$ The cluster has been initialized 
$ Navigate to http://localhost:8080 
$ to see the running flask app 
$ ------------------------------------ 

Open the browser to http://localhost:8080 and if the compilation of the application was successful then you will see the message Time to get building on the web page.

What’s the Goal of this Project

The goal of this project is to build an adaptable and modular stack that can be configured to be a lean full-stack framework or API depending on your business objectives needs with little to no configuration.

Why I Chose These Technologies

  • Docker – Leveraging the modularity of Docker allowed me to structure the application in a way such that anyone who forks my repository can switch out the source code, web server, or database to whatever technologies they feel comfortable using. For example, switching out PostgreSQL for MySQL is as easy as updating the docker-compose.yml and 1 line of code in the Alembic configuration and that’s it! When technologies change you will be able to swap out any container to stay one step ahead of disruption.
  • Nginx – Nginx was specifically written to address the performance limitations of Apache web servers. It can be deployed as a standalone web server or front-end proxy for other servers. Nginx was designed to support high concurrency where each worker process can handle thousands of HTTP connections simultaneously.
  • Flask – Most of my experiences in web development have come from working with full-stack frameworks such as Laravel or CakePHP that are out of the box and heavy solutions. Full-stack frameworks are great to have many layers of abstraction for a reason, however, they abstract away a lot of what goes on under the hood. I chose Flask because I have full control of what goes on in my application and only import the libraries that are essential to the application. Flask is everything you need it to be and nothing you don’t want it to be. Building out each feature and functionality from scratch has given me a much better understanding of what happens behind the scenes of full-stack frameworks.
  • PostgreSQL – I chose PostgreSQL because it is a powerful open source RDBMS (relational database management system) and I’m most familiar with. Since Flask does not have an ORM (object-relational model) library built in I use Flask-Migrate to manage the evolution of my database.

What’s Next on My TODO List?

  • Mapping the hot reload port on the Flask Container to my Local for faster development
  • Show how to connect your PostgreSQL container to Navicat for PostgreSQL
  • Show configuration for using MySQL instead of PostgreSQL
  • Show how to connect a MySQL DB visitation tool (e.g. MySQL Workbench) to the right port on the database docker container
  • Build out restful routes to populate the basic user authentication tables

Let’s Collaborate

Check it out on Github – I would love to collaborate with anyone! Pass this project along to anyone who you know would benefit from using it or be interested in improving it with me. I will update this blog post as I improve this project.

My top 5 Sketch plugins to increase productivity

The purpose of this article is to share what I think are the most valuable sketch plugins to my workflow when designing desktop and mobile screens. Enjoy!

1. Runner

Sketch Runner Plugin

Regardless of what you’re designing on Sketch, you will need Sketch runner to speed up your Sketch workflow. With this plugin, you will be able to search through all available plugins and Sketch menu commands without having to navigate through those long drop downs. You can also insert symbols, jump to any page, apply text & layer styles, and install new plugins.

2. Content Generator

Sketch Content Generator Plugin

Almost every client or project I’ve worked on has required me to populate my screens with fake data such as names, phone numbers, geo locations, profile images, etc which took a lot of my time because I had to come up with believable data off the top of my head for at least 50 rows of data. The content generator allows you to populate any number of rows of dummy data such as avatars, names, photos, geodata, etc in seconds.

3. Spell Check Whole Page

Sketch Content Generator Plugin

There are few mistakes more embarrassing allowing a spelling error slip through the cracks from design all the way into production. Spell check whole page allows you to spell check all text of every layer on the current page you are on. I also supplement this plugin by typing all of my screen text into Grammarly to check my grammar as well.

4. Merge Duplicate Symbols

Sketch Content Generator Plugin

As I have become savvier utilizing the power of Sketch symbols this tool has saved me a lot of time cleaning up my duplicate symbols from copying and pasting other symbols. This plugin allows you to merge symbols with the same name. You simply choose the one you want to keep and press OK. The other symbols will be removed, and all of their instances will be replaced by the one you choose to keep.

5. Symbol Organizer

Sketch Symbol Organizer Plugin

There comes a point where you have 50+ symbols throughout your Sketch file and you are dreading looking at the symbols page because of how messy you know it will be. Fortunately, the symbol organizer plugin organizes your symbols page alphabetically into groupings determined by symbols names in a clean grid.

Final Notes

I hope that these Sketch plugins add value to your daily workflow. What Sketch plugins have either changed the way you design or increase your productivity? Write them below!

Deploy an Angular App in Production with Nginx & Ubuntu on EC2

This purpose of this tutorial is to show you how to configure Nginx to serve an Angular app on AWS EC2. This tutorial assumes the following:

  • You already have an Amazon Web Services account (if not you can make one here) and have basic knowledge of security groups
  • You already have a purchased a domain name and have associated it with a publicly accessible IP address
  • You have an existing Angular Project hosted on a code repository (Github, GitLab, BitBucket, etc.) and have some basic knowledge of Angular

Summary of technologies used

  • Ubuntu 16.04 LTS
  • Nginx 1.10.3
  • AWS EC2
  • Angular 6.1.3

Step overview

  • Step 1 – Open an EC2 instance
  • Step 2 – Install packages and dependencies
  • Step 3 – Configure Nginx
  • Step 4 – Deployment

Step 1 – Open an EC2 instance

Log into your AWS account, navigate to the EC2 Dashboard, and select “Launch Instance”. From the list of AMIs select Ubuntu Server 16.04 LTS (HVM).

While setting up the instance, you will be brought to a page where you select the instance type. Select t2.micro (free tier eligible). Once selected, click “Review and Launch” at the bottom of the page. On the next page click “Launch” on the bottom of the page as well.

Once launched it will take a few minutes for AWS to boot up your very own EC2 instance. Store your generated key pair in a safe place on your local computer. (Here’s documentation from AWS on how to handle your key pair)

Note: You may have to adjust the security group on your EC2 instance so that your website is publicly available. There’s plenty of resources and stack overflow questions solving this potential issue.


Step 2 – Install packages and dependencies

Time to ssh into your Ubuntu server with:

ssh -i ~/path-to-your-key-pair ubuntu@ec2-your-public-ip.compute-1.amazonaws.com

Once you have successfully logged into your public server it’s time to install some packages. Execute these commands from within your Ubuntu machine:

# update Ubuntu's local package index 
$ sudo apt-get update 

# install git 
$ sudo apt-get install -y git 

# install Nginx 
$ sudo apt-get install -y nginx 

# clear out the local repository of retrieved package files 
$ sudo apt-get -s clean 

Step 3 – Configure Nginx

If you are new to Nginx I highly recommend reading the following to understand what these next steps actually do.

Common Pitfalls using Nginx

Nginx Quick Start

Nginx Configuration

Navigate the sites-available directory.

$ cd /etc/nginx/sites-available

and use your preferred editor (I use vim) to create a new file. In this case we’re storing our nginx configuration as example.com.

$ sudo vim example.com

Enter the following in your new file:

server {     
    listen 80;      
    listen [::]:80;            
    root /var/www/your-angular-app-name/dist;   
    server_tokens off;   
    index index.html index.htm;     
 
    location / {         
        # First attempt to server request as file, then         
        # as directory, then fall back to displaying a 404.          
        try_files $uri $uri/ /index.html =404;      
    } 
}

***The line root /var/www/your-angular-app-name/dist will tell Nginx where the index.html file is for your compiled Angular app.

Save your new file and symlink it to the sites-enabled folder.

$ cd /etc/nginx/sites-enabled 
$ sudo ln -s ../sites-available/example.com 
$ ls -l

Remove the default file that comes with Nginx in the sites-enabled directory. This default file was placed here by Nginx when it was installed.

$ sudo rm default

For good practice run a test on your Nginx configuration to correct any configuration or syntax errors (syntax always gets the best of us).

$ sudo nginx -t

• Restart Nginx:

$ sudo nginx -s reload

Step 4 – Deployment

Before deploying an angular application we must use the Angular CLI to create the production build that will be served on our EC2. You have the option of building the production bundle right on your local or on your live server. If you are working by yourself on a project, it’s okay to build and add the generated dist folder to git source control. Otherwise you should avoid adding the compiled dist bundle to git when working with others to avoid merge conflicts from everyone’s own build.

Angular CLI documentation on deployments

Below I will show you two ways to deploy your app. Both methods below are ok to “test the waters” to build small applications to understand how to deploy an Angular app but I don’t recommend you keep deploying Angular in the ways detailed below. It is well worth your time to learn how to build an automation pipeline that takes care of this process for you. See my article building a simple CI/CD pipeline from GitLab to AWS. (You can build and deploy your Angular app virtually free!)

Path 1: Building the production bundle locally

In the case that you are building the production build on your local you will need to run:

$ ng build --prod

If there are no errors when Angular is building the production bundle then a dist directory will be generated in the root directory (/) of your project.

Check in the new dist dist folder to source control so that you can pull it into your server.

You will then have to ssh into your EC2 and clone the git repository into the /var/www/ directory.

$ cd /var/www
var/www $ git clone https://your-project-name

Note: You may need to use the $ sudo flag if your user inside the server does not have the right permissions to run these commands.

Restart Nginx:

$ sudo nginx -s reload

Navigate to your URL or Elastic IP address and your site should be live! If all you see is an Nginx 404 page then double check the directory on the root ...; line in your Nginx sites-available file is pointing to the right directory.

Path 2: Building on the server

DISCLAIMER: Depending on how large your application is this following method can run up your cloud provider bill.

In the case that you are building the production build on your server, you will then have to ssh into your EC2 and clone the git repository into the /var/www/ directory:

$ cd /var/www
var/www $ git clone https://your-project-name

Note: You may need to use the $ sudo flag if your user inside the server does not have the right permissions to run these commands.

Now it’s time to create the production build right on the server by making sure you currently are in your source code directory. First we must install some additional dependencies on the EC2 instance with the following commands:

# install node package manager 
$ sudo apt-get install -y npm 

# install curl 
$ sudo apt-get install -y curl  
  
# install node.js $ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - 
 

# update node.js 
$ sudo apt-get install -y nodejs 
 
# install the Angular CLI 
$ sudo npm install -g @angular/cli  

Next we navigate to the directory where we cloned the repository

$ cd /var/www/the-project-you-just-cloned

Once in the project directory, you will run:

$ ng build --prod

If there is an issue with the production build then your website will display the generic Nginx 404 page. To avoid this I highly recommend testing the production build process by running the $ ng build --prod command on your local first for testing.

Once the dist folder has been built we will restart Nginx. Nginx has already been configured to look at the var/www/your-project/dist from our configuration above.

Restart Nginx:

$ sudo nginx -s reload

Navigate to your URL or Elastic IP address and your site should be live! If all you see is an Nginx 404 page then double check the directory on the root ...; line in your Nginx sites-available file is pointing to the right directory.


If you have this process down pat and want more of a challenge then check out my next post on building a simple CI/CD pipeline from GitLab to AWS.

How to preserve your static assets in the production bundle

If you want your static assets (images, svgs, etc.) to show up in production you’ll have to do the following:

  1. In your angular.json make sure that your assets folder holding your static assets is included in the assets block like so:
“tsconfig”:…
“assets”: [
  “src/favicon.ico”,
  “src/assets”,
  “src/robots.txt”,
  “src/sitemap.xml”
],
“styles”:…

With this addition to angular.json, you’re telling angular where to find the assets when you reference them throughout your code in the build process.

2. Make sure that you’re referencing the correct directory path to your assets in your HTML blocks. In the configuration above, each asset in the assets folder should be accessed like the following:

<img src="/assets/images/my_cool_image.jpg" /> 

Now when you build and deploy, the assets should show up because Angular knows where to find them now.

You’re done!

If you’ve followed all these steps, you’ll be able to navigate to your site domain in any browser and see your basic angular app up and running. If not, remember it can take up to 48 hours for any DNS changes to fully propagate if you’ve just associated your Elastic IP to your domain name manager! Thanks for reading!

Small Startup? Need to find tech talent?

The purpose of the article is to share my experiences finding tech talent with a small budget. If your company is a native or web application it’s absolutely imperative that you have a great technology foundation that meets your business’ needs – and is built by the right people. Here’s a list of mediums that may help you find tech talent in no particular order:

“People are not your most important asset. The right people are.” – Jim Collins

1. Meetups

Meetups are a great way of networking yourself amongst a group of people who generally have the same set of interests. Nowadays you can find a meet up that’s focused around certain technologies, frameworks or content management systems that your business needs.

Post a succinct description of the position and a way to contact you on the message boards of the groups you’re trying to target. Be mindful not to spam the groups with your job postings as you may want to check in with the group admins for guidelines regarding job postings on the group message board. The group admins may even help you reach the right people you’re looking for.

https://www.meetup.com/

1. AngelList

Angel list is great for finding talent that’s specifically looking for startup work. Make a company profile, add your job, and start inviting candidates to look at your job posting. When you do get a match on AngelList, be proactive and quickly respond to any developers questions about your job posting.

I would not recommend posting your job on platforms such as LinkedIn or Indeed Prime for those looking for employment on those sites are probably looking for a stable job with full benefits – not a volatile startup with no guarantee of success.

https://angel.co/

3. Code Bootcamps

Contact local code boot camps in your area and ask to speak with someone responsible for making sure the new graduates are employed ASAP after they graduate. When you reach out to these schools you will have to provide them with a short description of your ideal candidate. In turn, they will send you resumes and introduce you to the candidates that you wish to interview.  The majority of the candidates will not have 5+ years of development experience, however, most are eager to learn and jump into the next opportunity if given the chance.

4. Freelancers

Leveraging the plethora of freelancers out there is a great idea. If you’ve hired a freelancer just based on a cheap hourly rate or quote, don’t be surprised when you’re about to hit a deadline and you find out that almost nothing is production ready. Simply put, you get what you pay for. It would be best if you had a tech-savvy person, CTO, or product manager on your team that can negotiate with and properly screens the freelancers. 

https://www.upwork.com

Final Notes

Don’t focus too much on finding someone who is super passionate about your brilliant startup idea. You may be spinning your wheels looking for the “perfect fit” who fits the exact mold of what you’re looking for. You’re much better off looking for someone who loves to build awesome things regardless of what it is they’re building.

Know of another cost-efficient way to find great talent? Comment and let me know!