Getting started
This guide runs a complete local catalog in a few minutes: start the serving stack, generate STAC from a CSV, load it into pgSTAC, and browse it.
For the CLI options you will use, see CLI reference. For the input fields and filename conventions, see Metadata.
1. Prepare the environment
cp .env.example .env
Set a PostgreSQL password in .env:
POSTGRES_DB=stac
POSTGRES_USER=postgres
POSTGRES_PASSWORD=stac
⚠️ Do not commit
.envor your Google Sheets credentials.
2. Prepare input
Create the bind-mounted directories the Compose stack expects:
mkdir -p input output
For CSV input, place at least collections.csv in input/:
input/
├── collections.csv # required
├── providers.csv # optional
└── catalogs.csv # optional
A minimal collections.csv only needs id and main_url:
id,main_url
ampl.season1_clms.mrvpp,https://s3.opengeohub.org/ai4sh/arco/ampl.season1_clms.mrvpp_m_500m_s_20000101_20001231_eu_epsg.3035_v20250805.tif
See the repository's examples/basic/ and examples/grouped-datacube/ for
complete working inputs.
3. Start the local stack
docker compose config # validate
docker compose up -d # start db, api, titiler, browser
docker compose ps # check status
For local development, publish PostgreSQL on loopback only so the host
stac-catalog CLI can reach pgSTAC without exposing it to the network:
ports:
- "127.0.0.1:5432:5432"
4. Generate and load
sync runs generate and then load in one step:
stac-catalog sync \
--source csv \
--input ./input \
--output ./output
Generation writes:
output/
├── catalogs.json
├── providers.json
├── collections.json
└── items.ndjson
(catalogs.json and providers.json may be empty when those tables are not
supplied.) Loading uses pgSTAC upsert semantics, so re-running updates existing
Collection and Item IDs instead of duplicating them.
Load needs the pgstac extra
For load/sync on the host, install it and provide the database:
python -m pip install -e ".[pgstac]"
export POSTGRES_HOST=localhost
export POSTGRES_PORT=5432
export POSTGRES_DB=stac
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=stac
(Or pass --dsn postgresql://postgres:stac@localhost:5432/stac.)
5. Access the services
| Service | URL |
|---|---|
| STAC API (landing) | http://localhost:8081 |
| STAC Collections | http://localhost:8081/collections |
| One Collection | http://localhost:8081/collections/<collection-id> |
| Items in a Collection | http://localhost:8081/collections/<collection-id>/items |
| STAC Browser | http://localhost:8082 |
| TiTiler (docs) | http://localhost:8000/docs |
Quick check with curl:
curl http://localhost:8081/
curl http://localhost:8081/collections
Open STAC Browser at http://localhost:8082 to browse the catalog,
collections, and items on a map.
Updating metadata
Because loading uses pgSTAC upsert, updating is simply:
- Edit your CSV (or Google Sheet).
- Re-run
stac-catalog sync(orstac-catalog load --output ./outputif you only changed the generated output). - Refresh the STAC API or Browser.
Run the tests
pytest -q
Next steps
- Configuration — config file, sources, environment
- CLI reference — every flag for
generate,load, andsync - Metadata — input fields, filename convention, grouping
- Deployment — production, networking, persistence