# weatherapi Operations `weatherapi` is a read-only HTTP service. It serves latest weather records from Postgres tables populated by `weatherfeeder`; it does not ingest provider data, create tables, or run database migrations. ## Runtime Model At startup, the executable: 1. resolves the config path from `-config`, `WEATHERAPI_CONFIG`, or `config.yml`; 2. loads feedapi YAML configuration; 3. opens all configured database handles; 4. selects the first configured database as the primary weather data store; 5. registers HTTP endpoints and text templates with feedapi; 6. starts the HTTP server. See [`docs/cli.md`](cli.md) for invocation details and [`docs/config.md`](config.md) for configuration fields. ## Prerequisites - A reachable PostgreSQL database. - Weatherfeeder-owned weather tables already created and populated. - A config file with at least one `databases` entry. - The `templates/` directory when `format=text` responses are needed. - Network access from the service process or container to Postgres. The first database entry in the config is the only database used for weather reads. Additional configured handles may be opened by feedapi, but `weatherapi` selects the first entry as primary. ## Local Run Use the checked-in local sample only when its database settings match your environment: ```sh go run ./cmd/weatherapi -config config.yml ``` For a local binary: ```sh go build -o ./weatherapi ./cmd/weatherapi ./weatherapi -config config.yml ``` Keep the process working directory aligned with `templates.base_dir`. With the checked-in config, run from the repository root so `templates` resolves to the repository's template directory. ## Container Run The Docker image copies these runtime files into `/weatherapi`: - `/weatherapi/weatherapi` - `/weatherapi/config.yml` - `/weatherapi/templates` The runtime working directory is `/weatherapi`, and the entrypoint is the `weatherapi` binary. To use the image's bundled config and templates: ```sh docker run --rm -p 8080:8080 weatherapi ``` To provide an external config file: ```sh docker run --rm -p 8080:8080 \ -v "$PWD/examples/config.production.yml:/weatherapi/config.yml:ro" \ weatherapi ``` To use a different config path, append the CLI flag: ```sh docker run --rm -p 8080:8080 \ -v "$PWD/config.yml:/config/weatherapi.yml:ro" \ weatherapi -config /config/weatherapi.yml ``` If you mount a custom template directory, make `templates.base_dir` point to the mounted path. The repository's Woodpecker image build uses Kaniko and passes private Gitea credentials as build arguments so Go can download private modules during the build. ## Database Dependency `weatherapi` expects weatherfeeder-compatible tables for observations, current conditions aggregation, active alerts, forecasts, forecast discussions, weather stories, and convective outlooks. It only reads those tables. Convective outlook endpoints require weatherfeeder's `weather.outlook.v2` table shape, including `outlook_runs`, `outlooks`, and `outlook_discussions`. If operators reset or recreate outlook tables during a weatherfeeder upgrade, complete that weatherfeeder-side migration before starting `weatherapi`. Operational ownership is split: - `weatherfeeder` owns provider polling, normalization, writes, table creation, and schema compatibility. - PostgreSQL owns durable storage, backups, replication, and restore. - `weatherapi` owns serving read-only HTTP responses from the configured primary database. When restoring from backup or replacing the database, verify that weatherfeeder has resumed writes before treating stale `weatherapi` responses as an API problem. ## Templates and Text Output JSON and XML responses do not depend on text templates. `format=text` uses the template named by each endpoint, with templates stored under `templates.base_dir`. The repository includes templates for all implemented endpoint families: observations, current conditions, active alerts, hourly forecasts, narrative forecasts, forecast discussions, weather stories, and convective outlooks. If text rendering fails or returns an unsupported-format error, verify: - the process can read `templates.base_dir`; - expected `*.txt.tmpl` files are present; - the requested endpoint supports `format=text`, which all implemented endpoints currently do. ## Startup and Shutdown Startup failures are fatal and are logged with the prefix `weatherapi failed`. Common failure contexts include: - `load config` - `config.databases requires at least one entry` - `open databases` - `select primary database` - `build app` The process handles `SIGINT` and `SIGTERM`. Feedapi performs graceful HTTP shutdown after the runtime context is canceled. Database close errors during shutdown are logged, but they occur after the service has already begun stopping. ## Verification There is no dedicated health endpoint in `weatherapi`. Use an implemented read endpoint as a practical service check: ```sh curl -i 'http://localhost:8080/observations?format=json' ``` Interpretation: - `200 OK` with `{"data": null}` means the service is running but no latest observation is available. - `200 OK` with a populated `data` object means the service and that read path are working. - `400 Bad Request` indicates request validation, not service health. - `406 Not Acceptable` indicates format negotiation. - `5xx` indicates a runtime, database, or handler failure. For a broader smoke check, use the requests in [`examples/requests.http`](../examples/requests.http). ## Logs The executable uses Go's standard logger with date, time, and microseconds. Startup and fatal runtime errors are written to standard error. Container platforms should collect stdout and stderr from the process. ## Backup and Recovery Boundaries Back up and restore PostgreSQL using normal database procedures. `weatherapi` has no local durable weather state to back up. After a database restore or failover: 1. confirm the configured database is reachable from the service; 2. confirm weatherfeeder-owned tables exist; 3. confirm weatherfeeder is writing fresh rows if current data is expected; 4. restart `weatherapi` if database connection settings changed; 5. verify with an implemented endpoint such as `/observations`. ## Related Docs - [`docs/api.md`](api.md): HTTP contract and error envelope - [`docs/config.md`](config.md): configuration reference - [`docs/troubleshooting.md`](troubleshooting.md): symptom-oriented fixes - [`docs/integrations/feedapi.md`](integrations/feedapi.md): runtime and rendering contracts - [`docs/integrations/weatherfeeder-postgres.md`](integrations/weatherfeeder-postgres.md): storage contract assumptions