This project provides a Docker image for running Pi Network nodes, including stellar-core and horizon services.
This image runs in persistent mode, storing all data and configuration on a mounted volume. This ensures data is preserved between container restarts and allows for configuration customization.
The image uses the following software:
- PostgreSQL 12 - for storing both stellar-core and horizon data
- stellar-core 19.6.0
- horizon 2.23.1
- Supervisord - for managing the processes of the services above
- stellar-archivist - for managing history archives(optional scripts)
To use this project successfully, you should first decide a few things:
--mainnet- Pi Network mainnet (production network)--testnet- Pi Testnet (testnet)--testnet2- Pi Testnet2 (alternative test network)
The software listens on several ports. At minimum, expose the horizon HTTP port (8000). See the "Ports" section below for details.
You must mount a host directory to /opt/stellar to store persistent data:
$ docker run --rm -it -p "31401:8000" -v "/path/to/data:/opt/stellar" --name pi-node pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --testnetThe -v option mounts the host directory into the container at /opt/stellar. Use an absolute path and keep it consistent across container restarts.
Docker containers can be run interactively (using the -it flags) or in a detached, background state (using the -d flag). Many of the example commands below use the -it flags to aid in debugging but in many cases you will simply want to run a node in the background. It's recommended that you familiarize yourself with Docker tutorials.
- Run an interactive session first, ensuring all services start correctly.
- You will be prompted to set a PostgreSQL password (or set
POSTGRES_PASSWORDenvironment variable). - Shut down the interactive container (using Ctrl-C).
- Start a new container using the same host directory in the background.
Default configurations are copied to the data directory on first launch:
/opt/stellar
├── core
│ └── etc
│ └── stellar-core.cfg # stellar-core configuration
├── horizon
│ └── etc
│ └── horizon.env # Horizon environment variables
├── postgresql
│ └── etc
│ ├── postgresql.conf # PostgreSQL configuration
│ ├── pg_hba.conf # PostgreSQL client authentication
│ └── pg_ident.conf # PostgreSQL user mapping
├── supervisor
│ └── etc
│ └── supervisord.conf # Supervisord configuration
├── migration_status # Tracks executed migrations (auto-created)
└── migration_backups/ # Backup files from migrations (auto-created)
Stop the container before editing configuration files, then restart after changes.
WARNING: Incorrect configuration edits can break services. Understand each service before customizing.
| Option | Description |
|---|---|
--mainnet |
Connect to Pi Network mainnet |
--testnet |
Connect to Pi Testnet |
--testnet2 |
Connect to Pi Testnet2 |
--enable-auto-migrations |
Run database/config migrations on startup |
| Variable | Description |
|---|---|
POSTGRES_PASSWORD |
Set PostgreSQL password (avoids interactive prompt) |
NODE_PRIVATE_KEY |
Set the node's private key (secret seed). Optional - auto-generated if not provided |
The container includes migration scripts that update database schemas, modify deprecated configuration parameters, and apply other necessary changes when upgrading to newer versions. Migrations run automatically on startup when enabled with --enable-auto-migrations.
- Migration scripts are located in
/migrations/inside the container - Scripts execute in alphanumeric order (e.g.,
001_*.sh,002_*.sh, ...) - Each script runs only once - completed migrations are tracked in
/opt/stellar/migration_status - If a migration fails, the container stops immediately (fail-fast)
- Failed migrations will re-run on next startup
- Backups are created in
/opt/stellar/migration_backups/before changes
Add --enable-auto-migrations to your container command:
$ docker run -d \
-v "/path/to/data:/opt/stellar" \
-p "31401:8000" \
--name pi-node \
pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --mainnet --enable-auto-migrationsYou can also run migrations manually inside a running container:
$ docker exec -it pi-node /migrations/migration_runner.shOr invoke a specific migration script:
$ docker exec -it pi-node /migrations/001_update_validator3.shIf you prefer not to rely on scripts and want to manage configuration changes manually, you can find step-by-step documentation in the migrations/docs folder.
| Port | Service | Description |
|---|---|---|
| 5432 | PostgreSQL | Database access port |
| 8000 | Horizon | Main HTTP port |
| 6060 | Horizon | Admin port |
| 31402 | stellar-core | Peer node port |
| 11626 | stellar-core | HTTP port (internal) |
| 1570 | webfsd | Local history server |
| Host Port | Container Port | Service |
|---|---|---|
| 31401 | 8000 | Horizon HTTP |
| 31402 | 31402 | stellar-core peer |
| 31403 | 1570 | Local history server |
- PostgreSQL (5432): Keep protected. An attacker with write access can corrupt your view of the network.
- Horizon HTTP (8000): Safe to expose publicly. Designed for internet-facing use.
- Horizon Admin (6060): Expose only to trusted networks.
- stellar-core HTTP (11626): Expose only to trusted networks. Allows administrative commands.
- stellar-core Peer (31402): Can be exposed publicly to improve network connectivity.
- Local history (1570): Used for serving local history archives.
Access a running container:
$ docker exec -it pi-node bashServices are managed using supervisord. Launch the supervisor shell:
$ supervisorctl
horizon RUNNING pid 143, uptime 0:01:12
postgresql RUNNING pid 126, uptime 0:01:13
stellar-core RUNNING pid 125, uptime 0:01:13
supervisor>Common commands:
supervisor> restart horizon
supervisor> stop stellar-core
supervisor> helpLogs are located at /var/log/supervisor/. Use supervisorctl tail for live logs.
This image manages two PostgreSQL databases:
core- stellar-core datahorizon- Horizon data
Connect using:
- Username:
stellar - Password: The password you set during initial setup (or via
POSTGRES_PASSWORDenv var)
Initialize a new mainnet node (interactive, for initial setup):
$ docker run -it --rm \
-v "/path/to/data:/opt/stellar" \
-p "31401:8000" \
-p "31402:31402" \
-p "31403:1570" \
--name pi-node \
pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --mainnetStart a mainnet node in the background (after initialization):
$ docker run -d \
-v "/path/to/data:/opt/stellar" \
-p "31401:8000" \
-p "31402:31402" \
-p "31403:1570" \
--name pi-node \
pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --mainnetStart a testnet node with all ports exposed:
$ docker run -d \
-v "/path/to/data:/opt/stellar" \
-p "31401:8000" \
-p "31402:31402" \
-p "31403:1570" \
--name pi-node \
pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --testnetStart with pre-set PostgreSQL password (non-interactive):
$ docker run -d \
-v "/path/to/data:/opt/stellar" \
-p "31401:8000" \
-p "31402:31402" \
-p "31403:1570" \
-e POSTGRES_PASSWORD=your_secure_password \
--name pi-node \
pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6 --mainnetRecommended docker-compose.yml configuration:
name: pi-node
services:
mainnet:
image: pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6
container_name: mainnet
env_file:
- ./.env
volumes:
- ./data/stellar:/opt/stellar
- ./data/supervisor_logs:/var/log/supervisor
- ./data/history:/history
ports:
- "31401:8000"
- "31402:31402"
- "31403:1570"
command: ["--mainnet --enable-auto-migrations"]Create a .env file with your configuration:
POSTGRES_PASSWORD=your_secure_password
NODE_PRIVATE_KEY=your_node_private_key # Optional - auto-generated if not providedStart the node:
$ docker compose up -d mainnet$ make buildThis builds the image as pinetwork/pi-node-docker:organization_mainnet-v1.3-p19.6.
If you encounter issues, open an issue in the repository.