# Backend, database and storage Understand initialization, shared runtime roles and persistent data in the core reference setup. The [reference core](/install/reference.md) starts PostgreSQL, RustFS and a one-shot bucket initializer before the API becomes usable. Its migration, API and jobs services use the same pinned server image and mounted `server/server.yaml`. | Service | Command/responsibility | Persistent data | | --- | --- | --- | | `postgres` | Database with the selected release's vector/text-search extensions | `database` volume | | `storage` | S3-compatible recording/file storage | `recordings` volume | | `storage-init` | Idempotent creation of private `recordings` bucket | Exits after initialization | | `migrator` | `migrate`, once before API/jobs start | Updates database schema | | `server` | `serve`, backend API | Shared `uploads` plus database/storage | | `jobs` | `run jobs`, released background job runtime | Same config/uploads/database/storage | The [PostgreSQL Dockerfile](/examples/reference/database/Dockerfile) preserves the maintained extension setup so historical migrations can run on a fresh database. Do not remove extensions based only on the current schema's indexes. The database and storage have no host-published ports in this example. ## Validate and initialize From the archive root, with the profile's complete Compose prefix: ```sh docker compose --env-file secrets.env run --rm --no-deps migrator validate-config docker compose --env-file secrets.env run --rm --no-deps migrator validate-config --resolve-env docker compose --env-file secrets.env up --build -d postgres storage storage-init docker compose --env-file secrets.env up --build -d docker compose --env-file secrets.env ps --all ``` `storage-init` and `migrator` must exit zero. Runtime config validation does not connect to databases/providers or prove credentials work. Check logs without publishing them if they contain user data. Verify public API discovery at `https://YOUR_HOST/api/info/v1/server_info` and complete the client recording test. Keep `db.run_migrations: false` when using the explicit migrator. Never start a different jobs version against the new schema accidentally. The jobs/API upload mount must remain shared, and all private configuration must survive container recreation. See [backups and upgrades](/operations/backup-upgrade.md). # Deploy the inference gateway Route stable model aliases to private transcription and LLM services with explicit authentication. The optional `hippolabs-org/llm-server` is a gateway, not a model host. The reference profile uses version `v1.0.12`, a private Docker network, API-key authentication, and [models.json](/examples/reference/llm-server/models.json). Registry access may be required independently of access to the public docs. ## Configure routes and credentials `MODEL_ROUTES_FILE=/models.json` selects the mounted routes file. Its two public aliases are `whisper` and `llm-default`; each maps to its upstream service and the exact model ID that service accepts. Targets use the server root, such as `http://llm-gpt-oss-120b:8000`, while Dicto uses the full API root ending `/v1`. Set `INFERENCE_API_KEY` in `secrets.env`. The reference passes it as `API_KEYS` to enable gateway authentication. Set Dicto's chat/transcription keys to the same value. In this gateway, omitting `API_KEYS` disables its API-key check; do not expose an unauthenticated instance as a public service. ## Start and check Start the full [self-hosted recipe](/install/self-hosted-ai.md), including the model servers. On the inference host: ```sh read -rsp 'Inference key: ' INFERENCE_API_KEY export INFERENCE_API_KEY curl --fail -H "Authorization: Bearer $INFERENCE_API_KEY" http://127.0.0.1:8002/v1/models unset INFERENCE_API_KEY ``` Expect a successful models response. Then perform an audio request and a chat request through the same endpoint; model listing does not establish upstream readiness. See the [downloaded checks](/examples/reference/checks/README.md). The separate internal listener on port 9090 exposes `/livez`, `/readyz` and `/metrics`; it is not the public inference API and is not published by this sample. When splitting hosts, secure connectivity explicitly and change the route target URLs. The Docker aliases in the sample do not resolve automatically across hosts. Keep internal health/metrics private and test from the API's network. # Deploy the text-generation LLM Run the maintained GPT-OSS serving profile, test generation and connect its model alias to Dicto. ## Scope and requirements This guide uses [llm/compose.yaml](/examples/reference/llm/compose.yaml) from the [reference archive](/install/reference.md): `vllm/vllm-openai:v0.32.0` serving `openai/gpt-oss-120b`. It preserves the maintained parser options, 65,536-token context, 0.90 GPU memory utilization and device `2` assignment. These are reference-host settings, not a recommended capacity promise for every GPU. The maintained host has 96 GB-class devices. Check model architecture, image/CUDA support, weights, context, concurrency, VRAM/RAM and model-cache disk for your machine. Context/concurrency settings can make a configuration fail even when the model weights fit. Model repository access and terms are separate from pulling the image. The [vLLM Docker guide](https://docs.vllm.ai/en/latest/deployment/docker/) describes runtime and cache requirements. Whisper is a different service and model. Installing this LLM does not add transcription, embeddings, reranking, speech synthesis or realtime capabilities. ## Start and inspect From the extracted reference directory: ```sh docker compose --env-file secrets.env -f compose.yaml -f llm/compose.yaml --profile self-hosted-ai config --quiet docker compose --env-file secrets.env -f compose.yaml -f llm/compose.yaml --profile self-hosted-ai up -d llm-gpt-oss-120b docker compose --env-file secrets.env -f compose.yaml -f llm/compose.yaml --profile self-hosted-ai logs --tail 100 llm-gpt-oss-120b ``` `HF_TOKEN` is optional for repositories you can download anonymously; obtain authorized model access when required. The two named caches survive container recreation. Keep the model service private; its diagnostic port binds only to `127.0.0.1:8001` on the inference host. ## Verify generation On the inference host, wait for readiness and send a real generation request: ```sh curl --fail http://127.0.0.1:8001/health curl --fail -H 'Content-Type: application/json' http://127.0.0.1:8001/v1/chat/completions -d '{"model":"openai/gpt-oss-120b","messages":[{"role":"user","content":"Reply with a short greeting."}],"max_tokens":256}' ``` Expect HTTP 200 and a non-empty assistant message. Reasoning models may consume part of the token budget before visible output; inspect finish reasons and increase the budget when needed. Test streaming, tool calls and any structured outputs required by your chosen features separately. See the [upstream API guide](https://docs.vllm.ai/en/latest/serving/online_serving/openai_compatible_server/). For the full recipe, start the gateway too and send the same request to `127.0.0.1:8002/v1/chat/completions` with `model: llm-default` and `Authorization: Bearer YOUR_INFERENCE_KEY`. The gateway alias maps to the upstream model ID. Read the key into an environment variable rather than putting its literal value into shell history; see the bundle's [checks](/examples/reference/checks/README.md). ## Configure Dicto The reference server uses: ```yaml chat: base_url: "${CHAT_BASE_URL}" api_key: "${CHAT_API_KEY}" models: - id: default name: GPT-OSS 120B provider_model: llm-default is_default: true ``` Merge under `ai`. Use the complete gateway root `http://llm-server:8000/v1` and the gateway credential in `secrets.env`. For a direct connection, use `http://llm-gpt-oss-120b:8000/v1` and upstream model ID `openai/gpt-oss-120b`, with the authentication that direct endpoint requires. Validate configuration, recreate API/jobs and test a chat turn from the client. Do not offer unsupported reasoning choices. [Model configuration](/configure/models.md) explains catalog IDs, provider IDs and optional capabilities. ## Scripto and additional models The maintained deployment also runs a separate Scripto agent service. A chat model alone does not provision that runtime or prove Scripto tool execution. Configure the matching released agent service and its `scripto_agent.server_url` when deploying that feature; it is outside this core download. Embeddings, reranking and organization-specific model routes likewise need their own services and checks. Keep absent capabilities unconfigured. When substituting a smaller model or changing hardware, update the vLLM model, model-specific parser options, gateway `upstream_model` and Dicto catalog together. Retest the actual feature requests instead of assuming model IDs are interchangeable. # Deploy the management app Configure the management browser application, reverse proxy, public API URL and authentication callbacks. ## Outcome and prerequisites Deploy the management app at `https://dicto.example.org/management/` against `https://dicto.example.org/api`, matching the maintained path layout. You need an initialized backend/database, HTTPS routing, registry pull access and an administrator account. The [reference archive](/install/reference.md) pins the management image by digest and includes the service in `compose.yaml`. The management app is a static browser application served by its container. Its `API_URL` is used by users' browsers, so the value must be reachable from their networks. Do not set it to `http://server:3000`. ## Runtime configuration Edit [app-management/public.env](/examples/reference/app-management/public.env): ```dotenv API_URL=https://dicto.example.org/api BASE_HREF=/management/ ``` Use a leading and trailing slash in `BASE_HREF`. For a dedicated hostname, set `BASE_HREF=/` and route that hostname to the management container. Recreate the container after changing runtime configuration. A compiled API URL override may take precedence; verify the effective URL in browser network requests. Browser configuration is public. Keep database passwords, auth secrets and inference keys on the backend, never in this environment file or browser assets. ## Routing and authentication The reference proxy sends `/management/*` to `management:80` **without stripping the prefix**. It sends `/api/*` to `server:3000` after stripping `/api`. Use the same host in: - `api.url`: `https://dicto.example.org/api`. - `auth.base_url`: `https://dicto.example.org/api/auth`. - `auth.trusted_origins`: `https://dicto.example.org` (origin, with no path). - `auth.web_redirect_uris`: `https://dicto.example.org/management/auth.html`. For a dedicated management hostname, add that origin and its actual callback URL instead. SSO providers additionally need their server callback registered with the identity provider; see [authentication](/configure/authentication.md). ## Start or update From the reference root, use your selected recipe's complete Compose prefix. For the core profile: ```sh docker compose --env-file secrets.env config --quiet docker compose --env-file secrets.env up --build -d docker compose --env-file secrets.env logs --tail 100 management server ``` Migrations and bucket initialization must finish before the API is usable. To apply only a browser configuration edit after initialization: ```sh docker compose --env-file secrets.env up -d --no-deps --force-recreate management ``` For updates, review the new image digest alongside the API/client compatibility notes; pulling an unchanged digest does not update the application. ## Verify in a browser 1. Open `/management/` over HTTPS and check the runtime configuration/asset requests load successfully. 2. Confirm API calls use the public `/api` URL, not an internal container name. 3. Sign in with an authorized account and inspect an administration page. 4. Reload a nested route and complete the actual sign-in callback flow. 5. Verify a non-administrator does not gain administration access. If the shell loads but sign-in fails, inspect actual callback URLs, trusted origins and the API auth logs. If assets return 404 or HTML instead of JavaScript, check `BASE_HREF` and proxy prefix handling. After bootstrap, disable the server's admin seeder and recreate API/jobs. Never publish working bootstrap credentials. # Deploy the transcription service Serve Whisper with vLLM, connect its model to Dicto and verify a real audio upload. ## Scope and files The [reference download](/install/reference.md) includes [transcription/compose.yaml](/examples/reference/transcription/compose.yaml) and [its Dockerfile](/examples/reference/transcription/Dockerfile). This example runs vLLM 0.26.0 with its matching audio dependencies and public `openai/whisper-large-v3`, served as `whisper`. The maintained setup uses a local fine-tuned checkpoint plus runtime patches; neither weights nor private patch code are shipped in this portable example. It covers non-streaming JSON transcription. Do not enable token logprobs, diarization or realtime flags until your actual endpoint passes those tests. ## Requirements and GPU assignment Use Linux AMD64 with NVIDIA drivers/Container Toolkit compatible with the image. Verify GPU visibility and enough VRAM, RAM and disk for weights, compilation and your recording workload. Check access to the model registry and any model terms. The first startup downloads weights into the `model-cache` volume. The overlay retains devices `0`/`1` and `--tensor-parallel-size=2`. To use one GPU, change both the device list and tensor-parallel size to one, then validate capacity on that GPU. A Docker reservation does not impose a VRAM quota. When sharing a host, avoid assigning the LLM to the same devices accidentally. ## Start the service From the extracted setup root, with `secrets.env` filled: ```sh docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml --profile self-hosted-ai config --quiet docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml --profile self-hosted-ai up --build -d whisper-loadbalancer docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml --profile self-hosted-ai logs --tail 100 whisper-loadbalancer ``` Wait for startup to finish; model download and compilation may take minutes. The diagnostic listener is `127.0.0.1:8000` on the host. Other containers use `http://whisper-loadbalancer:8000`, not host loopback. The service is not routed publicly by the example proxy. ## Verify with real audio Put a short non-sensitive recording at `sample.wav` on the inference host: ```sh curl --fail http://127.0.0.1:8000/health curl --fail http://127.0.0.1:8000/v1/audio/transcriptions -F model=whisper -F response_format=json -F file=@sample.wav ``` Expect HTTP 200 and JSON with non-empty `text` matching your spoken sample. The health endpoint alone does not test decoding or transcription accuracy. Use an actual audio file, not an empty file or a renamed arbitrary payload. See the upstream [speech-to-text API documentation](https://docs.vllm.ai/en/latest/serving/online_serving/speech_to_text/) for request formats; check differences against the pinned runtime version. ## Connect Dicto For a direct private connection, merge this into the server's `ai` section: ```yaml transcription: type: vllm base_url: http://whisper-loadbalancer:8000/v1 models: - id: whisper name: Whisper provider_model: whisper is_default: true ``` `id` is Dicto's catalog identity; `provider_model` is what the upstream accepts. The retained `type: vllm` value is a compatibility setting, not a requirement that every provider be vLLM. Supply the complete API root, including `/v1`. The full recipe instead routes through the [gateway](/components/gateway.md), uses `http://llm-server:8000/v1`, and supplies its API key. Preserve the alias `whisper` in `llm-server/models.json`. Validate the mounted server configuration and recreate API/jobs, then record, play back and transcribe from a Dicto client. ## Troubleshooting - GPU unavailable: verify NVIDIA runtime and the selected device IDs first. - Download denied: verify model permissions/token, license acceptance and egress. - Out of memory: review concurrency, parallelism and other GPU workloads before changing context/worker settings blindly. - Model not found: compare `provider_model`, served-model name and gateway alias. - Upload rejected: check provider/proxy limits and request format. The example explicitly configures 500 MB upload and 7,200-second decode limits; these settings do not change limits elsewhere in the client/API/proxy path. - Optional capability fails: leave its flag off and test it separately. A generic OpenAI-compatible label does not establish support for every feature. # Schemas & examples Download validated configuration references for the server and desktop app. ## Downloads | Configuration | Schema | Example | | --- | --- | --- | | Dicto server — `server.yaml` | [server.schema.json](/schemas/server.schema.json) | [server.example.yaml](/examples/server.example.yaml) | | Dicto desktop app — `config.yaml` | [app.schema.json](/schemas/app.schema.json) | [config.example.yaml](/examples/config.example.yaml) | The server schema includes its dashboard definitions, so it can be used as a single offline JSON file. The app embeds its schema for startup validation; it does not fetch a schema from the network. Use the configuration and schema matching the release you deploy. These downloads are committed exports from Dicto-Dev. The [export manifest](/schemas/manifest.json) identifies the source revision and checksums. It records the current documentation snapshot; it does not declare compatibility with every released app or server. The documentation build verifies the snapshots without accessing private source. ## Validate in your editor Save the matching schema beside your YAML and add this first line: ```yaml # yaml-language-server: $schema=./app.schema.json config_version: 1 ``` For the server, use `./server.schema.json` instead. A schema-aware YAML editor can show supported settings, completion and validation errors. Server commands and app startup also validate settings; editor checks do not test service connectivity. ## Minimal desktop configuration ```yaml # yaml-language-server: $schema=./app.schema.json config_version: 1 server_config: api_url: https://api.dicto.example.com ``` Omitted sections keep their release defaults. Optional values should be omitted rather than set to `null`. Booleans must be `true` or `false` without quotes. The version is an integer. Feature states are `enabled`, `hidden`, or `disabled`. ## App settings | Section | Purpose | | --- | --- | | `server_config` | Public API URL without a trailing slash, query or fragment | | `app_updater` | Update availability, automatic checks, App Manager URL, channel or appcast | | `onboarding` | Onboarding availability and server selection options | | `authentication` | System or integrated SSO browser and whether integrated SSO is allowed | | `feature_flags` | Individual feature availability policies | | `analytics` | Enable/disable analytics or configure an organization-managed endpoint | | `sentry` | Enable/disable error reporting, DSN and trace sample rate from 0 to 1 | App configuration contains literal values. Server-style `${NAME}` substitution is not supported in the desktop app file. Keep provider credentials and server secrets on the server. ## Migrate from config.json This is a breaking change. Replace the old installation-directory file with `config.yaml`, preserve its supported section names and values in YAML, and add `config_version: 1`. Use `app_manager_base_url` for the update manager URL if your old file used `app_release_manager_base_url`. Validate the YAML, remove `config.json`, and restart Dicto. A remaining legacy JSON file or an invalid YAML file stops startup with a configuration error. Explicit managed YAML takes precedence over compiled server defaults. Missing managed configuration keeps the normal release defaults and server-selection flow. # Authentication and browser URLs Configure public auth roots, trusted origins, callbacks and bootstrap administration coherently. The core example uses a new bootstrap administrator and email/password sign-in. It does not copy an organization's identity-provider registration, tenant IDs, passkey associations or credentials. Decide which released sign-in methods your installation should offer before rollout. ## Align the URLs For the reference path layout: ```yaml api: url: https://dicto.example.org/api auth: base_url: https://dicto.example.org/api/auth trusted_origins: - https://dicto.example.org web_redirect_uris: - https://dicto.example.org/management/auth.html ``` Merge these values into the complete server file, retaining its required settings. An origin is scheme/host/port, without a URL path. A callback is a complete allowed return URL. Add your actual browser-app callbacks separately; do not authorize a wildcard solely to work around an incorrect URL. ## Bootstrap and SSO Supply a unique long-lived `AUTH_SECRET` and new bootstrap administrator values. After first successful sign-in, disable `seed.admin.enabled` and recreate API/jobs. The seeder skips existing users and is not an account recovery mechanism. Keep auth secrets, any configured encryption keyring and database backups together when migrating an existing installation; do not regenerate them as an upgrade. For SSO, provision your own provider registration and configure the matching `auth.sso_providers` entry from the [schema/example](/configuration.md). Register the exact server callback required by the selected auth API version and provider ID. The management return URL and identity-provider server callback are different URLs. Verify the complete browser redirect chain rather than guessing a callback from the app hostname. Passkeys/native associations need their own domain and device verification and are outside the bootstrap example. Browser runtime files must not contain server/provider credentials. Verify administration permissions with both authorized and non-administrator accounts. See [management deployment](/components/management.md) for path-prefix checks. # Configure models and capabilities Map Dicto catalog identities to provider models and verify each capability explicitly. Dicto configures model catalogs in server YAML under `ai`. The backend keeps provider credentials; clients receive the appropriate authorized catalog. | Field | Meaning | | --- | --- | | `id` | Stable Dicto catalog ID used by the app | | `name` | Human-readable model name | | `provider_model` | Model string sent to the provider or gateway alias | | `base_url` | Complete provider API root, including `/v1` or other prefix | | `api_key` | Credential for that endpoint, usually an environment reference | | `is_default` | Default selection in that capability's catalog | Model-level `base_url` and `api_key` override capability defaults. References such as `"${CHAT_API_KEY}"` must be complete server YAML string values; do not assume a global `OPENAI_API_KEY` implicitly configures every service. Desktop app YAML does not use the server's environment-substitution mechanism. ## Separate the capabilities - `transcription`: audio upload to `/audio/transcriptions`; verify real audio and the desired response format. - `chat`: text-generation requests; verify the APIs, streaming, tools and output formats the consuming feature actually uses. - `embeddings` and `reranking`: independent optional model/services for selected retrieval features, with their own model/dimension compatibility. - `realtime_speech` and optional transcription realtime/diarization: independent contracts, not implied by a successful batch transcription. The [reference file](/examples/reference/server/server.yaml) uses gateway alias `whisper` for transcription and `llm-default` for chat. The [route file](/examples/reference/llm-server/models.json) maps them to upstream models. Change all relevant layers together when replacing a model. Do not enable `supports_token_logprobs`, realtime or diarization flags merely because an endpoint calls itself OpenAI-compatible. The portable Whisper example does not include the maintained deployment's token-logprob patch. Keep optional reasoning efforts/summaries absent unless the selected model/provider supports them. The [generated server schema](/schemas/server.schema.json) describes the exported configuration contract; the deployed server performs final validation. # Improve these docs Improve installation instructions, configuration examples and troubleshooting guides. Use the shared [Dicto repository](https://github.com/TruhnLab/Dicto) to improve these guides. Include the relevant app and server versions when reporting a documentation issue. ## Improve a guide Edit Markdown under `content/`. Give each guide a title, description, intended audience, prerequisites and a useful verification step. Keep links relative to the published site and identify the applicable component versions when the instructions depend on a release. Run `just check` before proposing a change. ## Report a problem Include your app version, server version, platform, expected behavior, steps to reproduce and the result. Use synthetic examples and remove account information, credentials and sensitive content from screenshots or logs. ## Update configuration downloads The reusable Hippo docs image owns rendering, search and verification. This repository supplies content and `docs.yaml`; no Dart or Flutter source is needed to build it. Configuration schemas are generated exports. Request an update from the owning product package instead of editing these files by hand. Maintainers export the reviewed artifacts from Dicto-Dev and update their checksums together. # Set up the client Connect managed workstations and browser applications to your Dicto server. ## Before you begin Have the public API URL, an approved Dicto release, and a provisioned account or SSO provider. Check API reachability from the user's network. Use the API base URL, such as `https://api.dicto.example.com`, without a trailing slash, query, fragment or `/auth` suffix. ## Desktop installation Install the Windows, macOS or Linux release through your software distribution process. Download the [app schema](/schemas/app.schema.json) and [configuration example](/examples/config.example.yaml). Place `config.yaml` beside the actual Dicto executable: | Platform | Typical location | | --- | --- | | Windows | `C:\Program Files\Dicto\config.yaml`, beside `Dicto.exe` | | macOS | `/Applications/Dicto.app/Contents/MacOS/config.yaml` | | Linux | `/opt/dicto/config.yaml`, beside the Dicto binary | Paths depend on the installation. On macOS, **Show Package Contents** opens the application bundle. Include configuration through your managed installation process and verify the resulting signed app according to that process. Minimal managed configuration: ```yaml # yaml-language-server: $schema=./app.schema.json config_version: 1 server_config: api_url: https://api.dicto.example.com ``` Save `app.schema.json` beside the file for editor validation. Startup validation uses the schema embedded in Dicto, so distributing the schema beside the executable is optional. ## Managed updates and telemetry For centrally controlled updates and disabled analytics/error reporting: ```yaml config_version: 1 server_config: api_url: https://api.dicto.example.com app_updater: enabled: false check_automatically: false analytics: enabled: false sentry: enabled: false ``` Omitted settings inherit release defaults. Managed YAML takes precedence over compiled server defaults. Restart Dicto after changes. Incorrect types, unknown keys, unsupported values or invalid URLs stop startup rather than silently reverting to other settings. > Info `config.json` is no longer supported. Follow the [YAML migration instructions](/configuration.md#migrate-from-configjson) before rolling out this release. ## Features and SSO Merge these sections into your configuration as needed: ```yaml feature_flags: scripto: enabled chat: hidden tools: disabled authentication: sso_browser_mode: system allow_integrated_sso: true ``` `enabled` makes a feature available, `hidden` starts it off and permits a Developer Settings toggle, and `disabled` makes it unavailable. Server policies and service availability still apply. Desktop SSO uses the system browser by default. You can select `integrated` when allowed, or set `allow_integrated_sso: false` to enforce the system browser. The [app schema](/schemas/app.schema.json) lists all supported keys. Use lowercase enum values and unquoted booleans. Omit optional settings rather than supplying `null`. ## Web application containers The management app has its own [deployment guide](/components/management.md), including public API configuration, path prefixes and auth callbacks. The [reference setup](/install/reference.md) pins its image and configuration. For the end-user web app, deploy your approved `ghcr.io/truhnlab/dicto-app` release behind HTTPS, route to its container port 80, and use `BASE_HREF=/` for its own hostname (or the actual slash-terminated path prefix). Choose **Custom server** during onboarding and enter the public API URL. The selection is stored in the browser. Add that browser origin and its actual auth callback to the server configuration and verify sign-in and a nested-page reload. Desktop `config.yaml` does not configure management browser runtime settings. Keep credentials and provider keys out of both public browser applications. ## Verify the installation 1. Open Dicto and confirm it connects to your intended server. 2. Sign in with a provisioned account or your configured SSO flow. 3. Grant microphone permission. Desktop auto-paste may require additional platform permissions. 4. Select or create a workspace as permitted by your account. 5. Record a short sample, stop recording, and confirm transcription completes. 6. Restart and verify that the connection and sign-in flow still work. Use [troubleshooting](/operations/troubleshooting.md) for configuration, connection or transcription failures. # Server deployment Find the complete installation recipes and backend component guide. The server instructions now live in complete recipes with a downloadable setup. This URL remains available for existing links. - [Download the reference setup](/install/reference.md). - [Install with existing inference endpoints](/install/external-ai.md). - [Install self-hosted transcription and LLM](/install/self-hosted-ai.md). - [Backend, database and storage](/components/backend.md). - [Management app deployment](/components/management.md). Use the pinned files and ordered checks in the selected recipe. Older individually downloadable examples remain available for existing links; they are not the maintained reference bundle. # Dicto Docs Install Dicto, connect its AI services, use the apps and operate your deployment. ## Start with a complete setup Understand the [architecture](/start/architecture.md), check [requirements](/start/requirements.md), then choose an installation recipe: | Your installation | Start here | | --- | --- | | You already have transcription and chat endpoints | [Install with existing AI](/install/external-ai.md) | | You want to host Whisper and a text-generation model | [Install self-hosted AI](/install/self-hosted-ai.md) | | You want editable files matching our service layout | [Download our reference setup](/install/reference.md) | The reference download includes Compose files, configuration templates, schemas, a standalone README and verification steps. It uses published images without requiring access to product source. Read its version/validation scope before adapting it to your infrastructure. ## Deploy and configure each component - [Backend, database and storage](/components/backend.md) - [Transcription service](/components/transcription.md) - [Text-generation LLM](/components/llm.md) - [Optional inference gateway](/components/gateway.md) - [Management app](/components/management.md) - [Desktop and browser clients](/deployment/client.md) Configure [models and capabilities](/configure/models.md) and [authentication/browser URLs](/configure/authentication.md) explicitly. Transcription and text generation are separate services with separate verification steps. ## Use and operate Dicto [Connect a client and make a recording](/learn/getting-started.md), then verify stored audio and transcription. Use [troubleshooting](/operations/troubleshooting.md) and [backups/upgrades](/operations/backup-upgrade.md) to keep the installation healthy. ## Reference and agent access Download [schemas and examples](/configuration.md), inspect [versions and provenance](/reference/versions.md), or use [clean Markdown and setup metadata](/reference/agents.md). Agents can start at [llms.txt](/llms.txt); the machine-readable views share the handbook's source. [Improve these docs](/contributing.md) with the relevant app/server versions and a reproducible verification step. # Install with existing AI endpoints Deploy the Dicto core and management app while using separately hosted transcription and text-generation APIs. ## Outcome and requirements This recipe installs the reference core stack and uses inference endpoints you already operate or are authorized to use. Follow [requirements](/start/requirements.md) and [download the setup](/install/reference.md). All commands run from the extracted `dicto-reference-setup` directory. The pinned server is 2.4.2; see [validation scope](/reference/versions.md). Collect a public hostname, ACME email, registry access, bootstrap administrator credentials, and each provider's full API root, API key and model identifier. The server's network must reach those providers. A successful `/v1/models` list alone does not verify audio uploads or generation. ## Configure the files ```sh cp secrets.env.example secrets.env chmod 600 secrets.env openssl rand -hex 32 ``` Generate independent random values for database/auth/storage secrets. Replace every `REPLACE_` placeholder. Set `DICTO_HOST` and `ACME_EMAIL`. Replace `dicto.example.org` in `server/server.yaml`, `app-management/public.env` and `config/app.yaml`; the hostname appears in both the public API URL and auth settings. Set `CHAT_BASE_URL`, `CHAT_API_KEY`, `TRANSCRIPTION_BASE_URL` and `TRANSCRIPTION_API_KEY` to the actual provider settings. Include required `/v1` or gateway prefixes. In `server/server.yaml`, change each `provider_model` to an ID accepted by that provider. The example IDs `llm-default` and `whisper` are aliases for the self-hosted recipe and may not exist on your external service. Only advertise capabilities you have verified. See [model configuration](/configure/models.md) and [authentication](/configure/authentication.md). If chat is not part of the installation, omit its configured model catalog instead of claiming a working LLM feature. Scripto may require a separate agent service. ## Validate and start Authenticate Docker to GHCR using an authorized pull credential, then: ```sh docker compose --env-file secrets.env config --quiet docker compose --env-file secrets.env run --rm --no-deps migrator validate-config docker compose --env-file secrets.env run --rm --no-deps migrator validate-config --resolve-env docker compose --env-file secrets.env up --build -d postgres storage storage-init docker compose --env-file secrets.env up --build -d docker compose --env-file secrets.env ps --all ``` The bucket initializer and migrator must exit zero before API/jobs start. The GPU overlays and gateway profile are not enabled in this recipe. Leave their unused variables supplied as placeholders, or remove the unused gateway definition when creating your own deployment. ## Verify and finish bootstrap Open `https://YOUR_HOST/management/`, sign in and verify the browser uses your public `/api` URL. Run the [end-to-end checklist](/operations/troubleshooting.md), including stored-audio playback, transcription and a separate chat check if enabled. Disable `seed.admin.enabled` in `server/server.yaml`, then recreate the consumers: ```sh docker compose --env-file secrets.env up -d --force-recreate server jobs ``` See [management deployment](/components/management.md) for browser routing and [operations](/operations/backup-upgrade.md) before rolling out to users. # Our reference deployment Download a sanitized core setup derived from the maintained deployment, with topology, configuration and checks. ## Download the complete directory Download [dicto-reference-setup-1.1.0.zip](/downloads/dicto-reference-setup-1.1.0.zip) and its [SHA-256 checksum](/downloads/dicto-reference-setup-1.1.0.zip.sha256). The archive includes an independent README, configuration, Compose definitions, schemas and per-file checksums. No private source checkout is needed. ```sh sha256sum --check dicto-reference-setup-1.1.0.zip.sha256 unzip dicto-reference-setup-1.1.0.zip cd dicto-reference-setup sha256sum --check checksums.sha256 ``` On macOS, use `shasum -a 256 -c` in place of `sha256sum --check`. Download individual files from the links below if you want to review before extracting. Never overlay this example onto an existing installation's data. ## What this represents This is a sanitized **core profile** derived from the maintained deployment snapshot recorded in [versions.yaml](/examples/reference/versions.yaml). It retains the `/api` and `/management/` topology, PostgreSQL/RustFS, API/migrator/jobs roles, and separate inference services behind a gateway. It uses an isolated project/network and example hostname instead of production identities, shared data-volume names, credentials and internal network details. The portable transcription recipe substitutes public Whisper weights and the standard vLLM audio runtime for the maintained private checkpoint/patches. It does not promise token logprobs, realtime or diarization. The core profile omits organization-specific SSO/passkeys, plugins, document workers, additional AI models and the separate Scripto agent runtime. See the [version and validation notes](/reference/versions.md) before adopting it. ## Layout | File/directory | Purpose | | --- | --- | | [README.md](/examples/reference/README.md) | Standalone ordered installation instructions | | [compose.yaml](/examples/reference/compose.yaml) | Core services and optional inference gateway | | [secrets.env.example](/examples/reference/secrets.env.example) | Required operator-supplied values | | [server/server.yaml](/examples/reference/server/server.yaml) | Shared API/jobs/migrator configuration | | [app-management/public.env](/examples/reference/app-management/public.env) | Public management browser configuration | | [config/app.yaml](/examples/reference/config/app.yaml) | Managed desktop configuration | | [database/Dockerfile](/examples/reference/database/Dockerfile) | PostgreSQL and migration-required extensions | | [transcription/compose.yaml](/examples/reference/transcription/compose.yaml) | Optional Whisper GPU service | | [transcription/Dockerfile](/examples/reference/transcription/Dockerfile) | Audio dependencies for pinned vLLM | | [llm/compose.yaml](/examples/reference/llm/compose.yaml) | Optional GPT-OSS GPU service | | [llm-server/models.json](/examples/reference/llm-server/models.json) | Gateway aliases and upstream model IDs | | [monitoring/compose.yaml](/examples/reference/monitoring/compose.yaml) | Optional Prometheus service | | [monitoring/prometheus.yaml](/examples/reference/monitoring/prometheus.yaml) | Internal metrics scrape target | | [proxy/README.md](/examples/reference/proxy/README.md) | Routing and existing-proxy adaptation | | [checks/README.md](/examples/reference/checks/README.md) | Commands, expected results and limitations | The archive and individual downloads are generated from the same reviewed files. Generated hashes are also available in the [setup index](/setup/index.json). ## Continue with a recipe Choose [existing AI endpoints](/install/external-ai.md) or [self-hosted Whisper and LLM](/install/self-hosted-ai.md). Both describe their required inputs, startup order and verification without requiring private source access. # Install self-hosted transcription and LLM Start Whisper, GPT-OSS and an authenticated internal gateway alongside the reference Dicto core. ## Outcome and scope This recipe adds GPU-backed Whisper transcription, GPT-OSS text generation and the internal gateway to the [reference setup](/install/reference.md). It targets Linux AMD64 with NVIDIA Container Toolkit and the configured GPU allocations. Read [requirements](/start/requirements.md), [transcription](/components/transcription.md) and [LLM deployment](/components/llm.md) before starting large downloads. The maintained deployment's service layout is represented here, with public Whisper substituted for its private checkpoint. The docs build checks files and configuration; it does not certify GPU capacity or a completed product deployment. ## Configure Extract the archive and run from `dicto-reference-setup`. Copy `secrets.env.example` to `secrets.env`, restrict its permissions and replace all placeholders as described in its README. Supply real hostnames in all three public configuration files. Set `INFERENCE_API_KEY`, `CHAT_API_KEY` and `TRANSCRIPTION_API_KEY` to the same newly generated random value. Keep: ```dotenv CHAT_BASE_URL=http://llm-server:8000/v1 TRANSCRIPTION_BASE_URL=http://llm-server:8000/v1 ``` The gateway receives aliases `whisper` and `llm-default` and rewrites them to the upstream model IDs in `llm-server/models.json`. It does not run the models. Model weights need their own access/license review and are cached on first use. ## Start inference and verify it Use this complete Compose prefix throughout this recipe, from the archive root: ```sh docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai config --quiet docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai up --build -d whisper-loadbalancer llm-gpt-oss-120b llm-server docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai logs --tail 100 whisper-loadbalancer llm-gpt-oss-120b llm-server ``` Wait for model loading/compilation and check the endpoints on the inference host. Follow [transcription verification](/components/transcription.md#verify-with-real-audio) and [LLM verification](/components/llm.md#verify-generation). A gateway model list can succeed while an upstream is still loading. ## Start Dicto ```sh docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai run --rm --no-deps migrator validate-config --resolve-env docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai up --build -d docker compose --env-file secrets.env -f compose.yaml -f transcription/compose.yaml -f llm/compose.yaml --profile self-hosted-ai ps --all ``` The core initializes the recordings bucket, runs migrations and starts API/jobs and management. Open `https://YOUR_HOST/management/`, sign in, connect a client and verify a recording, playback and transcription. Check chat separately. Disable the bootstrap seeder after first sign-in and recreate API/jobs using the same complete prefix. ## Separate application and GPU hosts Docker service names work only on their shared network. To split hosts, move the GPU services/gateway to a controlled inference network, bind the gateway to an explicitly secured interface, and use its reachable authenticated HTTPS API root in the application's provider settings. Keep the individual model servers private. Test uploads, timeouts and generation from the application network. The included loopback bindings cannot be reached from another host without a tunnel or explicit network/proxy configuration. Back up the core's persistent data and preserve the complete Compose prefix for updates and recovery. See [backup and upgrades](/operations/backup-upgrade.md). # Getting started with Dicto Connect to your server, select a workspace and verify your first recording workflow. Dicto brings recording, transcription and workspace tools together. The features available to you depend on your organization's server, your workspace permissions and the app version installed on your device. ## Connect your app Ask your administrator for the Dicto server address and your sign-in method. Follow the [client setup guide](/deployment/client.md) to connect a desktop client or open your organization's web app. Use your own account to sign in. ## Choose a workspace Select the workspace where you want to work. If the expected workspace or tools are missing, ask your workspace administrator to check membership and feature availability before changing device settings. ## Verify recording and transcription Use a short, non-sensitive sample to verify microphone access and transcription. Confirm that the recording appears in the intended workspace, that playback works and that the transcript is available. If your organization supports file import, you can also verify the workflow with a permitted sample audio file. Transcription needs a working provider configured on the server. A successful sign-in alone does not verify that provider. Follow the [verification and troubleshooting guide](/operations/troubleshooting.md) when a recording cannot be processed. ## Get help Follow [verification and troubleshooting](/operations/troubleshooting.md) to check connection, configuration or transcription problems. Ask your administrator for help with account access and workspace permissions. # Backups, restoration and upgrades Preserve persistent data and configuration, then migrate matched runtime versions with a tested recovery path. ## What to preserve Back up PostgreSQL, object storage, shared upload data and private configuration as one recoverable installation. Record image digests, configuration/schema revision and the inference model versions used. Keep `AUTH_SECRET`, storage credentials and any configured encryption keyring with restricted access. Model/compile caches can generally be downloaded/rebuilt, but a private checkpoint may need an independent backup and access policy. The reference volumes are isolated under the Compose project. `down` retains them; `down --volumes` deletes them. Never use a volume-removal command as an ordinary update step. Backups are useful only after a restoration test. ## Example database backup From the reference root, use the same Compose files/profile as the installation. Pause writes and background jobs for a consistent database/storage/upload snapshot, or use a coordinated backup mechanism appropriate to your storage system. ```sh docker compose --env-file secrets.env stop server jobs umask 077 docker compose --env-file secrets.env exec -T postgres pg_dump -U dicto -d dicto -Fc > dicto.dump test -s dicto.dump ``` While writes remain paused, take the matching object-storage/upload backups and save private config securely. Restart API/jobs with your selected prefix after the coordinated backup completes. The dump alone does not contain recording bytes or upload drafts. Do not publish backups or private env files in the docs. ## Upgrade sequence 1. Review release notes and compatibility; pin the same new server image for migrator/API/jobs, and review the management/client versions. 2. Validate the new configuration with that image before changing live services. 3. Verify a recoverable coordinated backup and retain old image references. 4. Stop API/jobs before applying an incompatible schema migration. 5. Run the new migrator and require a zero exit code. 6. Start matched API/jobs and browser applications; verify sign-in, playback, transcription and each configured AI feature. For the reference core, after updating the reviewed image reference: ```sh docker compose --env-file secrets.env pull migrator server jobs management docker compose --env-file secrets.env stop server jobs docker compose --env-file secrets.env run --rm --no-deps migrator migrate docker compose --env-file secrets.env up -d server jobs management ``` Keep all selected overlay files/profile flags when managing a self-hosted AI or monitoring installation. An old image does not reverse database migrations. Recovery after an incompatible migration may require restoring database, storage/uploads, config and compatible images together into an isolated host. Perform and record that restore exercise before relying on the procedure. # Verify & troubleshoot Check the complete path from client to API, storage, and transcription. ## Deployment checks 1. Validate the server YAML, then validate with resolved environment values. 2. Confirm the migration container exits successfully before the server starts. 3. Check container logs and the API root through the public HTTPS origin. 4. Sign in through a real client using a provisioned account or SSO. 5. Record a short sample and verify stored audio and finished transcription. 6. Confirm that your backup process covers the database and object storage. A successful configuration validation checks structure and values, not database connectivity, storage access or inference credentials. A responding API root confirms the HTTP process; a successful transcription checks a much larger part of the deployment. ## Server checks From the extracted [reference setup](/install/reference.md), use your selected recipe's complete Compose prefix: ```sh docker compose --env-file secrets.env ps --all docker compose --env-file secrets.env logs --tail=100 migrator storage-init server jobs curl --fail https://YOUR_HOST/api/info/v1/server_info ``` `/health` and `/metrics` are installed only with `monitoring.enabled: true`. A separate monitoring port may be configured. Keep metrics exposure aligned with your deployment's access rules. For self-hosted AI, check [transcription](/components/transcription.md#verify-with-real-audio) and [LLM generation](/components/llm.md#verify-generation) separately. A model list from the gateway does not establish upstream readiness. Verify the management app's public API URL and callback using its [deployment guide](/components/management.md). ## Common symptoms | Symptom | Check | | --- | --- | | Server rejects YAML | Unknown or duplicate keys, `config_version`, required sections, model IDs/defaults, matching release schema | | Missing environment variable | YAML references, container `env_file`, and whether the name has a non-blank value | | Server ignores old env settings | Server 2.0 reads YAML; environment values only apply through explicit YAML references | | Database connection fails | DNS/network reachability, credentials, TLS requirements, database existence and migrations | | Stored audio fails | Bucket exists, access policy, endpoint/region, or persistent filesystem mount in the server | | HTTP S3 endpoint rejected | `storage.allow_http: true` must be explicit when using HTTP | | Transcription never finishes | Server logs, full provider API root, selected model, credentials and worker capacity | | API works but browser fails | Browser-accessible API URL, HTTPS, trusted origins and proxy behavior; app custom-server selection or management runtime `.env` | | Desktop config appears ignored | Correct executable directory, valid YAML/schema version, and app restart | | SSO callback fails | Auth base URL, provider settings, allowed origins and registered callback URI | | Admin seeding creates no user | Seeding enabled with email/password; an existing user causes the seeder to skip | | `/health` returns 404 | Monitoring may be disabled or listening on a separate port | ## Share useful diagnostics Record the server and client versions, time of failure, public endpoint, affected operation and relevant container logs. Redact credentials and sensitive recording/transcription content before sharing diagnostics. For a deployment upgrade, keep configuration changes with the release identifier so a reviewer can see exactly what changed. A rollback plan must account for the database schema and stored objects as well as the container image. ## Client configuration errors The desktop app rejects unknown fields, invalid types, unsupported enum values, invalid API URLs and trace sample rates outside 0–1. Diagnostics identify the affected field and YAML position without printing credential values. Check [the app schema](/schemas/app.schema.json) for the accepted settings. If an error reports a legacy `config.json`, migrate it to `config.yaml`, add `config_version: 1`, and remove the JSON file. A missing managed configuration uses release defaults; an invalid managed configuration does not. # Agent access and setup metadata Read clean Markdown, discover installation recipes and verify downloadable files without private source access. The HTML handbook and machine-readable views come from the same canonical Markdown and reviewed configuration files. Start at [llms.txt](/llms.txt) and fetch only the relevant guides. Every handbook page links to its Markdown view and declares `rel="alternate" type="text/markdown"` and `rel="describedby"`. | Resource | Purpose | | --- | --- | | [/llms.txt](/llms.txt) | Compact discovery index with guide descriptions and downloads | | [/llms-full.txt](/llms-full.txt) | Combined Markdown handbook when a complete snapshot is useful | | [/index.md](/index.md) | Homepage Markdown; other guides append `.md` to their route | | [/setup/index.json](/setup/index.json) | Recipe IDs, required inputs, ordered steps, validation scope and bundle hashes | | [Reference archive](/downloads/dicto-reference-setup-1.1.0.zip) | Complete editable directory, README and file checksums | | [Schemas and examples](/configuration.md) | Exported configuration contracts and source checksums | The [llms.txt convention](https://llmstxt.org/) is a discovery aid. Agents can also follow ordinary links; no JavaScript, private source checkout or browser session is required for this public handbook. Deployments that protect the handbook must apply the same access policy to Markdown, indexes and downloads. ## Setup contract Select a recipe in the JSON index and read its guide/README before execution. Collect required values from the operator; do not invent credentials, model access, DNS or hardware capacity. Check version/validation metadata, download the matching bundle, verify its archive and file checksums, then edit the explicit input files. Run steps in dependency order and stop on failed checks. The index describes commands and expected outcomes; it is not a deployment executor or authorization to modify an installation. `validation` records what was actually checked. Compose/YAML validation does not prove credentials, inference, permissions or user workflows. Report which checks ran and their results rather than turning an expected HTTP 200 into a claim of success. Never put real secrets, patient data or private source into logs, generated instructions, repository files or documentation feedback. For an installation task, follow the operator's authorization and preserve existing data and keys. # Versions, provenance and validation Identify the maintained setup snapshot, image pins, adaptations and limits of documentation validation. The downloadable core reference is derived from a maintained deployment configuration snapshot, revision `3de2ef19266e4276df6191da7a887058d7cedb61`, exported on 2026-11-05. The [bundle's versions file](/examples/reference/versions.yaml) travels with the example. It is not a claim that every optional production component is represented or that the bundle has been installed on every platform. | Component | Reference selection | | --- | --- | | Dicto API/migrator/jobs | `v2.4.2`, pinned to one image digest | | Management | Digest snapshot of the maintained `latest` image on 2026-11-05 | | PostgreSQL | 18.3 with pgvector 0.8.3 and pg_textsearch 1.3.1 | | RustFS | Digest snapshot recorded in the Compose file | | Inference gateway | `v1.0.12` | | Transcription | vLLM 0.26.0 + matching audio dependencies; public Whisper large-v3 | | Text generation | vLLM 0.32.0; GPT-OSS 120B | | Platform | Linux AMD64; NVIDIA hardware required by the GPU overlays | Product/storage digests are in the canonical Compose download. Other named image versions remain registry tags; upstream model revisions are not immutable pins in this example. Record the resolved model revisions and any additional digests in your deployment change record. Do not infer a supported app/server matrix from a moving tag or the date of a page. ## Adaptations from the maintained deployment The example replaces organization hostnames, SSO registrations and credentials, isolates data/network names, and combines the core orchestration under one Compose project. It preserves the path-based API/management deployment and separate backend roles. Public Whisper replaces the private local checkpoint and custom patches, so optional audio capabilities are left off. The sample auth profile bootstraps a new administrator instead of copying an existing SSO or passkey configuration. Organization-specific integrations, additional AI models, retrieval/document workers, Scripto's agent runtime, clinical assets and full monitoring are outside this download. Their absence is explicit; enabling related UI does not install them. ## What validation establishes The docs pipeline checks page links/anchors/search, generated artifact hashes, canonical embedded examples, generated Markdown/index coverage and archive/member checksums. Both reference Compose profiles are rendered in CI without pulling private product images. The mounted reference configuration also passed `validate-config --resolve-env` locally with the pinned v2.4.2 image and example values on 2026-11-05. These checks do not contact identity providers, run GPU models or validate the accuracy of a transcript. A fresh GPU/product end-to-end deployment must be performed by the operator; it is not run in the docs build. Local container smoke checks also verified the pinned management image serves `/management/`, its callback document and a nested route with the intended base path. The gateway accepted the sample route file, rejected an unauthenticated model-list request and returned the configured aliases with the example key. These isolated checks did not perform real administrator sign-in or upstream model inference. Exported schemas have their own [manifest](/schemas/manifest.json) recording the private-source revision and checksums. They are reviewed snapshots, not a full compatibility guarantee for every product release. The deployed image's `validate-config --resolve-env` check is authoritative for the settings it accepts. # Architecture and service connections Understand the public URLs, private services and inference path before installing Dicto. Dicto clients and the management app connect to the backend API. The backend uses PostgreSQL for application data and object storage for recordings/files. API, migration and jobs containers use the same release and configuration. Transcription and text generation run in separate inference services. ```text Browser / desktop client ── HTTPS ── reverse proxy ── Dicto API Management browser app ──── HTTPS ────────────────┘ │ ├─ PostgreSQL ├─ object storage ├─ transcription endpoint └─ chat/LLM endpoint Migration container ── PostgreSQL Jobs ── shared config + uploads ``` An optional LLM gateway supplies stable model aliases and routes requests to Whisper, a text model or other configured providers. It does not run model weights. Transcription can work without a chat model; a working chat model does not establish transcription, realtime or diarization compatibility. ## Public and private addresses The [reference deployment](/install/reference.md) follows the maintained path layout: | Audience | Address in the example | Purpose | | --- | --- | --- | | Browser/client | `https://dicto.example.org/api` | Public API base URL | | Administrator | `https://dicto.example.org/management/` | Management app | | API/jobs | `http://storage:9000` | Private S3-compatible storage | | API/jobs | `http://llm-server:8000/v1` | Optional inference gateway | | Proxy | `server:3000`, `management:80` | Private forwarding targets | Container names are resolved on the Docker network, not in users' browsers. The proxy strips `/api` before forwarding to the backend and preserves `/management/` for the management app. Configure both the browser-facing URLs and internal provider URLs explicitly. ## Pick a complete recipe Choose [existing inference endpoints](/install/external-ai.md) or [self-hosted AI](/install/self-hosted-ai.md). Both use the same downloadable core configuration. Start with [requirements](/start/requirements.md), then use the component guides when adapting one service. # Requirements and installation choices Choose a deployment profile and collect the infrastructure, credentials and model inputs it needs. ## Choose a profile | Profile | You supply | Guide | | --- | --- | --- | | Existing AI endpoints | Reachable transcription/chat API roots, credentials and accepted model IDs | [Install with existing endpoints](/install/external-ai.md) | | Self-hosted AI | NVIDIA host, model access/cache and sufficient compute for Whisper and GPT-OSS | [Install self-hosted AI](/install/self-hosted-ai.md) | Both recipes include the API, jobs, one-shot migrations, PostgreSQL, RustFS, bucket initialization, management app and an HTTPS proxy. A client is installed or hosted separately. Product images require registry pull access; product source access is unnecessary. ## Core infrastructure - Linux host with Docker Engine and Compose v2 supporting GPU reservations for the GPU profile. Docker Desktop can preview the docs, but is not the reference GPU deployment target. - DNS hostname, HTTPS certificate strategy and network access from client devices. The included proxy needs ports 80/443 free and inbound 443 for its ACME TLS challenge. - Persistent storage for PostgreSQL, recordings, upload drafts, certificates and caches; capacity and retention depend on your workload. - GHCR credentials authorized for the private Dicto images and, when selected, `hippolabs-org/llm-server`. Accept model terms and obtain separate model access credentials where required. - New credentials for the database, auth secret, storage and bootstrap account. Decide who will back up and recover the installation before rollout. ## GPU profile Install NVIDIA drivers and Container Toolkit compatible with your pinned inference images. Check `nvidia-smi` on the host and GPU visibility inside an approved CUDA container before troubleshooting model serving. The bundle assigns devices 0/1 to Whisper and device 2 to GPT-OSS, preserving the selected maintained allocations. It therefore needs those devices or an explicit allocation edit. The maintained host has 96 GB-class GPUs and additional workloads. Those allocations are not universal minimum requirements. Model weights, context size, parallelism, KV cache and concurrency determine capacity. Start from the [model guides](/components/llm.md), check model access and available VRAM/RAM/cache disk, and validate on your own hardware. Model weights are downloaded separately and are not inside the setup archive. ## Versions and validation The [reference snapshot](/reference/versions.md) records source provenance and exact product image digests. It also states what has been checked and which GPU/end-to-end checks need an operator run. A valid Compose file is not a completed installation.