Node.js: Getting started

Learn how to deploy a Node.js service on Stackhero quickly and securely

👋 Welcome to the Stackhero documentation!

Stackhero offers a ready-to-use Node.js cloud solution that provides a host of benefits, including:

  • Deploy your application in seconds with a simple git push.
  • Use your own domain name and benefit from the automatic configuration of HTTPS certificates for enhanced security.
  • Enjoy peace of mind with automatic backups, one-click updates, and straightforward, transparent, and predictable pricing.
  • Get optimal performance and robust security thanks to a private and dedicated VM.

Save time and simplify your life: it only takes 5 minutes to try Stackhero's Node.js cloud hosting solution!

Deploying a Node.js service on Stackhero is quick, efficient, and reliable. This guide walks you through the essential steps to deploy your app in seconds while ensuring top-notch security and performance.

Begin by creating a Node.js service on Stackhero. This step lays the foundation for your application deployment and gets you ready to explore all the benefits of Stackhero's cloud hosting solution.

Before you deploy on Stackhero, make sure you have the following tools installed:

  1. Git. You can download it from https://git-scm.com/downloads.
  2. For Windows users, we suggest using Windows Terminal available via the Microsoft Store for a better experience.

The only configuration you need is updating your SSH public key. This key allows Stackhero to securely access your code repository.

To locate your public key, run one of these commands:

cat ~/.ssh/id_rsa.pub

or

cat ~/.ssh/id_ed25519.pub

If you do not already have an SSH key pair, you can generate one by running ssh-keygen on Linux or macOS or ssh-keygen.exe on Windows.

After retrieving your public key, log in to the Stackhero dashboard, select your Node.js service, navigate to its configuration, and paste your key.

Tip: You can set your SSH public key globally so that all future services automatically include it. To do this, go to the Stackhero dashboard, click your profile picture (located in the top right corner), navigate to 'Your profile', and paste your SSH public key.

A sample Node.js application is provided to illustrate the deployment process on Stackhero. You can clone the repository with the following commands:

git clone https://github.com/stackhero-io/nodejsGettingStarted.git stackhero-nodejs-getting-started
cd stackhero-nodejs-getting-started

Deploying your application via git is fast, reliable, and straightforward on Stackhero. On your service's main page, you will find a command to add a git remote. It might look something like this:

git remote add stackhero ssh://stackhero@XXXXX.stackhero-network.com:222/project.git

Simply copy and paste the command into your terminal.

Push your code to Stackhero using the following command:

git push stackhero main

The first time you push, you will be prompted to add the key fingerprint. Type "yes" to continue.

After a few moments, your application will be live. You can verify its status by visiting the website URL provided on the Stackhero dashboard (for example, https://XXXXX.stackhero-network.com).

That is it. Your application is now deployed!

If you make changes to the app.js file, simply commit and push your modifications:

git add -A .
git commit -m "Update app.js"
git push stackhero main

For existing applications, add the remote repository as described earlier under Configure the remote repository server. Then, deploy your changes with:

git push stackhero main

If you encounter the following error:

error: failed to push some refs to '[...]'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
(e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

This error indicates that your local repository is not synchronized with the remote repository. In this case, you can force the push by executing:

git push -f stackhero main

If you see this error when running git push stackhero main:

error: src refspec main does not match any
error: failed to push some refs to 'ssh://<XXXXXX>.stackhero-network.com:222/project.git'

It indicates that the branch main does not exist. You might try pushing the master branch instead:

git push stackhero master

If git responds with "Everything up-to-date" but your changes are not deployed, it may be because you forgot to commit your changes. In such cases, run:

git add -A .
git commit -m "Your commit message"
git push stackhero main

If no changes have been made but you still wish to force a deployment, you can force an empty commit:

git commit --allow-empty -m "Force update"
git push stackhero main

If you want to deploy a branch other than main, such as production, you can use the following command:

git push stackhero production:main

If you work with tags and want to deploy a specific tag (for example, v1.0), run:

git push stackhero 'v1.0^{}:main'

Here, ^{} ensures that the commit associated with the tag is pushed.

If you need to deploy a specific commit, first identify the commit hash using git log. Then deploy it with:

git push -f stackhero <HASH>:main

You can set up multiple Node.js services for different environments, such as production and staging. To rename the current remote from stackhero to stackhero-staging, run:

git remote rename stackhero stackhero-staging

Next, create a new Node.js service in the Stackhero dashboard and add it as stackhero-production:

git remote add stackhero-production ssh://stackhero@XXXXX.stackhero-network.com:222/project.git

Deploy to production or staging using the respective commands:

git push stackhero-production main

or

git push stackhero-staging main

On macOS, you might be prompted for your SSH key password each time you push your code. For improved convenience and security (without removing your key password), you can save it in the macOS keychain by running:

/usr/bin/ssh-add --apple-use-keychain ~/.ssh/id_rsa

This command saves your key password to the keychain so that you will not be prompted again during future deployments.

For staging and production environments, securely managing secrets such as tokens or passwords is essential. Instead of storing these secrets directly in your repository, use environment variables for enhanced security.

You can add environment variables via the Stackhero dashboard and access them in your Node.js code. For example, if you define a variable named mySecret, you can access it in your app as follows:

process.env.mySecret

If your application does not use HTTP, you may need to open additional TCP and UDP ports through the Stackhero dashboard. Simply specify the public entry port, the destination port on your Node.js service, and the protocol (TCP or UDP) to ensure proper connectivity.

For storing files such as user photos, it is best to use an object storage solution. This approach enables file sharing across multiple services and instances while keeping your code separate from your data. We recommend MinIO as an easy, fast, and powerful solution compatible with the Amazon S3 protocol.

If you prefer local storage, you can use the persistent storage available with your Node.js instance. This storage is located at /persistent/storage/.

CAUTION: Never store data outside the /persistent/storage/ folder!

Data stored outside this folder may be lost if your instance reboots or if you push code changes.

When deploying a new version of your app, the old version receives a termination signal in advance. This provides it with time to gracefully close database connections and stop other services.

The termination signal SIGTERM is emitted. You can capture this signal in your code as follows:

process.on('SIGTERM', () => {
  // This log appears on the Stackhero dashboard in the 'logs' tab
  console.info('😯 SIGTERM signal received.');

  // Close open database connections or other services here
  // ...
});

By default, Node.js runs on a single core using one thread. To take full advantage of all available CPU cores, consider using the Node.js cluster API. You can review the official documentation here: https://nodejs.org/api/cluster.html.

Below is a simple example that creates an HTTP server utilizing all available CPUs:

const cluster = require('cluster');
const http = require('http');
const cpusCount = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);

  // Fork workers
  for (let i = 0; i < cpusCount; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
} else {
  // Workers share any TCP connection; in this case, an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}