Skip to main content

NGINX and App Daemon

Our server serves HTTP and HTTPS traffic using NGINX, it is used to serve static files and proxy requests to your app.

Because it operates for all users on the server, only a limited set of features are configurable, the only way to configure it is via the deployment system.

If you don't familiar with NGINX, you can read some of good resorces here:

Check current configuration

You can check the current configuration by going to Check -> NGINX.

The left side is the configurable options, and the right side is the current configuration applied in NGINX. The configurable option is written in YAML format, which when saved, applied as a new configuration configured via the runner.

Below is the example of the configuration:

nginx:
fastcgi: 'on'
root: public_html
index: index.html index.php
ssl: 'on'

Configure NGINX for HTTPS

The ssl option has three options: always, on, off. The always option will force the server to redirect all HTTP traffic to HTTPS. The default value for ssl is on.

Configure NGINX for PHP

The fastcgi option has three options: always, on, off. The default value for fastcgi is off.

This section is covered more in the PHP Deployment section.

Configure NGINX for General Apps

NGINX by default only forwards connection and can't invoke the desired app to run. We use Phusion Passenger so we can tell NGINX to invoke the app and forwards HTTP requests.

The minimum configuration to enable NGINX for general apps is:

nginx:
root: public_html/public
passenger:
enabled: on
app_start_command: env PORT=$PORT npm start

Which is equivalent to running npm start in the public_html (parent of root) directory, with the PORT environment variable set to the port that NGINX is listening to.

Passenger's enabled: on config is required to indicate that Passenger's module is activated for given host.

It is important that root is set to the directory that contains the public directory. This is because NGINX will serve the public directory as the root directory for serving static files as you don't want to expose the entire app scripts to the public.

If the app must be called from a subdirectory, you can use the app_root option to specify the directory that contains the app. For example, if the main app file is in public_html/server/app.js, you can set the app_root to public_html/server:

nginx:
root: public_html/public
passenger:
enabled: on
app_root: public_html/server
app_start_command: env PORT=$PORT node app.js

PORT environment variable

The $PORT environment variable is set by Phusion Passenger. It is a random port that's chosen as a HTTP proxy between your app and the internet. Your app must listen to $PORT to be able receiving HTTP requests from NGINX.

You can tell the app to listen to this port by setting the an environment variable via env like this:

nginx:
passenger:
app_start_command: env PORT=$PORT node app.js

Or you can set the port using the app's argument if available:

nginx:
passenger:
app_start_command: node app.js --port $PORT
caution

Your app must listen to the port that's set dynamically in the app_start_command option. If you don't see a way to pass custom $PORT either via environment variables or app's argument, then you might want to ask your app's or its framework's developer to make it possible.

info

If you make a social media app bot, you'll realize that the only way to make it work is via a webhook. It's a limitation by design, as we're not allowing any software running 24/7 and running a background polling.

Read it more for: Telegram, Discord, WhatsApp.

Set Environment Variables

Passenger has three ways to set environment variables:

app_env option

The app_env option is special option that's used to set environment mode. The default value is production. This option sets the value to the following environment variables:

  • RAILS_ENV
  • RACK_ENV
  • WSGI_ENV
  • NODE_ENV
  • PASSENGER_APP_ENV

You can set this value other values such as development or test.

env_var_list option

The env_var_list option is used to set environment variables directly from NGINX. It's a list of environment variables to set. The value is a string that's in the format of KEY=VALUE. For example:

nginx:
passenger:
enabled: on
app_start_command: env PORT=$PORT node app.js
env_var_list:
- APP_SECRET=SECRET_VALUE
- APP_CONFIG={"key":"value"}

~/.bashrc file

Passenger reads the ~/.bashrc file to set environment variables. You can set environment variables in this way. For example run this command to edit the ~/.bashrc file via SSH:

nano ~/.bashrc

Then add the following line to the file:

export APP_SECRET=SECRET_VALUE

The environment variable will be set when the app is started next time.

More information about setting environment variables can be found in the Passenger documentation.

Restarting App

Any edits either in the app file or ~/.bashrc file will not be applied until the app is restarted. You can restart the app forcibly by running restart in SSH, which will actually calls:

passenger-config restart-app ~

More information about restarting app can be found in the Passenger documentation.

Websocket

Websocket should works out of the box since only one app is spawned per website configuration.

caution

Server processes are often die, forked and respawned. Never hold a global value in memory! Use some kind of database (such as SQLite) when you want to handle one or more shared data such as websocket or authentication sessions.

Language-Specific Configuration

More information about configuring NGINX for specific languages can be found in the Deployment section.

Advanced Configuration

All other available options are specified in Deployment System section.

Global Configuration

Global configuration of NGINX cannot be changed. However, some of the configuration are set as optimally as possible. You can see more about the global configuration in this file. Some of the interesting configuration are:

  • Static files are cached with max expiration time.
  • Gzip are enabled for css, js, svg static files.
  • Maximum file upload size is set to 512MB.
  • There's rate limit of 2 requests per second with 500 burst request per IP address to mitigate DoS attack.
  • TLSv1.2 is the minimum HTTPS version to support, which works for browsers as old as Windows 7 era (with IE 11), older browsers such as in Windows XP era will not be able to open your website.