The goal of this exercice is to put in practice the knowledge acquired during previous exercices to deploy a new application from scratch on your server.
- The goal
- Getting started
- Create a systemd service
- Serve the application through nginx
- Provision a TLS certificate
- Set up an automated deployment with Git hooks
- End result
You must deploy the provided application in a similar way as the PHP todolist in previous exercises:
- You must install the language and database necessary to run the application, which are not the same as for the PHP todolist.
- You must run this application as a systemd service.
- You must serve this application through nginx acting as a reverse proxy.
- You must provision a TLS certificate for the application and configure nginx to use it.
- You must set up an automated deployment via Git hooks for this application.
Additionally:
- The application must run in production mode (see its documentation).
- The application must restart automatically if your server is rebooted (i.e. your systemd service must be enabled).
- The application must be accessible only through nginx. It must not be exposed directly on a publicly accessible port other than 80 or 443 (in the AWS instances used in this course, the other publicly accessible ports are 22, 3000 and 3001, with port 22 being already used by SSH).
- Clients accessing the application over HTTP must be redirected to HTTPS.
The application you must deploy is a real-time chatroom demo. Its code is available on GitHub.
It is developed with:
- Node.js (server-side JavaScript) for the backend
- Vue.js (client-side JavaScript) for the frontend
- MongoDB for the database (a non-relational, NoSQL database)
You do not need to know any of these technologies, as your goal is only to install and run the application, not modify it.
You should start by forking the repository with the Fork
button,
and use your own copy of the repository instead of the provided one. This will
make it easier for you to test the automated deployment at the end.
You must then follow the instructions in the project's README
to
install the necessary requirements and perform the initial setup. Where
necessary, you will need to find installation instructions for Ubuntu (version
20.04 Focal).
Before attempting to set up the systemd service, nginx configuration and automated deployment, you might want to simply run the application manually to make sure it works.
You can do that with the following command on your server:
$> cd /path/to/application
$> PORT=3001 npm start
You can set the
PORT
environment variable to3001
for this simple test, as that is one of the ports that should be open in your AWS virtual machine's firewall.
Visit http://W.X.Y.Z:3001 to check that it works (replacing W.X.Y.Z
by your
server's IP address). Stop the application with Ctrl-C
once you are done.
Note that you did not need to configure database access credentials as with the PHP todolist. The application tries to connect to the
one-chat-room
MongoDB database by default.It works out of the box for two reasons: MongoDB requires no user or password by default, and it's also a schema-less NoSQL database (databases and collections are created on-the-fly when they are accessed the first time).
Create and enable a systemd unit file like in the systemd exercise. Make the necessary changes to run the one chat room application instead of the PHP todolist.
Hints:
- You will find the correct command to run the application in the project's
README
. Remember that systemd requires absolute paths to commands.- You may want to set the
PORT
environment variable to choose the port on which the application will listen. You can use the publicly accessible 3001 port temporarily for testing, but you should use another free port that is not exposed to complete the exercise, since one of the requirements is to expose the application only through nginx.
Once you have enabled and started the service, it should start automatically the
next time you restart the server with sudo reboot
.
Advanced hint: if you know what you are doing, you can already set up the automated deployment project structure at this point, so that you can point your systemd configuration to the correct directory. That way you will not have to modify it later.
Create an nginx configuration to serve the application like in the nginx PHP-FPM exercise.
Hints:
- Skip all steps related to PHP FPM, since they are only valid for a PHP application.
- The
include
andfastcgi_pass
directives used in the PHP FPM exercise make no sense for a non-PHP application. You should replace them with aproxy_pass
directive. as presented during the course.
Obtain and configure a TLS certificate to serve the application over HTTPS like in the certbot exercise.
Change your deployment so that the application can be automatically updated via a Git hook like in the automated deployment exercise.
Hints:
Once you have set up the new directories, make sure to update your systemd unit file to point to the correct directory.
Update the
post-receive
hook. Compared to the PHP todolist, there are additional steps which must be performed in the script for the automated deployment to work correctly:
- Dependencies must be installed again (in case there are new ones).
- The systemd service must be restarted with
systemctl
. (Node.js code is not reinterpreted on-the-fly as with PHP; the process must be restarted so that the code is reloaded into memory).
In order for the new post-receive
hook to work, your user must be able to run
sudo systemctl restart one-chat-room
(assuming you have named your service
one-chat-room
) without entering a password, otherwise it will not work in a
Git hook.
A Git hook is not an interactive program. You are not running it yourself, so you are not available to enter your password where prompted.
Create a one-chat-room
Unix group:
$> sudo groupadd one-chat-room
Add your user to that group (replacing john_doe
with your username):
$> sudo usermod -a -G one-chat-room john_doe
Make sure that your user has been added to the group successfully by looking for
it in the /etc/group
file:
$> cat /etc/group | grep one-chat-room
one-chat-room:x:1005:john_doe
Make sure your default editor is nano
(or whichever you are more comfortable
with):
$> sudo update-alternatives --config editor
Now you will edit the sudoers
file to allow your user to run some specific
commands without a password.
WARNING: be VERY careful when editing the sudoers
file, as you may corrupt
your system if you introduce syntax errors.
$> sudo visudo
Add the following line at the bottom of the file (assuming you have named your
service one-chat-room
):
%one-chat-room ALL=(ALL:ALL) NOPASSWD: /bin/systemctl restart one-chat-room, /bin/systemctl status one-chat-room, /bin/systemctl start one-chat-room, /bin/systemctl stop one-chat-room
Exit with Ctrl-X
and save when prompted.
This line allows any user in the
one-chat-room
group to execute the listed commands withsudo
without having to enter a password (hence theNOPASSWD
option).You can test that it works by connecting to your server and running
sudo systemctl status one-chat-room
. It should no longer ask you for your password.
Clone your fork of the repository to your local machine, make sure you have added a remote to your server, then commit and push a change to test the automated deployment.
For example, the main title of the page is in the file
views/components/app.pug
.