From 19c9a9508137a50977b9e6ddc8f2e85e6d08fc18 Mon Sep 17 00:00:00 2001 From: Danielle9897 Date: Fri, 28 Aug 2026 13:18:15 +0300 Subject: [PATCH 1/2] RDoc-4093 Update article Networking & DNS --- quill/networking-and-dns.mdx | 70 ++++++++++-------------------------- 1 file changed, 19 insertions(+), 51 deletions(-) diff --git a/quill/networking-and-dns.mdx b/quill/networking-and-dns.mdx index 1b7b35d668..cba2eaf0d0 100644 --- a/quill/networking-and-dns.mdx +++ b/quill/networking-and-dns.mdx @@ -59,7 +59,7 @@ By default, all five resolve to the IP address provided during sign-up: | -------------------- | ---------------------------------------------------------------------------------------- | | `dashboard.` | The operator dashboard, dashboard API requests, and health checks. | | `api.` | Programmatic access to the Quill API and health checks, without the dashboard UI. | -| `public.` | Embedded chat pages and their chat requests. | +| `public.` | Embedded chat pages, widget assets, chat requests, and public channel webhooks. | | `db.` | Direct RavenDB access for applications authenticated with a client certificate. | | `a.` | RavenDB's advertised node URL, which RavenDB.Client may receive through topology discovery. | @@ -120,8 +120,8 @@ Because the records belong to a RavenDB-managed DNS zone: * You do not receive DNS-provider credentials or a DNS console for the instance. * Moving or restarting your Quill does not update the records automatically. -When a record must change, the update is requested through the RavenDB DNS service at `api.ravendb.net`. -The supported update command reads the license file from the activated setup package and uses it to authorize the request for the licensed domain. +When a record must change, run the supported `update-dns` command from the Docker host. +The command reads the licensed domain from the activated server certificate and uses the setup package's `license.json` file to authorize the request to the RavenDB DNS service at `api.ravendb.net`. The exact command and the records it updates are described in [Update the records](#update-the-records). @@ -226,55 +226,30 @@ If only the existing host's externally reachable IP address changes, no data-vol -{/* TODO before publication - See RavenDB-27372: -Do not publish either `docker exec quill update-dns --ip ...` -or the direct `/app/ravendb/rvn dns update ...` command -until the release image is finalized and the supported command is verified. - -The default release image currently has neither the wrapper nor an `rvn` version that supports `dns update`. -Dockerfile.source has them but is planned for removal. -The dashboard currently displays the wrapper command. -*/} - -Run the DNS update from the Docker host after your Quill is available at its new address. +Run the DNS update from the Docker host after the Quill container is running on the host with its new externally reachable address. The container must: * be running and activated; - * contain the activated setup package and its `license.json` file; + * contain the activated setup package, including its server certificate and `license.json` file; * have outbound HTTPS access to `api.ravendb.net`. -The DNS update uses the license file for authorization. -It does not use the Dashboard API key or an authenticated browser session. - ---- - -### Find the base domain - -If you do not know the instance's base domain, read `PublicServerUrl` from the activated setup package: - -```bash -docker exec quill jq -r '.PublicServerUrl' \ - /var/lib/quill/setup/A/settings.json -``` -
- -The value has the form `https://a.`. -Use only the `` portion in the DNS update command, without `https://`, `a.`, or a port number. +The command derives the base domain from the server certificate and uses the license file for authorization. +You do not need to supply the domain, the Dashboard API key, or an authenticated browser session. --- ### Update the five DNS records -Run the following command, replacing `` with the base domain and `` with the host's new address: +Run the following command, replacing `` with the host's new address: ```bash -docker exec quill /app/ravendb/rvn dns update \ - -l /var/lib/quill/setup/license.json \ - -d \ - -n =a,dashboard,db,public,api +docker exec quill update-dns --ip ```
+The command examples in this section use the container name `quill`, as defined in the supplied Docker Compose file. +If your container has a different name, replace `quill` with its actual name. + The command updates all five DNS records in one request: * `dashboard.` @@ -292,13 +267,10 @@ Callers may still receive the previous address from DNS caches, as explained in #### Assigning more than one address -To assign several addresses to each of the five DNS hostnames, list them before the `=` and separate them with commas: +To assign several addresses to each of the five DNS hostnames, separate them with commas in the value passed to `--ip`: ```bash -docker exec quill /app/ravendb/rvn dns update \ - -l /var/lib/quill/setup/license.json \ - -d \ - -n ,=a,dashboard,db,public,api +docker exec quill update-dns --ip , ```
@@ -362,10 +334,6 @@ Restarting an affected browser or application may clear its local cache, but it After allowing for propagation, confirm the current answers as described in [Verify the change](#verify-the-change). -{/* TTL verified against the live Quill DNS records on 2026-08-17. -Reverify if the DNS service configuration changes before publication. -*/} -
@@ -444,8 +412,8 @@ Use the point at which verification fails to identify the affected layer: | Symptom | Likely cause | Next check | | ------- | ------------ | ---------- | -| The DNS update command exits with an error | The new IP address is invalid, the activated setup package or license file is unavailable, outbound HTTPS failed, or the DNS service rejected the request | Read the returned error, verify the new IP address and setup files, confirm outbound access to `api.ravendb.net`, and verify all five DNS records before retrying | -| A hostname does not resolve | The hostname or base domain is incorrect, or the record was not provisioned | Compare the hostname with the `PublicServerUrl` in the activated setup package | +| The DNS update command exits with an error | The new IP address is invalid, the activated server certificate or license file is unavailable, outbound HTTPS failed, or the DNS service rejected the request | Read the returned error, verify the new IP address and the activated setup package, confirm outbound access to `api.ravendb.net`, and verify all five DNS records before retrying | +| A hostname does not resolve | The hostname or base domain is incorrect, the record was not provisioned, or a resolver cached an earlier "not found" response | Compare the hostname with the `PublicServerUrl` in the activated setup package. If the hostname was recently provisioned, wait for the cached response to expire, then resolve it again | | A hostname still resolves to the old address | The answer is cached or the update has not completed | Allow for the TTL, then resolve all five hostnames again | | The hostname resolves correctly, but the connection times out | External TCP port `443` is blocked or does not reach container port `443` | Check the firewall, cloud security rules, NAT or load-balancer forwarding, and Docker port mapping | | The hostname resolves correctly, but the connection is refused | The container is stopped or nothing is accepting the forwarded connection | Check the container state and Docker port mapping | @@ -553,8 +521,8 @@ For client-certificate requirements, see [Direct database access](security-and-a Routing, TLS termination, and authorization are handled by your Quill after the connection reaches the host on port `443`. -* If the host's externally reachable IP address changes, update all five DNS records. - The update uses the activated license file to authorize the request. +* If the host's externally reachable IP address changes, run `docker exec quill update-dns --ip `. + The command derives the domain from the activated server certificate and uses the activated license to authorize the update of all five DNS records. * Updating DNS does not move your Quill to another host. Preserve the `quill-data` volume and the required deployment environment values when moving it. @@ -562,4 +530,4 @@ For client-certificate requirements, see [Direct database access](security-and-a * The records have a TTL of 30 minutes. After an update, verify both DNS resolution and HTTPS connectivity. - \ No newline at end of file + From 821215ef9ee19bb032ea6eea1912ec0a655b6bc6 Mon Sep 17 00:00:00 2001 From: Danielle9897 Date: Fri, 28 Aug 2026 14:13:46 +0300 Subject: [PATCH 2/2] RDoc-4093 Update Quill DNS and container-name guidance --- quill/networking-and-dns.mdx | 40 ++++++++------- .../network-architecture.mdx | 22 ++++++--- .../operator-authentication.mdx | 49 +++++++------------ 3 files changed, 53 insertions(+), 58 deletions(-) diff --git a/quill/networking-and-dns.mdx b/quill/networking-and-dns.mdx index cba2eaf0d0..6ce4e989f8 100644 --- a/quill/networking-and-dns.mdx +++ b/quill/networking-and-dns.mdx @@ -201,7 +201,7 @@ The Quill domain and the URLs used by operators, chat users, and applications re | Wildcard server certificate | The certificate is issued for `*.`, not for a particular IP address. | | Activated setup package and license | Your Quill continues using the existing activated setup package and its license file. | | Dashboard API key | The key is independent of the host's IP address; supply the same `QUILL_API_KEY` value to a replacement container. | -| Quill configuration and data | Apps, agents, channels, conversations, RavenDB databases, and certificate registrations remain in the `quill-data` volume. | +| Quill configuration and data | Apps, agents, channels, conversations, RavenDB databases, and certificate registrations remain in the persistent Docker volume mounted at `/var/lib/quill`. | Repointing the DNS records therefore does not require a new domain, new URLs, a new wildcard certificate, or a different Dashboard API key. @@ -215,7 +215,7 @@ For information about preserving or replacing the Dashboard API key, see [Operat A DNS update does not copy your Quill's data or container configuration. -When moving your Quill to another host, transfer the `quill-data` volume and preserve the required deployment environment values, +When moving your Quill to another host, transfer the persistent Docker volume mounted at `/var/lib/quill` and preserve the required deployment environment values, including `QUILL_API_KEY` and `QUILL_LICENSE_KEY`, before directing traffic to the new host. If only the existing host's externally reachable IP address changes, no data-volume migration is required. @@ -240,15 +240,17 @@ You do not need to supply the domain, the Dashboard API key, or an authenticated ### Update the five DNS records +In the commands below, `` is the name specified by `docker run --name`. +By default, it matches your Quill name. + Run the following command, replacing `` with the host's new address: ```bash -docker exec quill update-dns --ip +docker exec update-dns --ip ```
-The command examples in this section use the container name `quill`, as defined in the supplied Docker Compose file. -If your container has a different name, replace `quill` with its actual name. +If the container uses the default name, the dashboard's **Settings > IP configuration** page generates this command with the container name filled in after you enter a new IPv4 address. The command updates all five DNS records in one request: @@ -270,7 +272,7 @@ Callers may still receive the previous address from DNS caches, as explained in To assign several addresses to each of the five DNS hostnames, separate them with commas in the value passed to `--ip`: ```bash -docker exec quill update-dns --ip , +docker exec update-dns --ip , ```
@@ -413,7 +415,7 @@ Use the point at which verification fails to identify the affected layer: | Symptom | Likely cause | Next check | | ------- | ------------ | ---------- | | The DNS update command exits with an error | The new IP address is invalid, the activated server certificate or license file is unavailable, outbound HTTPS failed, or the DNS service rejected the request | Read the returned error, verify the new IP address and the activated setup package, confirm outbound access to `api.ravendb.net`, and verify all five DNS records before retrying | -| A hostname does not resolve | The hostname or base domain is incorrect, the record was not provisioned, or a resolver cached an earlier "not found" response | Compare the hostname with the `PublicServerUrl` in the activated setup package. If the hostname was recently provisioned, wait for the cached response to expire, then resolve it again | +| A hostname does not resolve | The hostname or base domain is incorrect, the record was not provisioned, or a resolver cached an earlier "not found" response | Compare the hostname with the `PublicServerUrl` in the activated setup package. If the hostname was recently provisioned, wait up to 15 minutes for the cached response to expire, then resolve it again | | A hostname still resolves to the old address | The answer is cached or the update has not completed | Allow for the TTL, then resolve all five hostnames again | | The hostname resolves correctly, but the connection times out | External TCP port `443` is blocked or does not reach container port `443` | Check the firewall, cloud security rules, NAT or load-balancer forwarding, and Docker port mapping | | The hostname resolves correctly, but the connection is refused | The container is stopped or nothing is accepting the forwarded connection | Check the container state and Docker port mapping | @@ -426,22 +428,24 @@ Use the point at which verification fails to identify the affected layer: ### Check the container and published port +In the commands below, `` is the name specified by `docker run --name`. By default, it matches your Quill name. + Confirm that the container is running: ```bash -docker inspect quill --format "Status={{.State.Status}}" +docker inspect --format "Status={{.State.Status}}" ```
Confirm that the container's HTTPS port is published: ```bash -docker port quill 443/tcp +docker port 443/tcp ```
If the container is stopped, start it before continuing. -If port `443` is not published, review the Docker Compose configuration. +If port `443` is not published, review how the container was started and confirm that container port `443` is published to the host. --- @@ -450,7 +454,7 @@ If port `443` is not published, review the Docker Compose configuration. Bypass external DNS, the host firewall, and nginx by calling the Quill web application directly: ```bash -docker exec quill curl --fail --silent --show-error \ +docker exec curl --fail --silent --show-error \ http://127.0.0.1:5000/healthz ```
@@ -458,7 +462,7 @@ docker exec quill curl --fail --silent --show-error \ Then inspect the activation state: ```bash -docker exec quill curl --silent --show-error \ +docker exec curl --silent --show-error \ http://127.0.0.1:5000/api/bootstrap/status ```
@@ -474,7 +478,7 @@ If the internal health check also fails, investigate the Quill web application a Read the most recent Quill web application messages: ```bash -docker exec quill tail -n 100 \ +docker exec tail -n 100 \ /var/lib/quill/logs/web.log ```
@@ -482,7 +486,7 @@ docker exec quill tail -n 100 \ For nginx routing or TLS-termination failures, read: ```bash -docker exec quill tail -n 100 \ +docker exec tail -n 100 \ /var/lib/quill/logs/proxy.log ```
@@ -490,7 +494,7 @@ docker exec quill tail -n 100 \ For RavenDB startup or direct database failures, read: ```bash -docker exec quill tail -n 100 \ +docker exec tail -n 100 \ /var/lib/quill/logs/ravendb.log ```
@@ -498,7 +502,7 @@ docker exec quill tail -n 100 \ For wildcard-certificate renewal failures, read: ```bash -docker exec quill tail -n 100 \ +docker exec tail -n 100 \ /var/lib/quill/logs/certwatch.log ```
@@ -521,11 +525,11 @@ For client-certificate requirements, see [Direct database access](security-and-a Routing, TLS termination, and authorization are handled by your Quill after the connection reaches the host on port `443`. -* If the host's externally reachable IP address changes, run `docker exec quill update-dns --ip `. +* If the host's externally reachable IP address changes, run `docker exec update-dns --ip `. The command derives the domain from the activated server certificate and uses the activated license to authorize the update of all five DNS records. * Updating DNS does not move your Quill to another host. - Preserve the `quill-data` volume and the required deployment environment values when moving it. + Preserve the persistent Docker volume mounted at `/var/lib/quill` and the required deployment environment values when moving it. * The records have a TTL of 30 minutes. After an update, verify both DNS resolution and HTTPS connectivity. diff --git a/quill/security-and-architecture/network-architecture.mdx b/quill/security-and-architecture/network-architecture.mdx index 5c9fd1e3c9..682e6c2c3a 100644 --- a/quill/security-and-architecture/network-architecture.mdx +++ b/quill/security-and-architecture/network-architecture.mdx @@ -45,7 +45,7 @@ Its three main components are RavenDB, the Quill web application, and nginx. Acts as Quill's reverse proxy and external TLS entry point. It listens on port `443` and uses the requested hostname to route each connection to either the Quill web application or RavenDB. -In the default Docker Compose configuration, only port `443` is published to the host. +The default Quill deployment publishes only port `443` to the host. The internal ports used by the Quill web application and RavenDB are not published, so external connections can only enter through nginx. @@ -247,7 +247,7 @@ You can generate client certificates from the dashboard's Certificates page and #### Publish only port 443 -* The default `docker-compose.yml` publishes only the nginx entry point on port `443`. +* The default Quill deployment publishes only the nginx entry point on port `443`. * RavenDB does not start until the setup package is available. It then starts in secured mode and listens only on the container's loopback interface, at `127.0.0.1:8443`. @@ -258,8 +258,11 @@ You can generate client certificates from the dashboard's Certificates page and * For diagnostics, run commands inside the container instead of publishing an internal port: + In this command, `` is the name specified by `docker run --name`. + By default, it matches your Quill name. + ```bash - docker exec quill curl -s http://127.0.0.1:5000/api/bootstrap/status + docker exec curl -s http://127.0.0.1:5000/api/bootstrap/status ``` @@ -292,9 +295,12 @@ Successful nginx certificate reloads are recorded in `/var/lib/quill/logs/certwa Inspect these logs from the host: +In the commands below, `` is the name specified by `docker run --name`. +By default, it matches your Quill name. + ```bash -docker exec quill tail -n 100 /var/lib/quill/logs/ravendb.log -docker exec quill tail -n 100 /var/lib/quill/logs/certwatch.log +docker exec tail -n 100 /var/lib/quill/logs/ravendb.log +docker exec tail -n 100 /var/lib/quill/logs/certwatch.log ```
@@ -308,7 +314,7 @@ docker exec quill tail -n 100 /var/lib/quill/logs/certwatch.log * This is expected. Check the activation status from inside the container: ```bash - docker exec quill curl -s http://127.0.0.1:5000/api/bootstrap/status + docker exec curl -s http://127.0.0.1:5000/api/bootstrap/status ``` * Once activation reports `Ready`, connect through port `443` normally. @@ -336,7 +342,7 @@ nginx forwards the encrypted TLS connection unchanged. RavenDB then: * The generated RavenDB settings bind the native TCP listener to `tcp://127.0.0.1:38888`, so it is reachable only from inside the container. - RavenDB advertises this listener as `tcp://a.:38888`, but the default Docker Compose configuration publishes only port `443`, + RavenDB advertises this listener as `tcp://a.:38888`, but the default Quill deployment publishes only port `443`, and nginx does not route port `38888`. * Direct access through `db.` therefore uses RavenDB's HTTPS API on port `443`. @@ -374,7 +380,7 @@ Applications that require direct access must use their own client certificate wi -* The default Docker Compose configuration publishes one port, `443`, with nginx as the external entry point. +* The default Quill deployment publishes one port, `443`, with nginx as the external entry point. * Four customer-facing hostnames expose the dashboard, API, public chat, and direct RavenDB surfaces. The additional `a.` hostname is RavenDB's advertised node alias. * The public hostname exposes only embed-link chat routes, which require an active embed-link token. diff --git a/quill/security-and-architecture/operator-authentication.mdx b/quill/security-and-architecture/operator-authentication.mdx index 44b15e43d2..9d7119ad13 100644 --- a/quill/security-and-architecture/operator-authentication.mdx +++ b/quill/security-and-architecture/operator-authentication.mdx @@ -31,19 +31,18 @@ import ContentFrame from '@site/src/components/ContentFrame'; Quill reads its Dashboard API key from the `QUILL_API_KEY` environment variable when the container starts. -In the default Docker Compose configuration, you supply it in the `.env` file next to `docker-compose.yml`. +You supply it through the `-e QUILL_API_KEY=...` option in the `docker run` command. -The key is required: +The key is required for protected operational access: -* The default Docker Compose configuration prevents the container from starting when `QUILL_API_KEY` is missing. -* If Quill is started another way without the key, it rejects all requests to protected operational API endpoints. +* If Quill starts without the key, it rejects all requests to protected operational API endpoints. It does not allow anonymous access or use a default key. * When the key is configured, it can be used to create a browser session or authenticate an API request directly. For validation, Quill stores a salted SHA-256 hash in its configuration database and compares hashes using a constant-time operation. Quill does not expose the original key through its dashboard or API. -The original value remains in your deployment configuration, such as the `.env` file and the container environment. +The original value remains in your deployment configuration or secret store and in the container environment. Protect access to that configuration as you would any other secret. @@ -63,7 +62,7 @@ Using the License key instead results in `401 Unauthorized`. If you replace the signup-issued Dashboard API key with a value of your own, use a high-entropy value. -Quill logs a startup warning when `QUILL_API_KEY` is shorter than 16 characters. +Quill logs a warning the first time it validates a Dashboard API key if `QUILL_API_KEY` is shorter than 16 characters. @@ -158,8 +157,7 @@ By default, you configure each of those Quill instances with the signup-issued k Quill cannot derive the original Dashboard API key from the salted hash in its configuration database, and it does not expose the key through its dashboard or API. -First, check the deployment configuration from which `QUILL_API_KEY` was supplied, -such as the `.env` file or your secret store. +First, check the deployment configuration or secret store from which `QUILL_API_KEY` was supplied. If the Quill instance still uses the signup-issued key, you can also recover it in either of these ways: @@ -184,34 +182,22 @@ and recreate the container. -### Docker Compose - -Edit `QUILL_API_KEY` in the `.env` file next to `docker-compose.yml`, then run: - -```bash -docker compose up -d -``` -
- -Compose detects the changed environment and recreates the container with the new key. - -
- - - ### docker run +In these commands, `` is the name specified after `--name` in your original `docker run` command. +By default, it matches your Quill name. `` is the volume name specified before `:/var/lib/quill` in that command. + Remove the existing container, then rerun it with the new key and the same data volume: ```bash -docker rm -f quill +docker rm -f -docker run -d --name quill \ +docker run -d --name \ --restart unless-stopped \ -p 443:443 \ -e QUILL_LICENSE_KEY="YOUR_EXISTING_LICENSE_KEY" \ -e QUILL_API_KEY="YOUR_NEW_DASHBOARD_API_KEY" \ - -v quill-data:/var/lib/quill \ + -v :/var/lib/quill \ ravendb/quill:latest ```
@@ -226,7 +212,7 @@ preserve those values when recreating the container. #### Recreate the container; do not restart it Quill reads `QUILL_API_KEY` from the container environment when it starts. -Restarting the existing container reuses the same environment, so `docker restart quill` +Restarting the existing container reuses the same environment, so `docker restart ` keeps the exposed key in force. A browser session is not re-checked against the Dashboard API key after login. @@ -234,14 +220,14 @@ Restarting the existing container therefore also leaves previously issued sessio until they expire after eight hours of inactivity. With the default container layout, the cookie-protection keys are stored in the container’s writable layer, -outside the quill-data volume. Recreating the container discards those keys and invalidates previously issued sessions. +outside the persistent volume mounted at `/var/lib/quill`. Recreating the container discards those keys and invalidates previously issued sessions. -Recreating the container preserves the Quill data stored in the `quill-data` volume, +Recreating the container preserves the Quill data stored in the persistent volume mounted at `/var/lib/quill`, including its databases, activated setup package, and configured apps. -Do not delete that volume or run `docker compose down -v`; those operations remove the persisted Quill data. +Do not delete that volume; doing so removes the persisted Quill data. Which Quill instances must be updated depends on which key was exposed: @@ -295,8 +281,7 @@ and recreate those containers. * The Dashboard API key is required for Quill's operational API. - The default Docker Compose configuration prevents startup without it. - If Quill is started another way without the key, all requests to protected operational API endpoints are rejected. + If Quill starts without the key, all requests to protected operational API endpoints are rejected. * Quill stores a salted hash in its configuration database and does not expose the original key through its dashboard or API. Keep the original value in your deployment secret store.