Configuration

Environment variables

Env var Meaning
UNNODE_WORKERS Maximum number of CPUs the server should use. Omit or set to 0 to use all CPU cores.
UNNODE_LOGFILE Logfile name. Will be used as:
server-dir/log/{UNNODE_LOGFILE}-YYYY-MM-DD
server-dir/log/{UNNODE_LOGFILE} will be a symlink to current/latest logfile.

Logs are automatically rotated and kept for 30 days OR 30 files of 20mb each, whichever comes first.

If not set, no logfiles will be produced.
UNNODE_TIMEZONE Timezome for log timestamps.

Value must be supported by https://momentjs.com/timezone/

Usually this is autodetected, no need to set unless you want to explicitly change it.
UNNODE_SERVER_LISTEN_HOST IP-address or hostname to bind to.
UNNODE_SERVER_INSECURE_PORT HTTP server listen port (insecure)

Omit or set to 0 to skip starting insecure server.
UNNODE_SERVER_SECURE_PORT HTTPS server listen port.

If this is set, then...

UNNODE_SERVER_SECURE_DEFAULT_KEY
UNNODE_SERVER_SECURE_DEFAULT_CERT
UNNODE_SERVER_SECURE_DEFAULT_CA

... must also be set.

Omit or set to 0 to skip starting secure server.
UNNODE_SERVER_SECURE_DEFAULT_KEY Full path to a certificate key file in PEM format.
UNNODE_SERVER_SECURE_DEFAULT_CERT Full path to certificate file in PEM format.
UNNODE_SERVER_SECURE_DEFAULT_CA Full path to trusted CA certificates file in PEM format. Optional, only set if you want to override the trusted CA certificates.
UNNODE_SERVER_SECURE_MINVERSION Optionally set the minimum TLS version to allow. See https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options 'minversion' for supported values.
UNNODE_SERVER_CONFIG Full path to Unnode.js server config file (see below).

Default is server-dir/config/unnode-server-config.js
ROLLBAR_ACCESS_TOKEN Rollbar access token. Setting this and ROLLBAR_ENVIRONMENT will enable Rollbar logging for all log messages of level 'warning' and above.
ROLLBAR_ENVIRONMENT Rollbar environment.

Server config file

By default, Unnode.js will look for the server config file at server-dir/config/unnode-server-config.js or at the path specified in UNNODE_SERVER_CONFIG environment variable.

See below for an example config file.

The file should export an array of objects with the following properties:

Property Type Meaning
vhost array An array of strings for hostnames where the routes in this entry should respond to. This can be used to easily host multiple domains on a single instance of Unnode.js.

If this only contains one entry '*' , then this entry will be treated as a wild-card "catch-all" vhost if no other vhost entry matches.

You can also use wildcards, e.g. '*.mysite.org' . This would make the routes respond to any hostname under '.mysite.org'
secureContext object TLS certificate that will be served for this vhost.
secureContext.key string Full path to a certificate key file for this vhost, in PEM format.

If your default cert covers the hostnames for this vhost, then you can simply use process.env.UNNODE_SERVER_SECURE_DEFAULT_KEY here.
secureContext.cert string Full path to certificate file for this vhost, in PEM format.

The cert should be valid for all hostnames listed under vhosts.

If your default cert covers the hostnames for this vhost, then you can simply use process.env.UNNODE_SERVER_SECURE_DEFAULT_CERT here.
secureContext.ca string Full path to trusted CA certificates file in PEM format. Optional, only set if you want to override the trusted CA certificates for this vhost.

If your default cert covers the hostnames for this vhost, then you can simply use process.env.UNNODE_SERVER_SECURE_DEFAULT_CA here.
helmetOptions object Helmet configuration. Will be passed directly to the helmet middleware. See https://helmetjs.github.io/
robotsTxt string A string that will be served at /robots.txt. For example: "User-agent: *\nAllow: /"
serveFavicon string Full filesystem path to a favicon file. Will be served at /favicon.ico
routes array Routes configuration
routes[n].method string HTTP method for this route. GET / HEAD / POST / PUT / DELETE / PATCH etc.
routes[n].path string URL path for this route.
routes[n].controller string Controller for this route.

Example: unnodejs.org/unnodejs-controller#index

This would route requests for this route to server-dir/controllers/unnodejs.org/unnodejs-controller.js.

The file should export a class that contains a method of the name index. Example:
const logger  = require('unnode').workerLogger
const unUtils = require('unnode').utils
 
class IndexController {
    constructor() {
 
    }
 
    index(customParameter, req, res) {
        const ip     = unUtils.getClientIp(req)
        const method = req.method
        const url    = unUtils.getRequestFullUrl(req)
        const agent  = req.get('user-agent')
 
        logger.log('info',
            `Request ${method} ${url} (from: ${ip}, `
            + `User-Agent: ${agent})`)
 
        res.send('Hello World!')
    }
}
 
module.exports = new IndexController()


Either this or static must be set per route.
routes[n].static string Serve a static directory on this route instead. This should be a full filesystem path to the directory you want to serve.

Either this or controller must be set per route.
routes[n].customParameter any Send a custom variable as the first parameter to the route controller method/function.
routes[n].cacheControl object Cache-Control header directives for this route. This option will be passed directly to the express-cache-controller middleware.

NOTE: Does not apply for static routes, they will be automatically served with:

Cache-Control: public, max-age=16070400

and no Etag and Last-Modified headers (see here)

Example config:

//
// config/unnode-server-config.js
//

module.exports = [
    {
        // Answer on localhost also for development
        'vhost': ['localhost', 'my-site.org'],
        'secureContext': {
            'key': process.env.UNNODE_SERVER_SECURE_DEFAULT_KEY,
            'cert': process.env.UNNODE_SERVER_SECURE_DEFAULT_CERT
        },
        'helmetOptions': {
            // Allow external google font imports in our CSP policy
            contentSecurityPolicy: {
                directives: {
                    'default-src': ["'self'"],
                    'img-src': ["'self'", 'img.shields.io'],
                    'style-src': ["'self'", "'unsafe-inline'", 'fonts.googleapis.com'],
                    'font-src': ["'self'", 'fonts.gstatic.com'],
                    'script-src': ["'self'", "'unsafe-eval'"],
                    'object-src': ["'self'"],
                }
            }
        },
        'robotsTxt': "User-agent: *\nAllow: /",
        'serveFavicon': path.resolve(__dirname, '..', 'favicon.ico'),
        'routes': [
            // Serve some html pages
            {
                method: 'GET',
                path: '/',
                controller: 'site-controller#index',
                cacheControl: noCache
            },
            {
                method: 'GET',
                path: '/team',
                controller: 'site-controller#teamPage',
                cacheControl: noCache
            },
 
            // Serve some static assets
            { path: '/css', static: path.resolve(__dirname, '..', 'css') },
            { path: '/js', static: path.resolve(__dirname, '..', 'js') },
            { path: '/images', static: path.resolve(__dirname, '..', 'images') },
            { path: '/shared/images', static: path.resolve(__dirname, '..', 'images') },
        ]
    },
 
    {
        // This will catch every other request not matched to the above vhosts
        'vhost': ['*'],
        'routes': [
            {
                method: 'GET',
                path: '/',
                // Serve a 404 page via our controller
                controller: 'site-controller#not_found'
            }
        ]
    }
]

Next: Process clustering