# Docker Images

This repo provides two container images:

- `Dockerfile.server`: builds the AgentTeam Go server and schema/admin helper binaries.
- `Dockerfile.web`: builds the AgentTeam Web app and serves the static assets with nginx.

The web image does not proxy API traffic. Production deployments should use an
external ingress or reverse proxy to route backend paths to the server image and
all other paths to the web image.

## Local Compose

Use Docker Compose for a local deployment smoke test:

```bash
export AGENTTEAM_SERVER_VERSION="$(git describe --tags --always --dirty)"
export AGENTTEAM_SERVER_GIT_COMMIT="$(git rev-parse --short HEAD)"
docker compose up --build
```

Then open `http://localhost:8080`.

The compose stack includes:

- `tidb`: local TiDB in standalone unistore mode.
- `schema`: one-shot `/app/bin/agentteam-schema init` job.
- `server`: AgentTeam backend from `Dockerfile.server`.
- `web`: AgentTeam static web image from `Dockerfile.web`.
- `ingress`: local nginx entrypoint that mirrors the expected Kubernetes ingress
  split.

The local ingress routes backend-owned paths to `server:3001`:

- `/api/`
- `/internal/`
- `/socket.io/`
- `/healthz`
- `/readyz`

All other paths route to `web:80`.

The compose stack runs with `AGENTTEAM_ENV=development` and
`AGENTTEAM_PUBLIC_BASE_URL=http://localhost:8080` so it can run over local HTTP. It
also sets `AGENTTEAM_AUTH_REGISTRATION_MODE=open` for local sign-up testing.

To stop the stack while keeping local database and server data:

```bash
docker compose down
```

To remove local data as well:

```bash
docker compose down -v
```

## Build

For local smoke tests:

```bash
AGENTTEAM_SERVER_VERSION="$(git describe --tags --always --dirty)"
AGENTTEAM_SERVER_GIT_COMMIT="$(git rev-parse --short HEAD)"
docker build -f Dockerfile.server \
  --build-arg AGENTTEAM_SERVER_VERSION="${AGENTTEAM_SERVER_VERSION}" \
  --build-arg AGENTTEAM_SERVER_GIT_COMMIT="${AGENTTEAM_SERVER_GIT_COMMIT}" \
  -t agentteam-server:local .
docker build -f Dockerfile.web -t agentteam-web:local .
```

For Kubernetes releases, build for the cluster node platform and push immutable
git-SHA tags. For the current ACK deployment, use the registry names managed by
the GitOps repo:

```bash
SHA="$(git rev-parse --short HEAD)"
VERSION="$(git describe --tags --always --dirty)"
REGISTRY="pingcap-registry.cn-beijing.cr.aliyuncs.com/agentteam"
PLATFORM="linux/amd64"

docker buildx build --platform "${PLATFORM}" \
  -f Dockerfile.server \
  --build-arg AGENTTEAM_SERVER_VERSION="${VERSION}" \
  --build-arg AGENTTEAM_SERVER_GIT_COMMIT="${SHA}" \
  -t "${REGISTRY}/agentteam-server:${SHA}" \
  --push .

docker buildx build --platform "${PLATFORM}" \
  -f Dockerfile.web \
  -t "${REGISTRY}/agentteam-web:${SHA}" \
  --push .
```

If the cluster runs multiple CPU architectures, publish a multi-arch manifest
instead of a single-platform image. Do not rely on the platform of the local
developer machine.

## Server Image

The server listens on `3001` by default. At minimum, provide a TiDB/MySQL DSN:

```bash
docker run --rm \
  -p 3001:3001 \
  -v agentteam-data:/data \
  -e AGENTTEAM_DATABASE_DSN='root@tcp(tidb:4000)/agentteam?multiStatements=true&parseTime=true&loc=UTC' \
  agentteam-server:local
```

Before starting a new deployment or after upgrading the image, run schema init
against the same environment:

```bash
docker run --rm \
  -v agentteam-data:/data \
  -e AGENTTEAM_DATABASE_DSN='root@tcp(tidb:4000)/agentteam?multiStatements=true&parseTime=true&loc=UTC' \
  agentteam-server:local \
  /app/bin/agentteam-schema init
```

The image runs as user `65532:65532`. Its default writable state is under
`/data`, including:

- `AGENTTEAM_ARCHIVE_FILESYSTEM_ROOT=/data/archive`
- `AGENTTEAM_ORG_CREDENTIALS_KEY_FILE=/data/secrets/org_credentials_master_key`

Mount `/data` as a persistent volume unless all stateful features are configured
to use external services.

For production, set the normal runtime environment variables, including
`AGENTTEAM_ENV=production`, `AGENTTEAM_PUBLIC_BASE_URL`, and any required auth, mail,
media or integration settings.

If MeshX Knowledge Q&A Web Search is enabled, deploy SearXNG as a separate
service/container in the same private network as `agentteam-server`, enable the JSON
search format in SearXNG settings, and point AgentTeam at its internal service URL,
for example:

```env
MESHX_KNOWLEDGE_QA_WEB_SEARCH_PROVIDER=searxng
MESHX_KNOWLEDGE_QA_SEARXNG_BASE_URL=http://searxng:8080
```

Do not bake SearXNG into the `agentteam-server` image or process. For production
overlays, pin `docker.io/searxng/searxng` to an explicit version tag instead of
using `latest`.

If `AGENTTEAM_ENV=production`, the server enforces production-only validation such as
HTTPS public URLs. Keep any temporary non-production
mode in production overlays explicit in the deployment repo.

## Web Image

The web image serves static files on port `80`:

```bash
docker run --rm -p 8080:80 agentteam-web:local
```

It intentionally returns `404` for backend-owned paths:

- `/api`
- `/internal`
- `/socket.io`

Ingress should route those paths to `agentteam-server:3001`; all other paths should
route to `agentteam-web:80`.

## Kubernetes Deployment

The Kubernetes manifests live outside this repo in the GitOps delivery repo.
After pushing both images, update the tenant overlay image tags there:

```yaml
images:
  - name: pingcap-registry.cn-beijing.cr.aliyuncs.com/agentteam/agentteam-server
    newTag: <git-sha>
  - name: pingcap-registry.cn-beijing.cr.aliyuncs.com/agentteam/agentteam-web
    newTag: <git-sha>
```

The delivery repo should run `/app/bin/agentteam-schema init` as a schema Job before
rolling the `agentteam-server` Deployment. The same server image contains both
`agentteam-server` and `agentteam-schema`.

For ingress, route these paths to the server Service:

- `/api/`
- `/internal/`
- `/socket.io/`
- `/healthz`
- `/readyz`

Route `/` to the web Service. If the ingress controller uses backend health
checks, configure the server backend check path to `/healthz`.
