Added doker compose
This commit is contained in:
3
.env_example
Normal file
3
.env_example
Normal file
@@ -0,0 +1,3 @@
|
||||
OLLAMA_URL=https://ollama.host.com
|
||||
OLLAMA_AUTH="Basic <BASE64 Auth string>"
|
||||
#OLLAMA_AUTH="Bearer <TOKEN>"
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,4 @@
|
||||
/target
|
||||
/inbox
|
||||
/storage
|
||||
.env
|
||||
|
||||
54
README.md
54
README.md
@@ -164,7 +164,59 @@ All options can be set via CLI flags or environment variables.
|
||||
| `--oidc-client-secret` | `FURUMI_PLAYER_OIDC_CLIENT_SECRET` | — | OIDC client secret |
|
||||
| `--oidc-redirect-url` | `FURUMI_PLAYER_OIDC_REDIRECT_URL` | — | OIDC redirect URL |
|
||||
| `--oidc-session-secret` | `FURUMI_PLAYER_OIDC_SESSION_SECRET` | *(random)* | Session HMAC secret |
|
||||
|
||||
|
||||
## Docker Compose
|
||||
|
||||
The easiest way to run the entire backend stack (PostgreSQL, Agent, Web Player, and gRPC Server) is using Docker Compose.
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Prepare directories**:
|
||||
```bash
|
||||
mkdir -p inbox storage
|
||||
```
|
||||
2. **Start the services**:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
3. **Check logs**:
|
||||
```bash
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
The following services will be available:
|
||||
- **Web Player**: [http://localhost:8085](http://localhost:8085)
|
||||
- **Agent Admin UI**: [http://localhost:8090](http://localhost:8090)
|
||||
- **Metrics**: [http://localhost:9090/metrics](http://localhost:9090/metrics)
|
||||
|
||||
> [!NOTE]
|
||||
> The Agent expects Ollama to be running. By default, it tries to connect to the host at `http://localhost:11434`.
|
||||
|
||||
### Reference Commands
|
||||
|
||||
- **Start**: `docker compose up -d`
|
||||
- **Stop**: `docker compose stop`
|
||||
- **Stop and remove containers**: `docker compose down`
|
||||
- **Clear database and storage**: `docker compose down -v`
|
||||
|
||||
### Environment Variables
|
||||
|
||||
To configure the Agent (especially for remote Ollama or private models) and database, create an `.env` file in the root directory:
|
||||
|
||||
```env
|
||||
# Database
|
||||
POSTGRES_PASSWORD=secure-password
|
||||
|
||||
# LLM (Ollama)
|
||||
OLLAMA_URL=http://your-ollama-host:11434
|
||||
OLLAMA_AUTH="Bearer your-token"
|
||||
|
||||
# Server Security
|
||||
FURUMI_TOKEN=secure-server-token
|
||||
```
|
||||
|
||||
For more options, refer to the [Configuration](#configuration) section.
|
||||
|
||||
## Docker
|
||||
|
||||
Pre-built images are available on Docker Hub:
|
||||
|
||||
60
docker-compose.yml
Normal file
60
docker-compose.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:17-alpine
|
||||
container_name: furumi-db
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-furumi}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-furumi}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-furumi}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U furumi -d furumi"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
agent:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.agent
|
||||
container_name: furumi-agent
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8090:8090"
|
||||
environment:
|
||||
FURUMI_AGENT_DATABASE_URL: "postgres://${POSTGRES_USER:-furumi}:${POSTGRES_PASSWORD:-furumi}@db:5432/${POSTGRES_DB:-furumi}"
|
||||
FURUMI_AGENT_INBOX_DIR: "/inbox"
|
||||
FURUMI_AGENT_STORAGE_DIR: "/storage"
|
||||
FURUMI_AGENT_OLLAMA_URL: "${OLLAMA_URL:-http://host.docker.internal:11434}"
|
||||
FURUMI_AGENT_OLLAMA_AUTH: "${OLLAMA_AUTH:-CHANGE-ME}"
|
||||
FURUMI_PLAYER_BIND: "0.0.0.0:8090"
|
||||
volumes:
|
||||
- ./inbox:/inbox
|
||||
- ./storage:/storage
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
restart: always
|
||||
|
||||
web-player:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.web-player
|
||||
container_name: furumi-web-player
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8085:8085"
|
||||
environment:
|
||||
FURUMI_PLAYER_DATABASE_URL: "postgres://${POSTGRES_USER:-furumi}:${POSTGRES_PASSWORD:-furumi}@db:5432/${POSTGRES_DB:-furumi}"
|
||||
FURUMI_PLAYER_STORAGE_DIR: "/storage"
|
||||
FURUMI_PLAYER_BIND: "0.0.0.0:8085"
|
||||
volumes:
|
||||
- ./storage:/storage
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
@@ -32,6 +32,10 @@ pub struct Args {
|
||||
#[arg(long, env = "FURUMI_AGENT_OLLAMA_MODEL", default_value = "qwen3:14b")]
|
||||
pub ollama_model: String,
|
||||
|
||||
/// Authorization header value for Ollama API (e.g. "Bearer <token>" or "Basic <base64>")
|
||||
#[arg(long, env = "FURUMI_AGENT_OLLAMA_AUTH")]
|
||||
pub ollama_auth: Option<String>,
|
||||
|
||||
/// Inbox scan interval in seconds
|
||||
#[arg(long, env = "FURUMI_AGENT_POLL_INTERVAL_SECS", default_value_t = 30)]
|
||||
pub poll_interval_secs: u64,
|
||||
|
||||
@@ -22,6 +22,7 @@ pub async fn normalize(
|
||||
&state.config.ollama_model,
|
||||
&state.system_prompt,
|
||||
&user_message,
|
||||
state.config.ollama_auth.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -125,6 +126,7 @@ async fn call_ollama(
|
||||
model: &str,
|
||||
system_prompt: &str,
|
||||
user_message: &str,
|
||||
auth: Option<&str>,
|
||||
) -> anyhow::Result<String> {
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(120))
|
||||
@@ -151,7 +153,11 @@ async fn call_ollama(
|
||||
tracing::info!(%url, model, prompt_len = user_message.len(), "Calling Ollama API...");
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let resp = client.post(&url).json(&request).send().await?;
|
||||
let mut req = client.post(&url).json(&request);
|
||||
if let Some(auth_header) = auth {
|
||||
req = req.header("Authorization", auth_header);
|
||||
}
|
||||
let resp = req.send().await?;
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
if !resp.status().is_success() {
|
||||
|
||||
Reference in New Issue
Block a user