Documentation Index Fetch the complete documentation index at: https://mintlify.com/operatoronline/weaver/llms.txt
Use this file to discover all available pages before exploring further.
Weaver provides production-ready Docker images for deploying AI agents in containerized environments. This guide covers building images, using Docker Compose, and production best practices.
Dockerfile Overview
Weaver uses a multi-stage build for minimal image size and security (source/Dockerfile):
# ============================================================
# Stage 1: Build the weaver binary
# ============================================================
FROM golang:1.26.0-alpine AS builder
RUN apk add --no-cache git make
WORKDIR /src
# Cache dependencies
COPY go.mod go.sum ./
RUN go mod download
# Copy source and build
COPY . .
RUN make build
# ============================================================
# Stage 2: Minimal runtime image
# ============================================================
FROM alpine:3.23
RUN apk add --no-cache ca-certificates tzdata curl
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q --spider http://localhost:18790/health || exit 1
# Copy binary
COPY --from=builder /src/build/weaver /usr/local/bin/weaver
# Create weaver home directory
RUN /usr/local/bin/weaver onboard
ENTRYPOINT [ "weaver" ]
CMD [ "gateway" ]
Key Features
Multi-stage build : Separates build dependencies from runtime
Alpine base : Minimal image size (~50MB)
Health check : Built-in endpoint monitoring
Automatic onboarding : Creates default config on first run
Flexible entrypoint : Supports both agent and gateway modes
Building the Image
Clone Repository
git clone https://github.com/operatoronline/weaver.git
cd weaver
Build Docker Image
docker build -t weaver:latest .
This creates an image with:
Compiled Weaver binary
Default configuration structure
Health check endpoint at port 18790
Verify Build
Expected output: REPOSITORY TAG IMAGE ID CREATED SIZE
weaver latest abc123def456 2 minutes ago 52MB
Docker Compose Setup
Weaver includes a production-ready compose file (source/docker-compose.yml) with two deployment profiles:
Profile 1: One-Shot Agent
For running single queries without persistent state:
services :
# ─────────────────────────────────────────────
# Weaver Agent (one-shot query)
# docker compose run --rm weaver-agent -m "Hello"
# ─────────────────────────────────────────────
weaver-agent :
build :
context : .
dockerfile : Dockerfile
container_name : weaver-agent
profiles :
- agent
volumes :
- ./config/config.json:/root/.weaver/config.json:ro
- weaver-workspace:/root/.weaver/workspace
entrypoint : [ "weaver" , "agent" ]
stdin_open : true
tty : true
Profile 2: Long-Running Gateway
For persistent bot service with auto-restart:
services :
# ─────────────────────────────────────────────
# Weaver Gateway (Long-running Bot)
# docker compose up weaver-gateway
# ─────────────────────────────────────────────
weaver-gateway :
build :
context : .
dockerfile : Dockerfile
container_name : weaver-gateway
restart : unless-stopped
profiles :
- gateway
volumes :
# Configuration file
- ./config/config.json:/root/.weaver/config.json:ro
# Persistent workspace (sessions, memory, logs)
- weaver-workspace:/root/.weaver/workspace
command : [ "gateway" ]
volumes :
weaver-workspace :
Deployment Modes
One-Shot Agent Mode
Run a single query and exit:
Prepare Configuration
Create config/config.json with your API keys: {
"agents" : {
"defaults" : {
"model" : "claude-3-5-sonnet-20241022" ,
"max_tokens" : 8192
}
},
"providers" : {
"anthropic" : {
"api_key" : "${ANTHROPIC_API_KEY}"
}
}
}
Run One-Shot Query
docker compose --profile agent run --rm weaver-agent -m "What is the capital of France?"
Output: The capital of France is Paris.
Container automatically stops after response.
Interactive Session
For multi-turn conversations: docker compose --profile agent run --rm weaver-agent
Then interact via terminal.
Gateway Mode (Production)
Run persistent bot service:
Configure Channels
Update config/config.json with channel credentials: {
"channels" : {
"telegram" : {
"enabled" : true ,
"token" : "${TELEGRAM_BOT_TOKEN}" ,
"allow_from" : [ "${TELEGRAM_USER_ID}" ]
},
"discord" : {
"enabled" : true ,
"token" : "${DISCORD_BOT_TOKEN}"
}
},
"gateway" : {
"host" : "0.0.0.0" ,
"port" : 18790
}
}
Start Gateway Service
docker compose --profile gateway up -d
This:
Starts gateway in background
Auto-restarts on failure
Connects to all enabled channels
Exposes health check on port 18790
Verify Status
Check container health: docker compose --profile gateway ps
Expected output: NAME IMAGE STATUS PORTS
weaver-gateway weaver Up 30 seconds (healthy) 18790/tcp
View Logs
docker compose --profile gateway logs -f
Volume Management
Weaver uses Docker volumes for persistent data:
Workspace Volume
From docker-compose.yml:15 and :36:
volumes :
- weaver-workspace:/root/.weaver/workspace
Stores:
Agent session state
Conversation history
Tool execution results
User files created by agents
Configuration Mount
From docker-compose.yml:14 and :34:
volumes :
- ./config/config.json:/root/.weaver/config.json:ro
Mounted read-only (:ro) for security. Update host file and restart container to apply changes.
Inspecting Volume Data
List Volume Contents
Access Volume Shell
Backup Volume
Restore Volume
docker run --rm -v weaver-workspace:/workspace alpine ls -la /workspace
Health Checks
The Dockerfile includes a health check (Dockerfile:26):
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q --spider http://localhost:18790/health || exit 1
Health Check Parameters
Interval : Check every 30 seconds
Timeout : Consider unhealthy if check takes >3 seconds
Start period : Grace period of 5 seconds after container start
Retries : Mark unhealthy after 3 consecutive failures
Testing Health Endpoint
curl http://localhost:18790/health
Expected response:
Production Configuration
Using Environment Variables
Secure secrets with environment variables:
Create .env File
# LLM Providers
ANTHROPIC_API_KEY = sk-ant-xxx
OPENAI_API_KEY = sk-xxx
GEMINI_API_KEY = xxx
# Chat Channels
TELEGRAM_BOT_TOKEN = 123456:ABC-DEF
TELEGRAM_USER_ID = 123456789
DISCORD_BOT_TOKEN = xxx
# Tools
BRAVE_SEARCH_API_KEY = BSA...
# Timezone
TZ = Asia/Tokyo
Update docker-compose.yml
weaver-gateway :
build :
context : .
dockerfile : Dockerfile
container_name : weaver-gateway
restart : unless-stopped
env_file :
- .env
environment :
- WEAVER_CHANNELS_TELEGRAM_ENABLED=true
- WEAVER_CHANNELS_DISCORD_ENABLED=true
volumes :
- ./config/config.json:/root/.weaver/config.json:ro
- weaver-workspace:/root/.weaver/workspace
command : [ "gateway" ]
Reference in Config
{
"providers" : {
"anthropic" : {
"api_key" : "${ANTHROPIC_API_KEY}"
}
},
"channels" : {
"telegram" : {
"enabled" : true ,
"token" : "${TELEGRAM_BOT_TOKEN}" ,
"allow_from" : [ "${TELEGRAM_USER_ID}" ]
}
}
}
Reverse Proxy Setup
For webhook-based channels (LINE, Feishu), use nginx:
upstream weaver {
server localhost:18790;
}
server {
listen 443 ssl http2;
server_name weaver.yourdomain.com;
ssl_certificate /etc/ssl/certs/weaver.crt;
ssl_certificate_key /etc/ssl/private/weaver.key;
location /webhook/ {
proxy_pass http://weaver;
proxy_set_header Host $ host ;
proxy_set_header X-Real-IP $ remote_addr ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
}
location /health {
proxy_pass http://weaver;
access_log off ;
}
}
Update docker-compose.yml to expose port:
weaver-gateway :
ports :
- "18790:18790"
Multi-Service Deployment
Deploy with additional services:
docker-compose.production.yml
services :
weaver-gateway :
build :
context : .
dockerfile : Dockerfile
container_name : weaver-gateway
restart : unless-stopped
env_file :
- .env
volumes :
- ./config/config.json:/root/.weaver/config.json:ro
- weaver-workspace:/root/.weaver/workspace
command : [ "gateway" ]
depends_on :
- redis
networks :
- weaver-net
redis :
image : redis:7-alpine
container_name : weaver-redis
restart : unless-stopped
volumes :
- redis-data:/data
networks :
- weaver-net
prometheus :
image : prom/prometheus:latest
container_name : weaver-prometheus
restart : unless-stopped
volumes :
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
ports :
- "9090:9090"
networks :
- weaver-net
volumes :
weaver-workspace :
redis-data :
prometheus-data :
networks :
weaver-net :
driver : bridge
Start entire stack:
docker compose -f docker-compose.production.yml up -d
Monitoring and Logging
Container Logs
Follow Logs
Last 100 Lines
Logs Since Timestamp
Export Logs
docker compose --profile gateway logs -f weaver-gateway
Resource Usage
docker stats weaver-gateway
Output:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
abc123def456 weaver-gateway 2.5% 128MB / 2GB 6.4%
Updating Weaver
Rebuild Image
docker compose --profile gateway build
Restart Service
docker compose --profile gateway up -d
Docker automatically:
Stops old container
Starts new container
Preserves volume data
Maintains zero downtime with health checks
Verify Update
docker compose --profile gateway exec weaver-gateway weaver version
Troubleshooting
Container Exits Immediately
Verify health endpoint: docker compose --profile gateway exec weaver-gateway wget -O- http://localhost:18790/health
If failing:
Check gateway configuration
Ensure port 18790 is not blocked
Review container logs for errors
Configuration Not Applied
Ensure config.json has valid JSON syntax
Verify volume mount path is correct
Restart container after config changes
Check environment variable substitution
Fix workspace permissions: docker run --rm -v weaver-workspace:/workspace alpine chown -R 1000:1000 /workspace
Best Practices
Never commit API keys to version control
Use environment variables for secrets
Mount config as read-only (:ro)
Restrict allow_from to trusted users
Keep base image updated (alpine:3.23)
Use restart: unless-stopped for production
Configure health checks
Monitor container resource usage
Set up log rotation
Backup workspace volume regularly
Tag images with version numbers
Document configuration changes
Test updates in staging first
Keep compose files in version control
Next Steps