Deploy Node Apps
Node installation is powered by NVM. To install LTS version with deployment script:
features:
- node
Without this, you're using OS-dependent node
, npm
and yarn
which the version can't be customized, and you can't install global packages with it.
Install other version using node latest
, node lts
, node 20
, node 20.1.1
, etc. To uninstall use node off
or node system
(the latter leaves nvm installed).
Corepack is always enabled when using installation via deployment script.
Example
The deployment script below installs the latest node
compiler and writes app.js
and serves that through CJS-only bindings.
source: clear
features:
- node latest
nginx:
root: public_html/public
passenger:
enabled: "on"
app_type: node
startup_file: app.js
app_env: development
commands:
- filename: app.js
content: |
const http = require('http');
const html_text = `
<!DOCTYPE html>
<html>
<head>
<title>Node App</title>
<link rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css">
</head>
<body class="p-5 text-center">
<p><img src="//images.unsplash.com/photo-1465153690352-10c1b29577f8?fit=crop&w=200&h=200"
class="img-fluid rounded-circle"></p>
<h1 class="mb-3">Hello, world!</h1>
<p>Serving from Node version ${process.version}</p>
<p class="text-muted">DOM Cloud</p>
</body>
</html>
`
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.end(html_text);
});
server.listen(process.env.PORT || 8080);
Existing Node projects
- ESM
- TSC
- Next.js
- Nuxt.js
- SvelteKit
For projects that using ESM-style imports, GLS binding can be used as it's the basic for any custom web server either for Node and other code languages. The requirement to use this is your app must listen to given PORT
env/args (either node ... --port=$PORT
or env PORT=$PORT node ...
). You can also use alternative calls such as node app.js
here.
features:
- node lts
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT npm start
commands:
- npm install
For Node.js projects that using typescript, you need to build it first and let NGINX serve your JS scripts. We assume you're using a similar boilerplate we linked here.
features:
- node lts
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT npm start
commands:
- npm install
- npm run build
This is a typical deployment script for Next.js.
features:
- node lts
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT yarn start
locations:
- match: /_next/static/
alias: public_html/.next/static/
commands:
- yarn install
- yarn build
This is a typical deployment script for Nuxt.js.
features:
- node lts
nginx:
root: public_html/.output/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT node server/index.mjs
commands:
- yarn install
- yarn build
This is a typical deployment script for SvelteKit.
features:
- node lts
nginx:
root: public_html/.svelte-kit/output/client
passenger:
enabled: "on"
app_start_command: yarn preview --port $PORT --host
app_root: public_html
commands:
- yarn install
- yarn build
App Management
Your app do not restarted automatically after file changes. To restart, run restart
via SSH.
Environment variables can be set either using NGINX's env_var_list
or ~/.bashrc
. Usually your language framework also reads .env
files.
nginx:
passenger:
enabled: on
app_start_command: node app.js
app_env: development # Set NODE_ENV
env_var_list:
- APP_SECRET=SECRET_VALUE
- APP_CONFIG={"key":"value"}
See NGINX and App Daemon for more information about NGINX and App managements including restarting, environment variables, and other global limitations.
App Development
If you're editing your Node.js app in place (e.g. using Visual Studio Code Remote), it is helpful to run a separate Node instance so you can see your changes live using nodemon
or npm run dev
or other similar tools.
The requirement is you need to use port 32000
or above, since these port will not be blocked from the server. So when starting a development instance, use something like PORT=31234 npm run dev
in SSH.
To apply your changes back to NGINX, run your build flow (e.g. npm run build
) then restart it by calling restart
on SSH.
App Logging
You can see app log from Check -> Check Process Logs tab. Only startup problems displayed in the browser.
You might want to use a proper logging mechanism such as Pino or Winston then write it to a log file, or any other solution that suits you.
NGINX errors and traffic logs can be examined via Webmin or Check -> Check Process Logs tab.
Troubleshooting
FATAL ERROR: Reached heap limit Allocation failed
during package installation
We limit all processes to have physical 2GB memory to avoid crashing the whole system.
Most likely you're installing with npm
which is bad at managing memory, please use yarn
instead.
digital envelope routines::unsupported
during script builds
You're using Create-React-App but having version that uses old OpenSSL.
Please update your depedencies to latest version with npx npm-upgrade
. For Create-React-App
, please try yarn create react-app my-app
locally and copy all of their depedencies to your project.
You should not run the Vite HMR server in CI environments. You should build your assets for production instead
Please do not run npm run dev
or npm start
in deployments. That's not how it works. Most likely what you want to do npm run build
.
If you want to run npm run dev
for live-in-production edits, use PORT > 32000 (e.g. PORT=33210 npm run dev
).
error: cannot pull with rebase: You have unstaged changes.
You have uncommitted changes in your server. To resolve it please do git stash
then git pull
. Take your stashed changes back with git stash pop
.
Error: Cannot find module '/home/****.js
Either you need to npm install
if the missing module is in node_modules
or npm run build
otherwise.
Error: Cannot send secure cookie over unencrypted connection
You have to set proxy: true
and secure: true
somewhere in your cookie settings so it trust X-Forwarded-Proto
set from NGINX.
UntrustedHost: Host must be trusted.
You're using next-auth so you must set trustHost: true
. See relevant blog.
pnpm: command not found
You need to add node
feature in your deployment script. Which enables corepack
and pnpm
.
502 Bad Gateway
This is NGINX freshly restart and it seems too expensive to start your process in time. Please use Proxfix NOHUP to solve this issue.
Any other error
Please open WebSSH or VSCode remote to fix it yourself. Or chat us if you stuck with "but it works on my machine".