diff --git a/.gitignore b/.gitignore index f6cc248..7b87565 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .env +**/.env +!**/.env.example +!**/example.env # Logs logs *.log diff --git a/README.md b/README.md index 231fe1c..67c7fde 100644 --- a/README.md +++ b/README.md @@ -150,15 +150,19 @@ The entire STAC Atlas system can be started with a single command: git clone https://github.com/your-org/stac-atlas.git cd stac-atlas -# Create environment files (see Environment Configuration section) -cp db/example.env db/.env -cp api/.env.example api/.env +# Create shared credentials once (injected into db, api, crawler) +cp example.env .env +# Edit .env — set passwords here only + +# Optional component settings (no DB passwords needed for full stack) cp crawler/.env.example crawler/.env +cp api/.env.example api/.env # Start all services -docker-compose up --build +docker compose up --build -d ``` + This starts: - **Database** on port 5432 - **API** on port 3000 @@ -378,47 +382,28 @@ When running with Docker Compose, all services communicate over the `stac_net` i ## Environment Configuration -Each component requires its own environment configuration. Template files are provided: +### Full stack (recommended) -### Database (.env) +Create **one** root `.env` from `example.env`. Passwords and DB name/user are injected into `db`, `api` and `crawler` by the root `docker-compose.yml` — you do not repeat them elsewhere. ```env -POSTGRES_DB=stac_db -POSTGRES_USER=postgres -POSTGRES_PASSWORD=your_secure_password +POSTGRES_DB=example +POSTGRES_USER=example +POSTGRES_PASSWORD=example DB_PORT=5432 -STAC_API_PASSWORD=api_password -STAC_CRAWLER_PASSWORD=crawler_password +STAC_API_PASSWORD=example +STAC_CRAWLER_PASSWORD=example ``` -### API (.env) +Optional component files (no shared secrets): -```env -PORT=3000 -NODE_ENV=production -DATABASE_URL=postgresql://stac_api:api_password@db:5432/stac_db -# Or individual variables: -# DB_HOST=localhost -# DB_PORT=5432 -# DB_NAME=stac_db -# DB_USER=stac_api -# DB_PASSWORD=api_password -``` +- `crawler/.env` — crawl settings only (`CRAWL_*`, `MAX_*`, …) +- `api/.env` — API settings only (CORS, pool, logging, …) +- `ui/.env` — `VITE_API_BASE_URL` -### Crawler (.env) +### Standalone components -```env -PGHOST=localhost -PGPORT=5432 -PGUSER=stac_crawler -PGPASSWORD=crawler_password -PGDATABASE=stac_db - -CRAWL_MODE=both -MAX_CATALOGS=0 -MAX_APIS=0 -CRAWL_DAYS_INTERVAL=7 -``` +When running a component alone, use that component’s example file (including DB connection settings). For the database alone: `db/example.env`. ### UI (.env) diff --git a/api/.env.example b/api/.env.example index 219f246..e83b7fb 100644 --- a/api/.env.example +++ b/api/.env.example @@ -1,19 +1,19 @@ -# Server Configuration +# Copy to api/.env: cp .env.example .env +# +# Full-stack deploy: DB credentials come from the root .env via docker-compose. +# You do NOT need to set DB_* / DATABASE_URL here for `docker compose up` from root. +# +# Standalone API only — uncomment and fill in: +# DB_HOST=example +# DB_PORT=5432 +# DB_NAME=example +# DB_USER=example +# DB_PASSWORD=example +# DATABASE_URL=postgresql://example:example@example:5432/example + PORT=3000 NODE_ENV=development - -# Database Configuration (Debian Server) -# Option 1: Use DATABASE_URL (PostgreSQL connection string) -# The api-user is stac_api (read-only) -DATABASE_URL=postgresql://stac_api:[PASSWORD]@atlas.stacindex.org:5430/stac_db - -# Option 2: Use individual variables (currently active) -DB_HOST=atlas.stacindex.org -DB_PORT=5430 # 5432 for production -DB_NAME=stac_db -DB_USER=stac_api -DB_PASSWORD= # Add stac_api password here (api_password) DB_SSL=false # Connection Pool Configuration @@ -21,29 +21,29 @@ DB_POOL_MAX=20 DB_POOL_MIN=2 DB_IDLE_TIMEOUT=30000 DB_CONNECTION_TIMEOUT=10000 - # CORS Configuration + CORS_ORIGIN=* +# Logging Configuration CORS_CREDENTIALS=false +# API Configuration -# Logging Configuration LOG_LEVEL=debug -# API Configuration -API_TITLE=STAC Atlas -API_DESCRIPTION=A centralized platform for managing, indexing, and providing STAC Collection metadata -API_VERSION=1.0.0 - # Request Size Limits # MAX_URL_LENGTH: Maximum URL length including query parameters (default: 1MB) # MAX_HEADER_SIZE: Maximum total size of all HTTP headers (default: 100KB) # MAX_BODY_SIZE: Maximum request body size for POST/PUT (default: 10MB) +# Rate Limiting Configuration +# Set to "true" to disable rate limiting (useful for load testing) +# WARNING: Never disable rate limiting in production! # Formats: "100KB", "1MB", "10MB", etc. +API_TITLE=STAC Atlas +API_DESCRIPTION=A centralized platform for managing, indexing, and providing STAC Collection metadata +API_VERSION=1.0.0 + MAX_URL_LENGTH=1MB MAX_HEADER_SIZE=100KB MAX_BODY_SIZE=10MB -# Rate Limiting Configuration -# Set to "true" to disable rate limiting (useful for load testing) -# WARNING: Never disable rate limiting in production! DISABLE_RATE_LIMIT=false diff --git a/api/docker-compose.yml b/api/docker-compose.yml index cc9b9bb..b2a93e8 100644 --- a/api/docker-compose.yml +++ b/api/docker-compose.yml @@ -8,6 +8,8 @@ services: volumes: - .:/app - /app/node_modules - env_file: .env + env_file: + - path: .env + required: false environment: - PORT=3000 diff --git a/crawler/.env.example b/crawler/.env.example index 917fa2f..83da2ff 100644 --- a/crawler/.env.example +++ b/crawler/.env.example @@ -1,16 +1,15 @@ -# STAC Crawler Configuration -# Copy this file to .env and adjust values as needed - -# URI of the Postgres/PostGis Host -PGHOST=example_db_URL -# Postgres/PostGis Port -PGPORT=5432 -# Postgres/PostGis user -PGUSER=example_user -# Postgres/PostGis password -PGPASSWORD=example_password -# Postgres/PostGis databse -PGDATABASE=example_db +# STAC Crawler — crawl settings only. +# Copy: cp .env.example .env +# +# Full-stack deploy: DB credentials come from the root .env via docker-compose. +# You do NOT need PG* here for `docker compose up` from root. +# +# Standalone crawler only — uncomment and fill in: +# PGHOST=example +# PGPORT=5432 +# PGUSER=example +# PGPASSWORD=example +# PGDATABASE=example # For single Crawler run: # 'catalogs', 'apis', or 'both' diff --git a/crawler/docker-compose.yml b/crawler/docker-compose.yml index f154ad5..3bce849 100644 --- a/crawler/docker-compose.yml +++ b/crawler/docker-compose.yml @@ -5,6 +5,9 @@ services: dockerfile: Dockerfile container_name: stac-crawler # restart: unless-stopped + env_file: + - path: .env + required: false environment: - NODE_ENV=production networks: @@ -12,4 +15,4 @@ services: networks: stac-network: - external: true + driver: bridge diff --git a/db/docker-compose.yml b/db/docker-compose.yml index 76599c7..6692b51 100644 --- a/db/docker-compose.yml +++ b/db/docker-compose.yml @@ -3,27 +3,19 @@ services: image: postgis/postgis:16-3.4 container_name: stac_db restart: always + # Values come from env_file (.env next to this file for standalone, + # or root .env when started via the root docker-compose.yml). env_file: - .env - - environment: - # Admin user (required for initial database setup) - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - # Application user passwords - STAC_API_PASSWORD: ${STAC_API_PASSWORD} - STAC_CRAWLER_PASSWORD: ${STAC_CRAWLER_PASSWORD} - ports: - - "${DB_PORT}:5432" - + - "${DB_PORT:-5432}:5432" volumes: - stac_data:/var/lib/postgresql/data - ./init:/docker-entrypoint-initdb.d networks: [stac-network] healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + # Use container env at runtime ($$), not compose-time interpolation. + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 5s timeout: 5s retries: 10 @@ -34,5 +26,4 @@ volumes: networks: stac-network: - name: stac-network driver: bridge diff --git a/db/example.env b/db/example.env index ad3b4b9..cb812a4 100644 --- a/db/example.env +++ b/db/example.env @@ -1,15 +1,14 @@ -# PostgreSQL Database Configuration -# Admin user with superuser privileges (required for initial setup) -POSTGRES_DB= # stac_db is the database we are running on -POSTGRES_USER= # add postgres_user here (admin user) -POSTGRES_PASSWORD= # add postgres_password here (admin password) +# Only needed when running the database alone: +# cd db && cp example.env .env && docker compose up -d +# +# Full-stack deploy uses the root example.env / .env instead +# (credentials are injected by the root docker-compose.yml). -# Database Port (host:container) -DB_PORT= # 5432 / 5433 (at the moment both are available) +POSTGRES_DB=example +POSTGRES_USER=example +POSTGRES_PASSWORD=example -# Application Users (created via init scripts) -# stac_api: read-only access for API -STAC_API_PASSWORD= # Password for api user (read-only); add api_password here +DB_PORT=5432 -# stac_crawler: full read-write access for crawler -STAC_CRAWLER_PASSWORD= # Password for crawler user (read-write); add crawler_password here +STAC_API_PASSWORD=example #read-only access for api +STAC_CRAWLER_PASSWORD=example #read-write access for crawler diff --git a/docker-compose.yml b/docker-compose.yml index c627670..c30769b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,11 @@ -# This docker-compose file orchestrates the startup of the entire STAC-Atlas project. -# It includes the docker-compose configurations from the individual components. +# Orchestrates the full STAC-Atlas stack. +# Single source for DB credentials: project-root .env (see example.env) +# cp example.env .env +# docker compose up --build -d networks: stac-network: - name: stac-network - external: true + driver: bridge volumes: stac_data: @@ -14,6 +15,15 @@ services: extends: file: db/docker-compose.yml service: database + # Use root .env only — no need to duplicate credentials in db/.env + env_file: + - .env + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + STAC_API_PASSWORD: ${STAC_API_PASSWORD} + STAC_CRAWLER_PASSWORD: ${STAC_CRAWLER_PASSWORD} networks: [stac-network] crawler: @@ -21,15 +31,34 @@ services: file: crawler/docker-compose.yml service: crawler networks: [stac-network] + # DB connection comes from root .env; crawler/.env is only crawl settings + environment: + NODE_ENV: production + PGHOST: stac_db + PGPORT: "5432" + PGUSER: stac_crawler + PGPASSWORD: ${STAC_CRAWLER_PASSWORD} + PGDATABASE: ${POSTGRES_DB} depends_on: db: condition: service_healthy + api: extends: file: api/docker-compose.yml service: api networks: [stac-network] + # DB connection comes from root .env; api/.env is only API settings + environment: + DB_HOST: stac_db + DB_PORT: "5432" + DB_NAME: ${POSTGRES_DB} + DB_USER: stac_api + DB_PASSWORD: ${STAC_API_PASSWORD} + DATABASE_URL: postgresql://stac_api:${STAC_API_PASSWORD}@stac_db:5432/${POSTGRES_DB} depends_on: + db: + condition: service_healthy crawler: condition: service_started @@ -40,4 +69,4 @@ services: networks: [stac-network] depends_on: api: - condition: service_started \ No newline at end of file + condition: service_started diff --git a/example.env b/example.env index aa98c66..775f504 100644 --- a/example.env +++ b/example.env @@ -1,14 +1,14 @@ # PostgreSQL Database Configuration # Admin user with superuser privileges (required for initial setup) -POSTGRES_DB= # stac_db is the database we are running on -POSTGRES_USER= # add postgres_user here (admin user) -POSTGRES_PASSWORD= # add postgres_password here (admin password) +POSTGRES_DB=example # stac_db is the database we are running on +POSTGRES_USER=example # add postgres_user here (admin user) +POSTGRES_PASSWORD=example # add postgres_password here (admin password) # Database Port (host:container) -DB_PORT= # 5432 +DB_PORT=5432 # 5432 # Application Users (created via init scripts) # stac_api: read-only access for API -STAC_API_PASSWORD= # Password for api user (read-only); add api_password here +STAC_API_PASSWORD=example # Password for api user (read-only); add api_password here # stac_crawler: full read-write access for crawler -STAC_CRAWLER_PASSWORD= # Password for crawler user (read-write); add crawler_password here \ No newline at end of file +STAC_CRAWLER_PASSWORD=example # Password for crawler user (read-write); add crawler_password here \ No newline at end of file diff --git a/ui/src/i18n/de.ts b/ui/src/i18n/de.ts index 953dc0d..4c12c47 100644 --- a/ui/src/i18n/de.ts +++ b/ui/src/i18n/de.ts @@ -142,6 +142,7 @@ export default { // Items loadingItems: 'Elemente werden von der Quelle geladen...', noItems: 'Keine Elemente verfügbar', + noItemsOnPage: 'Keine Elemente auf dieser Seite.', // Coordinates coordinateLabels: { diff --git a/ui/src/i18n/en.ts b/ui/src/i18n/en.ts index ab0d801..508de13 100644 --- a/ui/src/i18n/en.ts +++ b/ui/src/i18n/en.ts @@ -142,6 +142,7 @@ export default { // Items loadingItems: 'Loading items from source...', noItems: 'No items available', + noItemsOnPage: 'No items on this page.', // Coordinates coordinateLabels: {