This project uses a Makefile to wrap common developer/ops tasks.
If you’re not a developer: you can ignore this file. Local setup notes are in development.md.
make lint: run Ruff lint on backend codemake format: format + auto-fix with Ruffmake lint-check: CI-style formatting + lint checks (no modifications)make cli-lint: run CLI formatting and lint checksmake cli-format: format the CLI package
make test: run tests with coverage (defaults:COVERAGE_THRESHOLD=50,PARALLEL_WORKERS=4)make test-no-coverage: run tests without coverage thresholdmake test-fast: fastest local tests (parallel, no coverage)make test-fresh-db: drop/recreatebtaa_geospatial_api_test(cloned frombtaa_geospatial_api)make lint-test:lint-check+testmake cli-test: run the full CLI pytest suite fromcli/make cli-build: build the CLI source and wheel distributionsmake cli-man: generate CLI man page artifacts fromcli/docs/*.1.mdmake k6-smoke: run a one-iteration k6 smoke test against both the public frontend and the backend API. Defaults toK6_BASE_URL=https://lib-btaageoapi-dev-app-01.oit.umn.edu, auto-discovers a resource id from search results unlessK6_RESOURCE_IDis provided, discovers live facet values from the same seed search, and writestmp/k6/smoke-summary.json.make k6-stress: run the concurrent k6 stress suite with separate frontend-page and direct-API scenarios. Defaults targetdev1, ramp frontend traffic toK6_FRONTEND_TARGET_VUS=4, ramp API traffic toK6_API_TARGET_VUS=8, and writetmp/k6/stress-summary.json. The API side now includes direct faceted searches plus/api/v1/search/facets/<facet_name>calls, and the frontend side includes faceted/searchpage requests plus the hydrated/search/resultsJSON request through the keyed frontend BFF route. Useful overrides includeK6_QUERY,K6_QUERY_POOLfor varied real query terms,K6_RESOURCE_ID,K6_API_KEYfor production-like rate-limited environments,K6_ENABLE_FRONTEND=0,K6_ENABLE_API=0,K6_CACHE_BUST_SEARCH=1for uncached search/facet miss-path runs,K6_ENDPOINT_BREAKDOWN=1for per-endpoint p95/p99 summary rows,K6_FRONTEND_P95_THRESHOLD_MS/K6_API_P95_THRESHOLD_MSfor capacity hunts, plusK6_FRONTEND_*andK6_API_*.make k6-endpoint-capacity: run one endpoint with k6's fixedconstant-arrival-rateexecutor so p95 can be tied to an explicit request rate instead of a blended VU scenario. Defaults toK6_ENDPOINT_TARGET=frontend_search_results_api,K6_REQUEST_RATE=50,K6_ENDPOINT_DURATION=3m, and writestmp/k6/endpoint-capacity-summary.json. Supported targets arefrontend_search_results_api,frontend_faceted_search_results_api,frontend_resource_page,api_search, andapi_faceted_search; tune withK6_RATE_TIME_UNIT,K6_PRE_ALLOCATED_VUS,K6_MAX_VUS,K6_ENDPOINT_P95_THRESHOLD_MS, andK6_ENDPOINT_P99_THRESHOLD_MS.
Overrides:
COVERAGE_THRESHOLD=25 make testPARALLEL_WORKERS=0 make test(disable xdist)
make resource-aux-init: ensureresource_downloads,resource_licensed_accesses,resource_assets, durablegenerated_visual_assets/generated_visual_asset_links,resource_thumbnail_state, durablegenerated_resource_representations, and durablegenerated_api_responsestables exist before bridge/legacy sync, cache priming, or thumbnail reporting work.make visual-assets-export: export only local durable generated visual asset rows totmp/generated_visual_assets.dump, and write a sidecar manifest totmp/generated_visual_assets.manifestwith the row counts and byte totals used for later verification. Use this after local visual-cache priming finishes. OverrideVISUAL_ASSETS_PG_DUMP_COMPRESS=0|1|...when you want to trade archive size for faster dump speed; the default is1.make visual-assets-import KAMAL_DEST=dev1: import that archive to one Kamal destination through staged tables. The target first runs the deployed visual-asset table migration, loads archive data intogenerated_visual_asset_*_stage, verifies the staged counts against the export manifest, then atomically swaps the staged tables into place. The previous live tables are preserved in schemavisual_asset_backupby default.make visual-assets-stream-import KAMAL_DEST=dev1: stream the local visual-asset tables directly into one Kamal destination without writingtmp/generated_visual_assets.dump. It uses the same staged-then-swap workflow asvisual-assets-import, so live traffic can keep using the existing visual asset tables until the staged copy verifies cleanly. This is the best fit for a single destination or a disk-constrained laptop.make visual-assets-sync-all: export once, then import the same archive plus manifest to each destination inVISUAL_ASSETS_DESTS(default:dev1 dev2 prd). Override withVISUAL_ASSETS_DESTS="dev1 dev2"orVISUAL_ASSETS_ARCHIVE=tmp/my_visual_assets.dump VISUAL_ASSETS_MANIFEST=tmp/my_visual_assets.manifestas needed.make prime-visual-caches: runs thumbnail priming first, then static-map priming. After a Redis reset, the priming scripts first try to reuse durable visual storage before regenerating remote thumbnails or maps. Static-map priming defaults to durable assets/links plus aliases without hydrating full PNG bodies into Redis; usePRIME_STATIC_MAP_HYDRATE_ASSETS=1only for small hotsets that should load image bodies. Full-corpus static-map hydration is refused unlessPRIME_ALLOW_FULL_HYDRATION=1is also set. Individual broken upstream assets are logged and recorded without making the task fail, so one bad provider thumbnail or map does not stop the full warming run. Local priming waits for ParadeDB to answerSELECT 1before starting, which avoids startup/recovery races after Docker restarts. On Kamal, usemake kamal-prime-visual-caches KAMAL_DEST=dev1or run the lower-levelkamal-prime-thumbnail-cache/kamal-prime-static-map-cachetargets.- The visual priming scripts wait through transient Redis
LOADINGstates by default (VISUAL_ASSET_REDIS_LOADING_MAX_WAIT_SECONDS=900, retry everyVISUAL_ASSET_REDIS_LOADING_RETRY_SECONDS=5) so a Redis restart/load does not become a flood of false per-resource failures. - For very large local warm-up runs, you can temporarily recreate Redis with
REDIS_APPENDONLY=noandREDIS_SAVE=""so Redis stays an in-memory hot cache while Postgres remains the durable store for generated visual assets and links.
- The visual priming scripts wait through transient Redis
make thumbnail-completeness-report: print a concise DB-backed thumbnail coverage report. It counts success only whenresource_thumbnail_state.source_hashpoints at durablegenerated_visual_assetsthumbnail bytes, and separates placeheld, failed, queued, stale success, not attempted, no-source, and restricted records. UseTHUMBNAIL_REPORT_SCOPE=all|urban|iiif,THUMBNAIL_REPORT_FORMAT=table|json|csv,THUMBNAIL_REPORT_SHOW_MISSING=25, andTHUMBNAIL_REPORT_FAIL_UNDER=100while launch-checking coverage. On Kamal, usemake kamal-thumbnail-completeness-report KAMAL_DEST=prdwith the same variables.make resource-cache-init: ensure the durablegenerated_resource_representationsandgenerated_api_responsescache tables exist.make api-response-cache-init: ensure only the durablegenerated_api_responses/generated_api_response_tagstables exist.make api-response-cache-prune: delete expired durablegenerated_api_responsesrows.make prime-resource-cache: build the shared JSON:API resource representation cache used by both/api/v1/resources/{id}and/api/v1/search. This writes Redis hot entries plus durablegenerated_resource_representationsrows, so Redis can be rehydrated quickly after cache loss. The primer batch-prefetches resource enrichments and bulk-writes cache rows; defaults arePRIME_BATCH_SIZE=500andPRIME_RESOURCE_CONCURRENCY=16. UsePRIME_LIMIT,PRIME_BATCH_SIZE,PRIME_RESOURCE_CONCURRENCY,PRIME_FORCE=1, orRESOURCE_IDS="..."to scope/tune a run. On Kamal, usemake kamal-prime-resource-cache KAMAL_DEST=dev1.make refresh-resource-caches: dry-run or purge and rehydrate caches for a selected resource set. Select resources withRESOURCE_IDS="...",RESOURCE_IDS_FILE=/app/backend/tmp/ids.txt,RESOURCE_WHERE_FILE=/app/backend/tmp/resource_where.sql,RESOURCE_QUERY_FILE=/app/backend/tmp/resource_ids.sql, orRESOURCE_ALL=1; addRESOURCE_LIMITfor a bounded run. SetREFRESH_APPLY=1to invalidateresource:<id>tagged Redis L1 entries and durable endpoint-response L2 rows, delete matching durablegenerated_resource_representationsrows plus exact Redis resource-representation keys for all known profiles (includingsearch-result), rebuild the resource representation cache, then warm/api/v1/resources/{id}and/api/v1/resources/{id}?format=json. UseREFRESH_SKIP_ENDPOINT_WARM=1,REFRESH_SKIP_REHYDRATE=1,REFRESH_BATCH_SIZE,REFRESH_CONCURRENCY, andREFRESH_VERBOSE=1as needed. On Kamal, usemake kamal-refresh-resource-caches KAMAL_DEST=dev1with the same selector variables.make reindex: atomic local reindex using a versioned index + alias swap (non-destructive build + atomic cutover). Defaults favor safety: swap is blocked on indexing errors/count mismatch, and one previous versioned index is retained. After a successful swap, it automatically clears localsearchcache.- Useful local tuning overrides:
REINDEX_CHUNK_SIZE,REINDEX_BULK_SIZE,REINDEX_BULK_MAX_RETRIES,REINDEX_FAST_SETTINGS,REINDEX_FORCE_REPLICAS_ZERO,REINDEX_RETAIN_PREVIOUS. - Benchmark mode:
make reindex-benchmark(orREINDEX_BENCHMARK=true make reindex) prints per-chunk timings and a final phase summary.
- Useful local tuning overrides:
make sitemap-generate: generate and cache the crawler-facing sitemap payload served at/sitemap.xml(and supporting/sitemaps/*.xmlparts when the URL count exceeds sitemap protocol limits).robots.txtonly advertises that sitemap whenSEARCH_ENGINE_INDEXING_ENABLED=true; the default remains block-all for local/dev safety.
make analytics-maintenance: ensure monthlyanalytics_*partitions exist, roll up completed daily analytics into compact summary tables, and drop expired raw partitions once they are safely summarized.make analytics-size-report: print current Postgres sizes foranalytics_*parent tables, partitions, and rollup tables.make ogm-refresh: trigger OpenGeoMetadata harvest for all enabled weekly repos (POST /api/v1/admin/ogm/harvestwith{"ogm_all":true,"ogm_trigger":"weekly"}).make ogm-refresh-repo OGM_REPO_NAME=edu.stanford.purl: trigger OpenGeoMetadata harvest for one repo ({"ogm_repo_name":"...","ogm_trigger":"manual"}).- OGM harvests update local Postgres records,
resource_distributions, andresource_relationshipsautomatically. Runmake reindexif you need local Elasticsearch/search results updated immediately after the harvest. make ogm-status: show current OGM harvest runs (GET /api/v1/admin/ogm/harvest/runs).make ogm-status OGM_RUN_ID=<run_id>: show detail for one run (GET /api/v1/admin/ogm/harvest/runs/{run_id}).make ogm-status-watch [OGM_RUN_ID=<run_id>] [OGM_STATUS_POLL_SECONDS=5]: poll OGM status until you stop it (Ctrl+C).make ogm-failures: show only failed OGM harvest runs withogm_errordetails.- These OGM make tasks run
curlfrom inside theapicontainer and use that container'sADMIN_USERNAME/ADMIN_PASSWORD, so they stay aligned with the live API auth config. make verify-h3-index: query Elasticsearch to verify H3 pyramid fields (h3_res2–h3_res8,geo_or_near_global) are present (run after reindex)make bridge-sync: trigger a background bridge crawl through the admin API.- Full crawl example:
make bridge-sync - Single-record example:
make bridge-sync RESOURCE_ID=b1g_PJxxfKgpqpUT - Optional filters:
BRIDGE_LIMIT=50,BRIDGE_CHANGED_SINCE=2026-04-01T00:00:00Z,BRIDGE_TRIGGER=manual RESOURCE_IDis aliased toBRIDGE_RESOURCE_ID, so either variable works.
- Full crawl example:
make bridge-status: show a readable bridge sync summary instead of raw JSON by default.- It now includes processed/imported counts, pages, elapsed time, throughput, and an estimated total/ETA for full crawls when a prior successful full run exists.
- Use
make bridge-status BRIDGE_STATUS_RAW=1if you need the raw API JSON payload.
make bridge-status-watch: poll the current bridge run with the same readable summary.- By default it shows only the current run, with processed/imported counts, pages, throughput, and estimated remaining time for full crawls.
- Use
make bridge-status-watch BRIDGE_STATUS_SHOW_LAST=1if you also want the last completed run for comparison.
make kamal-cron-test-bridge: run the bridge cron trigger script inside a Kamal cron container. UseCHANGED_SINCE=2026-04-23T00:00:00Zto replay a specific bridge delta window.- Bridge delta syncs update changed resources in Elasticsearch, delete durable generated resource representations for changed IDs, invalidate Redis entries tagged with changed
resource:<id>values, warm thumbnails/static maps/resource-class icon assets, then re-warm tagged search/resource GETs plus the canonical/api/v1/resources/{id}response for each changed resource. This keeps Redis and the durable generated-resource table hot after nightly Bridge edits. Tune withBRIDGE_SEARCH_INDEX_REFRESH_ENABLED,BRIDGE_SEARCH_INDEX_MAX_RESOURCE_IDS,BRIDGE_CACHE_REFRESH_ENABLED,BRIDGE_GENERATED_ASSET_REFRESH_ENABLED,BRIDGE_CACHE_REFRESH_MAX_RESOURCE_IDS,BRIDGE_CACHE_REWARM_MAX_URLS,BRIDGE_CACHE_REWARM_TIMEOUT_SECONDS,BRIDGE_CACHE_THUMBNAIL_CONCURRENCY,BRIDGE_CACHE_STATIC_MAP_CONCURRENCY,BRIDGE_CACHE_RESOURCE_ICON_CONCURRENCY, andBRIDGE_CACHE_REFRESH_FORCE_GENERATED_ASSETS. - Nightly bridge cron syncs identify themselves with
BRIDGE_TRIGGER=nightly_cronby default. The Kamal cron crontab now pinsCRON_TZ=America/Chicago, and the bridge script computeschanged_sincefrom the previous America/Chicago day before converting to UTC for the bridge API. Cron shells also source/app/scripts/cron_env.shthroughBASH_ENVso Celery, Redis, DB, and Python-path settings match the live container instead of falling back to local defaults. - Cron bridge and blog triggers now enqueue work with
apply_async(ignore_result=True)so they do not need a Celery result-backend subscription just to queue fire-and-forget jobs. - Set
BRIDGE_SYNC_REPORT_ENABLED=trueandBRIDGE_SYNC_REPORT_FROMto email the styled nightly report after the Celery sync task concludes. Default recipients areewlarson@gmail.com,majew030@umn.edu; override only withBRIDGE_SYNC_REPORT_RECIPIENTSif the recipient list intentionally changes. Reports are sent only fromKAMAL_DEST=prdby default; override withBRIDGE_SYNC_REPORT_DESTINATIONS. prd usesBRIDGE_SYNC_REPORT_DELIVERY=sendmail; the Kamal image installsmsmtp-mtato provide/usr/sbin/sendmailand relays through UMNsmtp.umn.eduwithout app-level SMTP credentials. SMTP delivery is still available withBRIDGE_SYNC_REPORT_DELIVERY=smtpandSMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_STARTTLS. Reports are sent fornightly_cron,crontriggers by default; override withBRIDGE_SYNC_REPORT_ON_TRIGGERSand useBRIDGE_SYNC_REPORT_MIN_DELTA_PROCESSEDto flag suspiciously small delta runs. - One-time Kamal host bootstrap: prepare each server with the shared
deploySSH account before routine deploys. Usebackend/scripts/bootstrap_kamal_deploy_user.sh --host <host> --ssh-user <existing_admin_user>, then keepKAMAL_SSH_USER=deployin.kamal/secrets.<dest>. Seedocs/backend/kamal_deployment.md. make kamal-reindex: atomic remote reindex on Kamal using a versioned index + alias swap (runs once by default with--roles web). UsesKAMAL_DEST=dev1by default and supports any configured destination such asdev2orprd; secrets come from.kamal/secrets-common+.kamal/secrets.<dest>. On success, runsmake kamal-clear-cache.- Useful overrides:
KAMAL_REINDEX_RETAIN_PREVIOUS=1(default),KAMAL_REINDEX_PRUNE_OLD=true(default),KAMAL_REINDEX_ALLOW_PARTIAL=false(default; blocks swap on indexing/count mismatch),KAMAL_REINDEX_REMOVE_LEGACY_INDEX=true(default; one-time migration from legacy non-alias index name).
- Useful overrides:
make kamal-verify-h3-index: verify H3 fields on remote Kamal app containers. UseKAMAL_DEST=<destination>such asdev1,dev2, orprd.make kamal-clear-cache: clear remote API cache on Kamal (defaults toKAMAL_CACHE_TYPE=search). UseKAMAL_DEST=<destination>such asdev1,dev2, orprd. Override withKAMAL_CACHE_TYPE=all(orsuggest/item).make kamal-prime-resource-cache: build the shared resource representation cache inside a Kamal app container. This ensures the durable generated-resource table exists, writes durable rows, and fills Redis. This is useful after deploy/cache clears before collecting search/detail performance HARs.make kamal-prime-visual-caches: build the thumbnail and static-map hot Redis caches inside a Kamal app container. The lower-level Kamal priming targets ensure the durable generated-visual-asset tables exist before warming. This complementskamal-prime-resource-cache; use both before performance HARs when you want search JSON, thumbnail redirects, and static-map/icon redirects all warm.make kamal-prime-static-map-cache: build only the static-map/resource-class-icon visual cache on Kamal. By default, full runs write durable static-map assets/links and Redis aliases without hydrating full PNG bodies into Redis DB 1. SupportsPRIME_LIMIT,PRIME_BATCH_SIZE,PRIME_STATIC_MAP_CONCURRENCY,PRIME_FORCE=1,PRIME_STATIC_MAP_HYDRATE_ASSETS=1,PRIME_ALLOW_FULL_HYDRATION=1, andRESOURCE_IDS="...".make kamal-api-response-cache-init: ensure the durable Postgres L2 response cache tables exist on Kamal.make kamal-api-response-cache-prune: delete expired durable Postgres L2 response cache rows on Kamal.make kamal-refresh-resource-caches: run the generic resource cache purge and rehydration flow inside a Kamal app container. It is a dry run unlessREFRESH_APPLY=1; select resources withRESOURCE_IDS="...",RESOURCE_IDS_FILE,RESOURCE_WHERE_FILE,RESOURCE_QUERY_FILE, orRESOURCE_ALL=1. For broad cache repair after thumbnail/cache behavior changes, deploy the cache-invalidation code first, then run this withRESOURCE_ALL=1 REFRESH_APPLY=1in tuned batches or during a maintenance window.make kamal-network-sanity: compare host-shell and app-container connectivity on a Kamal destination. It probes a few external URLs plus the server's own public hostname and exits nonzero if the container cannot reach something the host can. Defaults toKAMAL_DEST=dev1, roleweb, self URLhttps://$(KAMAL_HOST), and external URLshttps://api.github.com https://raw.githubusercontent.com https://gin.btaa.org http://example.com. Override withKAMAL_DEST=prd,KAMAL_APP_ROLE=cron,KAMAL_NETWORK_SELF_URL=..., orKAMAL_NETWORK_EXTERNAL_URLS="...".make ingest: ingest BTAA fixture JSON files into the DB (runs inside theapiDocker container). Default:data/fixtures/btaa_fixtures_data. Override withmake ingest FIXTURES_DIR=btaa_featured_resources REPO_NAME=btaa_featured_resources. After ingest, runmake reindexto index into Elasticsearch.make ingest-featured: ingestdata/fixtures/btaa_featured_resourcesinto the DB and then reindex into Elasticsearch (one-step for featured resources).make clear_cache: flush Redis cache DB (REDIS_DB). The target readsREDIS_PASSWORDfrom the running Redis container so it matches the password Redis was started with and avoids passing the secret on the host command line.
Analytics storage knobs live in .env / deploy env vars:
ANALYTICS_RETENTION_API_USAGE_DAYSdefault30ANALYTICS_RETENTION_SEARCH_DAYSdefault90ANALYTICS_RETENTION_IMPRESSION_DAYSdefault30ANALYTICS_RETENTION_EVENT_DAYSdefault90ANALYTICS_PARTITION_HISTORY_MONTHSdefault2ANALYTICS_PARTITION_FUTURE_MONTHSdefault2ANALYTICS_ROLLUP_MAX_DAYS_PER_RUNdefault31
make frontend-reset: clear Vite cache infrontendand restart the dev server. Use after changingoptimizeDepsor when seeing "Failed to fetch dynamically imported module" or 504 "Outdated Optimize Dep". After running it, do a hard refresh (Ctrl+Shift+R or Cmd+Shift+R) or open the app in an incognito window—otherwise the browser may keep requesting old chunk URLs and still get 504s.make db-export: export local DB →tmp/btaa_geospatial_api_export.sql.gz, and also build thedb-syncimport archive used bydb-importmake db-import: import thedb-syncarchive to remote via Kamal. By default this preserves destination-local tables listed inDB_SYNC_PRESERVE_TABLES(api_service_tiers,api_keys,analytics_api_usage_logs,analytics_searches,analytics_search_impressions,analytics_events) and their owned sequences listed inDB_SYNC_PRESERVE_SEQUENCES. UseKAMAL_DEST=<destination>such asdev1,dev2, orprdto target a server. To force a full overwrite, runmake db-export DB_SYNC_PRESERVE_LOCAL_TABLES=falseand thenmake db-import DB_SYNC_PRESERVE_LOCAL_TABLES=false ....make db-sync:db-export+db-importwith destination-local table preservation enabled by default- GBL Admin production sync:
make gbl-admin-db-syncdownloads the latestpgdump-geoportal_production-*.sql.gzfrom the GBL Admin server and restores the newest local matching dump into local ParadeDB, whether that file is compressed (.sql.gz) or already decompressed (.sql). It streams from the compressed file when using.gz, so you only need space for the.gz. After restore, it keeps the newly restored database plus the newest previously restoredgeoportal_production_*database, pruning older ones by default (GBL_ADMIN_RETAIN_DBS=2). The production rolegeomgis created locally so restore does not fail on OWNER clauses. If ParadeDB crashes during restore (e.g. OOM), increase Docker memory for theparadedbservice and re-run; you may need to drop the partial DB first:docker compose exec paradedb psql -U postgres -d postgres -c "DROP DATABASE IF EXISTS geoportal_production_YYYYMMDD;". - GBL Admin add latest BTAA fields:
make gbl-admin-db-add-latest-btaa-fieldsadds latest BTAA compatibility columns toresources. - GBL Admin import resources:
make gbl-admin-db-import-resourcesimports fromkithe_to_resources_bridgeintobtaa_geospatial_api(OLD_DB_NAMEauto-detected unless provided). To soft-retire local resources that are missing from the current old-prod snapshot, runmake gbl-admin-db-import-resources GBL_ADMIN_RETIRE_MISSING=true. - GBL Admin populate distributions:
make populate-distributionsrebuildsresources.dct_references_s,resource_distributions,resource_downloads, andresource_assetsfrom legacy old-production data (OLD_DB_NAMEauto-detected unless provided).- This now includes child Kithe asset rows, so PMTiles/download URLs that never lived on the parent record are preserved.
- Single-record example:
make populate-distributions RESOURCE_ID=b1g_PJxxfKgpqpUT RESOURCE_IDis aliased toGBL_ADMIN_RESOURCE_ID, so either variable works.
- GBL Admin populate data dictionaries:
make populate-data-dictionariesmigrates legacydocument_data_dictionariesanddocument_data_dictionary_entriesintoresource_data_dictionariesandresource_data_dictionary_entries. - GBL Admin full import pipeline:
make gbl-admin-db-import-allruns latest-field migration, resource import, soft-retires local resources missing from the current old-prod snapshot, migrates distributions and data dictionaries, repopulates relationships, and reindexes published resources. make populate-relationships: populateresource_relationshipsfromresources(run after ingest or when relationship columns change). Seedocs/backend/relationships.md.
Use this sequence when rebuilding from the old GBL Admin production snapshot.
-
Restore latest old-prod DB snapshot and build bridge materialized view:
make gbl-admin-db-sync
-
Run full import pipeline into API DB, including distributions/relationships and reindex:
make gbl-admin-db-import-all
If you need to pin a specific restored old DB instead of auto-detect:
OLD_DB_NAME=geoportal_production_YYYYMMDD make gbl-admin-db-import-allEquivalent explicit step-by-step (instead of the all-in-one target):
make gbl-admin-db-add-latest-btaa-fields
make gbl-admin-db-import-resources GBL_ADMIN_RETIRE_MISSING=true
make populate-distributions
make populate-data-dictionaries
make populate-relationships
make reindexTargeted recovery examples:
make bridge-sync RESOURCE_ID=b1g_PJxxfKgpqpUT
make populate-distributions RESOURCE_ID=b1g_PJxxfKgpqpUTElasticsearch blocks writes when the disk passes the flood-stage watermark (e.g. 95% full) so the node doesn’t fill the disk. Reindex will fail until there is more free space or the threshold is relaxed.
Options:
-
Free disk space (recommended): Remove unneeded data, clean Docker (
docker system prune -aif appropriate), or move the ES data volume to a disk with more space. The watermark is configured indocker-compose.ymlfor theelasticsearchservice (cluster.routing.allocation.disk.watermark.*). -
After freeing disk space, clear the read-only block so writes (e.g. reindex) work again:
make es-unblock
Then run
make reindexas needed. -
Relax watermarks for local dev only: In
docker-compose.yml, under theelasticsearchservice env, you can temporarily set e.g.cluster.routing.allocation.disk.watermark.flood_stage=99.9%(or disable withcluster.routing.allocation.disk.threshold_enabled=false). Only do this on a dev machine with enough free space; otherwise you risk filling the disk. -
Use a remote Elasticsearch with more space: Point the app at another ES (e.g. via
ELASTICSEARCH_URLand run reindex there).