Upgrade Guide
How to upgrade GeoLens between versions.
Standard Upgrade
Section titled “Standard Upgrade”For most upgrades (patch and minor versions):
# Pull latest codegit pull
# Rebuild and restart — migrations run automaticallydocker compose up -d --buildThe migrate service runs Alembic migrations before the API starts, so database schema changes are applied automatically.
Major Version Upgrades
Section titled “Major Version Upgrades”Major versions may include breaking changes. Always read the Changelog for the target version before upgrading.
Pre-upgrade checklist
Section titled “Pre-upgrade checklist”-
Back up your database before any major upgrade:
Terminal window docker compose exec db pg_dump -U geolens geolens > backup-$(date +%Y%m%d).sql -
Review the changelog for breaking changes, removed features, or required configuration changes.
-
Check
.env.examplefor new required environment variables. Compare with your current.env:Terminal window diff <(grep -v '^#' .env.example | grep -v '^$' | cut -d= -f1 | sort) \<(grep -v '^#' .env | grep -v '^$' | cut -d= -f1 | sort) -
Run the upgrade:
Terminal window git pulldocker compose downdocker compose up -d --build -
Verify all services are healthy:
Terminal window docker compose pscurl http://localhost:8080/health
Rollback
Section titled “Rollback”If an upgrade fails, restore from backup:
# Stop servicesdocker compose down
# Check out previous versiongit checkout v<previous-version>
# Restore databasedocker compose up -d dbdocker compose exec -T db psql -U geolens -d geolens < backup-YYYYMMDD.sql
# Restart all servicesdocker compose up -d --buildVersion-Specific Notes
Section titled “Version-Specific Notes”Unreleased — JWT_SECRET_KEY minimum length
Section titled “Unreleased — JWT_SECRET_KEY minimum length”The backend now enforces a 32-character minimum on JWT_SECRET_KEY at startup (HS256 requires ≥ 256 bits of entropy). A deployment with a shorter secret will fail fast on the next restart with:
FATAL: JWT_SECRET_KEY must be at least 32 characters. Generate one with: openssl rand -hex 32Before upgrading, verify your secret length:
echo -n "$JWT_SECRET_KEY" | wc -cIf it reports fewer than 32, generate a replacement and update your .env:
JWT_SECRET_KEY=$(openssl rand -hex 32)Rotating the key invalidates all issued JWT tokens — all users will be logged out and need to sign in again. Plan the rotation during a low-traffic window, or coordinate with your user base.
The fresh-install default in .env.example (dev-only-change-me-in-production, 32 chars) passes the validator unchanged, so new deployments are unaffected.
Other env hardening in this release:
- Secret fields (
POSTGRES_PASSWORD,JWT_SECRET_KEY,GEOLENS_ADMIN_PASSWORD,ANTHROPIC_API_KEY,OPENAI_API_KEY,S3_SECRET_ACCESS_KEY,TILE_SIGNING_SECRET) are now stored as PydanticSecretStrinternally. Values are masked in logs,repr(), and validation-error output. Application behavior is unchanged — this is a defense-in-depth improvement. LOG_LEVELvalues are now validated against the stdlib logging set (DEBUG,INFO,WARNING,ERROR,CRITICAL). A typo likeLOG_LEVEL=verbosenow fails at startup instead of crashing later.- Two previously undocumented env vars —
ENV_ONLY_CONFIGandGEOLENS_EDITION— are now documented in.env.example. Neither is required. - The
backend/.envsymlink has been removed. Host-side workflows (cd backend && uv run pytest) now resolve./.envat the project root via the Settingsenv_filepath. No action required unless you had local scripts depending onbackend/.envas a literal path. VITE_API_PROXY_TARGET(docker-compose.yml frontend service) was renamed toAPI_PROXY_TARGET. The old name still works for one release via a fallback invite.config.ts— update your local compose overrides when convenient.
Unreleased — Landing page removal
Section titled “Unreleased — Landing page removal”The landing page has been removed. The root route (/) now serves the Search page directly. The SHOW_LANDING_PAGE environment variable has been removed from backend config and the branding API.
What this means:
- Existing bookmarks to
/will show the Search page instead of the landing page. - The
/searchroute redirects to/— existing/searchbookmarks continue to work. - Remove
SHOW_LANDING_PAGEfrom your.envif present (it is ignored but produces no error).
About 1.0.0 (the public release)
Section titled “About 1.0.0 (the public release)”GeoLens 1.0.0 is the first public release. Prior to 1.0.0, the project was internally versioned as 2.0 → 13.0 during pre-public development. Those legacy versions never shipped to anyone outside the project.
If you somehow have a checkout from a pre-1.0.0 internal build:
- No data migration is required. The 1.0.0 schema is compatible with the most recent pre-public versions; Alembic migrations apply normally on the first 1.0.0 startup.
- The version number resets, but the codebase moves forward. 1.0.0 is the cumulative state of all prior internal work, not a downgrade.
- No
git checkout v13.xrollback path exists from 1.0.0. If you need to roll back, restore from the database backup you took before upgrading (see Pre-upgrade checklist). - No environment variables changed at the 1.0.0 boundary. Your existing
.envfrom any pre-public build continues to work without modification.
For all subsequent upgrades, follow the standard procedure above.
v12.x → v13.0
Section titled “v12.x → v13.0”- Security hardening: CORS configuration tightened. If you use cross-origin API access, verify
CORS_ALLOWED_ORIGINSis set in your.env. - Docker images: Base images pinned to specific digests. Rebuild with
--buildflag.
v10.x → v11.0
Section titled “v10.x → v11.0”- Performance optimizations: New database indexes added via migration. The migration may take a few minutes on large datasets.
v9.x → v10.0
Section titled “v9.x → v10.0”- Raster support: New
titilerservice added todocker-compose.yml. Ensure your deployment includes this service for raster/COG tile rendering.