--- title: 'Run on Ollama' description: 'Point a workspace at Ollama or another OpenAI-compatible gateway on your own hardware: the endpoint, the model id, a packaged box, and the errors you meet on the way.' position: 8 --- # Run on Ollama > Any OpenAI-compatible gateway can replace OpenRouter as your **model > provider**, the endpoint the box sends every model call to. This page uses > Ollama as the example. LM Studio, LiteLLM and vLLM take the same steps with > their own address. Two things must agree: the box must reach the gateway, and > every model id your project names must be one the gateway serves. ## Configure the provider ### In Studio Open **Settings › Model provider** and pick the **Ollama** preset. It fills the base URL with `http://localhost:11434/v1`. Keep the `/v1` at the end, because that is the path Ollama serves its OpenAI-compatible API on. Leave **API key** empty. Ollama answers without one. Click **Test connection**, then **Save**. The box runs the test, not your browser. It calls `/models` from where your agents run, so a green result means your agents can reach the gateway too. A save applies to the running box at once. `localhost` is correct for `stackbone dev`, which runs your code on your own machine. A box in a container needs another address, see [Reach the gateway from the container](#reach-the-gateway-from-the-container). ### From the environment The base URL alone is enough. Export it before you start `stackbone dev`: ```sh export MODEL_PROVIDER_BASE_URL=http://localhost:11434/v1 stackbone dev ``` On a box built with [`stackbone package`](/docs/cli/reference/package), add the same line to the deploy folder's `.env`. The compose file passes that whole file to the agent container. Recreate the container to apply it: ```sh docker compose up -d --force-recreate agent ``` A value the box exports outranks the one saved in Studio. The [Gateway](/docs/home/features/gateway) page explains how the screen shows that. ## Name a model the gateway serves A new project's agent names `openai/gpt-4o-mini`: ```ts export default defineDeepAgent({ name: 'support', model: 'openai/gpt-4o-mini', tools: [addNumbers], }); ``` That is an OpenRouter id. Ollama serves no model of that name, so the first turn fails with `400 invalid model ID`. Pull a model and write its Ollama tag instead: ```sh ollama pull qwen3:4b ``` ```ts export default defineDeepAgent({ name: 'support', model: 'qwen3:4b', tools: [addNumbers], }); ``` The **Models** tab of the Model provider screen lists every id the gateway serves. Pick a model that supports tool calls, because every deep agent runs a tool loop. You can also leave the code alone and pick the model in Studio. Open the agent in the catalogue and choose a model on the `model` row of its **Models** block. A pick outranks the `model` in the code, and the agent rebuilds so the next turn uses it. On a packaged box that saves a rebuild of the image. The full order is in [`stackbone.models`](/docs/sdk/platform/models#the-resolution-order). Other ids in your project need the same check: a `model` you pass to [`stackbone.ai`](/docs/sdk/platform/ai), and the embedding `model` you pass to [`stackbone.rag`](/docs/sdk/data/rag). RAG stores 1536-dimension vectors, so its embedding model must return 1536 dimensions. Most Ollama embedding models return fewer (`nomic-embed-text` returns 768), and ingest fails with them. ## Ship a change to a packaged box The image contains your compiled workspace. A change to `index.ts` reaches the box only after you package again, into the same folder, and rebuild: ```sh stackbone package # the same flags as the first time cd dist/deploy docker compose build --pull docker compose up -d ``` `stackbone package` keeps the `.env` already in the folder, so the box keeps its secrets, and replaces the `workspace/` folder whole. Update the CLI before you package again: an older one writes a new `.env` with new secrets, and a box with a new `STACKBONE_SECRET_KEY` cannot decrypt the secrets it already stored. `--pull` refreshes the runtime base image, `ghcr.io/stackbone/stackbone-workspace-runtime:node24-base`. Without it Docker reuses the copy it cached on your first build, and runtime fixes never reach your box. With plain Docker, use `docker build --pull -t .`. An `--offline` folder has no build step: `stackbone package --offline` builds the image on your machine. Run `docker pull` on the base image above before you package, then follow the update steps in the folder's `README.md`. ## Reach the gateway from the container Inside the box container, `localhost` is the container itself. Use `http://host.docker.internal:11434/v1` when Ollama runs on the Docker host, or `http://ollama:11434/v1` when Ollama is a service named `ollama` on the same Compose network. ## Troubleshooting | Error | Cause | Fix | | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `no model provider is configured (MODEL_PROVIDER_API_KEY is not set)` | The box runs an older runtime image, which still asks for a key. | Rebuild with `--pull` (see [above](#ship-a-change-to-a-packaged-box)). Or save any placeholder key, such as `ollama`, on the Model provider screen. Ollama ignores it. | | `400 invalid model ID`, or `model "…" not found` | The model id in your code, or the one picked in Studio, is not a model the gateway has. | Name an Ollama tag, or pick one in Studio. See [Name a model the gateway serves](#name-a-model-the-gateway-serves). | | `openrouter_key_missing` from a `stackbone.ai` call in a workflow step | A workflow carries the `@stackbone/sdk` your project had installed when you packaged it. An older SDK still asks for a key. | Update `@stackbone/sdk` in your project, then package and rebuild. Or save a placeholder key, as above. | | `The model provider could not be reached`, or **Test connection** fails | The base URL does not resolve from inside the box. | Use an address the container can reach. See [Reach the gateway from the container](#reach-the-gateway-from-the-container). | ## What's next - [Which models can I use?](/docs/faqs/general/supported-models): what a provider resolves, and what changes when you swap one. - [Gateway](/docs/home/features/gateway): every caller that uses the model provider, and the models the platform tools use. - [`stackbone package`](/docs/cli/reference/package): what the deploy folder holds and what you set on the container.