<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Database &#8211; Digitaldocblog</title>
	<atom:link href="https://digitaldocblog.com/category/database/feed/" rel="self" type="application/rss+xml" />
	<link>https://digitaldocblog.com</link>
	<description>Various digital documentation</description>
	<lastBuildDate>Sat, 13 Aug 2022 10:48:17 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://digitaldocblog.com/wp-content/uploads/2022/08/cropped-website-icon-star-500-x-452-transparent-32x32.png</url>
	<title>Database &#8211; Digitaldocblog</title>
	<link>https://digitaldocblog.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Setup Ubuntu Linux ready for Node Apps</title>
		<link>https://digitaldocblog.com/web-development/setup-ubuntu-linux-ready-for-node-apps/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 26 Feb 2021 10:47:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Web-Development]]></category>
		<category><![CDATA[Express.js]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Mongoose]]></category>
		<category><![CDATA[NginX]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[NPM Node package manager]]></category>
		<guid isPermaLink="false">https://digitaldocblog.com/?p=122</guid>

					<description><![CDATA[We have a new server in front of us and are now starting from the beginning with the preparation of the system to operate nodejs and node express applications. SSH&#8230;]]></description>
										<content:encoded><![CDATA[
<p>We have a new server in front of us and are now starting from the beginning with the preparation of the system to operate nodejs  and node express applications. </p>



<h2 class="wp-block-heading">SSH public key authentication for the root user</h2>



<p>First we create the ssh keys on the local machine. </p>



<pre class="wp-block-code"><code>PatrickMBNeu:~ patrick$ ssh-keygen -t rsa -b 4096 -C "your_email@domain.com"
Enter file in which to save the key (/home/patrick/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
PatrickMBNeu:~ patrick$ ls -l .ssh/id_*
-rw-------@ 1 patrick  staff  3434  4 Feb 14:58 .ssh/id_rsa
-rw-r--r--  1 patrick  staff   750  4 Feb 14:58 .ssh/id_rsa.pub
PatrickMBNeu:~ patrick$ 
</code></pre>



<p>We log in to the server with the <code>root</code>  user via ssh and are in the root user&#8217;s home directory and create the <code>.ssh</code>  directory and the <code>authorized_keys</code> file. The we log out from the server and install the public key from the local machine on the server. </p>



<pre class="wp-block-code"><code>PatrickMBNeu:~ patrick$ ssh root@85.134.111.90
root@85.134.111.90's password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Fri Feb 19 07:10:43 2021 from 112.11.237.18
root@h2866085:~# ls -al
insgesamt 28
drwx------  3 root root 4096 Feb 19 07:10 .
drwxr-xr-x 23 root root 4096 Feb 19 06:41 ..
-rw-------  1 root root   12 Feb 19 07:10 .bash_history
-rw-r--r--  1 root root 3106 Aug 14  2019 .bashrc
drwx------  2 root root 4096 Feb 19 07:09 .cache
-rw-r--r--  1 root root  148 Aug 13  2020 .profile
-rw-r--r--  1 root root   20 Feb 19 06:37 .screenrc
root@h2866085:~# mkdir .ssh
root@h2866085:~# ls -al
insgesamt 32
drwx------  4 root root 4096 Feb 19 07:20 .
drwxr-xr-x 23 root root 4096 Feb 19 06:41 ..
-rw-------  1 root root   12 Feb 19 07:10 .bash_history
-rw-r--r--  1 root root 3106 Aug 14  2019 .bashrc
drwx------  2 root root 4096 Feb 19 07:09 .cache
-rw-r--r--  1 root root  148 Aug 13  2020 .profile
-rw-r--r--  1 root root   20 Feb 19 06:37 .screenrc
drwxr-xr-x  2 root root 4096 Feb 19 07:20 .ssh
root@h2866085:~# chmod 700 .ssh
root@h2866085:~# ls -al
insgesamt 32
drwx------  4 root root 4096 Feb 19 07:20 .
drwxr-xr-x 23 root root 4096 Feb 19 06:41 ..
-rw-------  1 root root   12 Feb 19 07:10 .bash_history
-rw-r--r--  1 root root 3106 Aug 14  2019 .bashrc
drwx------  2 root root 4096 Feb 19 07:09 .cache
-rw-r--r--  1 root root  148 Aug 13  2020 .profile
-rw-r--r--  1 root root   20 Feb 19 06:37 .screenrc
drwx------  2 root root 4096 Feb 19 07:20 .ssh
root@h2866085:~# cd .ssh
root@h2866085:~/.ssh# touch authorized_keys
root@h2866085:~/.ssh# ls -al
insgesamt 8
drwx------ 2 root root 4096 Feb 19 07:21 .
drwx------ 4 root root 4096 Feb 19 07:20 ..
-rw-r--r-- 1 root root    0 Feb 19 07:21 authorized_keys
root@h2866085:~/.ssh# chmod 600 authorized_keys
root@h2866085:~/.ssh# ls -al
insgesamt 8
drwx------ 2 root root 4096 Feb 19 07:21 .
drwx------ 4 root root 4096 Feb 19 07:20 ..
-rw------- 1 root root    0 Feb 19 07:21 authorized_keys
root@h2866085:~/.ssh# exit
Abgemeldet
Connection to 85.214.161.41 closed.

PatrickMBNeu:~ patrick$
PatrickMBNeu:~ patrick$ cat ~/.ssh/id_rsa.pub | ssh root@85.214.161.41 "cat &gt;&gt; ~/.ssh/authorized_keys"
PatrickMBNeu:~ patrick$ ssh root@85.134.111.90
root@85.214.161.41's password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Fri Feb 19 07:18:57 2021 from 185.17.207.18

root@h2866085:~# cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCfV32OLcC90/0CE0nDsSRZwO5XtyRRBWkgKhkd+wlIad09Vi6URGO3XkUhac2bKWe6t9DP3GWSk23ruMj8M6UV9W1Fb7ZfFW3SXhz5+pRB1v0Uy5PDdxLH1foSz0hpbubCQ0AbEWWRNfMqKC6l2tFWrOfl5AXlbmZsHTH1Th9FSoBhqs8ZH33Oovs+lchzbpmObjUNzr0Y/ZWaNjNlAxvFtt8fMHxqEz3tw7ASub2eaVcGSiNioV3GKwlzbho62AF6b+KGbQkH92P5j4+KnDQpY92Ejd55c4kfq7DcG0pXLC2e77Ci/XnpROzllcOlSjmR5fsAIuWMw7dQyePCar2seVx7WBo0/Z/jnvF0exDJprtxPLlCbFRwj1nVMlKpUsqbE8mZs0L5k7Zh2GLkGJQekYR1X7zDthJHPMLeoepKw20onuCoTkquirwYhy4xCndjZ3VYk0033Rgu13ETrCB+eXc7UrbyyJJyTTs77BQZ/deTLZcXARYU96wQoQGzlevYjyWNhn6WEjkoBc2dcIHzV0Fp3enhLhptG6imHGsvAm+1uNkXbg46hYL4WZdJxkGXOoRo+oT/deRNvzMjDgL2SMUOgSzj7U+Krw0bUCY2LpkWp0lNAuT+YsF2O/k/TEVFBfKthrJd9f/PynTR+IFiRHK7jayhBQXIWSsqI9AlJw== p.rottlaender@icloud.com
root@h2866085:~# 
</code></pre>



<h2 class="wp-block-heading">Ubuntu Version check</h2>



<p>Another action we take is to check which OS version and kernel version we are dealing with. This provides important information when we install software later. Often we have to download special software releases for the Linux version used. Type any of the following commands to find OS Name and OS Version running on your Linux server.</p>



<pre class="wp-block-code"><code>root@h2866085:~$ cat /etc/os-release

NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

root@h2866085:~$ lsb_release -a

No LSB modules are available.
Distributor ID:    Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:    18.04
Codename:    bionic

root@h2866085:~$
</code></pre>



<p>To print the Linux kernel version running on your server type the following command. I am running Linux kernel version 4.15.</p>



<pre class="wp-block-code"><code>root@h2866085:~$ uname -r
4.15.0
root@h2866085:~$
</code></pre>



<h2 class="wp-block-heading">Create a user</h2>



<p>Of course, we don&#8217;t want to log in to the system with the root user all the time. It is therefore advisable to create another user with whom we can then log in and work.</p>



<p>A user can be created in Ubuntu Linux with the command <code>useradd</code> or <code>adduser</code>. I use the <code>adduser</code> command because with this perl script, in addition to creating the user in <code>/etc/passwd</code> and creating a dedicated user group in <code>/etc/group</code>, the home directory in <code>/home</code> is also created for that user and default files are copied from <code>/etc/skel</code> if necessary.</p>



<p>As root run the command <code>adduser mynewuser</code>.</p>



<pre class="wp-block-code"><code>root@h2866085:~$ adduser mynewuser

Benutzer »mynewuser« wird hinzugefügt …
Neue Gruppe »mynewuser« (1001) wird hinzugefügt …
Neuer Benutzer »mynewuser« (1001) mit Gruppe »mynewuser« wird hinzugefügt …
Persönliche Ordner »/home/mynewuser« wird erstellt …
Dateien werden von »/etc/skel« kopiert …
Geben Sie ein neues UNIX-Passwort ein: 
Geben Sie das neue UNIX-Passwort erneut ein: 
passwd: password updated successfully
Changing the user information for mynewuser
Enter the new value, or press ENTER for the default
    Full Name &#91;]: Tech User
    Room Number &#91;]: 
    Work Phone &#91;]: 
    Home Phone &#91;]: 
    Other &#91;]: This user is only for tech 
Ist diese Information richtig? &#91;J/N] J

root@h2866085:~$
</code></pre>



<p>This create the user <code>mynewuser</code>. In <code>/etc/passwd</code> you see that the user has been created with userID (1000) and a groupID (1000). In <code>/etc/group</code> you find the new group <code>mynewuser</code>. When you check the home directory you find the new home directory in <code>/home/mynewuser</code>. </p>



<pre class="wp-block-code"><code>root@h2866085:~$ grep mynewuser /etc/passwd
mynewuser:x:1000:1000::/home/mynewuser:/bin/bash
root@h2866085:~$ cat /etc/group
....
....
mynewuser:x:1000:
...
root@h2866085:~$ ls -l /home
drwxr-xr-x 2 mynewuser mynewuser 4096 Jan 23 05:31 mynewuser
root@h2866085:~$
</code></pre>



<p>The last entry in the <code>/etc/passwd</code> specifies the shell of the new user. Here the newly created user has the Bash shell. In general a Unix shell is a command processor running in a command line window. The user types commands and these commands will be executed and cause actions. For more details you can read the wiki article about <a href="https://en.wikipedia.org/wiki/Unix_shell">Unix Shells</a>.<br></p>



<p>Because there are some different shells available there might be the need to change the user&#8217;s shell which basically mean that you change the variety of available commands on your command line. To change the shell of a user type  <code>usermod --shell &lt;/path/toShell&gt; &lt;mynewuser&gt;</code>. To see which shells you can use pls. check the <code>/etc/shells</code> directory. </p>



<pre class="wp-block-code"><code>root@h2866085:~$ ls -l /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/screen
/bin/tcsh
/usr/bin/tcsh
root@h2866085:~$ usermod --shell /bin/sh mynewuser
root@h2866085:~$ grep mynewuser /etc/passwd
mynewuser:x:1001:1001:Tech User,,,,This user is only for tech:/home/mynewuser:/bin/sh
</code></pre>



<h2 class="wp-block-heading">Sudo configuration</h2>



<p>This newly created user can create files in his home directory and access those files. However, it cannot copy files to directories owned by root. To demonstrate this, I log in to the system with the newly generated user. I create a file in the home directory and then I try to copy this file into a directory owned by root. The error message is that I am not authorized. To do this copy you must be root. </p>



<p>A user can still execute commands as root. That&#8217;s why there is sudo. So when I try to execute the command with sudo I get the message that the user is not in the sudoers-file.</p>



<pre class="wp-block-code"><code>Patricks-MacBook-Pro:~$ ssh mynewuser@85.214.161.41
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Fri Feb  5 08:57:52 2021 from 87.161.105.46
mynewuser@h2866085:~$  touch testfile
mynewuser@h2866085:~$ ls -l
insgesamt 4
-rw-rw-r-- 1 mynewuser mynewuser 24 Jan 23 06:20 testfile
mynewuser@h2866085:~$ cp testfile /etc/nginx/sites-available/testfile
cp: reguläre Datei '/etc/nginx/sites-available/testfile' kann nicht angelegt werden: Keine Berechtigung
mynewuser@h2866085:~$ sudo cp testfile /etc/nginx/sites-available/testfile
&#91;sudo] Passwort für mynewuser: 
mynewuser ist nicht in der sudoers-Datei. Dieser Vorfall wird gemeldet.
mynewuser@h2866085:~$
</code></pre>



<p>Sudo allows the <code>root</code> user of the system to give other users on the system (or groups) the ability to run some (or all) commands as <code>root</code>. The sudo configuration is detailed in <code>/etc/sudoers</code> file. </p>



<p>In my sudo configuration file it is already preconfigured that all users in the sudo group can execute all commands as <code>root</code>.  Please note the corresponding entry <code>%sudo ALL=(ALL:ALL) ALL</code> in the <code>/etc/sudoers</code> configuration file below. </p>



<p>I want that the the user <code>mynewuser</code> should be able to execute all commands as <code>root</code>. Therefore <code>mynewuser</code> must be added to the <code>sudo</code> group. </p>



<p>To make <code>mynewuser</code> a member of the <code>sudo</code> group I use the command <code>usermod</code>.  Therefore I log in with <code>root</code> using the <code>su root</code> command. Then I run <code>usermod</code> with <code>-a</code> and <code>-G</code> option, which basically says to append a user to a Group. </p>



<p>Finally I check with <code>cat /etc/group</code> that the sudo group contain the <code>mynewuser</code> and logoff from the root account using <code>exit</code>.</p>



<pre class="wp-block-code"><code>mynewuser@h2866085:~$ su root
Passwort: 
root@h2866085:/home/mynewuser# 
root@h2866085:/home/mynewuser# cat /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo    ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

root@h2866085:/home/mynewuser# usermod -a -G sudo mynewuser
root@h2866085:/home/patrick# cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
...
sudo:x:27:mynewuser
....
root@h2866085:/home/patrick# exit
mynewuser@h2866085:~$
</code></pre>



<h2 class="wp-block-heading">Advanced Package Tool on Ubuntu Linux</h2>



<p>But before we start with software installations I need to give you some background info about Ubuntu or Debian package management. </p>



<p>Whenever you want to install software on your Ubuntu system, you can use the Advanced Package Tool or APT for short. Users interact with APT using the <code>apt</code> command. APT download the software package from a package source and then install it. </p>



<p>The software package can only be installed if the package source is known to the APT system. Therefore package sources are listed in the file <code>/etc/apt/sources.list</code> or in further files with the extension <code>.list</code> in the directory  <code>/etc/apt/sources.list.d</code>. </p>



<p>When you call <code>apt install &lt;package-name&gt;</code> on your console APT first check the package sources listed in your <code>/etc/apt/sources.list</code> file. When the system find the package on one of these package sources APT will install the software from there. </p>



<p>When the software is not available on any package sources listed in <code>/etc/apt/sources.list</code> APT check the package sources listed in the <code>.list</code>  files in your <code>/etc/apt/sources.list.d</code> directory. </p>



<p>When APT does not find the package on any package sources the software package cannot be installed until the package source is entered either in <code>/etc/apt/sources.list</code> or in a separate <code>.list</code> file in the <code>/etc/apt/sources.list.d</code> directory.</p>



<p>The entries in <code>.list</code> files regardless of whether they are in <code>/etc/apt/sources.list</code> or  <code>/etc/apt/sources.list.d/*.list</code> are structured identically. The structure of the <code>.list</code> files is divided into 4 sections. </p>



<pre class="wp-block-code"><code>Example:
deb    ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic     main restricted universe
&lt;type&gt; &lt;URI&gt;                                       &lt;archive&gt;  &lt;component&gt;
</code></pre>



<p>The above listed package source is an ftp server that contain binary packages for the Ubuntu Bionic Distribution (bionic). The Binary Packages include packages that meet the Ubuntu licensing requirements and are supported by the Ubuntu team (main), software packages that the Ubuntu developers support because of their importance, but which are not under Ubuntu licensing (restricted) and a wide range of free software (no licensing restrictions) that is not officially supported by Ubuntu (universe). </p>



<p>Universe software is maintained by the <a href="https://wiki.ubuntu.com/MOTU">Masters of the Universe</a> (MOTU Developers).  If a MOTU Developer want a software to be included in the Ubuntu package sources, this Developer must suggest the package for the Universe. MOTUs also maintain Multiverse software. Multiverse software is also managed by the MOTUs but the difference is that Multiverse software is not free Software. Multiverse software is subject to licensing restrictions. More details can be read in the <a href="https://ubuntu.com/server/docs/package-management">Ubuntu Package Management Documentation</a> on the Ubuntu Website.<br></p>



<p>The <code>.list</code> file can be crated manually using an editor like <code>nano</code> or with the following command. Here in this example to create a mongoDB source file.</p>



<pre class="wp-block-code"><code>echo "deb &#91; arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
</code></pre>



<p>In order to check a package source for authenticity, the GPG key of the package source provided by the manufacturer must also be downloaded and added to the Ubuntu APT keyring using the <code>apt-key add</code> command. Here in this example to add the key to verify the mongoDB source. </p>



<pre class="wp-block-code"><code>wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
</code></pre>



<p>With <code>wget</code> I download the public key from the mongodb.org server and pipe it into the <code>apt-key add</code> command which finally add the key to the keyring.</p>



<p>Alternatively you can use the <code>add-apt-repository</code> utility or script to automate package source entries in your <code>/etc/apt/sources.list</code> file. From Debian 8 on  <code>add-apt-repository</code> is part of the Debian Package <code>software-properties-common</code> which must be installed in case you want to use this utility for your package source management.</p>



<pre class="wp-block-code"><code>apt-get update
apt-get install software-properties-common
</code></pre>



<p>Using <code>add-apt-repository</code> the package source will be appended to the <code>/etc/apt/sources.list</code>file. No separate file will be created in <code>/etc/apt/sources.list.d</code> directory. Here is the example how to add the package source for the mongoDB. </p>



<pre class="wp-block-code"><code>sudo add-apt-repository 'deb &#91;arch=amd64] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse'
</code></pre>



<p>The utility <code>add-apt-repository</code> can also be used to install software from Personal Package Archives (PPA). PPAs are a special service for MOTU Developers (<a href="https://wiki.ubuntu.com/MOTU">Masters of the Universe</a>) to provide Ubuntu packages that are built and published with <a href="https://launchpad.net">Launchpad</a>. When you use <code>add-apt-repository</code> to install a PPA a new <code>.list</code> file will be created in your <code>/etc/apt/sources.list.d</code> directory. </p>



<pre class="wp-block-code"><code>add-apt-repository ppa:user/ppa-name
</code></pre>



<p>When you use <code>add-apt-repository</code> the PPA&#8217;s key is automatically fetched and added to the keyring. You can read more about PPA packaging on the <a href="https://help.launchpad.net/Packaging/PPA">launchpad help page</a>.</p>



<p>You should not use PPA software in production environments. The reason is that PPA software is often not maintained regularly by the MOTUs on launchpad. In general MOTUs publish their first versions on launchpad and then integrate them into the main Ubuntu Universe or Multiverse sources. So read the documentation and if possible try to install your production packages from main sources. You can see this in the following example when I install nodejs and npm from a main source. </p>



<h2 class="wp-block-heading">Nodejs and NPM Installation</h2>



<p>To run a node application you definitely need the node platform nodejs and the node package manager npm. </p>



<p>Go to the <a href="https://nodejs.org/en/download/">nodejs.org download page</a> to find out the latest version of node to install. I recommend to install the latest LTS version (<a href="https://nodejs.org/en/about/releases/">Long Term Support</a>) which is at the time of writing this document node version 14.15.5 including npm in version 6.14.11. </p>



<p>When you scroll down on the nodejs.org download page you see the install options. I prefer to install <a href="https://nodejs.org/en/download/package-manager/">nodejs via package manager</a>. Here you select your distribution so I select Debian and Ubuntu based Linux distributions. The nodejs binaries are available on <a href="https://github.com/nodesource/distributions/blob/master/README.md">GitHub nodesource repository</a>.  I choose Debian and Ubuntu based distributions (deb) <a href="https://github.com/nodesource/distributions/blob/master/README.md#debmanual">manual installation</a>.<br></p>



<p>Since I did not installed nodejs via PPA before I can skip the first step described here in the documentation. So I start with the import of the package signing key to ensure that apt can verify the new node source.</p>



<pre class="wp-block-code"><code>$ wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
</code></pre>



<p>The key ID at the time of writing this document is <code>1655A0AB68576280</code>.</p>



<p>You can check the imported key using the apt-key command.</p>



<pre class="wp-block-code"><code>$ sudo apt-key fingerprint ABF5BD827BD9BF62
</code></pre>



<p>The output should be.</p>



<pre class="wp-block-code"><code>pub   rsa4096 2014-06-13 &#91;SC]
      9FD3 B784 BC1C 6FC3 1A8A  0A1C 1655 A0AB 6857 6280
uid        &#91; unbekannt] NodeSource &lt;gpg@nodesource.com&gt;
sub   rsa4096 2014-06-13 &#91;E]
</code></pre>



<p>Then I create the <code>nodesource.list</code> file in my  <code>/etc/apt/sources.list.d</code> directory to make the nodejs package source known to apt. I create 2 entries in that file one for the nodejs debian binaries (deb) and one for the nodejs sources (deb-src).</p>



<pre class="wp-block-code"><code># Replace $VERSION with Node.js Version you want to install: i.e. node_14.x
# $VERSION=node_14.x
# Replace $DISTRO with the output of the command lsb_release -s -c
# $DISTRO=bionic
$ echo "deb https://deb.nodesource.com/$VERSION $DISTRO main" | sudo tee /etc/apt/sources.list.d/nodesource.list
$ echo "deb-src https://deb.nodesource.com/$VERSION $DISTRO main" | sudo tee -a /etc/apt/sources.list.d/nodesource.list
</code></pre>



<p>Then I update the source package list and install.</p>



<pre class="wp-block-code"><code>$ sudo apt-get update
$ sudo apt-get install nodejs
</code></pre>



<p>Here is my manual installation.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/apt$ ls -l sources.list.d
insgesamt 0
patrick@h2866085:/etc/apt$ apt-key list
/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg
------------------------------------------------------
pub   rsa4096 2012-05-11 &#91;SC]
      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32
uid        &#91; unbekannt] Ubuntu Archive Automatic Signing Key (2012) &lt;ftpmaster@ubuntu.com&gt;

/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg
------------------------------------------------------
pub   rsa4096 2012-05-11 &#91;SC]
      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092
uid        &#91; unbekannt] Ubuntu CD Image Automatic Signing Key (2012) &lt;cdimage@ubuntu.com&gt;

/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
------------------------------------------------------
pub   rsa4096 2018-09-17 &#91;SC]
      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C
uid        &#91; unbekannt] Ubuntu Archive Automatic Signing Key (2018) &lt;ftpmaster@ubuntu.com&gt;

patrick@h2866085:~$ sudo wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
&#91;sudo] Passwort für patrick: 
OK
patrick@h2866085:~$ apt-key list
/etc/apt/trusted.gpg
--------------------
pub   rsa4096 2014-06-13 &#91;SC]
      9FD3 B784 BC1C 6FC3 1A8A  0A1C 1655 A0AB 6857 6280
uid        &#91; unbekannt] NodeSource &lt;gpg@nodesource.com&gt;
sub   rsa4096 2014-06-13 &#91;E]

/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg
------------------------------------------------------
pub   rsa4096 2012-05-11 &#91;SC]
      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32
uid        &#91; unbekannt] Ubuntu Archive Automatic Signing Key (2012) &lt;ftpmaster@ubuntu.com&gt;

/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg
------------------------------------------------------
pub   rsa4096 2012-05-11 &#91;SC]
      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092
uid        &#91; unbekannt] Ubuntu CD Image Automatic Signing Key (2012) &lt;cdimage@ubuntu.com&gt;

/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
------------------------------------------------------
pub   rsa4096 2018-09-17 &#91;SC]
      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C
uid        &#91; unbekannt] Ubuntu Archive Automatic Signing Key (2018) &lt;ftpmaster@ubuntu.com&gt;

patrick@h2866085:~$ sudo apt-key fingerprint 1655A0AB68576280
pub   rsa4096 2014-06-13 &#91;SC]
      9FD3 B784 BC1C 6FC3 1A8A  0A1C 1655 A0AB 6857 6280
uid        &#91; unbekannt] NodeSource &lt;gpg@nodesource.com&gt;
sub   rsa4096 2014-06-13 &#91;E]

patrick@h2866085:~$ lsb_release -s -c
bionic
patrick@h2866085:~$ sudo echo "deb https://deb.nodesource.com/node_14.x bionic main" | sudo tee /etc/apt/sources.list.d/nodesource.list
deb https://deb.nodesource.com/node_14.x bionic main
patrick@h2866085:~$ sudo echo "deb-src https://deb.nodesource.com/node_14.x bionic main" | sudo tee -a /etc/apt/sources.list.d/nodesource.list
deb-src https://deb.nodesource.com/node_14.x bionic main
patrick@h2866085:~$ ls -l /etc/apt/sources.list.d
insgesamt 4
-rw-r--r-- 1 root root 110 Feb 20 08:14 nodesource.list
patrick@h2866085:~$ sudo cat /etc/apt/sources.list.d/nodesource.list
deb https://deb.nodesource.com/node_14.x bionic main
deb-src https://deb.nodesource.com/node_14.x bionic main
patrick@h2866085:~$ sudo apt-get update
OK:1 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic InRelease
Holen:2 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates InRelease &#91;88,7 kB]
Holen:3 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-security InRelease &#91;88,7 kB]
Holen:4 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic/main Translation-de &#91;454 kB]
Holen:5 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic/restricted Translation-de &#91;2.268 B]
Holen:6 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic/universe Translation-de &#91;2.272 kB]                       
Holen:7 https://deb.nodesource.com/node_14.x bionic InRelease &#91;4.584 B]                                                  
Holen:8 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates/universe Sources &#91;446 kB]
Holen:9 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates/main amd64 Packages &#91;1.885 kB]
Holen:10 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates/universe amd64 Packages &#91;1.718 kB]
Holen:11 https://deb.nodesource.com/node_14.x bionic/main amd64 Packages &#91;764 B]
Holen:12 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates/universe Translation-en &#91;363 kB]
Holen:13 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-security/universe Sources &#91;277 kB]
Holen:14 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-security/universe amd64 Packages &#91;1.109 kB]
Holen:15 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-security/universe Translation-en &#91;248 kB]
Es wurden 8.957 kB in 3 s geholt (3.459 kB/s).                    
Paketlisten werden gelesen... Fertig
patrick@h2866085:~$ sudo apt-get install nodejs
patrick@h2866085:~$ node -v
v14.15.5
patrick@h2866085:~$ npm -v
6.14.11
patrick@h2866085:~$ 
</code></pre>



<p>Basically we installed npm in a bundle together with nodejs using the  <code>apt</code> package manager. But npm itself is also an additional package manager. We now have <code>apt</code> and <code>npm</code> as package managers on our system. </p>



<p>We need npm to have an additional source for software available on <a href="https://www.npmjs.com/">npmjs.com</a>.  We will for example install PM2 via npm (see next chapter) but but in particular we need npm to add local software packages or dependencies to our node application projects. So when we want to develop a node app based on the expressjs framework we will install express locally in our project directory. But this will be part of a separate tutorial. </p>



<p>When you ask npm to find outdated packages you can run the <code>npm outdated</code> command (using the -g option to show only global packages). </p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ npm outdated -g --depth=0
Package  Current   Wanted  Latest  Location
npm      6.14.11  6.14.11   7.5.4  global
</code></pre>



<p>As you see from an npm point of view the latest version of npm is 7.5.4. But npm know that we installed npm together as a bundle with nodejs via <code>apt</code> and in the apt package sources we say that our wanted version is 14.15.5 (see above). This is a bit confusing but basically <code>npm outdated</code> tell us that that there is a higher npm version available (latest) but on our system we are up to date as the current version and the one we defined in our package sources (wanted) are equal. </p>



<p>We can update npm together only together with the nodejs update which must be initiated with <code>apt-update</code>. And here you see the packages are all up to date.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo apt update
OK:1 https://deb.nodesource.com/node_14.x bionic InRelease
OK:2 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic InRelease
OK:3 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-updates InRelease
OK:4 ftp://ftp.stratoserver.net/pub/linux/ubuntu bionic-security InRelease
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.       
Statusinformationen werden eingelesen.... Fertig
Alle Pakete sind aktuell.
patrick@h2866085:~$  
</code></pre>



<h2 class="wp-block-heading">PM2 Installation with NPM</h2>



<p>Go to <a href="https://www.npmjs.com/">npmjs.com</a> and search for PM2 Process Manager. You find the <a href="https://www.npmjs.com/package/pm2">PM2 package</a> on npmjs.com. Follow the install instructions.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo npm install pm2 -g
patrick@h2866085:~$ pm2 -v
                        -------------

__/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____
 _\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___
  _\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__
   _\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___
    _\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____
     _\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________
      _\/\\\_____________\/\\\_____________\/\\\___/\\\/___________
       _\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_
        _\///______________\///______________\///__\///////////////__

                          Runtime Edition

        PM2 is a Production Process Manager for Node.js applications
                     with a built-in Load Balancer.

                Start and Daemonize any application:
                $ pm2 start app.js

                Load Balance 4 instances of api.js:
                $ pm2 start api.js -i 4

                Monitor in production:
                $ pm2 monitor

                Make pm2 auto-boot at server restart:
                $ pm2 startup

                To go further checkout:
                http:&#47;&#47;pm2.io/
                        -------------
&#91;PM2] Spawning PM2 daemon with pm2_home=/home/patrick/.pm2
&#91;PM2] PM2 Successfully daemonized
4.5.4
patrick@h2866085:~$ 
</code></pre>



<h2 class="wp-block-heading">Nano Installation with apt</h2>



<p>Nano is part of the Ubuntu 18.04 bionic main packages that are provided via the standard ftp package sources from my provider at stratoserver.net. These standard ftp package sources are in my <code>/etc/apt/sources.list</code> file and can be installed with <code>apt</code>. </p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo apt install nano
patrick@h2866085:~$
</code></pre>



<h2 class="wp-block-heading">Nginx Installation with apt</h2>



<p>Also Nginx is a package that is available under the standard Ubuntu main sources. Nginx is part of the Ubuntu 18.04 bionic main packages provided via the standard ftp package sources from my provider at stratoserver.net. Nginx can be installed from these sources using the <code>apt</code> command. </p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo apt install nginx
patrick@h2866085:~$
</code></pre>



<p>After the installation is complete the Nginx configuration files are in <code>/etc/nginx</code> directory.<br></p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ ls -l /etc/nginx
insgesamt 64
drwxr-xr-x 2 root root 4096 Jan 10  2020 conf.d
-rw-r--r-- 1 root root 1077 Apr  6  2018 fastcgi.conf
-rw-r--r-- 1 root root 1007 Apr  6  2018 fastcgi_params
-rw-r--r-- 1 root root 2837 Apr  6  2018 koi-utf
-rw-r--r-- 1 root root 2223 Apr  6  2018 koi-win
-rw-r--r-- 1 root root 3957 Apr  6  2018 mime.types
drwxr-xr-x 2 root root 4096 Jan 10  2020 modules-available
drwxr-xr-x 2 root root 4096 Feb 20 12:46 modules-enabled
-rw-r--r-- 1 root root 1482 Apr  6  2018 nginx.conf
-rw-r--r-- 1 root root  180 Apr  6  2018 proxy_params
-rw-r--r-- 1 root root  636 Apr  6  2018 scgi_params
drwxr-xr-x 2 root root 4096 Feb 20 12:46 sites-available
drwxr-xr-x 2 root root 4096 Feb 20 12:46 sites-enabled
drwxr-xr-x 2 root root 4096 Feb 20 12:46 snippets
-rw-r--r-- 1 root root  664 Apr  6  2018 uwsgi_params
-rw-r--r-- 1 root root 3071 Apr  6  2018 win-utf
patrick@h2866085:~$ 
</code></pre>



<p>Then I edit the <code>/etc/nginx.conf</code> as follows.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx$ sudo cat nginx.conf
##
# nginx.conf
##

user www-data; 
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Timeout Settings
##
keepalive_timeout  30s; 
keepalive_requests 30;
send_timeout       30s;
##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

##
# Gzip Settings
##

gzip on;
gzip_vary on;
gzip_comp_level 2;
gzip_min_length  1000;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE &#91;4-6] \."; 
##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

patrick@h2866085:/etc/nginx$
</code></pre>



<p>In the directory <code>/etc/nginx/sites-available</code> you find the sever configuration files and in <code>/etc/nginx/sites-enabled</code> you find the sym links to the sever configuration files that are enabled on your nginx server. </p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx$ ls -l sites-available
insgesamt 4
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
patrick@h2866085:/etc/nginx$ ls -l sites-enabled
insgesamt 0
lrwxrwxrwx 1 root root 34 Feb 20 12:46 default -&gt; /etc/nginx/sites-available/default
patrick@h2866085:/etc/nginx$ 
</code></pre>



<p>First we deactivate the default site by removing the default symlink in <code>/etc/nginx/sites-enabled</code>. </p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx$ cd sites-enabled
patrick@h2866085:/etc/nginx/sites-enabled$ ls -l
insgesamt 0
lrwxrwxrwx 1 root root 34 Feb 20 12:46 default -&gt; /etc/nginx/sites-available/default
patrick@h2866085:/etc/nginx/sites-enabled$ sudo unlink default
&#91;sudo] Passwort für patrick: 
patrick@h2866085:/etc/nginx/sites-enabled$ ls -l
insgesamt 0
patrick@h2866085:/etc/nginx/sites-enabled$ 
</code></pre>



<p>I want to use my nginx server as reverse proxy server for node application servers running on the localhost. Therefore I create a new file <code>prod-reverse-proxy</code> in the directory <code>sites-available</code> .</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx/sites-enabled$ cd ..
patrick@h2866085:/etc/nginx$ 
patrick@h2866085:/etc/nginx$ cd sites-available
patrick@h2866085:/etc/nginx/sites-available$ ls -l
insgesamt 4
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
patrick@h2866085:/etc/nginx/sites-available$ sudo touch prod-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ ls -l
insgesamt 4
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
-rw-r--r-- 1 root root    0 Feb 21 08:31 prod-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ 
</code></pre>



<p>Then I put the following content in the file <code>prod-reverse-proxy</code> and link this file into <code>/etc/nginx/sites-enabled</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx/sites-available$ sudo nano prod-reverse-proxy
server {
        listen 80;
        listen &#91;::]:80;
        server_name digitaldocblog.com www.digitaldocblog.com;

        access_log /var/log/nginx/prod-reverse-access.log;
        error_log /var/log/nginx/prod-reverse-error.log;

        location / {

	proxy_set_header HOST $host;
</code></pre>



<p>proxy_set_header X-Forwarded-Proto $scheme;</p>



<p>proxy_set_header X-Real-IP $remote_addr;</p>



<p>proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</p>



<p></p>



<pre class="wp-block-code"><code>	proxy_pass http://127.0.0.1:3000;


  }
}
patrick@h2866085:/etc/nginx/sites-available$ sudo ln -s /etc/nginx/sites-available/prod-reverse-proxy /etc/nginx/sites-enabled/prod-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ cd ..
patrick@h2866085:/etc/nginx$ ls -l sites-enabled
insgesamt 0
lrwxrwxrwx 1 root root 50 Feb 21 08:37 prod-reverse-proxy -&gt; /etc/nginx/sites-available/prod-reverse-proxy
patrick@h2866085:/etc/nginx$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
patrick@h2866085:/etc/nginx$ 
</code></pre>



<p>The production proxy server is running under the domain server names <strong>digitaldocblog.com</strong> and <strong>www.digitaldocblog.com</strong> and is listening on <strong>localhost port 80</strong>. This production proxy server pass all HTTP traffic from port 80 to a server running on localhost port 3000 (127.0.0.1:3000). Nginx configuration test was tested successful after using <code>nginx -t</code>. </p>



<p>The following commands can be used to check, start and stop the nginx server.</p>



<pre class="wp-block-code"><code>sudo systemctl status nginx

sudo systemctl start nginx 

sudo systemctl stop nginx 

sudo systemctl restart nginx
</code></pre>



<p>I restart the nginx server and then check the status. The basic configuration is now complete.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx$ sudo systemctl restart nginx
patrick@h2866085:/etc/nginx$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2021-02-21 08:53:31 CET; 9s ago
     Docs: man:nginx(8)
  Process: 29759 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
  Process: 29761 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 29760 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 29762 (nginx)
    Tasks: 5 (limit: 60)
   CGroup: /system.slice/nginx.service
           ├─29762 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           ├─29763 nginx: worker process
           ├─29764 nginx: worker process
           ├─29765 nginx: worker process
           └─29766 nginx: worker process

Feb 21 08:53:31 h2866085.stratoserver.net systemd&#91;1]: Starting A high performance web server and a reverse proxy server...
Feb 21 08:53:31 h2866085.stratoserver.net systemd&#91;1]: Started A high performance web server and a reverse proxy server.
patrick@h2866085:/etc/nginx$ 
</code></pre>



<h2 class="wp-block-heading">Letsencrypt SSL Certificate</h2>



<p>To run your server with HTTPS you must install a certificate from an official Centification Authority (CA). <a href="https://letsencrypt.org/">Letsencrypt</a> is such a CA where you can get free certificates. Letsencrypt recommends the use of <a href="https://certbot.eff.org/">certbot</a> for easy creation and management of domain certificates.</p>



<p>On the certbot site you can select the webserver and your operating system. I choose nginx and Ubuntu 18.04 LTS bionic and get to a website with the <a href="https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx">install instructions</a>. Since I am not interested in installing certbot with snap, I choose alternate installation instructions and get to the website with the install instructions of the <a href="https://certbot.eff.org/docs/install.html#operating-system-packages">operating system packages</a>.</p>



<p>I must Install certbot and the certbot nginx plugin with <code>apt</code>.</p>



<pre class="wp-block-code"><code>$ sudo apt update
$ sudo apt-get install certbot
$ sudo apt-get install python-certbot-nginx
</code></pre>



<p>Then I run <code>certbot</code> <code>--``nginx</code> to request the letsencrypt certificate for my domain and domain servers.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): p.rottlaender@icloud.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https:&#47;&#47;acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: digitaldocblog.com
2: www.digitaldocblog.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for digitaldocblog.com
http-01 challenge for www.digitaldocblog.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/prod-reverse-proxy
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/prod-reverse-proxy

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number &#91;1-2] then &#91;enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/prod-reverse-proxy
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/prod-reverse-proxy

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://digitaldocblog.com and
https://www.digitaldocblog.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=digitaldocblog.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.digitaldocblog.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/digitaldocblog.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/digitaldocblog.com/privkey.pem
   Your cert will expire on 2021-05-24. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

patrick@h2866085:~$ 
</code></pre>



<p>Then I check the new directory and the files in <code>/etc/letsencrypt</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/letsencrypt$ sudo ls -l live
insgesamt 4
drwxr-xr-x 2 root root 4096 Feb 23 06:33 digitaldocblog.com
patrick@h2866085:/etc/letsencrypt$ sudo ls -l live/digitaldocblog.com
insgesamt 4
lrwxrwxrwx 1 root root  42 Feb 23 06:33 cert.pem -&gt; ../../archive/digitaldocblog.com/cert1.pem
lrwxrwxrwx 1 root root  43 Feb 23 06:33 chain.pem -&gt; ../../archive/digitaldocblog.com/chain1.pem
lrwxrwxrwx 1 root root  47 Feb 23 06:33 fullchain.pem -&gt; ../../archive/digitaldocblog.com/fullchain1.pem
lrwxrwxrwx 1 root root  45 Feb 23 06:33 privkey.pem -&gt; ../../archive/digitaldocblog.com/privkey1.pem
-rw-r--r-- 1 root root 682 Feb 23 06:33 README
patrick@h2866085:/etc/letsencrypt$ 
</code></pre>



<p>I also check the file <code>prod-reverse-proxy</code> in the directory <code>/etc/nginx/sites-available</code> and see that the file has been updated by certbot. There is a new server section defined (first) an this server is now listening to port 443 ssl and the links to the ssl certificates has been added. The original server section (second) has been changed so that all traffic for hosts <strong>digitaldocblog.com</strong> and <strong>www.digitaldocblog.com</strong> will be redirected to the https version of the site (<code>return 301 https://$host$request_uri&#x1f609;</code> and requests to port 80 will be answered with 404 site not found. </p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ cd /etc/nginx/sites-available
patrick@h2866085:/etc/nginx/sites-available$ ls -l
insgesamt 12
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
-rw-r--r-- 1 root root 1089 Feb 23 06:34 prod-reverse-proxy

patrick@h2866085:/etc/nginx/sites-available$ sudo cat prod-reverse-proxy
server {
server_name digitaldocblog.com www.digitaldocblog.com;

        access_log /var/log/nginx/prod-reverse-access.log;
        error_log /var/log/nginx/prod-reverse-error.log;

        location / {

	proxy_set_header HOST $host;
</code></pre>



<p>proxy_set_header X-Forwarded-Proto $scheme;</p>



<p>proxy_set_header X-Real-IP $remote_addr;</p>



<p>proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</p>



<pre class="wp-block-code"><code>	proxy_pass http://127.0.0.1:3000;


  }
    listen &#91;::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/digitaldocblog.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/digitaldocblog.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {

    if ($host = www.digitaldocblog.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = digitaldocblog.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
        listen &#91;::]:80;
        server_name digitaldocblog.com www.digitaldocblog.com;
        return 404; # managed by Certbot
}

patrick@h2866085:/etc/nginx/sites-available$ 
</code></pre>



<p>To renew all certificates I must run the following command.</p>



<pre class="wp-block-code"><code>$ certbot renew
</code></pre>



<p>To renew all certificates automatically I attach the following line to my system crontab. </p>



<pre class="wp-block-code"><code>40 6 * * * root /usr/bin/certbot renew &gt; certrenew_log
</code></pre>



<p>The <code>certbot renew</code> command in this example run daily at 6:40 am (in the morning) as <code>root</code> and log the output in the logfile <code>certrenew_log</code> in the home directory of <code>root</code>. The command checks to see if the certificate on the server will expire within the next 30 days, and renews it if so.</p>



<p>Therefore you must edit the <code>/etc/crontab</code> file as follows. </p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc$ sudo nano crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
15 * * * * root cd / &amp;&amp; run-parts --report /etc/cron.hourly
28 0 * * * root test -x /usr/sbin/anacron || ( cd / &amp;&amp; run-parts --report /etc/cron.daily )
9 5 * * 7 root test -x /usr/sbin/anacron || ( cd / &amp;&amp; run-parts --report /etc/cron.weekly )
52 0 20 * * root test -x /usr/sbin/anacron || ( cd / &amp;&amp; run-parts --report /etc/cron.monthly )

40 6 * * * root /usr/bin/certbot renew &gt; certrenew_log
#
patrick@h2866085:/etc$
</code></pre>



<h2 class="wp-block-heading">Separate Letsencrypt SSL Certificate for another proxy server</h2>



<p>I currently have 2 server files in my <code>/etc/nginx/sites-available</code> directory. </p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx/sites-available$ ls -l
insgesamt 8
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
-rw-r--r-- 1 root root 1089 Feb 23 06:34 prod-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ 
</code></pre>



<p>The file <code>default</code> is disabled. </p>



<p>The file  <code>prod-reverse-proxy</code> is enabled. The server run as reverse proxy server for the hostnames <strong>digitaldocblog.com</strong> and <strong>www.digitaldocblog.com</strong> already using SSL (see above).</p>



<p>For my hostname <code>dev.digitaldocblog.com</code>, which is a valid subdomain of domain <code>digitaldocblog.com</code> I create a separate proxy server file <code>dev-reverse-proxy</code> in the directory <code>/etc/nginx/sites-available</code>, link this file in ****<code>/etc/nginx/sites-enabled</code>, test the nginx configuration and restart nginx.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx/sites-available$ sudo touch dev-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ ls -al
insgesamt 16
drwxr-xr-x 2 root root 4096 Feb 23 13:42 .
drwxr-xr-x 8 root root 4096 Feb 23 06:34 ..
-rw-r--r-- 1 root root 2416 Apr  6  2018 default
-rw-r--r-- 1 root root    0 Feb 23 13:42 dev-reverse-proxy
-rw-r--r-- 1 root root 1089 Feb 23 06:34 prod-reverse-proxy
patrick@h2866085:/etc/nginx/sites-available$ sudo nano dev-reverse-proxy
server {
    listen 80;
    server_name dev.digitaldocblog.com;

        access_log /var/log/nginx/dev-reverse-access.log;
        error_log /var/log/nginx/dev-reverse-error.log;

        location / {

	proxy_set_header HOST $host;
</code></pre>



<p>proxy_set_header X-Forwarded-Proto $scheme;</p>



<p>proxy_set_header X-Real-IP $remote_addr;</p>



<p>proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</p>



<pre class="wp-block-code"><code>            	proxy_pass http://127.0.0.1:3030;
  }

}
patrick@h2866085:/etc/nginx/sites-available$ cd ..
patrick@h2866085:/etc/nginx$ sudo ln -s /etc/nginx/sites-available/dev-reverse-proxy /etc/nginx/sites-enabled
patrick@h2866085:/etc/nginx$ ls -l sites-enabled
insgesamt 0
lrwxrwxrwx 1 root root 44 Feb 23 13:51 dev-reverse-proxy -&gt; /etc/nginx/sites-available/dev-reverse-proxy
lrwxrwxrwx 1 root root 45 Feb 22 19:33 prod-reverse-proxy -&gt; /etc/nginx/sites-available/prod-reverse-proxy
patrick@h2866085:/etc/nginx$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
patrick@h2866085:/etc/nginx$ sudo systemctl restart nginx
patrick@h2866085:/etc/nginx$
</code></pre>



<p>Then I run <code>certbot --nginx</code> to request a seperate letsencrypt SSL certificate only for the subdomain <code>dev.digitaldocblog.com</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/nginx$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: digitaldocblog.com
2: dev.digitaldocblog.com
3: www.digitaldocblog.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for dev.digitaldocblog.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/dev-reverse-proxy

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number &#91;1-2] then &#91;enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/dev-reverse-proxy

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://dev.digitaldocblog.com

You should test your configuration at:
https:&#47;&#47;www.ssllabs.com/ssltest/analyze.html?d=dev.digitaldocblog.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/dev.digitaldocblog.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/dev.digitaldocblog.com/privkey.pem
   Your cert will expire on 2021-05-24. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

patrick@h2866085:/etc/nginx$
</code></pre>



<p>Then I check the new directory and the files in <code>/etc/letsencrypt</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc/letsencrypt$ pwd
/etc/letsencrypt
patrick@h2866085:/etc/letsencrypt$ sudo ls -l live
&#91;sudo] Passwort für patrick: 
insgesamt 8
drwxr-xr-x 2 root root 4096 Feb 23 13:54 dev.digitaldocblog.com
drwxr-xr-x 2 root root 4096 Feb 23 06:33 digitaldocblog.com
patrick@h2866085:/etc/letsencrypt$ sudo ls -l live/dev.digitaldocblog.com
insgesamt 4
lrwxrwxrwx 1 root root  46 Feb 23 13:54 cert.pem -&gt; ../../archive/dev.digitaldocblog.com/cert1.pem
lrwxrwxrwx 1 root root  47 Feb 23 13:54 chain.pem -&gt; ../../archive/dev.digitaldocblog.com/chain1.pem
lrwxrwxrwx 1 root root  51 Feb 23 13:54 fullchain.pem -&gt; ../../archive/dev.digitaldocblog.com/fullchain1.pem
lrwxrwxrwx 1 root root  49 Feb 23 13:54 privkey.pem -&gt; ../../archive/dev.digitaldocblog.com/privkey1.pem
-rw-r--r-- 1 root root 682 Feb 23 13:54 README
patrick@h2866085:/etc/letsencrypt$ 
</code></pre>



<h2 class="wp-block-heading">Directory Setup for node applications</h2>



<p>I run my node applications on my server in <code>/var/www/node</code> directory. The node directory is owned by <code>root</code>.</p>



<p>All files of my <strong>Node Dev Applications</strong> will be copied to <code>/var/www/node/dev</code> using the user <code>patrick</code>. This directory is owned by <code>patrick</code> . According to the configuration in <code>dev-reverse-proxy</code> all http requests coming in for server name <code>dev.digitaldocblog.com</code> will be passed to localhost 127.0.0.1 server port 3030. All dev applications must listen on localhost <code>127.0.0.1 server port 3030</code>.</p>



<p>All files of my <strong>Node Prod Application</strong> will be copied to <code>/var/www/node/prod</code> also using the user <code>patrick</code>. The prod directory is also owned by the user <code>patrick</code>. According to configuration in <code>prod-reverse-proxy</code> all http requests coming in for server names <code>digitaldocblog.com</code> and <code>www.digitaldocblog.com</code> will be passed to localhost 127.0.0.1 server port 3000. Prod application must listen on localhost <code>127.0.0.1 server port 3000</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc$ cd /var
patrick@h2866085:/var$ ls
backups  cache  lib  local  lock  log  mail  opt  run  spool  tmp  www
patrick@h2866085:/var$ cd www
patrick@h2866085:/var/www$ ls -l
insgesamt 4
drwxr-xr-x 2 root root 4096 Feb 20 12:46 html
patrick@h2866085:/var/www$ sudo mkdir node
patrick@h2866085:/var/www$ ls -l
insgesamt 8
drwxr-xr-x 2 root root 4096 Feb 20 12:46 html
drwxr-xr-x 2 root root 4096 Feb 23 08:53 node
patrick@h2866085:/var/www$ cd node
patrick@h2866085:/var/www/node$ ls -l
insgesamt 0
patrick@h2866085:/var/www/node$ sudo mkdir prod
patrick@h2866085:/var/www/node$ sudo mkdir dev
patrick@h2866085:/var/www/node$ ls -l
insgesamt 8
drwxr-xr-x 2 root root 4096 Feb 23 08:56 dev
drwxr-xr-x 2 root root 4096 Feb 23 08:56 prod
patrick@h2866085:/var/www/node$ sudo chown patrick:patrick dev
patrick@h2866085:/var/www/node$ sudo chown patrick:patrick prod
patrick@h2866085:/var/www/node$ ls -al
insgesamt 16
drwxr-xr-x 4 root    root    4096 Feb 23 08:56 .
drwxr-xr-x 4 root    root    4096 Feb 23 08:53 ..
drwxr-xr-x 2 patrick patrick 4096 Feb 23 08:56 dev
drwxr-xr-x 2 patrick patrick 4096 Feb 23 08:56 prod
patrick@h2866085:/var/www/node$
</code></pre>



<h2 class="wp-block-heading">MongoDB Community Server Installation</h2>



<p>Most node applications also interact with a database. My preferred database is MongoDB. Go on the <a href="https://www.mongodb.com">MongoDB website</a> and read more about the free <a href="https://www.mongodb.com/try/download/community">MongoDB Community Server</a>. To read how to install the mongoDB in your environment go to the <a href="https://docs.mongodb.com/manual/">MongoDB Documentation Site</a>. </p>



<p>I select the <a href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/">installation instructions</a> of the MongoDB Community Server for my Ubuntu Linux 18.04 bionic LTS system.<br></p>



<p>Then I Import the public key used by the package management system to verify the package source.</p>



<pre class="wp-block-code"><code>$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
</code></pre>



<p>Then I create the list file <code>/etc/apt/sources.list.d/mongodb-org-4.4.list</code> for my version of Ubuntu.</p>



<pre class="wp-block-code"><code>$ echo "deb &#91; arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
</code></pre>



<p>I reload the local package database with <code>apt-get update</code> and install a specific release including all relevant component packages with <code>apt-get install</code> such as</p>



<ul class="wp-block-list"><li>server</li><li>shell</li><li>mongos</li><li>tools<br><br><br>$ sudo apt-get update<br>$ sudo apt-get install -y mongodb-org=4.4.4 mongodb-org-server=4.4.4 mongodb-org-shell=4.4.4 mongodb-org-mongos=4.4.4 mongodb-org-tools=4.4.4<br></li></ul>



<p>Mongodb can be started, restarted etc. with the following commands.</p>



<pre class="wp-block-code"><code>:$ sudo service mongod status

:$ sudo service mongod start

:$ sudo service mongod stop

:$ sudo service mongod restart
</code></pre>



<p>After the installation the mongoDB server must be started.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ sudo service mongod status
● mongod.service - MongoDB Database Server
   Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: https://docs.mongodb.org/manual

patrick@h2866085:~$ sudo service mongod start
patrick@h2866085:~$ sudo service mongod status
● mongod.service - MongoDB Database Server
   Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-02-23 08:49:14 CET; 3s ago
     Docs: https://docs.mongodb.org/manual
 Main PID: 27830 (mongod)
   CGroup: /system.slice/mongod.service
           └─27830 /usr/bin/mongod --config /etc/mongod.conf

Feb 23 08:49:14 h2866085.stratoserver.net systemd&#91;1]: Started MongoDB Database Server.
patrick@h2866085:~$
</code></pre>



<p>Then I create the admin user <code>myUserAdmin</code> against the admin db.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ mongo
MongoDB shell version v4.4.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&amp;gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("8df6776d-4228-43f5-9222-65893d6f146c") }
MongoDB server version: 4.4.4
---
The server generated these startup warnings when booting: 
        2021-02-23T08:49:15.047+01:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
        2021-02-23T08:49:15.718+01:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
        2021-02-23T08:49:15.718+01:00: You are running in OpenVZ which can cause issues on versions of RHEL older than RHEL6
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
&gt; use admin
switched to db admin
&gt; db
admin
&gt; db.createUser({ user: "myUserAdmin", pwd: "yourAdminPassword", roles: &#91;{ role: "userAdminAnyDatabase", db: "admin" }, {"role" : "readWriteAnyDatabase", "db" : "admin"}] })
Successfully added user: {
"user" : "myUserAdmin",
"roles" : &#91;
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
},
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
}
]
}
&gt; db.auth("myUserAdmin", "yourAdminPassword")
1
&gt; show users
{
"_id" : "admin.myUserAdmin",
"userId" : UUID("6b32b520-090b-411b-9569-4ecc70109707"),
"user" : "myUserAdmin",
"db" : "admin",
"roles" : &#91;
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
},
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
}
],
"mechanisms" : &#91;
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
&gt; exit
bye
patrick@h2866085:~$
</code></pre>



<p>Then I open <code>/etc/mongod.conf</code> file in my editor an add the following lines to the file if it does not already exist <code>security: authorization: enabled</code>.</p>



<pre class="wp-block-code"><code>#security:
security:
  authorization: enabled
</code></pre>



<p>Then I restart the mongoDB service.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc$ sudo service mongod restart
</code></pre>



<p>I create a new database <code>dev-bookingsystem</code> and the Db-User <code>myUserDevBookingsystem</code> as the Db-owner.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc$ mongo
MongoDB shell version v4.4.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&amp;gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("48d8e3cb-8076-47cb-8166-8e48cfae3d9a") }
MongoDB server version: 4.4.4
&gt; use admin
switched to db admin
&gt; db.auth("myUserAdmin", "yourAdminPassword")
1
&gt; use dev-bookingsystem
switched to db dev-bookingsystem
&gt; db.createUser({ user: "myUserDevBookingsystem", pwd: "yourDbUserPassword", roles: &#91;{ role: "dbOwner", db: "dev-bookingsystem" }] })
Successfully added user: {
"user" : "myUserDevBookingsystem",
"roles" : &#91;
{
"role" : "dbOwner",
"db" : "dev-bookingsystem"
}
]
}
&gt; db
dev-bookingsystem
&gt; exit
bye
</code></pre>



<p>Then I create a default collection in <code>dev-bookingsystem</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/etc$ mongo
MongoDB shell version v4.4.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&amp;gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d3494272-8651-4c7e-a781-231f48a60ec4") }
MongoDB server version: 4.4.4
&gt; use admin
switched to db admin
&gt; db.auth("myUserAdmin", "yourAdminPassword")
1
&gt; show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
&gt; use dev-bookingsystem
switched to db dev-bookingsystem
&gt; db.runCommand( { create: "col_default" } )
{ "ok" : 1 }
&gt; show collections
col_default
&gt; show dbs
admin              0.000GB
config             0.000GB
dev-bookingsystem  0.000GB
local              0.000GB
&gt; db
dev-bookingsystem
&gt; exit
bye
patrick@h2866085:/etc$
</code></pre>



<p>I do the same thing for my production database <code>prod-digitaldocblog</code>.</p>



<pre class="wp-block-code"><code>patrick@h2866085:~$ mongo
MongoDB shell version v4.4.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&amp;gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2402f47f-d1dd-4399-931e-b327ea1cf4b4") }
MongoDB server version: 4.4.4
&gt; use admin
switched to db admin
&gt; db.auth("myUserAdmin", "yourAdminPassword")
1
&gt; show dbs
admin              0.000GB
config             0.000GB
dev-bookingsystem  0.000GB
local              0.000GB
&gt; use prod-digitaldocblog
switched to db prod-digitaldocblog
&gt; db.createUser({ user: "myUserProdDigitaldocblog", pwd: "yourDbUserPassword", roles: &#91;{ role: "dbOwner", db: "prod-digitaldocblog" }] })
Successfully added user: {
"user" : "myUserProdDigitaldocblog",
"roles" : &#91;
{
"role" : "dbOwner",
"db" : "prod-digitaldocblog"
}
]
}
&gt; db
prod-digitaldocblog
&gt; show dbs
admin              0.000GB
config             0.000GB
dev-bookingsystem  0.000GB
local              0.000GB
&gt; db
prod-digitaldocblog
&gt; db.runCommand( { create: "col_default" } )
{ "ok" : 1 }
&gt; show collections
col_default
&gt; show dbs
admin                0.000GB
config               0.000GB
dev-bookingsystem    0.000GB
local                0.000GB
prod-digitaldocblog  0.000GB
&gt; exit
bye
patrick@h2866085:~$
</code></pre>



<p>Now I can connect each app with their database with the following string.</p>



<pre class="wp-block-code"><code>mongodb://&lt;youruser&gt;:&lt;yourpassword&gt;@localhost/&lt;yourdatabase&gt;
</code></pre>



<h2 class="wp-block-heading">Deploy the production node app</h2>



<p>To deploy my node app into production I first copy the <code>package.json</code> file into the <code>/var/www/node/prod</code> directory and run <code>npm install</code> to install all dependencies. The directory <code>node_modules</code> now exists in my <code>/var/www/node/prod</code> directory.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/var/www/node/prod$ ls -l
insgesamt 116
-rw-r--r--   1 patrick patrick   615 Jan 18 14:36 package.json
patrick@h2866085: npm install
patrick@h2866085:/var/www/node/prod$ ls -l
insgesamt 116
drwxrwxr-x 220 patrick patrick 12288 Feb 23 13:15 node_modules
-rw-r--r--   1 patrick patrick   615 Jan 18 14:36 package.json
-rw-rw-r--   1 patrick patrick 67705 Feb 23 13:15 package-lock.json
patrick@h2866085:
</code></pre>



<p>Then I copy all the application files on the server into the directory ****<code>/var/www/node/prod</code> .</p>



<pre class="wp-block-code"><code>patrick@h2866085:/var/www/node/prod$ ls -al
insgesamt 132
drwxr-xr-x  10 patrick patrick  4096 Feb 23 13:17 .
drwxr-xr-x   4 root    root     4096 Feb 23 08:56 ..
drwxr-xr-x   3 patrick patrick  4096 Feb 23 13:16 app
drwxr-xr-x   2 patrick patrick  4096 Feb 23 13:16 config
-rw-------   1 patrick patrick   167 Feb 19  2020 .env
-rw-r--r--   1 patrick patrick    33 Feb 19  2020 .env.example
drwxr-xr-x   2 patrick patrick  4096 Feb 23 13:16 middleware
drwxr-xr-x   2 patrick patrick  4096 Feb 23 13:16 modules
drwxrwxr-x 220 patrick patrick 12288 Feb 23 13:15 node_modules
-rw-r--r--   1 patrick patrick   615 Jan 18 14:36 package.json
-rw-rw-r--   1 patrick patrick 67705 Feb 23 13:15 package-lock.json
-rw-r--r--   1 patrick patrick  1281 Mai 17  2020 prod.digitaldocblog.js
drwxr-xr-x   2 patrick patrick  4096 Feb 23 13:17 routes
drwxr-xr-x   7 patrick patrick  4096 Feb 23 13:17 static
drwxr-xr-x   2 patrick patrick  4096 Feb 23 13:17 views
patrick@h2866085:/var/www/node/prod$ nano .env
</code></pre>



<p>I edit my environment variables in the <code>.env</code> file. Here I configure in particular the server port and the database connection string.<br></p>



<pre class="wp-block-code"><code>patrick@h2866085:/var/www/node/prod$ cat .env
port= 3000
host=127.0.0.1
mongodbpath=mongodb://&lt;youruser&gt;:&lt;yourpassword&gt;@localhost/&lt;yourdatabase&gt;
jwtkey=&lt;yourjwtkey&gt;
patrick@h2866085:/var/www/node/prod$
</code></pre>



<p>Finally I start the production application with PM2.</p>



<pre class="wp-block-code"><code>patrick@h2866085:/var/www/node/prod$ pm2 start prod.digitaldocblog.js
</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mongodb and Mongoose on Ubuntu Linux</title>
		<link>https://digitaldocblog.com/database/mongodb-and-mongoose-on-ubuntu-linux/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 28 Feb 2020 08:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MongoDB]]></category>
		<guid isPermaLink="false">https://digitaldocblog.com/?p=105</guid>

					<description><![CDATA[In this article I will show you how to install mongodb on a Ubuntu Linux System. For this I use the step by step installation guide from mongodb. Since the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In this article I will show you how to install mongodb on a Ubuntu Linux System. For this I use the step by step installation guide from <a href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/">mongodb</a>.</p>



<p>Since the installation of mongodb is developed specifically for certain Ubuntu system versions, the system version of the Ubuntu system must first be found out. This is done by entering the following command in the terminal.</p>



<pre class="wp-block-code"><code>:# lsb_release -dc

Description:	Ubuntu 18.04.3 LTS
Codename:		bionic

</code></pre>



<p>So my system is an Ubuntu 18.04.3 LTS (Long Term Support) with the code name <em>bionic</em>. This information is important when, as shown in the following section, the list file entry is created.</p>



<p>The installation itself is carried out with the package manager <code>apt</code>.</p>



<p>Basically there is also a <code>mongodb</code> package managed by Ubuntu that could be installed with the standard <code>apt</code> or <code>apt-get</code> installation from the apt repository. <code>mongodb</code> is not the desired installation and should, if it was installed on the system beforehand, be removed with <code>apt-get remove</code>.</p>



<p>It is therefore recommended to install the <code>mongodb-org</code> package managed by MongoDB Inc.</p>



<p>Since this <code>mongodb-org</code> package comes from a source that has not yet been verified, it is strongly recommended to import the GPG verification key offered by MongoDB Inc. to enable the apt program to check the confidentiality of the package. The corresponding public key must therefore be imported from the mongodb server.</p>



<p>From a terminal, issue the following command to import the MongoDB public GPG Key used by the Ubuntu <code>apt</code> program.</p>



<pre class="wp-block-code"><code>wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -

</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>note</strong>: <code>wget</code> is a program that can be used to download files from FTP or HTTP servers from a terminal. The program is often used to start a download of data with the code of a shell script. However, it is also possible to enter a wget command directly in the terminal and thus get data from servers.</p><p>The <code>-q</code> option prevents <code>wget</code> from displaying information on the console. The option <code>-O &lt;FILE&gt;</code> writes the content of the downloaded file to a file on the local file system. If you specify the <code>-</code> option after the <code>-O</code> option, <code>wget</code> writes the contents of the downloaded file directly to the standard output (stdout) of the terminal. The latter is useful, for example, for reading GPG key files if these keys are then to be added directly to the keychain.</p><p>And that&#8217;s exactly what we want to do with the <code>apt-key</code> command. With <code>apt-key</code>, various commands can be used to perform actions that are carried out with the keychain.</p><p>For example, the <code>apt-key add</code> command adds a new key to the keychain. This key can either be stored in a file and read from there or forwarded from a previous command via the standard output of the terminal (stdout) to the standard input (stdin) for processing <code>apt-key add</code>. The latter is instructed by <code>-</code> at the end of the command.</p></blockquote>



<p>Since this <code>mongodb-org</code> package is located on external mongodb http or ftp servers, these external servers must be made known to the system as confidential sources by making a corresponding list file entry in the <code>/etc/apt/source.list.d</code> directory.</p>



<p>Create the list file <code>/etc/apt/sources.list.d/mongodb-org-4.2.list</code> for your version of Ubuntu.</p>



<pre class="wp-block-code"><code>echo "deb &#91; arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list

</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>note</strong>: With <code>echo</code>, strings and variables can be displayed line by line on the standard terminal output <code>stdout</code>. The string to be output is specified either with single quotation marks <code>'string'</code> or with double quotation marks <code>"string"</code>. Thus with the command <code>echo 'this is an example'</code> &#8222;this is an example&#8220; can be shown directly in the terminal.</p><p>The pipe operator <code>|</code> belongs to the terminal redirects and forwards the output of a command instead of <code>stdout</code> directly to <code>stdin</code> of another command. The subsequent command can then process the result or the output of the first command. In this case here, the output of a string is forwarded to the <code>tee</code> command.</p><p><code>tee</code> reads from the standard input <code>stdin</code> and doubles the read data. The data is then forwarded once to a file and to the standard edition <code>stdout</code>.</p></blockquote>



<p>Now the GPG key has been added to the keychain and apt can use it to verify the mongodb-org package. In addition, the source directory of the installation packages is known to the system as a verified external source in the list file.</p>



<p>Installation with <code>apt</code> can now begin.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>note:</strong> APT (Advanced Packaging Tool) is the command line tool for managing installation packages in Debian Linux. Ubuntu and other Linux distributions that come from Debian Linux also use APT. <code>apt</code> is the successor to <code>apt-get</code> and offers a different but also a wider range of functions. The commands of <code>apt</code> are essentially the same as those of <code>apt-get</code>.</p></blockquote>



<p>Issue the following commands in the terminal.</p>



<pre class="wp-block-code"><code>:# sudo apt-get update

:# sudo apt-get install -y mongodb-org

</code></pre>



<p>The repository index is updated with <code>upgrade</code>. This should always be done before each installation. The <code>-y</code> option ensures that all interactive questions are answered with <em>yes</em> during the installation.</p>



<p>After the installation issue the following commands to check the status, start, stop and restart the <em>mongod</em>.</p>



<pre class="wp-block-code"><code>:# sudo service mongod status

:# sudo service mongod start

:# sudo service mongod stop

:# sudo service mongod restart

</code></pre>



<p>Mongodb comes with 3 standard dbs pre installed:</p>



<ul class="wp-block-list"><li>admin</li><li>config</li><li>local<br></li></ul>



<p>If you want to use mondodb for a project you setup your own database. databases in mongodb contain collections and collections contain the data. So for example you could have the following structure for your project:</p>



<p><code>your-db -&gt; your-db-users-collection -&gt; your-db-users-collection-user-data</code></p>



<p>MongoDB by default does not enable client authentication. So you could now  setup your new database like <em>your-db</em> and connect to it without authentication. This would mean that everyone in the world is able to access your data.</p>



<p>Thefore you should enable client authentication and follow the given steps. Here we will implement a very simple security concept.<br></p>



<p>The following steps include the setup of an admin user in standard admin db and the creation of a project database with a seperate user. The admin user will be able to create databases and manage users for all databases in the mondodb instance. Each seperate project database become a seperate user and this user will be the owner and can do everything.</p>



<p>First we create an admin user in mongo shell. After we create that admin user we test if authentication works with <code>db.auth</code> and <code>exit</code> mongo shell.</p>



<pre class="wp-block-code"><code>:# mongo

&gt; use admin
switched to db admin

&gt; db
admin

&gt; db.createUser({ user: "myUserAdmin", pwd: "adminpassword", roles: &#91;{ role: "userAdminAnyDatabase", db: "admin" }, {"role" : "readWriteAnyDatabase", "db" : "admin"}] })

&gt; db.auth("myUserAdmin", "adminpassword")
1

&gt; show users
{
	"_id" : "admin.myUserAdmin",
	"userId" : UUID("5cbe2fc4-1e54-4c2d-89d1-317340429571"),
	"user" : "myUserAdmin",
	"db" : "admin",
	"roles" : &#91;
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		},
		{
			"role" : "readWriteAnyDatabase",
			"db" : "admin"
		}
	],
	"mechanisms" : &#91;
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

&gt; exit

</code></pre>



<p>In this case the admin user got the role <code>userAdminAnyDatabase</code> and the role <code>readWriteAnyDatabase</code>. With userAdminAnyDatabase the admin user will be able to create, update, delete users on all databases except local and config.</p>



<p><code>readWriteAnyDatabase</code> provides all the privileges to read plus the ability to modify data on all non-system collections.</p>



<p>Then open <code>/etc/mongod.conf</code> file in your editor an add the following lines to the file if they do not already exist. Therefore pls. note the <code>security:</code> option (<em>security: authorization: enabled</em>).</p>



<pre class="wp-block-code"><code># mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1


#processManagement:

#security:
security:
  authorization: enabled

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:

</code></pre>



<p>Pls. note the <code>net:</code>option (<em>net: port: 27017 bindIp: 127.0.0.1</em>). For security reasons it is necessary that the mongodb instance only connects on the loopback interface (127.0.0.1). Mongodb may only accept connections from this interface and never from outside, such as from an interface that is connected to the internet. Therefore <code>bindIp</code> must be configured with <code>127.0.0.1</code> in <em>mongod.conf</em> as is the case in this configuration above.</p>



<p>Then you should <em>stop</em> and <em>start</em> or simply <em>restart</em> your mongod.</p>



<pre class="wp-block-code"><code>:# sudo service mongod restart

</code></pre>



<p>Authentication is now enabled and we can logon with the admin user to a create a new project database with a user that will be the owner.</p>



<pre class="wp-block-code"><code>:# mongo

&gt; use admin
switched to db admin

&gt; db.auth("myUserAdmin", "adminpassword")
1

&gt; use yourdatabase
switched to db yourdatabase

&gt; db.createUser({ user: "youruser", pwd: "yourpassword", roles: &#91;{ role: "dbOwner", db: "yourdatabase" }] })

&gt; db.auth("youruser", "yourpassword")
1

&gt; exit

</code></pre>



<p>The database owner can perform any administrative action on <em>yourdatabase</em> (database that has just been created by the admin). The owner role is something like the master role and combines privileges granted by the readWrite, dbAdmin and userAdmin roles.</p>



<p>Now you can connect to <em>yourdatabase</em> using the following connection string.</p>



<pre class="wp-block-code"><code>mongodb://youruser:yourpassword@localhost/yourdatabase

</code></pre>



<h3 class="wp-block-heading">Install Mongoose local package in a project directory</h3>



<p>Mongoose offers a schema-based solution to apply modeling and structure to application data and then to save the data in a Mongodb. mongoose is an open source node.js package and is ideal for the development of database-based node js web applications such as node express.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>note:</strong> This article focuses on the installation and commissioning of Mongodb. Mongoose is required for the development of node js applications and is only briefly described here. Scheme and data modeling as well as CRUD application examples are explained in one of the next articles in the context of an express application.</p></blockquote>



<p>Suppose we have created a project directory called <code>express</code> on our computer. Then we will now change to this directory and list all currently installed npm packages with the command <code>npm list --depth 0</code>.</p>



<pre class="wp-block-code"><code>:# cd /software/dev/express

:# npm list --depth 0

</code></pre>



<p>In the project directory, the following command is executed in the terminal to install mongoose for your project.</p>



<pre class="wp-block-code"><code>:# npm install mongoose

server@1.0.0 /home/patrick/software/dev/express
`-- mongoose@5.8.9  extraneous

</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>**note: ** If you have problems with installing packages pls. create the package.json file with all the dependencies and then run <code>npm install</code>.</p></blockquote>



<pre class="wp-block-code"><code>:# cat package.json

{
  "name": "server",
  "version": "1.0.0",
  "private": true,
  "description": "this is test node application",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
    "start": "node server.js"
  },
  "author": "Patrick Rottländer",
  "license": "ISC",
  "dependencies": {
    "envy": "^2.0.0",
    "express": "^4.17.1",
    "mongoose": "^5.8.3"
  },
  "devDependencies": {}
}

:# npm install

</code></pre>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
