{"id":50998203,"url":"https://github.com/eclipse-iofog/nats-server","last_synced_at":"2026-06-20T11:32:36.421Z","repository":{"id":365076230,"uuid":"1212065899","full_name":"eclipse-iofog/nats-server","owner":"eclipse-iofog","description":"NATS Server for Eclipse ioFog","archived":false,"fork":false,"pushed_at":"2026-06-15T18:23:52.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-06-15T20:13:11.488Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eclipse-iofog.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-16T03:01:09.000Z","updated_at":"2026-06-15T18:24:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/eclipse-iofog/nats-server","commit_stats":null,"previous_names":["eclipse-iofog/nats-server"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/eclipse-iofog/nats-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-iofog%2Fnats-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-iofog%2Fnats-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-iofog%2Fnats-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-iofog%2Fnats-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eclipse-iofog","download_url":"https://codeload.github.com/eclipse-iofog/nats-server/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-iofog%2Fnats-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34568741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T11:32:34.683Z","updated_at":"2026-06-20T11:32:36.404Z","avatar_url":"https://github.com/eclipse-iofog.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NATS Server for Eclipse ioFog\n\n[![CI](https://github.com/eclipse-iofog/nats-server/actions/workflows/ci.yml/badge.svg)](https://github.com/eclipse-iofog/nats-server/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/github/v/release/eclipse-iofog/nats-server?include_prereleases)](https://github.com/eclipse-iofog/nats-server/releases)\n[![Go](https://img.shields.io/badge/Go-1.26.4-blue.svg)](https://go.dev/)\n[![License](https://img.shields.io/badge/License-EPL--2.0-blue.svg)](LICENSE)\n[![govulncheck](https://github.com/eclipse-iofog/nats-server/actions/workflows/govulncheck.yml/badge.svg)](https://github.com/eclipse-iofog/nats-server/actions/workflows/govulncheck.yml)\n\n**Upstream:** [eclipse-iofog/nats-server](https://github.com/eclipse-iofog/nats-server) · **Datasance distribution:** [Datasance/nats-server](https://github.com/Datasance/nats-server)\n\nNATS server image for use on **Eclipse ioFog**  and **Datasance PoT** (Kubernetes or edge with Edgelet). Config, account config, and TLS certs are provided via **volume mounts**; the wrapper starts [nats-server](https://github.com/nats-io/nats-server) v2.14.2 and watches for file changes, triggering reload (SIGHUP) or restart (leaf mode, non-TLS changes) as appropriate.\n\nBoth **Kubernetes** (ioFog-controller mounting ConfigMaps/Secrets) and **Edgelet** (Edgelet binding config) use the same contract: mount the server config, account config, and TLS directory at the paths below (or override with env vars).\n\n## Environment variables\n\n| Variable            | Default                   | Description                                                                 |\n| ------------------- | ------------------------- | --------------------------------------------------------------------------- |\n| `NATS_CONF`         | `/etc/nats/config/server.conf`   | Server config file path (passed to nats-server as `-c`).                    |\n| `NATS_ACCOUNTS`     | `/etc/nats/config/accounts.conf` | Account config file; watched for changes and triggers reload.               |\n| `NATS_TLS_DIR`      | `/etc/nats/certs`           | Directory for TLS material; watched for changes and triggers reload.        |\n| `NATS_SSL_DIR`      | (deprecated fallback)     | Deprecated; used only when `NATS_TLS_DIR` is unset.                         |\n| `NATS_JWT_DIR`      | `/home/runner/nats/jwt`     | Writable directory for JWT assets used by nats-server resolver (server config must point here). Synced from `NATS_JWT_MOUNT_DIR` at startup and on change. |\n| `NATS_JWT_MOUNT_DIR`| `/tmp/nats/jwt`             | Read-only mount (e.g. K8s/ioFog) where account JWTs are placed. Watched for changes; contents are synced into `NATS_JWT_DIR` (copy and remove orphans) before reload. |\n| `NATS_SERVER_MODE`  | `server`                   | `server` (full reload on any change; reconcile + claims push on JWT) or `leaf` (SIGHUP only on TLS cert change; SIGINT+restart for other changes; reconcile + claims push on JWT; full resolver). |\n| `NATS_CREDS_DIR`    | `/etc/nats/creds/`          | Directory for creds files; watched for changes and triggers reload.         |\n| `NATS_SERVER_BIN`   | `/home/runner/bin/nats-server` | Path to the nats-server binary (override for local dev, e.g. `nats-server`). |\n| `NATS_MONITOR_PORT` | `8222`                    | HTTP monitoring port (nats-server `-m`). Set to `0` to disable.             |\n| `NATS_SYS_USER_CRED_PATH` | (none)              | Path to system account user credentials file. If not absolute, resolved relative to `NATS_CREDS_DIR`. When set, the wrapper calls the JetStream Account Purge API for accounts removed from the resolver (see below). |\n| `NATS_CLIENT_URL`   | `nats://127.0.0.1:4222` | URL used by the wrapper to connect to NATS for the JetStream purge API.   |\n| `NATS_JETSTREAM_STORE_DIR` | (none)            | JetStream store directory (same as `jetstream.store_dir` in server config). If unset, the wrapper tries to parse it from the server config file. |\n\nThe server config file may use **environment variable placeholders** (e.g. `$SERVER_NAME`, `$HUB_NAME`). NATS resolves these from the process environment; the wrapper preserves the container environment when starting nats-server so K8s/ioFog-injected vars are available.\n\n## Volume mounts\n\n- **Server config**: Mount the NATS server config file at `NATS_CONF`. It may `include` the account file and reference cert paths under `NATS_TLS_DIR`.\n- **Account config**: Mount at `NATS_ACCOUNTS` (or include it from the server config via a relative path).\n- **TLS certs**: Mount TLS material (e.g. `ca.crt`, `tls.crt`, `tls.key`) under `NATS_TLS_DIR` (or subdirs). Paths in the server config should match the mount location.\n\n## Reload behaviour\n\nThe wrapper watches `NATS_CONF`, `NATS_ACCOUNTS` (if present), `NATS_TLS_DIR`, `NATS_JWT_MOUNT_DIR` (if present), and `NATS_CREDS_DIR` (directory watchers start only if paths exist). Before starting nats-server, and on each change to `NATS_JWT_MOUNT_DIR`, it syncs `*.jwt` files from the mount dir into `NATS_JWT_DIR` (copy and remove orphans so the JWT dir exactly mirrors the mount). It sends **SIGHUP** when appropriate: **server** mode on any change; **leaf** mode only when `NATS_TLS_DIR` (TLS certs) changes. In **leaf** mode, config, accounts, or creds changes trigger **SIGINT** stop and restart so new settings load. When the cause is JWT, after reload the wrapper runs JetStream account reconciliation and pushes account JWTs via `$SYS.REQ.CLAIMS.UPDATE` for both server and leaf (leaf uses full resolver).\n\n## JetStream account purge (reconcile on account removal)\n\nWhen an account is removed from the JWT resolver directory, NATS no longer accepts that account but JetStream may still hold its data. The wrapper reconciles accounts that have JetStream data on disk (subdirectories under the JetStream store directory) with the current resolver accounts (`NATS_JWT_DIR`). Any account that has a JetStream directory but is no longer in the resolver is purged via the JetStream Account Purge API (`$JS.API.ACCOUNT.PURGE.{account}`) using system account credentials. This runs once after startup (after a short delay) and again after each JWT directory change (after reload). No snapshot file is used; behaviour is consistent across reboots. Set `NATS_SYS_USER_CRED_PATH` (and optionally `NATS_JETSTREAM_STORE_DIR` or rely on parsing from server config) to enable purge; if unset, reconciliation still runs but purge API calls are skipped.\n\n## Container image\n\n| Platform | Dockerfile | Base | Registry example |\n|----------|------------|------|------------------|\n| linux/amd64, linux/arm64 | `Dockerfile` | UBI 9 micro (Red Hat certified) | `ghcr.io/datasance/nats:2.14.2` |\n| linux/arm/v7, linux/riscv64 | `Dockerfile.edge` | Alpine 3.22 | same manifest tag |\n\n- **User**: non-root `runner` (uid 10000).\n- **Production binaries**: `iofog-nats` (entrypoint), `nats-server` v2.14.2, **`curl`**, and **`grep`** for in-container healthchecks. **No nats-cli** in published images.\n- **Healthcheck**: UBI has no shell — use exec form, e.g. `[\"CMD\", \"/usr/bin/curl\", \"-f\", \"http://127.0.0.1:8222/healthz\"]`. Edge images include `/bin/sh` for `CMD-SHELL` (e.g. `curl … | grep -q`).\n- **Release tags** (on `v*` git tag only): `:semver` (e.g. `:2.14.2`), `:latest`, and `:main` (same digest).\n\nUse **`Dockerfile.dev`** locally when you need nats-cli for debugging; it is not published to GHCR.\n\n## CI\n\n| Workflow | Purpose |\n|----------|---------|\n| [`.github/workflows/ci.yml`](.github/workflows/ci.yml) | Lint, test, Docker runtime smoke per arch (`/healthz` via host and in-container `curl`) |\n| [`.github/workflows/govulncheck.yml`](.github/workflows/govulncheck.yml) | Weekly dependency vulnerability scan |\n| [`.github/workflows/release.yml`](.github/workflows/release.yml) | Multi-arch GHCR publish on `v*` tag push |\n\n## Build\n\n```bash\nmake build\n# or\ngo build -o bin/iofog-nats ./cmd/iofog-nats\n```\n\nOther targets: `make test`, `make lint`, `make clean`, `make docker-build` (image name via `IMAGE=...`).\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nSee [LICENSE](LICENSE) and [NOTICE](NOTICE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclipse-iofog%2Fnats-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feclipse-iofog%2Fnats-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclipse-iofog%2Fnats-server/lists"}