What goes in the Caddyfile that the Tares docker compose file mounts, and what happens if it is missing?
Tares ships a small Caddyfile with one hostname that sends /mcp and /sse to the MCP server and everything else to the daemon. The compose file mounts it into the Caddy container, so compose fails to start without it. Save the Caddyfile next to docker-compose.yml and the server comes up with one address for the console and the MCP endpoint.
How it works
The server setup runs three services: the daemon (taresd), the MCP server (mcp) and a Caddy reverse proxy. The proxy is the only service that publishes ports, 80 and 443. The other two are only exposed on the compose network.
The Caddy service mounts your Caddyfile from the directory that holds the compose file:
caddy:
image: caddy:2
ports: ["80:80", "443:443"]
environment:
TARES_DOMAIN: "${TARES_DOMAIN:-:80}"
volumes: ["./Caddyfile:/etc/caddy/Caddyfile:ro", "caddy-data:/data"]
depends_on: [taresd, mcp]
restart: unless-stoppedTwo things matter here:
- The mount is
./Caddyfile:/etc/caddy/Caddyfile:ro. Caddy reads the file from that path, read-only. The file is not baked into an image. TARES_DOMAINis passed into the Caddy container as an environment variable. It defaults to:80when you do not set it.
Because the mount points at a file you provide, a missing Caddyfile means compose fails to start. Nothing else about the stack changes. The daemon and MCP server definitions do not depend on the file, but the proxy that fronts them cannot come up without it.
Set it up
- Make one directory for the deployment and put
docker-compose.ymlin it. Both files ship in the Tares repo underdeploy/compose/, and the Deployment page has them in full. - Save the following as
Caddyfilein that same directory, with that exact name, because the compose file mounts./Caddyfile:
# Caddyfile: one hostname; /mcp and /sse go to the MCP server, the rest to the daemon
{$TARES_DOMAIN} {
handle /mcp* { reverse_proxy mcp:8788 }
handle /sse* { reverse_proxy mcp:8788 }
handle { reverse_proxy taresd:8787 }
}- Read the file as three routes under one site address:
- The site address is the value of
TARES_DOMAIN, so the same file serves a real hostname or plain:80. - Paths starting with
/mcpgo tomcp:8788, the MCP server. - Paths starting with
/ssealso go tomcp:8788, for clients that use the SSE transport. - The last
handlehas no path, so every other request goes totaresd:8787, the daemon. That covers the console, the API and ingest.
- The site address is the value of
- Set
TARES_AUTH_TOKENandTARES_DOMAINin your shell, then start the stack from that directory with compose, as the Deployment page shows. Compose requiresTARES_AUTH_TOKENand stops with the messageset TARES_AUTH_TOKENif it is empty. - Open the console at your domain, and point MCP clients at the same domain with
/mcpadded.
You do not edit the service names mcp and taresd in the Caddyfile unless you also rename the services in the compose file. The two files refer to each other by those names and ports (8788 and 8787).
What you get
- One public hostname for everything. The console, API and ingest answer on the root, and the MCP endpoint answers on
/mcp. - A clear failure when the file is absent. Compose fails to start, so you find the problem at launch and not after a half-working deploy.
- A file that is short enough to read in one pass and change when you need a different route.
- The same Caddyfile for a trial and for production, because the site address comes from
TARES_DOMAIN. Leave it unset and Caddy serves plain HTTP on:80.
How a real hostname turns into HTTPS, and what to set up in DNS first, is covered on the Deployment page. If you are using Tares for incident work, the AI SRE guide shows what to connect once the endpoint is reachable.
When something else fits
- If you only want the console on your own machine, run
tares upand skip compose and the Caddyfile. The console is then athttp://127.0.0.1:8787. - If you want the console and MCP endpoint without a proxy, run the two containers from the Docker section of the Deployment page. You get ports 8787 and 8788 directly, with no TLS.
- If you already run your own reverse proxy, you can route the same way there:
/mcpand/sseto the MCP server, everything else to the daemon.
Related
Still stuck? Get help