This guide explains how to install a Saito Web Node on a fresh Ubuntu 24.04 server.
It mirrors the behaviour of the automated install script, but allows you to execute each step manually.
Before starting:
node.example.com).Your domain must resolve to your server before SSL certificates can be issued.
Create an A record:
your.domain.com → YOUR.SERVER.IP
Verify DNS:
dig +short your.domain.com
You should see your server’s IP address.
Update the system and install basic build tools:
sudo apt update
sudo apt upgrade -y
sudo apt install -y git g++ make python3 python3-pip
Saito runs on Node.js. PM2 is used to keep the node running in production.
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g typescript
sudo npm install -g pm2
nginx serves as the reverse proxy. Certbot enables HTTPS via Let’s Encrypt.
sudo apt install -y nginx certbot python3-certbot-nginx
Clone the Saito repository into /opt and install dependencies.
cd /opt
sudo git clone https://github.com/saitotech/saito
git checkout prod
cd saito/node
sudo npm install
If the folder already exists:
cd /opt/saito
git checkout prod
sudo git pull
Initialize/reset the Saito node environment.
config/options to match your domain and join the network:nano config/options
{
"server": { // node local and remote ip information
"host": "localhost", // local host name or ip
"port": 12101, // local port
"protocol": "http", // local protocol [http/https]
"endpoint": { // external address to connect to this node on (usually reverse proxied)
"host": "your.domain.com", // external host name
"port": 443, // external port (usually 443 for ssl/https and 80 for unencrypted connections)
"protocol": "http" // external protocol [http,https]
},
"peers": [ // ip/host information for other nodes - this should be provided to you by the peer
{
"host": "eames.saito.io", // Saito public node one
"port": 443, // peer's port
"protocol": "https", // peer's connection protocol
"synctype": "full" // determines if the node requests full (complete) or lite (merkelerized with only relevant transactions) blocks
},
"host": "arthur.saito.io", // Saito public node one
"port": 443, // peer's port
"protocol": "https", // peer's connection protocol
"synctype": "full" // determines if the node requests full (complete) or lite (merkelerized with only relevant transactions) blocks
}
]
}
This is a minimal configuration that will let lite nodes (browsers) connect to you and connect you to nodes that will share blocks with you.
This configuration will autogenerate a wallet for the node.
Further configuration is possible though not recommended.
Edit the config/modules.config.js file to include the necessary modules.
module.exports = {
core: [
"admin/admin.js",
"arcade/arcade.js",
"archive/archive.js",
"chat/chat.js",
"encrypt/encrypt.js",
"explorer/explorer.js",
"poker/poker.js",
"qrscanner/qrscanner.js",
"redsquare/redsquare.js",
"registry/registry.js",
"relay/relay.js",
"settings/settings.js",
"settlers/settlers.js",
"solitrio/solitrio.js",
"spam/spam.js",
"status/status.js",
"stun/stun.js",
"wordblocks/wordblocks.js",
"wuziqi/wuziqi.js"
],
lite: [
"admin/admin.js",
"arcade/arcade.js",
"archive/archive.js",
"chat/chat.js",
"encrypt/encrypt.js",
"poker/poker.js",
"qrscanner/qrscanner.js",
"redsquare/redsquare.js",
"registry/registry.js",
"relay/relay.js",
"settings/settings.js",
"settlers/settlers.js",
"solitrio/solitrio.js",
"status/status.js",
"stun/stun.js",
"wordblocks/wordblocks.js",
"wuziqi/wuziqi.js"
]
};
Some moduels only run on the node, these can be added to the core section. Likewise modules that run only in the browser can be placed only in the lite section.
Adding a new modules is as simple as editig this file, compiling, and restarting (pm2 restart all).
sudo npm run nuke
Create a new nginx site for your domain. Replace your.domain.com with your own:
nano /etc/nginx/sites-available/your.domain.com
server {
listen 80;
server_name your.domain.com www.your.domain.com;
gzip on;
gzip_proxied any;
gzip_min_length 256;
gzip_comp_level 9;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 7d;
add_header Cache-Control "public, immutable";
proxy_pass http://localhost:12101;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
location / {
proxy_pass http://localhost:12101;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
}
}
Enable the new site and remove the default configuration:
sudo ln -sf /etc/nginx/sites-available/your.domain.com /etc/nginx/sites-enabled/your.domain.com
sudo rm -f /etc/nginx/sites-enabled/default
Test and start nginx:
sudo nginx -t
sudo systemctl start nginx
sudo systemctl enable nginx
Enable HTTPS using Certbot:
sudo certbot --nginx -d your.domain.com -d www.your.domain.com --non-interactive --agree-tos --email admin@your.domain.com
If DNS is correct, Certbot updates your nginx config automatically.
Apply all changes:
sudo systemctl restart nginx
PM2 ensures Saito runs continuously and starts on boot.
cd /opt/saito/node
sudo tee ecosystem.config.js > /dev/null << 'EOF'
module.exports = {
apps: [{
name: 'saito-node',
script: 'npm start',
instances: 1,
exec_mode: 'fork',
watch: false,
max_memory_restart: '8G',
error_file: './logs/err.log',
out_file: './logs/out.log',
log_file: './logs/saito.log',
time: true
}]
};
EOF
Saito logs can be verbose, we recommend adding log rotation.
# Install the PM2 logrotate module
pm2 install pm2-logrotate
# Optional: configure rotation settings
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:dateFormat "YYYY-MM-DD_HH-mm-ss"
# Reload PM2 to apply logrotate settings
pm2 restart all
Create log directory:
sudo mkdir -p /opt/saito/node/logs
Start and register the PM2 service:
sudo pm2 start ecosystem.config.js
sudo pm2 save
sudo pm2 startup systemd -u root --hp /root
Visit your node:
https://your.domain.com/
Check PM2:
pm2 status
pm2 logs saito-node
If using UFW, allow necessary ports:
sudo ufw allow 'Nginx Full'
Your Saito Web Node should now be running securely over HTTPS and managed by PM2.