You can install Stronghold in two ways:
- quick installation — a single-node server with
stronghold bootstrap service, available fromv1.19; - manual deployment — a multi-node cluster in high availability (HA) mode with Raft storage.
The stronghold bootstrap command group also generates other deployment artifacts: a Helm chart archive and a Docker image tarball. For the full CLI interface, see Bootstrap.
Prerequisites for both scenarios:
- a supported OS is installed on the server (Ubuntu, RedOS, Astra Linux);
- the Stronghold distribution is copied to the server, and the
strongholdbinary is available to run.
Quick installation
The stronghold bootstrap service command generates a shell script that prepares a single-node Stronghold environment: directories, a configuration file, a systemd unit, a system user, binary installation, and optional self-signed TLS certificates.
Self-signed TLS certificates are suitable for testing only.
For production, provide your own certificates and use the -no-tls flag.
By default, the script is written to stdout so you can review it before applying:
stronghold bootstrap service | lessApply the script in one of the following ways:
stronghold bootstrap service | sudo shor run the installation directly:
sudo stronghold bootstrap service -applyThe script creates the environment under /opt/stronghold (-base-dir), the systemd unit /etc/systemd/system/stronghold.service, and the stronghold system user, then enables and starts the service.
After the service starts, open https://<node-name>:8200 in a browser and complete initialization through the web UI.
Alternatively, continue with manual initialization as described below.
Set the path to the CA certificate created by bootstrap:
export STRONGHOLD_CACERT=/opt/stronghold/tls/stronghold-ca.pemInitialize Stronghold:
stronghold operator initIf necessary, you can specify the following parameters:
-key-shares— number of key shares (default: 5);-key-threshold— minimum number of shares required to unseal the storage (default: 3).
After initialization, all key shares and the root token are displayed in the terminal. Be sure to save them in a secure place. Without the required number of key shares, access to Stronghold data will be impossible.
Unseal the storage. Run the command multiple times, entering the unseal keys:
stronghold operator unsealIf the -key-threshold parameter was not changed, you need to enter 3 key shares.
Check the status:
stronghold statusMain bootstrap service options
Frequently used options:
| Option | Purpose |
|---|---|
-apply | Execute the generated script instead of printing it to stdout |
-base-dir | Base installation directory (default: /opt/stronghold) |
-force | Overwrite existing files |
-no-tls | Do not generate TLS certificates (use your own certificates) |
-tls-disable | Disable TLS in the listener configuration (development only) |
-no-systemd | Do not create or enable a systemd unit |
-listener-address | TCP listener address in host:port form (default: 0.0.0.0:8200) |
-api-addr | API address advertised to clients |
-cluster-addr | Cluster address for Raft |
-node-id | Raft node identifier (defaults to hostname) |
For the full list of options and other bootstrap subcommands (helm, docker), see Bootstrap or run stronghold bootstrap service -help.
For further server configuration, see Configuration.
Deploying a cluster in HA mode
Stronghold supports multi-server mode to ensure high availability (HA). This mode is automatically enabled when using a compatible data storage backend and protects the system from failures by running multiple Stronghold servers.
To check if your storage supports high availability mode, start the server and make sure the message HA available is displayed next to the storage information. In this case, Stronghold will automatically use HA mode.
To provide high availability, one of the Stronghold nodes acquires a lock in the storage system and becomes active, while the other nodes switch to standby mode. If standby nodes receive requests, they either forward them or redirect clients according to the configuration and the current state of the cluster.
To run Stronghold in HA mode with the integrated Raft storage, you need at least three Stronghold servers. This requirement is necessary to achieve quorum — without it, the cluster cannot operate with the storage.
Additional prerequisites:
- individual certificates are issued for each node in the Raft cluster;
- a root certificate authority (CA) certificate is prepared.
The following scenario describes a manual deployment of a Stronghold cluster with three nodes: one active and two standby.
Infrastructure preparation
Launch via systemd unit
All examples assume that a system user stronghold has been created and the service runs under this user.
If you need to use another user, replace stronghold with the appropriate name.
You can prepare the base environment on each node (directories, user, systemd unit, binary) with stronghold bootstrap service and the -no-tls flag, then place your own certificates and HA configuration.
Alternatively, create the systemd unit manually:
Create the file
/etc/systemd/system/stronghold.servicewith the following content:[Unit] Description=Stronghold service Documentation=https://deckhouse.io/products/stronghold/ After=network.target [Service] Type=simple ExecStart=/opt/stronghold/stronghold server -config=/opt/stronghold/config.hcl ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=5 User=stronghold Group=stronghold LimitNOFILE=65536 CapabilityBoundingSet=CAP_IPC_LOCK AmbientCapabilities=CAP_IPC_LOCK SecureBits=noroot [Install] WantedBy=multi-user.targetApply the systemd configuration changes:
systemctl daemon-reloadEnable the service to start automatically:
systemctl enable stronghold.serviceCreate the
/opt/stronghold/datadirectory and set the appropriate permissions:mkdir -p /opt/stronghold/data chown stronghold:stronghold /opt/stronghold/data chmod 0700 /opt/stronghold/data
Preparing the required certificates
To configure TLS, you need a set of certificates and keys in the /opt/stronghold/tls directory:
- root certificate authority (CA)
stronghold-ca.pem— the certificate used to sign Stronghold TLS certificates; - Raft node certificates (three nodes in this scenario):
node-1-cert.pem;node-2-cert.pem;node-3-cert.pem;
- private keys of the node certificates:
node-1-key.pem;node-2-key.pem;node-3-key.pem.
In this example, a root certificate and a set of self-signed certificates for each node are created.
Self-signed certificates are suitable only for testing and experimentation. For production use, it is strongly recommended to use certificates issued and signed by a trusted certificate authority (CA).
On the first node, create a directory for storing certificates (if it does not already exist) and switch to it:
mkdir -p /opt/stronghold/tls cd /opt/stronghold/tls/Generate a key for the root certificate:
openssl genrsa 2048 > stronghold-ca-key.pemIssue the root certificate:
openssl req -new -x509 -nodes -days 3650 -key stronghold-ca-key.pem -out stronghold-ca.pem Country Name (2 letter code) [XX]:RU Locality Name (eg, city) [Default City]:Moscow Organization Name (eg, company) [Default Company Ltd]:MyOrg Common Name (eg, your name or your server hostname) []:demo.tldThe certificate attributes are provided as an example.
To issue node certificates, create configuration files that contain the
subjectAltName(SAN) parameter. For example, for theraft-node-1node:cat << EOF > node-1.cnf [v3_ca] subjectAltName = @alt_names [alt_names] DNS.1 = raft-node-1.demo.tld IP.1 = 10.20.30.10 IP.2 = 127.0.0.1 EOFEach node must have valid FQDN and IP addresses. The
subjectAltNamefield in the certificate must contain values relevant to the specific node. Similarly, create a separate configuration file for each node.Generate certificate signing requests (CSRs) and keys for the nodes:
openssl req -newkey rsa:2048 -nodes -keyout node-1-key.pem -out node-1-csr.pem -subj "/CN=raft-node-1.demo.tld" openssl req -newkey rsa:2048 -nodes -keyout node-2-key.pem -out node-2-csr.pem -subj "/CN=raft-node-2.demo.tld" openssl req -newkey rsa:2048 -nodes -keyout node-3-key.pem -out node-3-csr.pem -subj "/CN=raft-node-3.demo.tld"Issue certificates based on the created CSRs:
openssl x509 -req -set_serial 01 -days 3650 -in node-1-csr.pem -out node-1-cert.pem -CA stronghold-ca.pem -CAkey stronghold-ca-key.pem -extensions v3_ca -extfile ./node-1.cnf openssl x509 -req -set_serial 02 -days 3650 -in node-2-csr.pem -out node-2-cert.pem -CA stronghold-ca.pem -CAkey stronghold-ca-key.pem -extensions v3_ca -extfile ./node-2.cnf openssl x509 -req -set_serial 03 -days 3650 -in node-3-csr.pem -out node-3-cert.pem -CA stronghold-ca.pem -CAkey stronghold-ca-key.pem -extensions v3_ca -extfile ./node-3.cnfIt is recommended to use unique
-set_serialvalues for each certificate.Copy the required files to each node:
- node certificate;
- node private key;
- root certificate.
For example, for the
raft-node-2andraft-node-3nodes:scp ./node-2-key.pem ./node-2-cert.pem ./stronghold-ca.pem raft-node-2.demo.tld:/opt/stronghold/tls scp ./node-3-key.pem ./node-3-cert.pem ./stronghold-ca.pem raft-node-3.demo.tld:/opt/stronghold/tlsIf the
/opt/stronghold/tlsdirectory does not exist on the target nodes, create it.
Deploying a Raft cluster
Connect to the first server where the Stronghold cluster initialization will be performed.
Allow network connections for TCP ports
8200and8201. Example forfirewalld:firewall-cmd --add-port=8200/tcp --permanent firewall-cmd --add-port=8201/tcp --permanent firewall-cmd --reloadIf necessary, you can use other ports by specifying them in the
/opt/stronghold/config.hclconfiguration file.Create the
/opt/stronghold/config.hclconfiguration file for Raft:ui = true cluster_addr = "https://10.20.30.10:8201" api_addr = "https://10.20.30.10:8200" disable_mlock = true listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/opt/stronghold/tls/node-1-cert.pem" tls_key_file = "/opt/stronghold/tls/node-1-key.pem" } storage "raft" { path = "/opt/stronghold/data" node_id = "raft-node-1" retry_join { leader_tls_servername = "raft-node-1.demo.tld" leader_api_addr = "https://10.20.30.10:8200" leader_ca_cert_file = "/opt/stronghold/tls/stronghold-ca.pem" leader_client_cert_file = "/opt/stronghold/tls/node-1-cert.pem" leader_client_key_file = "/opt/stronghold/tls/node-1-key.pem" } retry_join { leader_tls_servername = "raft-node-2.demo.tld" leader_api_addr = "https://10.20.30.11:8200" leader_ca_cert_file = "/opt/stronghold/tls/stronghold-ca.pem" leader_client_cert_file = "/opt/stronghold/tls/node-1-cert.pem" leader_client_key_file = "/opt/stronghold/tls/node-1-key.pem" } retry_join { leader_tls_servername = "raft-node-3.demo.tld" leader_api_addr = "https://10.20.30.12:8200" leader_ca_cert_file = "/opt/stronghold/tls/stronghold-ca.pem" leader_client_cert_file = "/opt/stronghold/tls/node-1-cert.pem" leader_client_key_file = "/opt/stronghold/tls/node-1-key.pem" } }Start the Stronghold service:
systemctl start strongholdSet the path to the CA certificate:
export STRONGHOLD_CACERT=/opt/stronghold/tls/stronghold-ca.pemInitialize the cluster:
stronghold operator initIf necessary, you can specify the following parameters:
-key-shares— number of key shares (default: 5);-key-threshold— minimum number of shares required to unseal the storage (default: 3).
After initialization, all key shares and the root token are displayed in the terminal. Be sure to save them in a secure place. Without the required number of key shares, access to Stronghold data will be impossible.
Unseal the cluster. Run the command multiple times, entering the unseal keys:
stronghold operator unsealIf the
-key-thresholdparameter was not changed, you need to enter 3 key shares.Configure the remaining nodes:
- set the appropriate
cluster_addrandapi_addrvalues in/opt/stronghold/config.hcl, as well as the certificate paths for that node; - skip the initialization step;
- immediately proceed to unsealing the cluster (
operator unseal).
- set the appropriate
Verify the cluster status:
stronghold status Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 5 Threshold 3 Version 1.15.2 Build Date 2025-03-07T16:10:46Z Storage Type raft Cluster Name stronghold-cluster-a3fcc270 Cluster ID f682968d-5e6c-9ad4-8303-5aecb259ca0b HA Enabled true HA Cluster https://10.20.30.10:8201 HA Mode active Active Node Address https://10.20.30.10:8200 Raft Committed Index 40 Raft Applied Index 40