<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>questions — Simple Engineering</title>
    <link>https://getsimple.works/tag:questions</link>
    <description></description>
    <pubDate>Sun, 15 Nov 2026 00:29:34 +0000</pubDate>
    <item>
      <title>How to configure nodejs applications</title>
      <link>https://getsimple.works/how-to-configure-nodejs-applications?pk_campaign=rss-feed</link>
      <description>Configuration is at forefront of any applications. This article discusses a couple strategies to go about nodejs configurations, and some...</description>
      <content:encoded><![CDATA[<p>Configuration is at forefront of any applications. This article discusses a couple strategies to go about <code>nodejs</code> configurations, and some tools available that can be leveraged to that end.</p>

<blockquote><p>Techniques explained in this blog, are also available with more details in <a href="http://bit.ly/2ZFJytb"><strong>“Configurations” chapter of the “Testing <code>nodejs</code> Applications”</strong></a> book. <strong><em><a href="http://bit.ly/2ZFJytb">You can grab a copy of this book on this link</a></em></strong>. <a href="http://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing Nodejs Applications Book Cover"/></a></p></blockquote>

<p><strong><em>In this article you will learn about:</em></strong></p>

<p><strong>—</strong></p>
<ul><li>Differentiation of configuration layers</li>
<li>Overview of tools that help to manage configuration files</li>
<li>Overview of basic configurations for a production ready <code>nodejs</code> application</li>
<li>Better manage configuration files, storing and provisioning production secret keys</li>
<li>Monitoring, failover, server and SSL certificate tools</li>
<li>Reducing configuration code change when new versions of system applications are released</li></ul>

<h2 id="layers-of-configuration-of-nodejs-applications">Layers of configuration of <code>nodejs</code> applications</h2>

<blockquote><p>Although this blog article provides overview of tools and configurations, it leaves modularization of configurations in a <code>nodejs</code> setting to another blog post: <strong>“Modularize <code>nodejs</code> configurations”</strong>.</p></blockquote>

<p>From production readiness perspective, there are two distinctive layers of application configurations, or at least in context of this blog post.</p>

<p>The first layer consists of configurations required by the system that is going to be hosting <code>nodejs</code> application. Database server settings, monitoring tools, SSH keys, and other third party programs running on the hosting entity, are few examples that fall under this category. We will refer to these as <em>system variables/settings</em>.</p>

<p>The second layer consists of configuration that <code>nodejs</code> application needs to execute intrinsic business logic. They will be referred to as <em>environment variables/settings</em>. Third party issued secret keys or server port number configurations, fall under this category. Most of cases, you will find such configurations in static variables found in the application.</p>

<p>This blog will be about working with the first layer: <em>system settings</em>.</p>

<blockquote><p>For disambiguation, the system is a computing entity composed of software(an operating system, etc) and hardware(virtual or physical).</p></blockquote>

<h2 id="managing-system-configuration-variables">Managing system configuration variables</h2>

<p>Since <em>environment variable</em> layer of the configuration is technically embedded within the code that uses it by default, changes in configurations are in <em>sync</em> with the code, and <em>vice-versa</em>.</p>

<p>Unlike the <em>environment variables</em>, <em>system variables</em> are not managed the same way <code>nodejs</code> applications they run is managed. Just because our application&#39;s new version saw some changes in <em>environment settings</em>, does not mean that the <code>nginx</code> server has its own settings changed as well. From another perspective, just because <code>nginx</code> latest version saw some changes in its settings, does not necessarily mean that our <code>nodejs</code> application environment settings have to change as well.</p>

<p>The problem we constantly face, is to figure out how to manage changes in configurations as the code evolves, and as the underlying system software evolves.</p>

<p>Things become a bit complicated, at least to manage when third party software(database, monitoring tools) code change also involves configuration changes. We will have to be informed about changes at hand, which is not always evident as those changes are released at will of the vendors, and not necessarily communicated to us in realtime. Next, we will have to figure out where every single configuration is located on our system, the apply new modifications. Additional complexity comes in when new changes become incompatible with our current version of <code>nodejs</code> application code, or when rollbacks are not avoidable.</p>

<p>The <code>nodejs</code> application code is not always in sync with the system that hosts it. This is where <em>configuration management(aka CM)</em> tools shine. Passing around both system and environment configuration variable values is a risky business, security-wise. This is where <em>configuration provisioning tools</em> come in handy.</p>

<h2 id="provisioning-secrets-at-deployment-time">Provisioning secrets at deployment time</h2>

<p>In teams that have CI/CD implemented, every programmer has ability to deploy latest code version to production. With great powers comes great responsibilities. Making sensitive data accessible to a larger audience, comes with an increased security risk – for instance leaking secret keys to the public.</p>

<p>The challenge relies on how to approach configuration data management, as a part of a software, giving access to developers ability to work with code, but limiting access to production configuration secrets.</p>

<p>The keyword is in provisioning production secrets at deployment time, and as a part of delivery step, and let any developer have own development secrets. This way, one compromised developer account cannot lead to organization wide data breach.</p>

<blockquote><p>Example of tools that makes provisioning secrets possible: <a href="https://secrethub.io">SecretHub</a>, Kubernetes, <a href="https://www.hashicorp.com/resources/best-practices-using-hashicorp-terraform-with-hashicorp-vault">HashiCorp Vault</a>, etc.</p></blockquote>

<h2 id="reducing-configuration-changes-when-new-system-applications-rollout">Reducing configuration changes when new system applications rollout</h2>

<p>The <a href="http://12factor.net/config">12 App Factor</a> suggests to manage configuration as code. That makes it fast to deploy application anywhere, with less code change upon receiving new code releases.</p>

<p>In most of applications that are not containerized, configurations can be stored on a file server, for example at <code>/etc/config/[app-name]/config.ext</code>. This works on a smaller scale. You will always realize that it becomes a problem to set up a new developer and production machines. But having such a convention in place, reduces the pain.</p>

<p>In case of managing multiple instances of same application, it is better to move this configuration inside the code, at least at build time, ideally at root: <code>[app-root]/config/config.ext</code>. At deployment time, there will be an additional <em>symlinking</em> step, to make sure the new deployment points to the right configuration files.</p>

<h2 id="configure-nginx-to-serve-nodejs-application">Configure <code>nginx</code> to serve <code>nodejs</code> application</h2>

<p><code>nginx</code> is a very good alternative to Apache server. Its non blocking, single threaded model makes it a perfect match to proxy <code>nodejs</code> applications. It is also possible to configure it as a load balancer.</p>

<p>The location of <code>nginx</code> configuration files depend on Operating System distribution, the application is hosted on. In our context, we assume that our operating system is Linux/Unix and <code>nginx</code> is installed and configured at <code>/etc/nginx</code>.</p>

<blockquote><p>Some other possible places are <code>/usr/local/nginx</code>, <code>/usr/local/etc/nginx</code> or any other location depending on how the operating system manages its filesystem. The paths above are of course on Linux or Unix distributions.</p>

<p><em>We recommend reading</em> <em><a href="https://getsimple.works/how-to-install-nodejs">“How to install <code>nodejs</code>“</a></em> and <em><a href="https://getsimple.works/how-to-install-nginx">“How to install <code>nginx</code>“</a></em> for more in-depth information that may not be found in current blog post.</p></blockquote>

<p>The magic happens at the <code>upstream nodeapps</code> section. This configuration plays the gateway role, and makes public a server that was otherwise private.</p>

<pre><code class="language-shell">
upstream nodeapps{
  # Directs to the process with least number of connections.
  least_conn;
  server 127.0.0.1:8080 max_fails=0 fail_timeout=10s;
  server localhost:8080 max_fails=0 fail_timeout=10s;
  keepalive 512;
}

server {
  listen 80;
  server_name app.website.tld;
  client_max_body_size 16M;
  keepalive_timeout 10;

  # Make site accessible from http://localhost/
  root /var/www/[app-name]/app;
  location / {
    proxy_pass http://nodeapps;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
</code></pre>

<p><em><em>Example</em>: Typical <code>nginx</code> configuration at <code>/etc/nginx/sites-available/app-name</code></em></p>

<h2 id="configure-redis-to-run-with-a-nodejs-server">Configure <code>redis</code> to run with a <code>nodejs</code> server</h2>

<p><code>redis</code> is a minimalistic yet feature complete in memory key-value data store engine. The need to have <code>redis</code> in addition to a database arises from the need to make realtime possible in clustered/multi-process <code>nodejs</code> deployment. It is possible to run as a standalone or clustered environment.</p>

<p>The location of <code>redis</code> configuration files depend on Operating System distribution, the application is hosted on. In our context, we assume that our operating system is Linux/Unix and <code>redis</code> is installed and configured at <code>/etc/redis.conf</code>.</p>

<blockquote><p>Some other possible places are <code>/usr/local/redis</code>, <code>/usr/local/etc/redis</code> or any other location depending on how the operating system manages its filesystem.</p></blockquote>

<p>There is little to no configuration required to run a <code>redis</code> instance, and same configuration data can be passed as arguments at start time.</p>

<pre><code class="language-shell">port 6380
maxmemory 2mb
</code></pre>

<p><em><em>Example</em>:</em></p>

<p>To launch <code>redis</code> via CLI, the following command can be typed on the interface:
  – <code>$ redis-server --port 6380 --slaveof 127.0.0.1 6379</code> in this configuration, <code>redis</code> starts on localhost as a slave of another instance running on port 6379.
  – <code>$ redis-server /usr/local/etc/redis.conf</code> in this configuration, <code>redis</code> starts using configuration settings stated in <code>/usr/local/etc/redis.conf</code>.</p>

<blockquote><p><em>We recommend reading</em> <em><a href="https://getsimple.works/how-to-install-redis">“How to install <code>redis</code>“</a></em> and <em><a href="https://getsimple.works/how-to-install-nodejs">“How to install <code>nodejs</code>“</a></em> for more in-depth information that may not be found in current blog post. <a href="https://redis.io/topics/config"><code>redis</code> configuration manual</a></p></blockquote>

<h2 id="configure-mongodb-as-a-database-server-for-nodejs-project">Configure <code>mongodb</code> as a database server for <code>nodejs</code> project</h2>

<p><code>mongodb</code> is a noSQL database engine that covers most use cases a <code>nodejs</code> application can do. It is possible to configure the database in a cluster, as well as standalone mode.</p>

<p>The location of <code>mongodb</code> configuration files depend on Operating System distribution, the database server is hosted on. In our context, we assume that our operating system is Linux/Unix and <code>mongodb</code> is installed and configured at <code>/etc/mongod.conf</code>.</p>

<blockquote><p>Some other possible places are <code>/usr/local/mongodb</code>, <code>/usr/local/etc/mongodb</code> or any other location depending on how the operating system manages its filesystem. As always, init scripts can be found at <code>//</code></p></blockquote>

<p>There is not a lot of configurations to change to run <code>mongodb</code> server. It is possible to start using the service right after installation, with one exception: when running multiple <code>mongodb</code> instances on the same server, or needing <em>replication and shard</em> features.</p>

<pre><code class="language-shell">processManagement:
   fork: true
net:
  - bindIp: localhost
  + bindIp: localhost,10.8.0.10,192.168.4.24,/tmp/mongod.sock
   port: 27017
storage:
  - dbPath: /srv/mongodb
  + dbPath: /custom/path/to/mongodb
systemLog:
   destination: file
  - path: &#34;/var/log/mongodb/mongod.log&#34;
  + path: &#34;/custom/path/to/mongod.log&#34;
  + logRotate: rename
    logAppend: true
storage:
   journal:
      enabled: true
+ security:
   keyFile: /srv/mongodb/keyfile
</code></pre>

<p><em><em>Example</em>: typical <code>mongodb</code> configuration in <code>/etc/mongod.conf</code></em></p>

<blockquote><p><em>We recommend reading</em> <em><a href="https://getsimple.works/how-to-install-mongodb">“How to install <code>mongodb</code>“</a></em> and <em><a href="https://getsimple.works/how-to-install-nodejs">“How to install <code>nodejs</code>“</a></em> for more in-depth information that may not be found in current blog post, <a href="https://docs.mongodb.com/manual/administration/configuration/"><code>mongodb</code> administration configuration manual</a></p></blockquote>

<h2 id="configure-nginx-to-serve-websockets-with-an-expressjs-and-socket-io-application">Configure <code>nginx</code> to serve WebSockets with an <code>expressjs</code> and <code>socket.io</code> application</h2>

<p>The configuration exposed above does make a <code>nodejs</code> server running on a private network public. However, since the protocol of communication is HTTP, any other protocol, for instance WebSocket, trying to communicated on the same channel will yield an error. To make WebSocket work and using the same port as HTTP(port:80), we will need <code>nginx</code> to upgrade HTTP so that WebSocket messages can pass as well.</p>

<p>The script below executes tasks in following order:</p>

<p>#1 Tells <code>nginx</code> which version to upgrade to
#2 Tells <code>nginx</code> to upgrade <code>HTTP</code> to version 1.1
#3 Tells <code>nginx</code> to upgrade upon receiving socket flash request</p>

<pre><code class="language-shell">server{
  #...
  location /{
      proxy_http_version 1.1; #1
      proxy_set_header Upgrade $http_upgrade; #2
      proxy_set_header Connection &#34;upgrade&#34;; #3
  }
}
</code></pre>

<p><em><em>Example</em>: 3 lines that enable <code>nginx</code> to serve WebSockets</em></p>

<blockquote><p>Proxying WebSockets in an nginx configuration is based on ideas of Chriss Lea&#39;s blog post <em><em><a href="https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/">Proxying WebSockets with Nginx</a></em></em></p></blockquote>

<h2 id="configure-upstart-to-start-nodejs-application">Configure <code>upstart</code> to start <code>nodejs</code> application</h2>

<p>With configurations we have at this point, the system applications are going to be useable, if we so state from the command line interface. That is, every application will have to be specifically executed.</p>

<p>The issue in production environment is that the terminal has to be closed at some point, once all tasks regarding a command line interface are completed. There is already some services such as <code>init</code> or <code>systemctl</code> that are already shipped with the system. Using upstart for starting and stopping any application is due to its ease of configurations, asynchronous and reactive nature of the tool, that other tools mentioned above lack.</p>

<p><code>upstart</code> is a free and open source task runner. It was designed with Ubuntu Linux distribution in mind, but can also work on other Linux/Unix distributions. It has expressive task declaration that even newbies can feel comfortable using.</p>

<p>The location of <code>upstart</code> configuration files depend on Operating System distribution the application is hosted on. In our context, we assume that our operating system is Linux/Unix and <code>upstart</code> is installed and configured at <code>/etc/upstart</code>.</p>

<blockquote><p>Some other possible places are <code>/usr/local/upstart</code>, <code>/usr/local/etc/upstart</code> or any other location depending on how the operating system manages its filesystem.</p></blockquote>

<p>At the end of a successful configuration of tasks, we should be able to start all of the system applications and services using the following script, either by running one by one, or by making an extra executable file to simplify our task</p>

<blockquote><p>As a reminder, the command follows following statement <code>sudo service &lt;servicename&gt; &lt;control&gt;</code>, where the service-name is technically our application and will be located at <code>/etc/init/&lt;servicename&gt;.conf</code>, whereas control is one of start/restart or stop keywords</p></blockquote>

<pre><code class="language-shell"># testing validity of configurations
init-checkconf /etc/init/nginx.conf
init-checkconf /etc/init/redis.conf
init-checkconf /etc/init/mongod.conf
init-checkconf /etc/init/appname.conf

# restart to re-use same script post deployment
service nginx   restart  
service redis   restart  
service mongodb restart  
service appname restart  
</code></pre>

<p><em><em>Example</em>: tasks to start/restart all deployment applications in <code>appname/bin/start.sh</code> or on a command line</em></p>

<p>Alternatively, we should be able to stop services either one by one, or all of the services, using the scripts as in the following example</p>

<pre><code class="language-shell">service nginx   stop  
service redis   stop  
service mongodb stop  
service appname stop  

# In case mongod stops to halt 
sudo /usr/bin/mongod -f /etc/mongod.conf --shutdown
</code></pre>

<p><em><em>Example</em>: tasks to stop applications in <code>appname/bin/stop.sh</code> or on a command line</em></p>

<p>Now that we know how to launch our services, the problem remains on how do we configure each one of those services we are just running. The following are typical example, aforementioned services can be brought online.</p>

<pre><code class="language-shell"># nginx

description &#34;nginx http daemon&#34;
author &#34;Author Name&#34;

start on (filesystem and net-device-up IFACE!=lo)
stop on runlevel [!2345]

env DAEMON=/usr/sbin/nginx
env PID=/var/run/nginx.pid

expect fork
respawn
respawn limit 10 5
#oom never

pre-start script
        $DAEMON -t
        if [ $? -ne 0 ]
                then exit $?
        fi
end script

exec $DAEMON
</code></pre>

<p><em><em>Example</em>: <code>nginx</code> job descriptor in <code>/etc/init/nginx.conf</code> <a href="https://www.nginx.com/resources/wiki/start/topics/examples/ubuntuupstart/">source</a></em></p>

<p>The job that will be executed by the <code>redis</code> service is as in the following script.</p>

<pre><code class="language-shell">description &#34;redis server&#34;

start on runlevel [23]
stop on shutdown

pre-stop script
    rm /var/run/redis.pid
end script

script
  echo $$ &gt; /var/run/redis.pid
  exec sudo -u redis /usr/bin/redis-server /etc/redis/redis.conf
end script

respawn limit 15 5
</code></pre>

<p><em><em>Example</em>: <code>redis</code> job descriptor in <code>/etc/init/redis.conf</code></em></p>

<blockquote><p>If planning to use external monitoring service, <code>respawn limit 15 5</code> should be either removed, or restart with the monitoring tool the failing service after 15 * 5 seconds time.</p></blockquote>

<p>The job that will be executed by the <code>mongodb</code> service is as in the following script.</p>

<blockquote><p>This example is minimalistic, more details can be found on this resource: <a href="https://github.com/mongodb/mongo/blob/master/debian/mongod.upstart">Github mongod.upstart</a>. Some tuning may be required before use.</p></blockquote>

<pre><code class="language-shell">#!upstart
description &#34;mongodb server&#34;
author      &#34;author name &lt;author@email&gt;&#34;

start on runlevel [23]
stop on shutdown

pre-stop script
    rm /var/run/mongod.pid
end script

script
  echo $$ &gt; /var/run/mongod.pid
  exec sudo -u mongod /usr/bin/mongod -f /etc/mongod.conf
end script

respawn limit 15 5
</code></pre>

<p><em><em>Example</em>: <code>mongod</code> job descriptor in <code>/etc/init/mongod.conf</code></em></p>

<blockquote><p>If planning to use external monitoring service, <code>respawn limit 15 5</code> should be either removed, or restart with the monitoring tool the failing service after 15 * 5 seconds time.</p></blockquote>

<p>The next and last step in this section, is an example of the script used to start the <code>nodejs</code> server. At this point, any disruption or un-handled problem in the application, will bring down the system as a whole. Other services will be up and running, unfortunately the <code>nodejs</code> server wont! To make failure recovery automatic, we will need yet another tool described in the next section.</p>

<pre><code class="language-shell">#!upstart
description &#34;appname nodejs server&#34;
author      &#34;author name &lt;author@email&gt;&#34;

start on startup
stop on shutdown

script
    export HOME=&#34;/var&#34; # this is required by node to be set 
    echo $$ &gt; /var/run/appname.pid
    exec sudo -u appname sh -c &#34;/usr/bin/node /var/www/appname/server.js &gt;&gt; /var/log/appname.log 2&gt;&amp;1&#34;
end script

pre-start script
    # Date format same as (new Date()).toISOString() for consistency
    echo &#34;[`date -u +%Y-%m-%dT%T.%3NZ`] Starting&#34; &gt;&gt; /var/log/appname.log
end script

pre-stop script
    rm /var/run/appname.pid
    echo &#34;[`date -u +%Y-%m-%dT%T.%3NZ`] Stopping&#34; &gt;&gt; /var/log/appname.log
end script
</code></pre>

<p><em><em>Example</em>: <code>appname</code> job descriptor in <code>/etc/init/mongod.conf</code></em></p>

<blockquote><p><em>We recommend reading</em> <em><a href="https://getsimple.works/how-to-install-upstart">“How to install <code>upstart</code>“</a></em> and <em><a href="https://getsimple.works/how-to-install-nodejs">“How to install <code>nodejs</code>“</a></em> for more in-depth information that may not be found in current blog post. <a href="https://www.digitalocean.com/community/tutorials/the-upstart-event-system-what-it-is-and-how-to-use-it">The upstart event system, what it is and how to use it</a>. On <code>nginx</code> blog: <a href="https://www.nginx.com/resources/wiki/start/topics/examples/ubuntuupstart/">Ubuntu upstart</a>.</p></blockquote>

<h2 id="configure-monit-to-monitor-nodejs-application">Configure <code>monit</code> to monitor <code>nodejs</code> application</h2>

<p>The previous section discussed how to automate starting/stopping services. However, when something goes unpredictably wrong, we will not be able to know that something bad happened, nor to tell which system is the culprit. Moreover, we will not be able to recover the from the failure at least by restarting the failing service.</p>

<p>The monitoring tool discussed henceforth, addresses most of the statement made above.</p>

<p><code>monit</code> is a free and open source monitoring alternative. With a little bit of ingenuity, it is possible to use it to trigger tasks execution, such as sending an alert when something goes off the rails or restarting a failing application.</p>

<p>The location of <code>monit</code> configuration files depend on Operating System distribution the application is hosted on. In our context, we assume that our operating system is Linux/Unix and <code>monit</code> is installed and configured at <code>/etc/monit</code>.</p>

<blockquote><p>Some other possible places are <code>/usr/local/monit</code>, <code>/usr/local/etc/monit</code> or any other location depending on how the operating system manages its filesystem.</p></blockquote>

<p>The order of monitoring will go as following:</p>
<ul><li>When <code>nginx</code> goes down, we will have to notify the administrator.</li>
<li>When <code>redis</code> runs out of memory or goes down, we will force a restart</li>
<li>When <code>mongodb</code> may trigger daily backup scripts, may notify when database is down or failed restart attempts</li>
<li>When <code>appname</code> goes down|uses abnormally high CPU|run out of memory, we will have to restart and notify the administrator</li></ul>

<pre><code class="language-shell"># The application
check host appname with address 127.0.0.1
    start &#34;/sbin/start appname&#34;
    stop &#34;/sbin/stop appname&#34;
    restart program  = &#34;/sbin/restart appname&#34;
    if failed port 80 protocol http
        request /ok
        with timeout 5 seconds
        then restart
    if cpu &gt; 95% for 2 cycles then alert          # Alert on excessive usage of CPU
    if total cpu &gt; 99% for 10 cycles then restart # Restart if CPU reaches 99 after 10 checks

# Checking using PID 
check process nginx with pidfile /var/run/nginx.pid
    start program = &#34;/etc/init/nginx start&#34;   # service nginx start
    stop program = &#34;/etc/init/nginx stop&#34;     # service nginx stop
    restart program  = &#34;/etc/init/nginx restart&#34;
    if failed port 80 protocol http then restart  # restart when process up, but not answering
    if failed port 443 protocol https then restart

check process redis with pidfile /var/run/redis.pid
    start program = &#34;/etc/init/redis start&#34;   # service redis start
    stop program = &#34;/etc/init/redis stop&#34;     # service redis stop
    if memory &gt; 50 MB then alert
    if total memory &gt; 500 MB then restart

check process mongod with pidfile /var/run/mongod.pid
    start program = &#34;/etc/init/mongod start&#34;   # service mongod start
    stop program = &#34;/etc/init/mongod stop&#34;     # service mongod stop
    restart program  = &#34;/etc/init/mongod restart&#34;
    if failed port 27017 protocol mongo then restart  
    if disk read &gt; 10 MB/s for 2 cycles then alert  # Alert on slow reads 
</code></pre>

<p><em><em>Example</em>: in <code>/etc/minit/monitrc</code></em></p>

<blockquote><p>To debug validity of <code>/etc/monit/monitrc</code> the following command can be used: <code>monit -t</code>. In case everything looks good, to start services using <code>monit</code> can be done with the following command: <code>monit start all</code>.</p></blockquote>

<p>There is one more aspect that was not discussed in scripts above, and that is <em>“How does <code>monit</code> knows where to send messages in case of alerting?”</em>. The answer is in the next script, as provided by the <code>monit</code> documentation, but that I feel sharing in this blog post:</p>

<pre><code class="language-shell"># Where to send the email
set alert foo@bar
# What message format 
set mail-format {
      from: Monit Support &lt;monit@foo.bar&gt;
  reply-to: support@domain.com
   subject: $SERVICE $EVENT at $DATE
   message: Monit $ACTION $SERVICE at $DATE on $HOST: $DESCRIPTION.
            Yours sincerely,
            monit
 }
 # Setting the mailserver, in our case, mailgun 
 set mailserver smtp.mailgun.org port 587
  username mailgunusr@domain.com password &lt;PASSWORD&gt;
  using &lt;SSL&gt; with timeout 30 seconds
# &lt;SSL&gt; can be SSLV2 | SSLV3 | TLSV1 | TLSV11 | TLSV12 | TLSV13
</code></pre>

<p><em><em>Example</em>: custom alert messages in <code>/etc/minit/monitrc</code></em></p>

<p>This is an example of few things that can be achieved. There are more that <code>monit</code> can do to enhance the deployment experience, and free of charge. Those things can include, but not limited to, schedule reporting, database backups, purging sessions or accounts that looks not right, as well as sending triggering tasks to send emails.</p>

<blockquote><p><em>We recommend reading</em> <em><a href="https://getsimple.works/how-to-install-monit">“How to install <code>monit</code>“</a></em> and <em><a href="https://getsimple.works/how-to-install-nodejs">“How to install <code>nodejs</code>“</a></em> for more in-depth information that may not be found in current blog post. Quick tutorial on <a href="https://mmonit.com/monit/"><code>monit</code></a>. <a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-monit">How to install and configure <code>monit</code></a>, <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#using-the-github_token-in-a-workflow">Creating issues when something goes wrong</a></p></blockquote>

<h2 id="conclusion">Conclusion</h2>

<p>The two tools that tie the whole system together, also need a system to start and stop them. Luckily, the Linux/Unix environment provides a way to make daemons start at start time.</p>

<h2 id="references">References</h2>
<ul><li><a href="https://www.thoughtworks.com/insights/blog/why-configuration-management-and-provisioning-are-different">Why Configuration Management and Provisioning are Different</a> ~ Carlos Nuñez</li>
<li><a href="https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c">Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation</a> ~ Yevgeniy Brikman author of <a href="https://www.terraformupandrunning.com/?ref=gruntwork-blog-2nd-edition">Terraform: Up &amp; Running</a></li>
<li><a href="https://devopscube.com/devops-tools-for-infrastructure-automation/">15 DevOps Tools for Infrastructure Automation and Monitoring</a> ~</li>
<li><a href="https://stackoverflow.com/a/4729870/132610">Monit vs Upstart</a></li>
<li><a href="https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/">Proxying WebSockets with nginx</a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:configurations" class="hashtag"><span>#</span><span class="p-category">configurations</span></a> <a href="https://getsimple.works/tag:questions" class="hashtag"><span>#</span><span class="p-category">questions</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a> <a href="https://getsimple.works/tag:y2020" class="hashtag"><span>#</span><span class="p-category">y2020</span></a> <a href="https://getsimple.works/tag:Jan2020" class="hashtag"><span>#</span><span class="p-category">Jan2020</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-configure-nodejs-applications</guid>
      <pubDate>Fri, 31 Jan 2020 05:04:17 +0000</pubDate>
    </item>
  </channel>
</rss>