Configuring
Prerequisites
-
You have identified the installation method for the host system:
- For bare-metal, you have two executables installed on the host operation system path:
stellar-horizon
andstellar-core
. - For running Horizon image with Docker daemon, you will use the stellar/stellar-horizon hosted on Docker Hub. You have already pulled the stellar/stellar-horizon image via
docker pull stellar/stellar-horizon:<tag_version>
onto host. This image contains thestellar-horizon
andstellar-core
within. - For Kubernetes with Horizon Helm Chart, you have followed the Install Horizon with Helm Chart.
- For bare-metal, you have two executables installed on the host operation system path:
You are now ready to identify the configuration parameters needed to perform three important roles:
- Serving read-only API requests via a regular web-based HTTP API;
- Ingesting ledgers from Core nodes of the Stellar network to keep its world-view up to date;
- Submitting transactions via a regular web-based HTTP API, forwarding the transaction submission request to the Stellar network.
To perform these roles, you can choose from one of two deployment modes below (single instance deployment or multiple instance deployment). Each has its own configuration parameters.
Single Instance Deployment
Run stellar-horizon
in a single o/s process and it will perform all three roles simultaneously.
environment variable | example |
---|---|
DATABASE_URL | postgres://localhost/horizon_pubnet |
NETWORK | pubnet |
HISTORY_RETENTION_COUNT | 518400 |
Multiple Instance Deployment
In this scalable deployment variant, you run multiple instances of stellar-horizon
, each performing a subset of the roles. This allows you to horizontally scale each of the role functions independently.
Ingestion Role Instance
You must allocate at least one instance to perform ongoing ingestion to capture network activity. This will default to limiting storage of ingested network activity in the database to our recommendation of a sliding window of the last 30 days.
environment variable | example |
---|---|
DATABASE_URL | postgres://localhost/horizon_pubnet |
NETWORK | pubnet |
HISTORY_RETENTION_COUNT | 518400 |
DISABLE_TX_SUB | true |
API Role Instance
You can run none or multiple instances to serve read-only API requests. Notice there is no need to define network settings here, as Horizon only reads from database.
environment variable | example |
---|---|
DATABASE_URL | postgres://localhost/horizon_pubnet |
INGEST | false |
DISABLE_TX_SUB | true |
Transaction Submission Role Instance
You can run none or multiple instances to serve transaction submission requests. If you run an instance with transaction submission enabled, the Horizon deployment is required to have at least one instance perform the ingestion role on the same database. Horizon transaction submission depends on this live ingestion taking place against the database in order to confirm tx submission status.
If ingestion is planned to be done on a separate instance, add INGEST=false
on this instance, otherwise don't include the parameter, Horizon will default to INGEST=true
. When a transaction submission enabled instance has INGEST=true
effective, it will configure the related STELLAR_CORE_URL
parameter automatically to use the internally launched captive core instance and the deployment does not need to set the configuration value explicitly.
If setting INGEST=false
, then must define the STELLAR_CORE_URL
variable on this transaction submission enabled instance, since there will be no internally hosted captive core instance as part of ingestion available to reference, instead the STELLAR_CORE_URL
provides the ability to define the URL of a core instance HTTP port which Horizon will send transaction submissions towards.
environment variable | example |
---|---|
DATABASE_URL | postgres://localhost/horizon_pubnet |
STELLAR_CORE_URL | http://example.watcher.core:11626 |
INGEST | false |
Notes
Ingestion
If you have configured your deployment to perform the ingestion role, then it is strongly recommended to review Ingestion first and Filtering second and factor that into configuration parameters to achieve best performance related to your application requirements before proceeding further.
- Horizon will create a sub-directory under the current working directory of the o/s process to store captive core runtime data files. Refer to Prerequisites for the type and amount of storage recommended. You can override this location with the optional
CAPTIVE_CORE_STORAGE_PATH
environment variable, set to a directory on the file system where captive core will store the runtime files.
DISABLE_TX_SUB
This config parameter is optional, set as FALSE by default. Controls whether Horizon will accept HTTP requests to the /tx
API endpoint and forward to the network. Refer to Channel Accounts for some recommendations on optional client transaction submission optimizations.
- When set to FALSE, it requires live ingestion process to be running on the same database because Horizon depends on new ledgers from the network to confirm a transaction submission status, Horizon will report a startup error if it detects no live ingestion. Requires
INGEST=true
orSTELLAR_CORE_URL
to be defined for access to a Core instance. - When transaction submission is disabled by setting it to TRUE, Horizon will return 405 on POSTs to /tx.
NETWORK
This config parameter is optional, can be one of Stellar's public networks, 'pubnet', or 'testnet'. Triggers Horizon to automatically set configurations for remaining Horizon settings and generate the correct core toml/cfg settings. If you only need Horizon to connect to one of those public Stellar networks, this will take care of all related configurations.
- If you want to connect Horizon to a different Stellar network other than pubnet or testnet or override any of the defaults that
NETWORK
usage will initiate, the key environment variables that can be set are:HISTORY_ARCHIVE_URLS
,CAPTIVE_CORE_CONFIG_PATH
,NETWORK_PASSPHRASE
,CAPTIVE_CORE_STORAGE_PATH
,STELLAR_CORE_URL
.
DB_URL
This config parameter is required, specifies the Horizon database. It's value follows this format: dbname=<pg_dbname> user=<pg_user_name> password=<pg_user_pwd> host=<host_address>
LOG_LEVEL
This config parameter is optional, can be one of 'info', 'error', 'debug'.
HISTORY_RETENTION_COUNT
This config parameter is optional, it determines the maximum sliding window of historical network data to retain on the database from ingestion. The value is expressed as absolute ledger count, which is an indirect way to define a duration of time, each ledger being approximately 5 seconds. It is defaulted to 0, which means it will not purge any history from the database. To enact the recommended sliding window of one month, set this to 518400, which is the approximate number of ledgers in 30 days. Refer to Compute Resources for how database storage space is closely related to this setting.
Passing Configurations to Horizon
The stellar-horizon
binary searches process environment variables for configuration. Depending on how Horizon was installed, the method you perform to configure the process environment will differ:
- Bare-metal
- Non-package manager: use O/S environment variables to pass configurations. There are many tools you can use to manage them, such as direnv or dotenv.
- Package manager: the provided
stellar-horizon-cmd
wrapper will start a new process and create environment variables in the process from/etc/default/stellar-horizon
and then launch the 'stellar-horizon'. To set configurations, edit the file at/etc/default/stellar-horizon
.infoThis script invokes Horizon with the
stellar
user, so make sure that permissions for the user are set up accordingly. The current working directory should be writable for this user and the user should be able to execute thestellar-horizon
andstellar-core
binaries; etc.
- Containerized
- Non-Helm: pass all configuration parameters to the horizon docker image as docker environment variables.
- Helm: pass all configuration parameters in the Helm install command as a values file.
Initialize Horizon Database
Before running the Horizon server for the first time, you must initialize the Horizon database. This database will be used for all of the information produced by Horizon, most notably historical information about transactions that have occurred on the Stellar network.
To prepare a database for Horizon's use, first ensure it is blank. It's easiest to create a new database on your PostgreSQL server specifically for Horizon's use. We recommend creating a new user(role) in postgres dedicated to Horizon's database and assigning that user(role) as the owner of this database.
To illustrate an example using psql
, first login to the database server using the psql
command-line tool as a superuser, and then create the new user(role) and database for Horizon:
postgres=#
postgres=# CREATE ROLE horizon WITH LOGIN;
CREATE ROLE
postgres=#
postgres=# CREATE DATABASE horizon OWNER horizon;
CREATE DATABASE
postgres=#
Additionally, you can set a password on your new horizon
postgres user with ALTER USER
.
Once completed, you can compose the full value of the configuration parameter for db access DATABASE_URL="dbname=horizon user=horizon password=<value_here> host=<address_of_pg_server>"
.
Next, execute the Horizon binary to install the schema onto the empty db from the command line. In this example, assume the current shell doesn't have DATABASE_URL
in environment yet, so export it first into shell:
$ export DATABASE_URL="dbname=horizon user=horizon password=<value_here> host=<address_of_pg_server>"
$ stellar-horizon db init
Optional Postgres Configurations
Based on performance observations over time, we recommend additional Postgres configuration settings(postgresql.conf), but these are not required:
- Set
random_page_cost=1
if you are using SSD storage. With this setting, Query Planner will make a better use of indices, especially forJOIN
queries. We've noticed a huge speed improvement for some queries with this setting.
_ To improve availability of ingestion, api, transaction submission servers it's recommended to set the following values:
tcp_keepalives_idle
: 10 secondstcp_keepalives_interval
: 1 secondtcp_keepalives_count
: 5
With the config above, if there are no queries from a given client for 10 seconds, Postgres should start sending TCP keepalive packets. It will retry 5 times every second. If there is no response from the client after that time it will drop the connection.
Next Step
After configuration is complete, you are now ready to proceed to Running Horizon!