milestone 20: declarative configuration for iac
This commit is contained in:
@@ -10,16 +10,29 @@ supported and is the last section of this page.
|
||||
For what each configuration field means, see
|
||||
[the configuration reference](../reference/configuration.md).
|
||||
|
||||
> Verification: the seed-file failure modes, the run and the two checks in
|
||||
> step 3 were run on the machine that wrote this page, against an image built
|
||||
> from this checkout rather than pulled from the registry — no release is
|
||||
> Verification: the failure modes, the run and the two checks in step 3 were run
|
||||
> on the machine that wrote an earlier revision of this page, against an image
|
||||
> built from this checkout rather than pulled from the registry — no release is
|
||||
> published yet, so nothing on this page could be run against a pulled image,
|
||||
> and step 1 could not be run at all. One command was run in altered form:
|
||||
> host port 8080 was occupied here, so the run and the verification commands
|
||||
> in step 3 were executed with the host side of the port mappings moved to
|
||||
> 25353 and 28088 rather than the 53 and 8080 printed below. The container
|
||||
> side was unchanged. See the note in step 3. The `chown` to uid 65532 needs
|
||||
> root and was not run.
|
||||
> and step 1 could not be run at all. One command was run in altered form: host
|
||||
> port 8080 was occupied there, so the run and the verification commands in
|
||||
> step 3 were executed with the host side of the port mappings moved to 25353
|
||||
> and 28088 rather than the 53 and 8080 printed below. The container side was
|
||||
> unchanged. See the note in step 3. The `chown` to uid 65532 needs root and was
|
||||
> not run.
|
||||
>
|
||||
> **Not re-run for the file-mode revision.** The compose file now ships
|
||||
> `command: ["run", "--config=/etc/nxdns/config.zon"]`, and no container was
|
||||
> started against that command on this host: staging a release image needs
|
||||
> `zig build dist`, which refuses to run while `web/dist` is stale, and the web
|
||||
> bundle was being rebuilt by other work in the same tree at the time. What was
|
||||
> checked instead is `docker compose -f deploy/docker/compose.yaml config`,
|
||||
> which resolves the file without contacting a registry and prints the `command`
|
||||
> and the `:ro` bind mount as written, and the same
|
||||
> `run --config=<file>` invocation driven directly against the locally built
|
||||
> binary: it printed the reconcile summary, `authority: file (<path>)`, and
|
||||
> `no changes` on the second start. The log lines quoted in step 3 come from
|
||||
> that run, with the paths and ports the container uses.
|
||||
|
||||
## 1. Pull and verify the image
|
||||
|
||||
@@ -65,7 +78,7 @@ does and does not prove.
|
||||
> `docker buildx imagetools inspect --format` shape was run here against
|
||||
> `alpine:3.22` on Docker Hub and printed that image's index digest.
|
||||
|
||||
## 2. Get the compose file and write the seed configuration
|
||||
## 2. Get the compose file and write the configuration
|
||||
|
||||
Every path on this page is relative to a checkout of the repository, because
|
||||
that is how it was verified. Running the published image needs no checkout,
|
||||
@@ -82,7 +95,7 @@ curl -fLO "$BASE/raw/tag/v$VERSION/deploy/docker/compose.yaml"
|
||||
> Gitea `1.27.0+dev` and returned the file with a 200.
|
||||
|
||||
Compose bind-mounts `deploy/docker/etc-nxdns` read-only at `/etc/nxdns`. Create
|
||||
it and put the seed file in it:
|
||||
it and put the configuration in it:
|
||||
|
||||
```sh
|
||||
mkdir -p deploy/docker/etc-nxdns
|
||||
@@ -100,15 +113,25 @@ upstream:
|
||||
}
|
||||
```
|
||||
|
||||
Without that file the container exits with code 2 on a fresh volume: an empty
|
||||
database has nothing to forward to. The log is
|
||||
`no configuration file at '/etc/nxdns/config.zon'; using the database as it is`
|
||||
followed by `nxdns run failed: NoUsableUpstreams`.
|
||||
**The compose file ships file mode**, with
|
||||
`command: ["run", "--config=/etc/nxdns/config.zon"]`. That file is the
|
||||
configuration: the container reconciles its database onto it at every start, and
|
||||
the admin interface answers 403 to configuration edits. To change anything, edit
|
||||
the file and restart the container. It also means a fresh or recreated
|
||||
`nxdns-data` volume rebuilds itself from the mounted file with no extra step.
|
||||
|
||||
The file is therefore required, and its absence is a hard failure rather than a
|
||||
start with defaults:
|
||||
|
||||
```
|
||||
FAIL /etc/nxdns/config.zon: no such file
|
||||
nxdns run failed: ManagedConfigUnreadable
|
||||
run `nxdns check` to see the configuration in full
|
||||
```
|
||||
|
||||
A file that is present but rejected is a different failure with the same exit
|
||||
code. No `default` group, no enabled upstream, a syntax error — `run` prints the
|
||||
diagnostic and exits 2 as well. Both were run here against a locally built
|
||||
image. A seed file whose only group was named `other`:
|
||||
diagnostic and exits 2 as well. A file whose only group was named `other`:
|
||||
|
||||
```
|
||||
FAIL groups: no group named 'default'; every unknown client is assigned to it
|
||||
@@ -116,18 +139,31 @@ nxdns run failed: MissingDefaultGroup
|
||||
run `nxdns check` to see the configuration in full
|
||||
```
|
||||
|
||||
and an empty `/etc/nxdns`:
|
||||
Under `restart: unless-stopped` any of these is a restart loop — Docker has no
|
||||
start limit and will retry forever. Read the lines above the failure, which name
|
||||
the fault. See [Troubleshoot nxdns](troubleshoot.md).
|
||||
|
||||
```
|
||||
info(config_bootstrap): no configuration file at '/etc/nxdns/config.zon'; using the database as it is
|
||||
nxdns run failed: NoUsableUpstreams
|
||||
run `nxdns check` to see the configuration in full
|
||||
### Database mode in Docker instead
|
||||
|
||||
Drop the `command:` line from `compose.yaml` and the container runs
|
||||
`nxdns run`, with the database as the configuration and the file read by nothing.
|
||||
On a fresh volume that database is empty and the container exits 2 with
|
||||
`NoUsableUpstreams`, so load it once before bringing the service up:
|
||||
|
||||
```sh
|
||||
docker compose -f deploy/docker/compose.yaml run --rm nxdns import /etc/nxdns/config.zon
|
||||
```
|
||||
|
||||
Under `restart: unless-stopped` either one is a restart loop, and the exit code
|
||||
alone no longer tells them apart: read the lines above the failure, which either
|
||||
name the diagnostic in the file or say there was no file at all. See
|
||||
[Troubleshoot nxdns](troubleshoot.md).
|
||||
The file is positional; add `--allow-delete` when re-running it against a
|
||||
populated volume and the diff deletes rows. Without this step, `restart:
|
||||
unless-stopped` plus exit 2 is a crash loop with no way out.
|
||||
|
||||
> Not run in a container on this host, for the reason in the verification note
|
||||
> at the top: no image could be staged here. The `nxdns import <file>` and
|
||||
> `nxdns import <file> --allow-delete` commands inside it were run directly
|
||||
> against the locally built binary — the first applied an additive file and
|
||||
> exited 0, the second was required after a plain `import` refused a
|
||||
> row-deleting file with `DestructiveImport` and exited 2.
|
||||
|
||||
The container runs as uid 65532, and the mount is read-only, so the container
|
||||
cannot repair permissions itself. Mode 0644 works and was used here. If the
|
||||
@@ -140,9 +176,12 @@ chmod 0600 deploy/docker/etc-nxdns/config.zon
|
||||
```
|
||||
|
||||
> Not verified on this host: `chown` to a uid you do not own needs root. What
|
||||
> was verified is the failure it prevents — a seed file at 0600 owned by
|
||||
> another uid makes the container log `nxdns run failed: AccessDenied` and
|
||||
> restart in a loop. See [Troubleshoot nxdns](troubleshoot.md).
|
||||
> was verified is the failure it prevents — a configuration file at 0600 owned
|
||||
> by another uid makes the container refuse to start and restart in a loop. In
|
||||
> file mode an unreadable file is a configuration fault:
|
||||
> `FAIL /etc/nxdns/config.zon: not readable` followed by
|
||||
> `nxdns run failed: ManagedConfigUnreadable`, exit 2. See
|
||||
> [Troubleshoot nxdns](troubleshoot.md).
|
||||
|
||||
## 3. Run it
|
||||
|
||||
@@ -169,14 +208,21 @@ bind mount — against the directory holding the file, not against your shell,
|
||||
and it takes the project name `docker` from that directory either way, which is
|
||||
why the container is `docker-nxdns-1`.
|
||||
|
||||
A healthy first start logs the seeding and the bound sockets:
|
||||
A healthy first start logs the reconcile, the authority and the bound sockets:
|
||||
|
||||
```
|
||||
info(config_bootstrap): seeded the database from '/etc/nxdns/config.zon'
|
||||
info(migrations): config.db migrated from schema version 0 to 2
|
||||
reconciled '/etc/nxdns/config.zon': upstreams +1 ~0 -0; settings +45 ~0 -0;
|
||||
settings keys changed: dns.bind_ipv4 dns.bind_ipv6 dns.port web.bind web.port …
|
||||
web authentication is now enabled
|
||||
info(nxdns): authority: file (/etc/nxdns/config.zon)
|
||||
info(nxdns): nxdns <version> serving on udp [::]:53 tcp [::]:53 tcp 0.0.0.0:53; 1 upstream(s); blocklist generation 1
|
||||
info(web_server): web interface listening on 0.0.0.0:8080
|
||||
```
|
||||
|
||||
Every later start on an unchanged file reports `reconciled
|
||||
'/etc/nxdns/config.zon': no changes` and writes nothing to the database.
|
||||
|
||||
Confirm it answers and that the admin interface is up:
|
||||
|
||||
```sh
|
||||
|
||||
Reference in New Issue
Block a user