Pubky Testnet
A local test network for developing Pubky Core or applications depending on it.
Quick start
Start Postgres if you don't already have one running:
For more Postgres setup options see the Install Guide — Set Up PostgreSQL.
Run a local testnet with persistent state:
TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres' \
The data directory is auto-initialized on first run with a config.toml and server keypair. On subsequent runs, the existing state is picked up and the homeserver keeps the same identity.
The TEST_PUBKY_CONNECTION_STRING environment variable is read on every startup and overrides the database_url in the on-disk config.
To seed a custom homeserver config on first run (errors if config.toml already exists):
TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres' \
If you don't need persistent state, omit the persist subcommand and add ?pubky-test=true to the connection string. The database is auto-created on startup and cleaned up on shutdown:
TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres?pubky-test=true' \
Ports and addresses
| Component | Port |
|---|---|
| DHT bootstrap node | 6881 |
| Pkarr relay | 15411 |
| HTTP relay | 15412 |
| Homeserver ICANN HTTP | 6286 |
| Homeserver Pubky HTTPS | 6287 |
| Homeserver admin | 6288 |
Homeserver address: 8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo
The CLI uses [StaticTestnet] under the hood — see the type's rustdoc for programmatic use.
Writing tests (EphemeralTestnet)
For automated Rust tests, use [EphemeralTestnet]. Each instance gets its own isolated DHT and homeserver with random ports, so tests run in parallel without conflicts.
use EphemeralTestnet;
// Cleans up ephemeral Postgres databases after the test
async
Postgres for tests
You need a running PostgreSQL instance (see Quick start for a Docker one-liner). By default, EphemeralTestnet reads the TEST_PUBKY_CONNECTION_STRING environment variable. The ?pubky-test=true parameter tells the homeserver to create an ephemeral pubky_test_* database. The #[pubky_testnet::test] macro ensures the database is cleaned up after the test completes or panics.
TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres?pubky-test=true' \
You can also pass the connection string programmatically:
use ;
async
Docker Postgres
To avoid managing Postgres yourself, enable the docker-postgres feature. This uses testcontainers to run PostgreSQL in a Docker container that is automatically cleaned up on drop and on Ctrl+C/SIGTERM. Docker must be running on the host.
[]
= { = "<version>", = ["docker-postgres"] }
#
#
#
use EphemeralTestnet;
#
async
Each call to .with_docker_postgres() starts a separate container. To share one container across all tests, use DockerPostgres::shared():
#
#
Each testnet still gets its own ephemeral database within the shared PostgreSQL instance, so tests remain isolated.
Custom configuration
use ;
async