Docker
Run indexd, PostgreSQL, and Caddy using Docker Compose
This guide will walk you through setting up indexd using Docker Compose. This is the recommended way to self-host: Compose runs indexd, PostgreSQL, and a Caddy HTTPS reverse proxy together.
If you just want to store files, you don't need to run indexd at all — Sia Storage gives you 50 GB free with nothing to run.
Pre-requisites
Software Requirements: Before installing
indexd, you will need to install Docker.Hardware Requirements: A stable setup that meets the following specifications is recommended.
A quad-core CPU
8GB of RAM
256 GB SSD for
indexdand its PostgreSQL database
Network Access:
indexdinteracts with the Sia network, so you need a stable internet connection and open network access to connect to the Sia blockchain.A domain to use for the public App API
Create the compose file
Create a new file named docker-compose.yml. You can use the following as a template. PostgreSQL stores the indexd index, and Caddy exposes the application API over HTTPS.
services:
caddy:
depends_on:
- indexd
image: caddy:2
restart: unless-stopped
environment:
INDEXD_DOMAIN: ${INDEXD_DOMAIN}
ports:
- 80:80/tcp
- 443:443/tcp
- 443:443/udp
volumes:
- ./caddy:/etc/caddy:ro
- caddy-data:/data
- caddy-config:/config
postgres:
image: postgres:18
restart: unless-stopped
shm_size: 128mb
environment:
POSTGRES_USER: indexd
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: indexd
volumes:
- postgres:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
indexd:
depends_on:
postgres:
condition: service_healthy
image: ghcr.io/siafoundation/indexd:latest
restart: unless-stopped
ports:
- 127.0.0.1:9980:9980/tcp # admin UI and API (kept local)
- 9981:9981/tcp # public syncer
expose:
- 9982/tcp # application API (available only to Caddy)
volumes:
- indexd-data:/data
volumes:
caddy-data:
caddy-config:
indexd-data:
postgres:Port 9980 is bound to 127.0.0.1 for the private admin UI and API. Port 9982 is not published on the host; only Caddy can reach it through the Compose network. Applications connect to Caddy on port 443. Port 9981 should be publicly reachable by the Sia network.
Create the Caddyfile
Create a directory named caddy beside docker-compose.yml, then create caddy/Caddyfile with the following contents:
Caddy uses the domain from .env, obtains and renews its HTTPS certificate, and forwards application API requests to indexd over the private Compose network. Before starting the stack, point the domain's DNS records to this server and allow inbound TCP ports 80 and 443. UDP port 443 enables HTTP/3.
Set the environment variables
Create a file named .env in the same directory as your docker-compose.yml. Set the PostgreSQL password and the public domain Caddy will use for the application API:
You will enter the same database password during the indexd configuration step. For the application API advertise URL, enter the domain as a complete HTTPS URL, such as https://indexd.example.com.
Get the container images
Download the container images:

Generate a recovery phrase
indexd uses a wallet to pay for storage contracts. If you don't already have a recovery phrase, generate one:
Write your recovery phrase down and store it somewhere safe. It controls the wallet that funds your contracts and cannot be recovered if lost.
Configuring indexd
Now launch the interactive configuration wizard:
The wizard will ask you for:
Your wallet recovery phrase (use the one you generated above).
An admin password used to unlock the
indexdadmin UI.A database password — enter the same value you set in
.env.An application API advertise URL — the exact base URL applications will use to reach this indexer, described below.
When asked whether to configure advanced settings, answer yes and set the database connection so indexd can reach the PostgreSQL container:
Database address
postgres:5432
Database user
indexd
Database name
indexd
SSL mode
disable

Choose the application API advertise URL
The advertise URL is not the address indexd listens on. It is the external base URL that an application uses to reach the application API. indexd puts this URL into the application-approval flow and uses its hostname when verifying signed requests, so an incorrect value can break application authentication even when indexd itself is running.
For an indexer reached through an HTTPS reverse proxy, a typical configuration is:
In this example, indexd listens on port 9982, while applications connect to https://indexd.example.com. The reverse proxy terminates HTTPS and forwards requests to port 9982.
The advertise URL must:
Include the scheme, such as
https://.Use the public hostname and port, if a non-standard port is required, that applications can actually reach.
Use
https://when a reverse proxy provides HTTPS, even if the proxy connects toindexdover HTTP.Be the same base URL entered in the application.
Omit a trailing slash and API endpoint paths such as
/apior/auth/connect.
Do not use 0.0.0.0, a Docker service name, or another internal address. Use localhost or 127.0.0.1 only when the application runs on the same machine as indexd; on a phone or another computer, localhost refers to that device instead of the indexer.
The admin UI URL is not the advertise URL. Port 9980 serves the private admin API; applications connect to the application API on port 9982 or its HTTPS reverse-proxy URL.
Running indexd
Now that you have indexd configured, start the services:

Once indexd has started, you can access the admin UI by opening your browser and going to http://localhost:9980.

indexd is now set up.
Verify the advertise URL
From the device or network where the application will run, test the advertise URL you configured:
An unsigned request should reach indexd and return 401 Unauthorized with a message about missing query parameters. A timeout, certificate error, or proxy error means the public URL is not ready.
To correct the URL, run the configuration wizard again, choose to change the existing value, and restart indexd:
Fund your wallet
indexd uses a built-in wallet to pay storage providers for the contracts it forms on your behalf, so it needs Siacoin (SC) before it can store any data. After signing in, the Welcome to Sia checklist in the admin UI walks you through the remaining setup, including funding your wallet.
Open the Wallet section of the UI, copy your receiving address, and send Siacoin to it from an exchange or another wallet. See Transferring Siacoins for the full send and receive flow.
Once your wallet shows a confirmed balance, indexd can begin forming contracts and storing data.
Checking the container status
To check the status of the containers run:
Checking the logs
To check the indexd logs run:
Upgrading indexd
New versions of indexd are released regularly and contain bug fixes and performance improvements. To upgrade to the newest version, run the following:
indexd is now updated to the latest version.
Next steps
Configure backups and recovery, then connect an application.
Last updated
Was this helpful?