Skip to content

Deployment and Operations

Thomas Maerz edited this page Oct 4, 2026 · 2 revisions

Deployment and Operations

Example deployment

Service Value
MCP http://mcp-host:8181/mcp
Liveness http://mcp-host:8181/healthz
Readiness http://mcp-host:8181/readyz
Metrics http://mcp-host:8181/metrics
Dagster UI http://dagster-host:3000
Code location slackquery
Schedule slackquery_hourly_reconciliation
PyTorch CUDA embeddings http://embedding-host:11435
Ollama transport http://ollama-host:11434

Example paths

Setting Default path
SLACKQUERY_CANONICAL_DB /path/to/slackpipe.duckdb
SLACKQUERY_STATE_DB /srv/slackquery/state/slackquery.duckdb
SLACKQUERY_ARTIFACT_DIR /srv/slackquery/artifacts
SLACKQUERY_CURRENT_LINK /srv/slackquery/artifacts/current.duckdb
SLACKQUERY_DUCKDB_EXTENSION_DIR /srv/slackquery/extensions
SLACKQUERY_ATTACHMENT_ROOT /srv/slackquery/attachments

The canonical database is always read-only to Slackquery. State, artifacts, and the extension cache are Slackquery-owned.

Manual lifecycle

Verify configuration and model

cp .env.example .env
uv sync --extra dev
uv run slackquery embedding-status

Project and embed

uv run slackquery project
uv run slackquery embed

Use --max-items to bound one embedding run:

uv run slackquery embed --max-items 1000

Projection and embedding mutate only Slackquery's state database. Embedding is checkpointed and resumable.

Build, validate, and publish

uv run slackquery build
uv run slackquery validate --checksum \
  /srv/slackquery/artifacts/search-<build-id>.duckdb
uv run slackquery publish \
  /srv/slackquery/artifacts/search-<build-id>.duckdb

Build fails unless every active projected document has a successful current- generation vector. Publication requires the candidate to reside in the configured artifact directory and repeats structural/checksum validation before atomically switching current.duckdb.

Run the MCP server

uv run slackquery run

Optional listen overrides:

uv run slackquery run --host 127.0.0.1 --port 8080

Compose deployment

docker compose up --build slackquery

The compose service:

  • publishes container port 8080 as host port 8181 by default;
  • defaults host binding to 127.0.0.1 unless SLACKQUERY_BIND_ADDRESS is set;
  • mounts canonical Slackpipe data read-only;
  • mounts state, artifacts, and extensions separately;
  • uses a read-only root filesystem and /tmp tmpfs;
  • drops all capabilities and enables no-new-privileges.

DuckDB FTS is preinstalled in /srv/slackquery/extensions. That directory must be writable during installation/build and mounted anywhere FTS is loaded. The read-only root filesystem makes the default home extension path unsuitable.

Health and readiness

curl -fsS http://mcp-host:8181/healthz
curl -fsS http://mcp-host:8181/readyz
  • /healthz reports process liveness and configured embedding backend/URL. It does not call the model server.
  • /readyz resolves and opens the current artifact read-only, then reads its metadata. It returns 503 when no usable artifact is published.

Because semantic and hybrid requests create a query vector, they can fail if the embedding backend becomes unavailable even while readiness remains healthy.

Authentication and exposure

Set SLACKQUERY_BEARER_TOKEN to require Authorization: Bearer ... on MCP requests. Health endpoints remain public. Keep the value in a protected secret facility and never include it in Git, wiki source, command transcripts, or logs.

The service is intended for a controlled LAN. Bind explicitly, apply firewall rules, and do not expose archived Slack data to the public Internet by default.

Rollback

At least two immutable artifacts are retained; the default retention count is three.

  1. Select a known-good search-*.duckdb and matching .manifest.json.
  2. Run slackquery validate --checksum <artifact>.
  3. Run slackquery publish <artifact> rather than editing the symlink manually.
  4. Verify /readyz and smoke-test all three retrieval modes.
  5. Pause or remediate hourly reconciliation if it would immediately replace the rollback artifact.

Rollback affects serving selection only. It does not mutate canonical Slackpipe or erase current Slackquery enrichment state.

Backup and recovery

  • Back up slackquery.duckdb only while no writer is active.
  • Preserve the current artifact/manifest and at least one prior known-good pair.
  • Treat artifacts as derived and rebuildable.
  • Treat state as rebuildable but expensive: it contains representative message corpus durable content-addressed vectors in the validated deployment.
  • Canonical Slackpipe backup remains the Slackpipe owner's responsibility.

Operational checks

  • Confirm Dagster daemons and the slackquery code location are healthy.
  • Confirm recent hourly schedule ticks launched successful runs.
  • Compare active projection, successful vector, artifact document, and artifact vector counts.
  • Confirm the blocking integrity check passes.
  • Verify /healthz and /readyz.
  • Run embedding-status after backend/model changes.
  • Monitor artifact disk use and retention.
  • Compare latency with Testing-and-Benchmarks.

Safety rules

  • Never make /path/to/slackpipe.duckdb writable to Slackquery.
  • Do not run competing state-database writers.
  • Do not bypass complete vector coverage or artifact checks.
  • Do not manually rewrite immutable artifacts.
  • Do not treat liveness as model health or readiness as relevance quality.
  • Do not claim the human relevance benchmark has completed.

See Dagster-Orchestration, Embeddings-and-Model-Identity, and Troubleshooting.

Clone this wiki locally