This article is outdated and may not work correctly for current operating systems or software.
In this tutorial, we will be learning how to set up a Koa.js web application for production, utilizing Node.js. We will also be linking a sample domain, with a reverse proxy, using Apache, and learn how to manage it with a proper process manager. Without further ado, let's get started.
Node.js is a fast, cross-platform JavaScript framework based on Chrome's V8 engine. It is used in both desktop and server applications and is famous for its single-threaded event loop handling. Node.js features a package registry called the Node Package Manager (NPM), which hosts over half a million packages. NPM packages (or modules) are the core backbone of Node.js, as they are community-driven code that can be useful in your Node.js application. In our Koa.js app, Node.js is the core part of its function.
Koa.js is a minimalistic web framework, built on the Node.js platform. Made by the same team behind the popular Express.js framework, its goal is to further minimize the already minimalistic Express.js framework by excluding middleware from its core. A major feature of Koa.js is the fact that there are no callbacks. Koa.js is built on ES6-based generators and ES6 features, such as Promises.
Apache is a popular open-source web server, used as a very basic starting point for web servers. In this tutorial, we will be using Apache as a reverse proxy, which will allow us to link our application to a sample domain. If you don't have a domain, this tutorial will still work for you, with the only difference being that the website will run on your VPS IP, instead of a domain.
As with any Node.js framework, you will need to install Node.js on your VPS. For the sake of this tutorial, I will assume that you already have Node.js installed on your system. If not, you can simply follow the instructions here.
We will need to create a folder, which will contain our application's core files.
mkdir site
Feel free to replace site
with any other name you would like for the directory. Next, we will need to initialize our Node.js package file. Change to the directory you've just created, and run npm init
, and complete the prompts. In the end, it should look something like this:
{
"name": "site",
"version": "1.0.0",
"description": "Koa.js Site",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "yourname",
"license": "ISC"
}
Now that we have our directory set up, we can proceed to install Koa.js. In the current working directory, /site
, type the following.
npm install koa
This will download the Koa.js module from NPM and install it in our project directory for future use. Next, we will create our sample application file that will hold our app code. To do so, create an index.js
file.
nano index.js
Once inside the file, create a sample application.
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
console.log('Website is live!')
Save and close the file. CTRL + X.
We will want to make sure that our application runs properly. To start it, run node index.js
, and you will see Website is live
in the console.
Now that we know our website is functional, we can proceed to install Apache and its dependencies.
sudo apt install -y libapache2-mod-proxy-html libxml2-dev
In order to use the reverse proxy feature found in Apache, we will need to enable the necessary modules.
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_ajp
a2enmod rewrite
a2enmod deflate
a2enmod headers
a2enmod proxy_balancer
a2enmod proxy_connect
a2enmod proxy_html
Some of these modules may have already been enabled, but it's always good to double-check them.
Now we need to edit the default configuration file for Apache.
sudo nano /etc/apache2/sites-enabled/000-default.conf
Here, we will need to add a block for our application.
<VirtualHost *:*>
ProxyPreserveHost On
ProxyPass / http://0.0.0.0:3000/
ProxyPassReverse / http://0.0.0.0:3000
ServerName localhost
</VirtualHost>
Save the file, CTRL + X.
You may notice that we are using port 3000
as the port for our ProxyPass
and ProxyPassReverse
IP. Since it is the same port that we are running our Koa.js application on, it is imperative that we input the correct port.
Once the changes are in place, we will need to restart Apache and relaunch our Koa.js application.
sudo systemctl restart apache2
This will ensure that our configuration file is active and ready to work when we start our Koa.js application. Once Apache is restarted, navigate back to your site directory, and start the Koa.js application like we did previously. From your web browser, navigate to http://yourdomain
, or http://yourip:
, and you will see "Hello World".
Now that we've covered the basics of creating a sample Koa.js application, we realize that in a production environment, starting the application as we are now is impractical. A process manager is definitely a requirement. That's where systemd comes into play. In simple terms, systemd consists of software that provides building blocks for a Linux system. Similar to "init", it provides a system to manage user processes after system startup. In the case of our application, systemd allows us to automatically start our website after the system has been rebooted, in case there is an event that disrupts system uptime. It also provides a set of tools that can come in handy when managing our application. The best part is the fact that it is built into Ubuntu 16.04 LTS, so we do not need to install any additional software.
Everything we need to start our application will be contained in a file called service
. It holds details about our app, such as its name, directory, environment and more. To create our system file, open a text editor.
sudo nano /lib/systemd/system/site.service
Edit and save the file like this.
[Unit]
Description=desc here
Documentation=https://example.com
After=network.target
[Service]
Environment=NODE_PORT=3000
Type=simple
User=youruser
ExecStart=/usr/bin/node /home/[youruser]/site/index.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
Replace youruser
with the username of your server. Here's a quick rundown of the important fields:
After
- This informs systemd to wait until the network interface is ready before starting our application.
Environment
- Here we can specify environment variables for our application. Our Node.js port is one of them.
Type
- This informs systemd that our app can just be started up, without forking user privileges and such.
User
- This tells systemd that we want to run the application under our user account, which is recommended. Running applications as the root user can lead to many security compromises.
ExecStart
- Essentially the command that systemd will be running to start our application, similar to how we started it manually before.
Restart
- Tells systemd under which conditions to restart our application. In this case, we want to have our website restarted in the case of an error.
We are now ready to start our systemd service.
sudo systemctl daemon-reload
This is necessary whenever a systemd service file changes in order for systemd to register any new changes made.
Then, start your application.
sudo systemctl start site
Navigate to the site in your browser once again, to verify that everything is working.
stop
- Stops the application completely.
restart
- Stops the application, and starts it again under a new process.
enable
- Tells systemd to start the application whenever you start up your computer.
status
- Shows info about the currently running application, such as uptime, application state and more.
To use any of these functions, run the following.
systemctl <function> site
We have successfully set up a Koa.js application and learned how to reverse proxy it, as well as manage it with systemd. You are now ready to expand your application and build upon this example. If you would like to learn more about Koa.js, and more things you can do with, visit their website, for more helpful information. In addition to that, if you'd like to learn more about systemd's process manager, read the documentation for it here. Finally, if you'd like to learn more about Apache's reverse proxy, feel free to check them out here.