Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Operations

How-to guide

Install a Linux node

Prepare an Ubuntu node with bootstrap-node.sh and install or upgrade a tagged Cluster ERP release on it with install.sh.

This guide installs a tagged Cluster ERP release on one Linux node, for staging or for production, and upgrades it later with the same command. It follows deploy/bootstrap-node.sh for the operating system and deploy/install.sh for the application. The reasons behind the staging and production split are in environments and promotion.

Prerequisites

  • A fresh Ubuntu 24.04 node with root access; the bootstrap script refuses other systems (deploy/bootstrap-node.sh:52-55).
  • The administrator's OpenSSH public key file (deploy/bootstrap-node.sh:46-51).
  • A PostgreSQL 16 server on the node. install.sh installs only the PostgreSQL client (deploy/install.sh:114), and pg-tune.sh stops when the PostgreSQL 16 configuration directory is missing (deploy/pg-tune.sh:23-31).
  • A release tag that exists on the repository remote, and read access from the node to that remote (deploy/install.sh:47-54, deploy/install.sh:85-90).
  • For production: the promotion record staging-ok/<tag> on the same commit (deploy/install.sh:101-107).

Steps

  1. Prepare the operating system once, as root. Source: deploy/bootstrap-node.sh:8-23, deploy/bootstrap-node.sh:36-44.

bash bash bootstrap-node.sh --admin <name> --pubkey <public-key-file> --admin-cidr <cidr>

--admin-cidr is optional; without it the SSH port stays open to every address and the script prints a note (deploy/bootstrap-node.sh:139-145). The script turns on unattended security updates, sets the clock to UTC with NTP, creates the administrator with sudo and the key, records every privileged session, switches SSH to keys only, and opens only SSH, HTTP, and HTTPS in the firewall (deploy/bootstrap-node.sh:57-149).

  1. Before you close the root session, open a new session with the key. Root login and passwords are off after step 1 (deploy/bootstrap-node.sh:151-154).

  2. Tune PostgreSQL for the node's memory and processor count, from a copy of the repository. The script writes one configuration file and restarts PostgreSQL. Source: deploy/pg-tune.sh:20, deploy/pg-tune.sh:48-69.

bash sudo deploy/pg-tune.sh

  1. Replace both password placeholders in deploy/postgres-roles.sql, then create the application role and the backup role. Source: deploy/postgres-roles.sql:1-11. See PostgreSQL roles and tuning.

bash psql -U postgres -f deploy/postgres-roles.sql

  1. Run the installer with the tag, the public host name, and the role. Source: deploy/install.sh:11-13.

bash sudo deploy/install.sh --tag <tag> --domain erp.example.com --role staging

On a node without an environment file the script copies deploy/env.example into place with mode 0640 and stops, because the file still holds <...> placeholders (deploy/install.sh:171-179).

  1. Fill in every placeholder value of the environment file. The variables are listed in the configuration reference.

  2. If the node has no TLS certificate yet, obtain one with the command that the script prints. Source: deploy/install.sh:204-209.

bash certbot certonly --webroot -w /var/www/html -d erp.example.com -m <mailbox> --agree-tos -n

  1. Run the same install.sh command again. It now runs all eight steps: system packages, service user and directories, code at the tag, virtual environment from requirements.lock with hashes, environment file check, systemd unit with nginx site and cron table, database migration with a backup first, and start or reload with a readiness check (deploy/install.sh:26-34, deploy/install.sh:110-261).

  2. If the node is a production node, first record the passed staging battery on the release commit, then run the installer with --role production. Source: deploy/install.sh:20-21.

bash git tag -a staging-ok/<tag> <tag> -m "<battery log, date>" git push origin staging-ok/<tag> sudo deploy/install.sh --tag <tag> --domain erp.example.com --role production

  1. To upgrade later, run the same command with the new tag (deploy/install.sh:13). The script reloads a running service. It restarts the service instead when the environment file changed after the service started, when the unit file changed, or when requirements.lock changed (deploy/install.sh:228-246).

Verify the result

  • The script ends with the line Cluster ERP <tag> is live on this <role> node (<domain>). (deploy/install.sh:261). It prints that line only after /ready answered HTTP 200 within five minutes and residency_check exited with code 0 (deploy/install.sh:247-259).
  • The readiness answer names each backing store with pass or fail (src/cluster_erp/server/app.py:1476-1504). See security.txt and readiness.
  • The cron table of the service user holds the jobs of deploy/cluster-erp.cron (deploy/install.sh:210). See scheduled jobs and retention.

Troubleshooting

Symptom Cause in code Fix
--tag is required: production runs a tagged release, never a branch tip No --tag flag (deploy/install.sh:77) Pass an existing release tag.
production refuses <tag>: no staging-ok/<tag> record The promotion tag is missing on the remote (deploy/install.sh:104-105) Install the tag on staging, run the battery, push the promotion tag.
staging-ok/<tag> points at ... the promotion record does not belong to this release The two tags resolve to different commits (deploy/install.sh:106) Set the promotion tag on the release commit.
this node is recorded as '<role>' ... a node never changes role The role differs from the recorded role (deploy/install.sh:123-125) Reinstall the node from a clean image.
... still contains <...> placeholders; the service is not started with a template A value line still holds a placeholder (deploy/install.sh:177-179) Fill in the value and run the script again.
no certificate yet for <domain> No certificate file for the domain (deploy/install.sh:204-209) Run the printed certbot command, then the script again.
/ready did not answer 200 within 5 minutes The service did not become ready; the script prints the last journal lines (deploy/install.sh:254-257) Read the journal lines; see service and process manager.
residency_check reported findings A setting contradicts the declared country (deploy/install.sh:258-259) Fix the declaration; see data residency check.
this script is written for Ubuntu 24.04 Another operating system (deploy/bootstrap-node.sh:54-55) Use an Ubuntu 24.04 image.
sshd rejected the new configuration; passwords are still on The SSH configuration test failed (deploy/bootstrap-node.sh:132) Not determined from code. The script stops before the new configuration takes effect.

Terms introduced

Term Code identifier Definition Turkish term Source
environment file ENV_FILE The node file, copied from deploy/env.example, that the service and the scripts read their settings from. ortam dosyası deploy/install.sh:45
service user SERVICE_USER The system account that owns the checkout and runs the service and the cron jobs. servis kullanıcısı deploy/install.sh:46
asset stamp cluster_asset_stamp A short token in the web app's asset URLs that changes when the shipped files change; the server computes it as a digest of the files, and nginx receives the release tag. varlık damgası deploy/install.sh:197-200

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13