For the complete documentation index, see llms.txt. This page is also available as Markdown.

Curio-PDP

Operate Dockerized Curio-PDP: start the stack, attach storage, fund a wallet, and register with FWSS. Build flags and make targets are at the end.

Curio-PDP is the Dockerized PDP-only storage provider. It runs PDP proving and the FWSS registration flow without PoRep, sealing, or the MK20 market.

This is a supported Getting Started path, not an experimental feature. Use it when you want a PDP provider and do not need a full Curio sealing cluster.

For PDP on a full Curio cluster (alpha), see Enable PDP.


Hardware and disks

Review hardware requirements before you start (RAM, CPU, capacity, public HTTPS domain). GPU is not required.

Start the Docker stack on fast storage (NVMe/SSD). Yugabyte, Forest, and the Curio repo need low-latency disks. Put YUGABYTE_DATA, FOREST_DATA, and SKIFF_REPO_DATA on that fast volume — or run Compose from an NVMe path so the defaults under docker/skiff/data/ land there.

Piece payloads can live on slow disk. Map HDD (or other bulk storage) into the container data folder with SKIFF_STORAGE (mounted at /data). Attach those paths in the admin GUI. Indexes stay in Yugabyte on the fast disk; only the piece files belong on the slow volume.


Prerequisites

  • Docker and Docker Compose

  • Fast disk for the stack (see Hardware and disks)

  • Optional slow disk for piece data, mapped into /data

  • Optional public HTTPS domain when exposing the PDP HTTP API (HTTP.DomainName)

  • FIL/tFIL to fund the PDP signing wallet before FWSS registration

The compose stack ships with Forest. You can still point FULLNODE_API_INFO at an external Lotus or Forest node instead.

Published images

Release builds are on Docker Hub as filecoin/curio-pdp:

Tag
Network

filecoin/curio-pdp:<version> / :latest

Mainnet

filecoin/curio-pdp:<version>-calibnet / :calibnet

Calibration

Set SKIFF_IMAGE in docker/skiff/.env (or the environment) to one of these tags. Do not use :dev unless you are building locally.


Main steps

1. Clone and start

Run Compose from fast storage. On the host that will run the stack:

Point the stack at a published image. In .env:

Start:

Stop:

up -d starts Forest, Yugabyte, and Curio-PDP. ps shows health; logs -f follows all three (Ctrl-C stops the follow, not the containers).

Calibration network:

This starts:

  • Forest — Filecoin chain node (official ghcr.io/chainsafe/forest:latest, the latest stable release); first start downloads a snapshot (mainnet is large)

  • Yugabyte — YSQL and YCQL on the Compose network skiff-net only (not published on the host)

  • Curio-PDP — local admin GUI on 127.0.0.1:4701; public PDP API on 80/443 only

HarmonyDB migrations run on connect. Curio starts once Forest RPC accepts connections; wallet balance and FWSS registration need Forest to finish syncing.

2. Admin GUI over SSH

The GUI is bound to localhost on the Docker host. From your laptop ($HOST is that machine):

-fN forwards the port in the background with no remote shell. Then open http://127.0.0.1:4701 on the laptop. The second ssh is a normal session on the host.

On the Docker host itself, browse http://127.0.0.1:4701 directly.

3. Configure docker/skiff/.env (optional)

Copy or edit docker/skiff/.env before starting the stack if you need non-default disks or an external chain node.

Disks. Defaults write everything under ./data/ in the compose directory. Split fast vs slow storage like this:

You can also bind extra slow-disk directories under SKIFF_STORAGE on the host so they appear as folders under /data for the GUI to attach.

Chain node. Leave FULLNODE_API_INFO empty to use the bundled Forest service. To use an external Lotus/Forest instead:

See Skiff binary — Chain API for config-layer alternatives ([APIs].ChainApiInfo).

4. Select storage folders (admin GUI)

Open http://127.0.0.1:4701 → Storage (or PDP Guide → Select storage folders).

  1. Attach any existing directory Curio-PDP should use — enter a custom path, or pick a suggested folder under /data (compose bind-mounts SKIFF_STORAGE there; that can be slow disk).

  2. Paths are not auto-registered.

  3. Attached paths get a sectorstore.json and are persisted in the repo storage.json.

5. PDP signing wallet (admin GUI)

Curio-PDP needs a PDP signing key stored in HarmonyDB (eth_keys with role=pdp) before FWSS registration. Configure it through the admin GUI — the key is not set in .env. Open the GUI as in Admin GUI over SSH.

Go to PDP → wallet section.

Action
When to use

Create

Generate a new secp256k1 key on this node; the private key is shown once — save it before closing the dialog

Import

Paste a hex private key for an existing 0x address you already control

Only one PDP key is allowed per cluster. After create or import, fund the displayed 0x address with enough FIL/tFIL for registration and ongoing on-chain messages (see Enable PDP — Import your Filecoin Wallet Private Key for recommended amounts and a Lotus delegated-wallet import workflow).

The wallet private key is stored in Yugabyte and survives container restarts as long as YUGABYTE_DATA is preserved. Back up Yugabyte before redeploying (see Yugabyte backup).

6. Register with FWSS

In the GUI Register tab, complete provider registration, then verify with:


Configuration

Curio-PDP reads only the base layer at runtime. Do not rely on separate pdp or gui layers — put operational settings in base (or let auto-seed populate defaults and edit via the GUI).

Typical base values:

  • Subsystems.EnablePDP = true (forced on)

  • Subsystems.EnableWebGui = true

  • Subsystems.GuiAddress = "127.0.0.1:4701" (never bind the GUI to 0.0.0.0 on a host reachable from the internet)

  • HTTP.Enable = false until a domain is configured for the public API

