141 lines
4.4 KiB
Markdown
141 lines
4.4 KiB
Markdown
# Deployment
|
|
|
|
## Docker
|
|
|
|
The service ships with a `Dockerfile` based on `python:3.12-slim-bookworm` using [uv](https://astral.sh/uv/) for fast dependency installation.
|
|
|
|
### Configuration sources
|
|
|
|
The application now supports two configuration sources:
|
|
- environment variables
|
|
- a YAML config file
|
|
|
|
Load order:
|
|
1. per-request overrides
|
|
2. environment variables
|
|
3. YAML config file
|
|
4. built-in defaults
|
|
|
|
Supported config file locations:
|
|
- `config.yml`
|
|
- `config.yaml`
|
|
- `/config/config.yml`
|
|
- `/config/config.yaml`
|
|
|
|
You can also set an explicit config path with:
|
|
|
|
```bash
|
|
export EMAIL_CLASSIFIER_CONFIG=/path/to/config.yml
|
|
```
|
|
|
|
Example `config.yml`:
|
|
|
|
```yaml
|
|
llm:
|
|
provider: anthropic
|
|
base_url: https://api.minimax.io/anthropic
|
|
api_key: your_api_key_here
|
|
model: MiniMax-M2.7
|
|
temperature: 0.1
|
|
timeout_seconds: 60
|
|
max_retries: 3
|
|
```
|
|
|
|
### Building
|
|
|
|
```bash
|
|
docker build -t email-classifier .
|
|
```
|
|
|
|
### Running
|
|
|
|
```bash
|
|
docker run -d --name email-classifier \
|
|
-p 7999:7999 \
|
|
-e EMAIL_CLASSIFIER_CONFIG=/config/config.yml \
|
|
-e EMAIL_CLASSIFIER_DB_PATH=/data/email_classifier.db \
|
|
-v /path/to/config.yml:/config/config.yml:ro \
|
|
-v /path/to/local/data:/data \
|
|
email-classifier
|
|
```
|
|
|
|
Mount a persistent volume for `/data` (or wherever `EMAIL_CLASSIFIER_DB_PATH` points) to preserve the dedupe database across container restarts.
|
|
|
|
Environment variables still override file-based config, so you can keep most settings in YAML and override just one or two values at deploy time.
|
|
|
|
## Docker Compose example
|
|
|
|
```yaml
|
|
services:
|
|
email-classifier:
|
|
image: your-registry.example.com/your-org/email-classifier:latest
|
|
container_name: email-classifier
|
|
ports:
|
|
- "7999:7999"
|
|
environment:
|
|
EMAIL_CLASSIFIER_CONFIG: /config/config.yml
|
|
EMAIL_CLASSIFIER_DB_PATH: /data/email_classifier.db
|
|
# Optional overrides. Env vars win over YAML values.
|
|
# LLM_MODEL: MiniMax-M2.7
|
|
# LLM_TIMEOUT_SECONDS: "90"
|
|
volumes:
|
|
- ./config.yml:/config/config.yml:ro
|
|
- ./data:/data
|
|
restart: unless-stopped
|
|
# If your LLM backend runs on the Docker host, one option is:
|
|
# extra_hosts:
|
|
# - "host.docker.internal:host-gateway"
|
|
```
|
|
|
|
### Compose notes
|
|
|
|
- Mount the YAML config read-only into the container, typically at `/config/config.yml`
|
|
- Mount a writable volume for `/data` so dedupe state survives restarts
|
|
- Override specific values with environment variables when needed
|
|
- If the LLM backend is another container on the same Compose network, use its service name in `base_url`
|
|
- If the LLM backend runs on the host, use `host.docker.internal` or a host-gateway mapping where appropriate
|
|
|
|
## Building for a Remote Registry
|
|
|
|
```bash
|
|
docker build -t \
|
|
your-registry.example.com/your-org/email-classifier:latest \
|
|
.
|
|
|
|
docker push your-registry.example.com/your-org/email-classifier:latest
|
|
```
|
|
|
|
## GitHub Actions CI/CD
|
|
|
|
The repository includes a workflow at `.github/workflows/build-publish.yaml` that builds and pushes a Docker image on every push to `main`.
|
|
|
|
### Required Secrets
|
|
|
|
Configure these in your GitHub/Gitea Actions secrets:
|
|
|
|
| Secret | Description |
|
|
|---|---|
|
|
| `DOCKER_REGISTRY` | Registry hostname (e.g., `ghcr.io` or your custom registry) |
|
|
| `DOCKER_USERNAME` | Registry username |
|
|
| `DOCKER_PASSWORD` | Registry password or access token |
|
|
|
|
The workflow tags the image as:
|
|
- `:latest` — always points to the latest commit on `main`
|
|
- `:<sha>` — the full git SHA of the triggering commit (useful for rollbacks)
|
|
|
|
### Deployment Considerations
|
|
|
|
- **Network access** — The container needs to reach your LLM backend. If using Ollama or another service on the host, use `host.docker.internal` or an explicit host-gateway mapping.
|
|
- **Dedupe persistence** — Mount a volume for the SQLite database to persist dedupe state across deploys.
|
|
- **Port** — The container exposes port `7999`. Map it to any host port you prefer.
|
|
- **Health check** — The service does not currently expose a dedicated `/health` endpoint. Use `GET /docs` as a liveness probe.
|
|
|
|
## Production Checklist
|
|
|
|
- [ ] Provide either a YAML config file or the required `LLM_*` environment variables
|
|
- [ ] Use HTTPS for remote `LLM_BASE_URL` values in production
|
|
- [ ] Mount a persistent volume for `EMAIL_CLASSIFIER_DB_PATH`
|
|
- [ ] Set appropriate resource limits (CPU/memory) on the container
|
|
- [ ] Configure `LLM_MAX_RETRIES` and `LLM_TIMEOUT_SECONDS` to suit your LLM backend's reliability
|
|
- [ ] Keep `LLM_TEMPERATURE` low for consistent classification results
|