Files
weatherapi/docs/operations.md

6.6 KiB

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 for invocation details and docs/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:

go run ./cmd/weatherapi -config config.yml

For a local binary:

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:

docker run --rm -p 8080:8080 weatherapi

To provide an external config file:

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:

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:

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.

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.