Only TCP 80 and 443 should be exposed on your public firewall for FWSS registration and client traffic. See Curio HTTP server for built-in Let's Encrypt TLS, or Optional TLS offloading and filtering for a reverse proxy that offloads TLS, keeps Curio hosts private, and can filter traffic.

Chain API: bundled Forest via compose, or set FULLNODE_API_INFO / [APIs].ChainApiInfo (see Skiff binary — Chain API).

On first start, Curio-PDP auto-seeds the base config layer with PDP defaults (EnablePDP, EnableWebGui, GuiAddress, StorageRPCSecret). If a separate pdp layer already exists from a prior full-Curio setup, it is merged into base once at startup.

Storage

Curio-PDP stores piece payloads on local disk. Attach folders in the admin GUI (Storage page) by entering any existing path, or by selecting a suggested candidate under /data. Paths are persisted in $CURIO_REPO_PATH/storage.json.

/data is the SKIFF_STORAGE bind mount. That volume can be slow disk; keep Yugabyte and Forest on fast disk as described in Hardware and disks.

On a full Curio cluster that also seals sectors, keep PDP data off certain disks with the "piece" DenyTypes filter. Or add a dedicated storage location with AllowTypes: ["piece"]. See Separate PDP / parked pieces from sealed storage.

Missing sectorstore.json files are created when you attach a folder.

Suggested candidates are scanned under /data by default. To change that scan root (without limiting custom attach):

You can also set [Subsystems].DataPath in the base config layer, or pass --data=/var/lib/curio-data.

Updating components

Run these commands from curio/docker/skiff with the stack already running. Update Forest and Curio-PDP independently so each command restarts only the selected component.

Forest

The default image follows the latest stable Forest release. Running containers do not upgrade automatically. From curio/docker/skiff, fetch and apply an update:

For calibration network:

To pin a specific release instead, set FOREST_IMAGE=ghcr.io/chainsafe/forest:<version-tag> in .env. Updates briefly interrupt Forest RPC while the container restarts.

Curio-PDP (Skiff)

Published images use filecoin/curio-pdp:latest for mainnet and filecoin/curio-pdp:calibnet for calibration. Running containers do not upgrade automatically. Set SKIFF_IMAGE in .env to the tag for your network; the repository's :dev setting is for local builds.

For mainnet, set:

Then fetch and apply the update:

For calibration, set SKIFF_IMAGE=filecoin/curio-pdp:calibnet in .env, then run:

To select a specific release, use filecoin/curio-pdp:<version> for mainnet or filecoin/curio-pdp:<version>-calibnet for calibration, then run the same update command. Keep the image network consistent with your Forest node.

The update recreates the Skiff container using the existing bind-mounted repo and storage paths. PDP proving, the public API, and the admin GUI pause while Skiff restarts. Database migrations run on startup; before upgrading, review the release notes and back up Yugabyte using the database backup guide. Restoring an older image alone does not undo database migrations.

For a locally built image, update your source checkout to the desired revision, then rebuild from the repository root:

For a local calibration build:

Troubleshooting

Symptom
Check

Forest still syncing / wallet balance Err

Wait for snapshot import + sync; docker compose -f curio/docker/skiff/docker-compose.yaml logs -f forest

Curio-PDP cannot reach chain node

Bundled Forest: check forest health and token volume; external: use host.docker.internal or LAN IP, not 127.0.0.1 inside the container

Alert: PDP wallet not configured

PDP signing wallet → Create or Import; verify eth_keys has role=pdp

Yugabyte connection errors

docker compose -f curio/docker/skiff/docker-compose.yaml ps; Curio-PDP uses CURIO_DB_HOST=yugabyte on skiff-net; see Yugabyte troubleshooting

No storage paths

Storage → enter a path or Attach a suggested folder under /data; write permissions on selected folders

Registration fails

Wallet funded; HTTP.DomainName / TLS; chain node synced and reachable

Startup warning about missing key

Expected until wallet is configured; clears after key insert


How it's built

This section is for people building Curio-PDP from source. Operators using published images can stop above.

Data stores

Deployment
HarmonyDB (tasks, config, PDP state)
Piece index (multihash → offset)

Full Curio

Yugabyte (YSQL)

Yugabyte YCQL / Cassandra-compatible

Curio-PDP

Yugabyte (YSQL)

Yugabyte YCQL

Tests / CI

Postgres

Scylla (CQL)

Curio-PDP omits PoRep/sealing, MK20 market code, and filecoin-ffi. The compose stack still runs Dockerized Yugabyte (YSQL + YCQL) and Forest. Piece payload files live on disk; index data lives in Yugabyte YCQL and must be backed up with the database (see Yugabyte backup).

Build flags, Go tags, and native-binary options: Skiff binary. Make targets: Build and Make Variables.

Local image and make targets

From a clone:

Local compose without a published tag uses filecoin/curio-pdp:dev.

Native binary (optional)

If running Curio-PDP outside Docker, start Yugabyte (and a chain node) first, then:

Compose does not publish Yugabyte on the host. For a native binary against the Compose DB, add host port mappings for 5433/9042 or run the binary on skiff-net.

Moving between deployment profiles

Full Curio and Curio-PDP both use Yugabyte (YSQL + YCQL). CI uses Postgres + Scylla and is not an operator deployment profile.

To move relational PDP state and piece indexes:

  1. Back up Yugabyte YSQL and YCQL (see Yugabyte backup).

  2. Restore into the target Yugabyte instance.

  3. Copy piece files separately; payloads are not in the database dump.

  4. If the imported DB has a separate pdp config layer, Curio-PDP merges it into base on next startup.

There is no dedicated migration tool — Yugabyte backup/restore plus file copy is sufficient.

Last updated