Containerized ExpressJS service in 10 mins or less
da club has asbestos
Posted on January 6, 2020
Intro
Yah this article has probably been written 100 times across different blogs. However there are two reasons why I am writing it:
1.) I'm trying to get into blogging and sharing my knowledge this year.
2.) I am trying to make this something a complete beginner could follow,and be running in 10 mins or less.
So what are we going to build here
We will be setting up a simple NodeJS server (powered by ExpressJS).
This server will support a API, along with a view engine for rendering some pretty things to the browser. Finally, we will wrap our application in a Docker container allowing easy hosting in a service like AWS.
Glossary (list of tools and concepts you need to know)
NodeJS
A javascript runtime that allows javascript code to be written and executed outside of a browser. It come with a set of standard utility libraries for handling file system operation, compression, and other low level tasks. It allows us to build backend servers in Javascript.
ExpressJS
A popular web framework that runs on top of NodeJS. It handles HTTP calls, routing, views, etc. Basically it abstracts away some of the low level stuff so that we can focus on building websites.
Docker
This is a popular software for running containers. Containers are operating systems that run as a virtualized instance on your machine (or on a cloud host). Since the docker environment is decoupled from your host machine, you have confidence that your software will run the same anywhere you decide to put it.
Step1: Setting up a ExpressJS server
First you will need to install NodeJS. If you are on OSX, the easiest way to do this is via a package manager like Homebrew. This allows you open your terminal and run
brew install nodejs
otherwise just install it manually from here.
Once node is setup we can bootstrap our ExpressJS project. The easiest way to do this is to use a tool called express-generator.
Install this as a global node package using
npm install -g express-generator
.
Once that finishes we run a command to setup our project
express --view=ejs my-app
This sets up a new express app, using the EJS view engine. Putting it into a folder called my-app.
Navigate to the my-app folder and run
npm install
This will parse the package.json and install an necessary dependencies.
With this you should be able to type
npm run start
Navigate to http://localhost:3000 to see your app. By default there are two routes active.
http://localhost:3000 -> Index/Title Page
http://localhost:3000/users -> A api page that returns a mock resource.
Im not going to go in depth here on how to build a full application here. Feel free to explore/experiment with this:
app.js -> This is your server entry point. High level route registration, and middleware injection happens here.
views/ -> this folder holds your UI templates
routes/ -> this holds the javascript route controllers. They tell your server what to do when a user tries to hit a specific page
public/ -> This holds your static assets CSS/Javascript/Images
Step 2: Running above code in Docker
First we need to install docker. Unfortunately this is a rare case where its actually more annoying to use Homebrew than it is to just get the software from the official website. Download here.
Once you have Docker installed we need to make 2 files in our /my-app/
directory.
1.) Create a .dockerignore
file and the following lines
node_modules
npm-debug.log
this prevents docker from packaging our dependencies. It will download those itself, using npm,
2.) Next create a file called Dockerfile
at the root of /my-app/
Read the comments here if you are curious what each line means
# We import our base operating image. In this case I use node:12
# as that is the most recent stable release of NodeJS
from node:12
# Create a directory where your app will run, inside the docker environment
WORKDIR /usr/src/app
# Copy package.json and package-lock.json these are your depedency definitions
COPY package*.json ./
# Install your dependencies
RUN npm install
# Copy your application into the container directory
COPY . .
# Expose whatever port your application is running on.
# In this case it is port 3000
EXPOSE 3000
# Start our application
CMD ["npm", "run", "start"]
With this we have defined what our Docker container will do. Now it is time to build it. Run the following while in the directory where your Dockerfile is located:
docker build -t my-app-container .
This will execute the above Dockerfile. Setup all dependencies, and build a executable image.
once this is complete run
docker images
you should see something like this:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app-container latest c4f59b39a747 9 minutes ago 915MB
node 12 6b5991bf650f 8 days ago 913MB
Now to run your app in the container you can run this command:
docker run -p 8080:3000 my-app-container
This command runs the images, and forwards traffic from the internal docker port (3000 where our app is running), to the local port 8080.
With this you should be able to navigate to http:localhost:8080, and see the express app running.
Conclusion
That it you now have a express app setup, and a portable Docker container. You can run this container locally, put it on a service like Amazon ECS, Digital Ocean, Azure, Google Container Service. Or just give it to a friend, and you will be sure that it runs exactly as on your machine.
Next Steps
Of course the app we made is far from production ready. There are a couple things we could do to improve the overall architecture here. For example.
1.) Add a NGINX layer for to act as a load balancing production server.
2.) Add Supervisor to auto restart our app process on failure.
3.) Add Typescript to express for type safe code.
4.) Serve a ReactJS bundle on one of our routes.
5.) Deploy our app to a cloud provider like Amazon ECS
6.) Add nodemon to speed up our development workflow.
Comment if any of these would interest you in future tutorials.
Posted on January 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.