App Deployment
2022-06
Niall McMahon
Some practical setup for (multi-tenant) app development/deployment using:
- PostgreSQL
- Node.js
- Express, Apache
Single- vs. Multi-tenant Architecture
Database Database Database | | | App App App ___ ___ ___ | | | User User User
Single-tenant architecture: everybody gets their own copy of everything; often used in enterprise application development and for desktop software.
Database | App | _________________________ | | | User User User
Multi-tenant architecture: users share the app and database; often used for multi-user online services.
Modern Single-page Application (SPA)
PEAN/PERN Technology Stack
- PostgreSQL.
- Node.js / Express web framework (and maybe Apache for serving client side).
- Angular / React.
Back End
Running on one (or more) Linux server(s), perhaps virtual machines.
- API and Business Logic, e.g. Node.js, Express.
- Database, e.g. PostgreSQL.
Client Side (Front End)
- Framework (React, Angular, Vue.js), in-browser code.
Server Setup
Install and configure:
- Linux (e.g. Debian and Debian-based, RHEL, Fedora, Centos Stream, AlmaLinux, among others).
- Database, e.g. PostgreSQL.
- Node.js and Express.
- Configure Apache (or Node.js etc.)
- Configure DNS / local network.
Development Machine Tools
- (.git and Sublime Text.)
- PostgreSQL and pgAdmin III.
- Node.js / Express etc.
- Angular and Command Line Interface (CLI) - front end development with Material Design.
- Postman - for API web hook / JSON testing.
PostgreSQL
Overview
From https://www.postgresql.org/about/:
PostgreSQL has earned a strong reputation for its proven architecture, reliability, data integrity, robust feature set, extensibility, and the dedication of the open source community behind the software to consistently deliver performant and innovative solutions.
In addition to being free and open source, PostgreSQL is highly extensible. For example, you can define your own data types, build out custom functions, even write code from different programming languages without recompiling your database!
https://www.postgresql.org/
https://www.postgresql.org/docs/
https://www.postgresql.org/about/
https://www.postgresql.org/docs/current/history.html
Installation
In Debian-based systems, use apt-get
:
sudo apt install postgresql-server postgresql
As a note, apt
is preferred to apt-get
these days.
In Red Hat derived systems, use yum
or dnf
:
sudo dnf install postgresql-server postgresql
dnf
is preferred to yum
these days.
The process is a little different if Postgres already exists - you'd want to back-up the database contents and configuration first.
The details of this are here: https://www.postgresql.org/docs/9.0/install-upgrading.html
Create User
To create a new user, type:
sudo -u postgres psql
This starts psql, a terminal-based front end for PostgreSQL using the default postgres
user.
Once psql starts, type:
CREATE ROLE new_user NOINHERIT LOGIN;
This creates a new PostgreSQL user called new_user ; this user can log in to the database and does not inherit any default privileges, i.e. these must be specified explicitly.
See https://www.postgresql.org/docs/9.1/sql-createrole.html
Assign Password to User
To set a password for the new user, type:
ALTER USER new_user WITH PASSWORD 'aweakpassword';
This assigns the password aweakpassword
to the user new_user
. If no password is set, the user will be unable to log in.
Create Database
The next step is to create a new database; type:
CREATE DATABASE new_database;
This creates a new database called new_database
; this database name might be a bit confusing in real life.
See, https://www.postgresql.org/docs/current/tutorial-createdb.html
Assign User to Database
You might want to assign the new user to the database; this new user can be the app that you'll write:
GRANT ALL PRIVILEGES ON DATABASE new_database TO new_user;
This gives new_user
full access to the database, new_database
.
Authentication
When the password is set, PostgreSQL checks the postgresql.conf file for the password_encryption field. This should be set to scram-sha-256, i.e.
password_encryption = 'scram-sha-256'
In addition, the authentication methods specification in the pg_hba.conf
file should also specify scram-sha-256, i.e.
host all new_user 127.0.0.1/32 scram-sha-256
Some precautions:
- Do not open the database to the internet by accident, i.e. be careful with
listen_addresses = '*'
- Only accept SSL remote logins or via SSH tunnels.
- Consider changing the default port from 5432.
https://www.postgresql.org/about/
https://www.postgresql.org/docs/11/auth-password.html
https://www.postgresql.org/docs/9.1/auth-pg-hba-conf.html
https://www.postgresql.org/docs/8.3/ssh-tunnels.html
Management and Development
pgAdmin is a tool you'll need; it makes PostgreSQL database management a lot easier with a nice GUI and lots of useful functionality.
https://www.pgadmin.org/MS Windows
PostgreSQL and pgAdmin can both run happily on Windows. This makes development (potentially) a lot easier in a Microsoft-centric organisation.
https://www.postgresql.org/download/windows/
https://www.pgadmin.org/download/
psql Syntax
As a note, psql commands do not have to be uppercase!
Both uppercase and lowercase work.
I've been using uppercase for clarity.
Node.js and Express
Installation
In Debian-based systems, use apt as usual:
sudo apt install nodejs
In Red Hat derived systems, use yum or dnf:
sudo dnf install nodejs
Debian and Red Hat include a version of Node.js in its default repositories. If you want to install a different version, the process is slightly different.
https://nodejs.org/en/download/package-manager/ https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-debian-10
Node Package Manager (npm)
Install npm, the Node package manager using:
sudo apt install npm
This allows you to install useful packages for Node.js. You can find out more at https://github.com/npm/documentation
Node Version Manager (nvm)
It's also possible to install the Node Version Manager first and then use this to install and maintain your Node.js installation.
https://github.com/nvm-sh/nvm/blob/master/README.md#installing-and-updating
Check Installation
Check that Node.js is installed by typing:
node --version
Initialise App
Assuming that Node.js and npm are correctly installed:
mkdir myapp
cd myapp
npm init
You will be prompted for the main app .js file, e.g. app.js.
Install Express
You can install Express with:
npm install express --save
The --save
flag adds Express to dependency list of app.js.
See https://expressjs.com/en/starter/installing.html
Install Packages
For example:
https://www.npmjs.com/package/express-jwt
https://www.npmjs.com/package/sequelize
https://www.npmjs.com/package/bcryptjs
https://www.npmjs.com/package/http-server
Express Server
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Runtime
Do not run a Node.js / Express server as root if at all possible. If you start the process as root, use setuid to drop the permissions once Node.js has started.
See https://syskall.com/dont-run-node-dot-js-as-root/
You can start the node application using:
node app.js
Nodemon is a useful package, adding auto restart for node servers.
See https://nodemon.io/
Summary
Mozilla has a nice summary.
See https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment
Apache
Installation
In Debian-based systems, use apt as usual:
sudo apt install apache2
sudo service apache2 start
In Red Hat derived systems, use yum or dnf:
sudo dnf install httpd
sudo systemctl enable httpd
sudo systemctl start httpd
Check Installation
In Debian derived systems:
sudo service apache2 status
In Red Hat derived systems:
sudo systemctl status httpd
Commands
To stop Apache:
sudo systemctl stop httpd
To start Apache:
sudo systemctl start httpd
To stop and then start:
sudo systemctl restart httpd
Reload configuration changes:
sudo systemctl reload httpd
To stop Apache from restarting automatically on boot:
sudo systemctl disable httpd
To re-enable automatic start-up:
sudo systemctl enable httpd
Apache will serve files located in the Document Root. This is usually:
/usr/local/apache/htdocs
But can be other locations also.
Configuration
Virtual hosts, e.g. frontend.mydomain.com and backend.mydomain.com
Security Enhanced Linux.
Firewalls
...
See http://httpd.apache.org/docs/2.4/