Self-Hosting an AI-Native CRM: Docker and Ollama - Relaticle             [  Back to blog ](https://relaticle.com/blog) 

 ![Self-Hosting an AI-Native CRM in 2026](https://relaticle.com/storage/ink/01M17KW7J3RKP1743041AJCDMP.png)Relaticle supports self-hosting, but the standard Compose file does not configure a working AI chat deployment by itself. It needs additional model and broadcasting configuration. This guide covers the core Docker Compose, Coolify, and Dokploy deployment paths. It also identifies the extra work needed for local AI and explains the limits that remain when you run the application yourself.

[](#why-the-ai-parts-are-worth-self-hosting-too "Permalink")Why the AI parts are worth self-hosting too
-------------------------------------------------------------------------------------------------------

A lot of CRMs that advertise an AI assistant or an MCP integration still run those specific features from their own cloud, even when the rest of the product is source-available. Relaticle's AI stack is ordinary application code, not a hosted add-on: the chat assistant is a Laravel package, the MCP server is a route registered in `routes/ai.php` like any other, and neither is gated behind a subscription check when the billing feature flag is off, which it is by default in the published Docker image. You can point the assistant at Anthropic or OpenAI with your own API key, or skip cloud providers entirely and run a local model through Ollama; both paths use the same chat interface and the same CRM access underneath. Separately, the MCP server exposes its full tool surface (search and fetch, plus full create/read/update/delete on companies, people, opportunities, tasks, and notes) to any MCP client, self-hosted exactly as it runs on Relaticle's own cloud plan; [connecting Claude to it](https://relaticle.com/blog/how-to-connect-claude-to-your-crm-with-mcp) takes about two minutes. Relaticle itself ships under AGPL-3.0.

[](#requirements "Permalink")Requirements
-----------------------------------------

All three deploy paths below pull the same official Docker image and the same `compose.yml`; they mostly differ in how much infrastructure you already have running.

| Deploy option | What you need |
|---|---|
| Docker Compose (your own server) | 2 GB RAM minimum (4 GB recommended), Docker 20.10+, Docker Compose v2+ |
| Coolify | A running Coolify instance, a domain to point at it |
| Dokploy | A running Dokploy instance, a domain to point at it |
| Manual, no containers | PHP 8.5+, PostgreSQL 17+, Redis 7+, Node 22.12+ and pnpm, Composer 2+, Nginx or Apache, Supervisor |

| Deploy option | Approx. time |
|---|---|
| Docker Compose (your own server) | ~15 minutes |
| Coolify | ~15 minutes |
| Dokploy | ~15 minutes |
| Manual, no containers | ~45-60 minutes |

![docker compose ps showing app, horizon, scheduler, postgres and redis all healthy](https://relaticle.com/storage/ink/01M09E1REFDVZZ0X83AX2KN5MA.png)

[](#deploy-with-docker-compose "Permalink")Deploy with Docker Compose
---------------------------------------------------------------------

This is the path Relaticle's own guide leads with, and it's the fastest if you already have a server with Docker on it.

Download the compose file:

```
curl -o compose.yml https://raw.githubusercontent.com/Relaticle/relaticle/main/compose.yml

```

Generate an application key:

```
echo "APP_KEY=base64:$(openssl rand -base64 32)"

```

Create a `.env` file next to `compose.yml` with at least the required variables:

```
APP_KEY=base64:your-generated-key-here
DB_PASSWORD=your-secure-database-password
APP_URL=https://crm.example.com
APP_PORT=8080

```

Start the core services:

```
docker compose up -d

```

This brings up five containers: the app (nginx + PHP-FPM), a Horizon worker for queued jobs, a scheduler container running `schedule:work`, PostgreSQL 17, and Redis 7. Database migrations run automatically on first boot, so there's no separate migrate step.

Create your first admin user:

```
docker compose exec app php artisan make:filament-user

```

Pick the `app` panel when prompted. After configuring your reverse proxy, open the CRM at `{APP_URL}/app`. If you also want the instance-wide `sysadmin` panel (useful later, see the limitations section below), run `docker compose exec app php artisan sysadmin:create` instead, or choose `sysadmin` at the same prompt.

Put a reverse proxy in front for TLS. The example above publishes the application on host port 8080, leaving ports 80 and 443 for your proxy. Route HTTPS traffic to that port and set `APP_URL` to your public HTTPS address. Restrict direct access to the application port. The app trusts forwarded headers from configured private and loopback networks, so keep the proxy and network boundary under your control.

*Tested September 24, 2026, with the official Relaticle 3.5.11 image. A fresh Docker Compose deployment passed all five service health checks, admin creation, and browser login.*

*This exercise did not run Coolify, Dokploy, a manual installation, TLS issuance, or AI inference. Those paths need their own deployment checks.*

[](#deploy-with-coolify "Permalink")Deploy with Coolify
-------------------------------------------------------

If you're already running [Coolify](https://coolify.io/) for other projects, adding Relaticle takes about the same five minutes as any other Docker Compose resource:

1. Create a new project in the Coolify dashboard.
2. Add a resource, choose **Docker Compose**, select **Empty** as the source, and paste in the contents of `compose.yml`.
3. Set the required environment variables (`APP_KEY`, `DB_PASSWORD`, `APP_URL`) in the resource's Environment Variables tab.
4. Set your domain under the app service's Settings tab. Coolify provisions the SSL certificate automatically.
5. Click Deploy, then open Coolify's Terminal feature for the `app` container and run `php artisan make:filament-user`.

[](#deploy-with-dokploy "Permalink")Deploy with Dokploy
-------------------------------------------------------

[Dokploy](https://dokploy.com/) follows the same shape:

1. Create a project, then add a Compose service with source set to **Raw**, pasting in `compose.yml`.
2. Set `APP_KEY`, `DB_PASSWORD`, and `APP_URL` in the service's Environment tab. Also set `APP_PORT=8080`, since Dokploy's own dashboard usually holds port 80, so mapping the app container to 8080 avoids a conflict.
3. Click Deploy and wait for health checks on all five containers to pass.
4. Add your domain under the app service's Domains tab, set the container port to 8080, and enable HTTPS (Dokploy handles Let's Encrypt).
5. Open Dokploy's terminal for the `app` container and run `php artisan make:filament-user`.

[](#skipping-containers-entirely "Permalink")Skipping containers entirely
-------------------------------------------------------------------------

If Docker isn't an option, Relaticle also documents a manual install: clone the repo, `composer install --no-dev --optimize-autoloader`, `pnpm install --frozen-lockfile && pnpm run build`, `php artisan migrate --force`, set permissions on `storage` and `bootstrap/cache`, then run Horizon under Supervisor and `schedule:run` from cron. It's the same application, just without the container boundary. That's worth it if you're already standardizing a fleet of bare-metal Laravel apps under one process manager, but there's no shortcut version, so budget closer to an hour and follow the full guide.

[](#ai-prerequisites-ollama-broadcasting-and-mcp "Permalink")AI prerequisites: Ollama, broadcasting, and MCP
------------------------------------------------------------------------------------------------------------

The Compose file starts the core services. MCP uses the application route. Chat additionally needs model credentials, working broadcasting, and a running Reverb service. The base Compose file does not configure those pieces. Treat the following as configuration guidance, not a complete tested chat deployment recipe. Verify a full chat turn on your configured stack before relying on it.

**Local model through Ollama.** Set these values in your deployment environment. Also forward them through the `environment` sections of both `app` and `horizon`. Compose does not pass arbitrary `.env` entries into containers. Recreate the services after editing configuration. These model settings do not replace the Reverb setup described above:

```
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_MODEL=qwen3:14b

```

`OLLAMA_BASE_URL` defaults to `http://localhost:11434`, which from inside a container means the container itself, not your host. On Docker Desktop (Mac or Windows), `host.docker.internal` reaches the host out of the box. On a Linux server, which is where most self-hosted installs live, two more steps are needed: that hostname only resolves if you add it to the app and horizon services in your compose file,

```
extra_hosts:
  - "host.docker.internal:host-gateway"

```

and Ollama binds to loopback by default. Bind it to a private interface reachable by the containers, following the [Ollama FAQ](https://docs.ollama.com/faq). If you bind all interfaces with `OLLAMA_HOST=0.0.0.0`, restrict port 11434 to the application network using your firewall. Never expose an unauthenticated Ollama endpoint publicly. Alternatively, run Ollama as another compose service on the same network and point `OLLAMA_BASE_URL` at its service name. Install the model in Ollama first. Setting `OLLAMA_MODEL` selects its tag for the in-app model picker; it does not download model files.

Not every local model is worth trusting with write access. The assistant has its own tools for searching CRM records and proposing changes. MCP exposes a separate tool registry, and small models frequently claim an action succeeded without actually invoking the tool. Before pointing real data at a model, verify it with:

```
docker compose exec app php artisan chat:models --probe=ollama

```

This runs a live tool-calling smoke test against your Ollama endpoint. The CRM server's RAM estimate does not include local inference. Check your chosen model's memory and hardware requirements separately. A successful probe tests tool calling, not response quality across every CRM task. If you'd rather serve multiple models to multiple users at once, `SELF_HOSTED_AI_URL`, `SELF_HOSTED_AI_KEY`, and `SELF_HOSTED_AI_MODELS` point the same picker at any OpenAI-compatible server (vLLM, LM Studio, LocalAI).

![The chat model picker with local Ollama models listed next to Claude and GPT entries](https://relaticle.com/storage/ink/01M09FYYE6NCKYW6X4Z462GGM2.png)

**MCP server.** With no `MCP_DOMAIN` set, the server is reachable at `{APP_URL}/mcp` out of the box, no separate deploy step. Create a personal access token from **Settings → Access Tokens** in the app, then point any MCP client at it:

```
{
  "mcpServers": {
    "relaticle": {
      "type": "streamable-http",
      "url": "https://crm.example.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

```

That's the full tool surface: account info, cross-entity search/fetch, and CRUD across companies, people, opportunities, tasks, and notes, plus schema resources so the client can see your custom fields. Nothing about the route is different on a self-hosted install versus the hosted one, other than the domain you point at.

[](#what-you-actually-give-up-self-hosting "Permalink")What you actually give up self-hosting
---------------------------------------------------------------------------------------------

Self-hosting the AI features doesn't mean unlimited or unmetered usage, and it's worth knowing where the edges are before you rely on it.

- **Chat is still credit-metered, even with your own API key or a local model.** With billing disabled, a new self-hosted workspace uses the Free allowance: 300 credits per calendar month. Hosted trials and subscriptions have different credit periods and allowances. Running Ollama on your own GPU doesn't change that ceiling by itself, since it's enforced in the same code path regardless of which model answered. If a team needs more, the instance-wide `sysadmin` panel (`{APP_URL}/sysadmin`, from the account you created earlier) can adjust a team's balance or switch its plan directly, with no Stripe account required for that path.

    ![The sysadmin panel's credit balances page with per-team Adjust and Reset period actions](https://relaticle.com/storage/ink/01M09FZ0J61P4D2TPPCEV27EJJ.png)
- **Every response has a 120-second budget.** If a model doesn't finish in time, the turn stops cleanly (your message stays in the conversation with a clear notice, nothing is silently lost), but "thinking" models like `qwen3` reason before answering and hit that ceiling more often. A smaller or faster model, or a GPU, helps.
- **Parallel tool-call controls differ by provider.** Relaticle disables parallel tool calls in its Anthropic and OpenAI integrations. Its self-hosted integrations do not receive that same control. A turn can contain several proposed steps, and writes still require approval. Review the complete proposal before approving.
- **Tool-calling reliability varies a lot by model.** This is the reason `chat:models --probe` exists: run it before trusting any new local or self-hosted model with real writes, rather than finding out the hard way that a smaller model silently skipped a delete it claimed to have made.

Credit metering and approval apply to the built-in assistant. Self-hosted administrators can manage workspace plans and balances without Stripe. Direct MCP usage does not consume the built-in assistant's credit balance, but your MCP client or model provider may charge separately.

[](#where-to-go-from-here "Permalink")Where to go from here
-----------------------------------------------------------

Back up PostgreSQL, uploaded files, deployment configuration, and the original `APP_KEY` together. Stop application writers while taking the database and storage copies.

For a recovery drill, use a separate deployment with an empty database. Restore the database before starting the application and running its automatic migrations.

Use `psql -v ON_ERROR_STOP=1` so SQL errors fail the import. Restore uploaded files and their ownership, then check relationships, encrypted values, and attachment bytes.

Keep outbound integrations blocked and workers stopped until recovery checks pass. Preserve the original image and encryption secrets throughout the drill.

The environment variable reference, deployment guidance, and troubleshooting for restart loops and failed migrations are in the self-hosting guide: [relaticle.com/developers/self-hosting](https://relaticle.com/developers/self-hosting). For the complete MCP tool list, schema resources, and setup instructions for Claude Desktop, Claude Code, Cursor, and VS Code, see [relaticle.com/developers/mcp](https://relaticle.com/developers/mcp).

 Tagged: [ #self-hosting ](https://relaticle.com/blog/tag/self-hosting) [ #mcp ](https://relaticle.com/blog/tag/mcp) 

 Related posts
-------------

 [  Guides   Oct 2, 2026  

 Five CRM workflows to hand to Claude 
--------------------------------------

Five CRM workflows for Claude: pipeline reviews, meeting notes, lead entry, data cleanup, and weekly digests, with explicit read and write boundaries.

 ![Five CRM workflows to hand to Claude](https://relaticle.com/storage/ink/01M17KWYEEY8XB0VPJB7VV1D1Z.png) ](https://relaticle.com/blog/five-crm-workflows-to-hand-to-claude) [  Guides   Sep 29, 2026  

 Backups, upgrades, and security for a self-hosted CRM 
-------------------------------------------------------

A practical operating playbook for backing up, upgrading, and securing a self-hosted CRM without treating customer data casually.

 ![Backups, upgrades, and security for a self-hosted CRM](https://relaticle.com/storage/ink/01M17KWWPXPKX3V7DN7YZGR2PW.png) ](https://relaticle.com/blog/backups-upgrades-and-security-for-a-self-hosted-crm) [  Guides   Sep 18, 2026  

 The Real Cost of Self-Hosting a CRM 
-------------------------------------

Self-hosting a CRM can be cheap, but it is not free. Here is the infrastructure, time, and SaaS comparison math.

 ![The Real Cost of Self-Hosting a CRM](https://relaticle.com/storage/ink/01M17KWQF2PGK7BC11JAF2MJ0W.png) ](https://relaticle.com/blog/the-real-cost-of-self-hosting-a-crm) 

    ###    On this page
