Publish a Pack to CDN
A Spatial Pack on your local machine is useful for development. Publishing it to a CDN makes it accessible to web applications, remote teams, and API consumers. The spatialpack pack publish command uploads all pack files with correct content types, rewrites manifest URIs to CDN URLs, and verifies integrity before upload.
This recipe walks through the publish workflow, covering the pack lifecycle from built pack to live CDN.
Prerequisites
Section titled “Prerequisites”spatialpackCLI installed (pip install -e ".[full]")- A built Spatial Pack (output from
spatialpack pack build) - CDN credentials configured (AWS profile with S3 write access)
- An S3 bucket configured for static file serving
1. Verify the pack is built
Section titled “1. Verify the pack is built”Confirm your pack directory contains a valid manifest and all declared layer files.
spatialpack validate ./my-solar-pack/Expected output:
Validating ./my-solar-pack/ Manifest: spatialpack.json (valid) Layers: 6/6 files present Hashes: 6/6 verified License: CC-BY-4.0 (all sources)
Result: PASSWhat just happened: The validator checked the manifest against the Spatial Pack schema, confirmed every declared layer file exists on disk, and verified integrity hashes. A pack must pass validation before it can be published.
2. Preview the upload (dry run)
Section titled “2. Preview the upload (dry run)”See exactly what files will be uploaded and where they will land, without actually uploading anything.
spatialpack pack publish ./my-solar-pack/ \ --bucket my-packs-cdn \ --dry-runExpected output:
Dry run: publish ./my-solar-pack/ -> s3://my-packs-cdn/packs/
Files to upload: packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/spatialpack.json (12 KB) packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/layers/cadastre.parquet (4.2 MB) packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/layers/cadastre.pmtiles (8.1 MB) packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/layers/roads.parquet (18.7 MB) packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/layers/roads.pmtiles (12.3 MB)
Total: 5 files, 43.3 MBManifest URIs will be rewritten to: https://cdn.spatial.properties/packs/...
No files uploaded (dry run).What just happened: The CLI calculated the S3 key paths based on the pack’s ID and version, checked file sizes, and showed the CDN URL that would be written into the manifest. The versioned path (pack_id/version/) ensures immutability — each version gets its own directory.
3. Publish the pack
Section titled “3. Publish the pack”Run the publish command without --dry-run to upload.
spatialpack pack publish ./my-solar-pack/ \ --bucket my-packs-cdnExpected output:
Publishing ./my-solar-pack/ to s3://my-packs-cdn/packs/
Uploading: [1/5] spatialpack.json (12 KB) ... done [2/5] layers/cadastre.parquet (4.2 MB) ... done [3/5] layers/cadastre.pmtiles (8.1 MB) ... done [4/5] layers/roads.parquet (18.7 MB) ... done [5/5] layers/roads.pmtiles (12.3 MB) ... done
Manifest URIs rewritten to CDN domain: cdn.spatial.propertiesPack published: https://cdn.spatial.properties/packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/What just happened: The CLI uploaded each file to S3 with the correct Content-Type header (e.g., application/x-parquet for GeoParquet, application/octet-stream for PMTiles) and appropriate Cache-Control headers. It then rewrote the manifest’s layer URIs from relative paths to full CDN URLs so consumers can fetch layers directly.
4. Customize the CDN domain
Section titled “4. Customize the CDN domain”If you host packs on a custom domain, use the --cdn-domain flag to control URI rewriting.
spatialpack pack publish ./my-solar-pack/ \ --bucket my-packs-cdn \ --cdn-domain packs.example.comWhat just happened: The manifest URIs were rewritten to use packs.example.com instead of the default domain. This is useful when serving packs through your own CloudFront distribution or custom CDN setup.
5. Use a specific AWS profile
Section titled “5. Use a specific AWS profile”For multi-account setups, specify the AWS profile and region.
spatialpack pack publish ./my-solar-pack/ \ --bucket my-packs-cdn \ --profile production \ --region ap-southeast-2What just happened: The CLI used the production AWS profile from your credentials file instead of the default profile. The --region flag targets the bucket’s AWS region.
6. Verify the published pack
Section titled “6. Verify the published pack”After publishing, confirm the manifest is accessible at the CDN URL.
curl -s https://cdn.spatial.properties/packs/spatial.properties:wa:solar-feasibility:v1/2025.01.31/spatialpack.json | head -20Expected output:
{ "pack_id": "spatial.properties:wa:solar-feasibility:v1", "version": "2025.01.31", "layers": [ { "id": "cadastre", "parquet": "https://cdn.spatial.properties/packs/.../layers/cadastre.parquet" } ]}What just happened: The manifest is live on the CDN with layer URIs pointing to the published files. Any consumer — a web application, a Python script, or a DuckDB query — can fetch this manifest, discover the available layers, and load them directly.
Next steps
Section titled “Next steps”- Pack Lifecycle — Understand the full build, validate, publish, load workflow
- Query Pack Data with DuckDB — Query your published layers remotely with DuckDB
- CLI pack reference — Full options for
spatialpack pack publish