From 8d8dc560f07725c7b23f990d52b65e37e45e92a4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 02:52:07 +0000 Subject: [PATCH 1/5] Add Docker support with Dockerfile and comprehensive documentation Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- .dockerignore | 66 +++++++ CHANGELOG.md | 1 + Dockerfile | 58 ++++++ Dockerfile.prebuilt | 42 ++++ docker-compose.example.yml | 82 ++++++++ docs/SUMMARY.md | 4 + docs/deployment/docker.md | 396 +++++++++++++++++++++++++++++++++++++ 7 files changed, 649 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 Dockerfile.prebuilt create mode 100644 docker-compose.example.yml create mode 100644 docs/deployment/docker.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..c53c024a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,66 @@ +# Git files +.git +.gitignore +.gitattributes + +# GitHub workflows and documentation +.github +docs/book +docs/TODO.md + +# Target and build artifacts +target/** +!target/release/wassette +bin +*.wasm + +# Examples and tests +examples/*/target +tests + +# Documentation +*.md +!README.md +LICENSE +NOTICE +SECURITY.md +CODE_OF_CONDUCT.md +CONTRIBUTING.md + +# Development files +.vscode +.idea +*.swp +*.swo +*~ + +# Rust artifacts +**/*.rs.bk +Cargo.lock.bak + +# OS files +.DS_Store +Thumbs.db + +# CI/Docker files +Dockerfile.ci +docker-compose.yml + +# Scripts +scripts + +# Package manager files +Formula +flake.nix +flake.lock +winget + +# Other +assets +audit.toml +deny.toml +_typos.toml +rustfmt.toml +component-registry.json +policy.yaml +install.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 64491ff9..2bfd66ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Added +- Comprehensive Docker documentation and Dockerfile for running Wassette in containers with enhanced security isolation, including examples for mounting components, secrets, configuration files, and production deployment patterns with Docker Compose - AI agent development guides (`AGENTS.md` and `Claude.md`) that consolidate development guidelines from `.github/instructions/` into accessible documentation for AI agents working on the project - Comprehensive installation guide page consolidating all installation methods (one-liner script, Homebrew, Nix, WinGet) organized by platform (Linux, macOS, Windows) with verification steps and troubleshooting sections - Cookbook section in documentation with language-specific guides for building Wasm components in JavaScript/TypeScript, Python, Rust, and Go ([#328](https://github.com/microsoft/wassette/pull/328)) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..18884d7e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# Wassette Docker Image +# This Dockerfile provides a containerized runtime for Wassette with additional security isolation + +# Stage 1: Build the Wassette binary +FROM rust:1.83-bookworm AS builder + +# Install ca-certificates for HTTPS support during build +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /build + +# Copy the project files +COPY Cargo.toml Cargo.lock ./ +COPY src ./src +COPY crates ./crates +COPY build.rs ./ + +# Build the release binary +RUN cargo build --release --bin wassette + +# Stage 2: Create the runtime image +FROM debian:bookworm-slim + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + libssl3 && \ + rm -rf /var/lib/apt/lists/* + +# Create a non-root user for running Wassette +RUN useradd -m -u 1000 -s /bin/bash wassette + +# Create necessary directories with proper permissions +RUN mkdir -p /home/wassette/.local/share/wassette/components && \ + mkdir -p /home/wassette/.config/wassette/secrets && \ + chown -R wassette:wassette /home/wassette + +# Copy the binary from the builder stage +COPY --from=builder /build/target/release/wassette /usr/local/bin/wassette + +# Set up environment +ENV HOME=/home/wassette +ENV XDG_DATA_HOME=/home/wassette/.local/share +ENV XDG_CONFIG_HOME=/home/wassette/.config + +# Switch to the non-root user +USER wassette +WORKDIR /home/wassette + +# Expose the default HTTP port (when using --http or --sse) +EXPOSE 9001 + +# Default command: start Wassette with stdio transport +# Override this in docker run or docker-compose for different transports +CMD ["wassette", "serve", "--stdio"] diff --git a/Dockerfile.prebuilt b/Dockerfile.prebuilt new file mode 100644 index 00000000..876b3357 --- /dev/null +++ b/Dockerfile.prebuilt @@ -0,0 +1,42 @@ +# Wassette Docker Image (Pre-built Binary) +# This Dockerfile uses a pre-built Wassette binary for faster builds +# Useful when you already have the binary compiled on your host system + +FROM debian:bookworm-slim + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + libssl3 && \ + rm -rf /var/lib/apt/lists/* + +# Create a non-root user for running Wassette +RUN useradd -m -u 1000 -s /bin/bash wassette + +# Create necessary directories with proper permissions +RUN mkdir -p /home/wassette/.local/share/wassette/components && \ + mkdir -p /home/wassette/.config/wassette/secrets && \ + chown -R wassette:wassette /home/wassette + +# Copy the pre-built binary from the host (build context) +# Build the binary first with: cargo build --release --bin wassette +# Then copy it: COPY target/release/wassette /usr/local/bin/wassette +COPY target/release/wassette /usr/local/bin/wassette +RUN chmod +x /usr/local/bin/wassette + +# Set up environment +ENV HOME=/home/wassette +ENV XDG_DATA_HOME=/home/wassette/.local/share +ENV XDG_CONFIG_HOME=/home/wassette/.config + +# Switch to the non-root user +USER wassette +WORKDIR /home/wassette + +# Expose the default HTTP port (when using --http or --sse) +EXPOSE 9001 + +# Default command: start Wassette with stdio transport +# Override this in docker run or docker-compose for different transports +CMD ["wassette", "serve", "--stdio"] diff --git a/docker-compose.example.yml b/docker-compose.example.yml new file mode 100644 index 00000000..c60d3012 --- /dev/null +++ b/docker-compose.example.yml @@ -0,0 +1,82 @@ +# Example Docker Compose configuration for Wassette +# Copy this file to docker-compose.yml and customize for your needs + +version: '3.8' + +services: + wassette: + build: . + image: wassette:latest + + # Expose port 9001 for HTTP/SSE access + ports: + - "9001:9001" + + # Mount volumes for components, secrets, and configuration + volumes: + # Component directory (read-only for security) + - ./components:/home/wassette/.local/share/wassette/components:ro + + # Secrets directory (read-only) + # Store API keys and credentials here + - ./secrets:/home/wassette/.config/wassette/secrets:ro + + # Optional: Custom configuration file + # - ./config.toml:/home/wassette/.config/wassette/config.toml:ro + + # Optional: Persistent component storage + # Use this if you want to load components via the MCP interface + # and persist them across container restarts + # - wassette-components:/home/wassette/.local/share/wassette/components + + # Environment variables + environment: + # Set log level (trace, debug, info, warn, error) + - RUST_LOG=info + + # Add any additional environment variables your components need + # - OPENWEATHER_API_KEY=your_api_key_here + + # Command to run (override the default CMD from Dockerfile) + # Note: stdio is the default and recommended for MCP clients + + # Option 1: Stdio transport (default, recommended) + command: ["wassette", "serve", "--stdio"] + + # Option 2: SSE transport (requires host networking on Linux) + # command: ["wassette", "serve", "--sse"] + # network_mode: host # Uncomment for SSE/HTTP access + + # Security: Limit container resources + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + cpus: '0.5' + memory: 256M + + # Security: Drop unnecessary capabilities + cap_drop: + - ALL + + # Security: Prevent privilege escalation + security_opt: + - no-new-privileges:true + + # Optional: Health check for SSE/HTTP transports + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9001/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Restart policy + restart: unless-stopped + +# Optional: Named volumes for persistent storage +# volumes: +# wassette-components: +# driver: local diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 1c04171b..c7543b75 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -19,6 +19,10 @@ - [CLI](./reference/cli.md) - [Permissions](./reference/permissions.md) +# Deployment + +- [Docker](./deployment/docker.md) + # Design & Architecture - [Architecture](./design/architecture.md) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md new file mode 100644 index 00000000..7cecb27d --- /dev/null +++ b/docs/deployment/docker.md @@ -0,0 +1,396 @@ +# Running Wassette in Docker + +This guide explains how to run Wassette in a Docker container for enhanced security isolation. Containerizing Wassette provides an additional layer of defense by isolating the runtime environment from your host system. + +## Why Use Docker with Wassette? + +Running Wassette in Docker provides several benefits: + +- **Enhanced Security**: Docker containers provide an additional isolation layer on top of Wassette's WebAssembly sandbox +- **Reproducible Environment**: Ensures consistent runtime behavior across different systems +- **Easy Deployment**: Simplifies deployment to production environments +- **Resource Control**: Allows fine-grained control over CPU, memory, and network resources + +## Prerequisites + +- Docker installed on your system ([Install Docker](https://docs.docker.com/get-docker/)) +- Basic familiarity with Docker commands + +## Quick Start + +### Build the Docker Image + +From the Wassette repository root: + +```bash +docker build -t wassette:latest . +``` + +This builds a multi-stage Docker image that: +1. Compiles Wassette from source in a Rust build environment +2. Creates a minimal runtime image with only necessary dependencies +3. Runs as a non-root user for enhanced security + +### Run with Stdio Transport + +For use with MCP clients that expect stdio: + +```bash +docker run -i --rm wassette:latest +``` + +### Run with HTTP/SSE Transport + +**Note**: The current version of Wassette binds to `127.0.0.1:9001`, which doesn't work directly with Docker port forwarding. The stdio transport is recommended for Docker deployments. HTTP/SSE support for Docker will be improved in a future release. + +If you need HTTP/SSE access in Docker, you can use a workaround with host networking: + +```bash +# Using host network mode (Linux only) +docker run --rm --network host wassette:latest wassette serve --sse +``` + +Then connect to `http://localhost:9001/sse` from your MCP client on the host. + +## Mounting Components + +To use custom WebAssembly components with Wassette in Docker, you need to mount the component directory: + +### Mount a Local Component Directory + +```bash +# Mount your local components directory +docker run -i --rm \ + -v /path/to/your/components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest +``` + +**Important**: Use `:ro` (read-only) for the component directory when possible to prevent accidental modifications. + +### Example: Running with Filesystem Component + +```bash +# Build example components first (on host) +cd examples/filesystem-rs +cargo build --release --target wasm32-wasip2 + +# Run Wassette with the example component mounted (stdio transport) +docker run -i --rm \ + -v $(pwd)/examples/filesystem-rs/target/wasm32-wasip2/release:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest + +# If you need SSE transport on Linux, use host networking: +# docker run --rm --network host \ +# -v $(pwd)/examples/filesystem-rs/target/wasm32-wasip2/release:/home/wassette/.local/share/wassette/components:ro \ +# wassette:latest wassette serve --sse +``` + +### Example: Running with Multiple Component Directories + +You can mount multiple component directories using multiple `-v` flags: + +```bash +docker run -i --rm \ + -v /path/to/components1:/home/wassette/.local/share/wassette/components:ro \ + -v /path/to/data:/data:rw \ + wassette:latest +``` + +## Mounting Secrets + +If your components require secrets (API keys, credentials, etc.), mount the secrets directory: + +```bash +docker run -i --rm \ + -v /path/to/secrets:/home/wassette/.config/wassette/secrets:ro \ + -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest +``` + +**Security Note**: Always mount secrets as read-only (`:ro`) and ensure proper file permissions. + +## Configuration + +### Using Environment Variables + +Pass environment variables to the container: + +```bash +docker run -i --rm \ + -e RUST_LOG=debug \ + -e OPENWEATHER_API_KEY=your_api_key \ + wassette:latest +``` + +### Using a Configuration File + +Mount a custom configuration file: + +```bash +docker run -i --rm \ + -v /path/to/config.toml:/home/wassette/.config/wassette/config.toml:ro \ + wassette:latest +``` + +Example `config.toml`: + +```toml +# Directory where components are stored +plugin_dir = "/home/wassette/.local/share/wassette/components" + +# Environment variables to be made available to components +[environment_vars] +API_KEY = "your_api_key" +LOG_LEVEL = "info" +``` + +## Docker Compose + +For more complex setups, use Docker Compose: + +```yaml +# docker-compose.yml +version: '3.8' + +services: + wassette: + build: . + image: wassette:latest + # Note: Port mapping works best with --network host on Linux + # or use stdio transport without port mapping + # ports: + # - "9001:9001" + volumes: + # Mount component directory (read-only) + - ./components:/home/wassette/.local/share/wassette/components:ro + # Mount secrets directory (read-only) + - ./secrets:/home/wassette/.config/wassette/secrets:ro + # Mount config file (optional) + - ./config.toml:/home/wassette/.config/wassette/config.toml:ro + environment: + - RUST_LOG=info + # Use SSE transport for network access + command: ["wassette", "serve", "--sse"] + # Security: Run with limited resources + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M +``` + +Run with: + +```bash +docker-compose up +``` + +## Security Best Practices + +### 1. Run as Non-Root User + +The Dockerfile already configures Wassette to run as a non-root user (`wassette:1000`). Never run as root: + +```bash +# Good: Uses default non-root user +docker run -i --rm wassette:latest + +# Bad: Don't do this! +# docker run -i --rm --user root wassette:latest +``` + +### 2. Use Read-Only Mounts + +Mount component and secret directories as read-only when possible: + +```bash +docker run -i --rm \ + -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest +``` + +### 3. Limit Container Resources + +Prevent resource exhaustion by setting limits: + +```bash +docker run -i --rm \ + --memory="512m" \ + --cpus="1.0" \ + --pids-limit=100 \ + wassette:latest +``` + +### 4. Use Read-Only Root Filesystem + +For maximum security, run with a read-only root filesystem: + +```bash +docker run -i --rm \ + --read-only \ + --tmpfs /tmp:rw,noexec,nosuid,size=50m \ + -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest +``` + +### 5. Drop Unnecessary Capabilities + +Drop Linux capabilities that Wassette doesn't need: + +```bash +docker run -i --rm \ + --cap-drop=ALL \ + --security-opt=no-new-privileges:true \ + wassette:latest +``` + +### 6. Enable Security Profiles + +Use AppArmor or SELinux for additional security: + +```bash +# With AppArmor +docker run -i --rm \ + --security-opt apparmor=docker-default \ + wassette:latest + +# With SELinux +docker run -i --rm \ + --security-opt label=type:container_runtime_t \ + wassette:latest +``` + +## Advanced Usage + +### Multi-Stage Build with Custom Base + +If you need a custom base image: + +```dockerfile +FROM rust:1.83-bookworm AS builder +# ... build stage ... + +FROM your-custom-base:latest +# ... runtime stage ... +``` + +### Health Checks + +Add health checks when running with HTTP/SSE transport: + +```yaml +# docker-compose.yml +services: + wassette: + # ... other config ... + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9001/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s +``` + +### Persistent Component Storage + +For persistent component storage across container restarts: + +```bash +# Create a named volume +docker volume create wassette-components + +# Use the volume +docker run -i --rm \ + -v wassette-components:/home/wassette/.local/share/wassette/components \ + wassette:latest +``` + +## Troubleshooting + +### Permission Denied Errors + +If you encounter permission errors when mounting volumes: + +```bash +# Check the ownership of your mounted directories +ls -la /path/to/components + +# Ensure the wassette user (UID 1000) can read the files +sudo chown -R 1000:1000 /path/to/components +``` + +### Container Cannot Access Components + +Verify the mount path matches Wassette's expected directory: + +```bash +# Check inside the container +docker run -i --rm \ + -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest sh -c "ls -la /home/wassette/.local/share/wassette/components" +``` + +### Network Connectivity Issues + +When using HTTP/SSE transport, ensure the port is properly exposed: + +```bash +# Check if the port is listening +docker run -d --name wassette-test -p 9001:9001 wassette:latest wassette serve --sse +docker logs wassette-test +curl http://localhost:9001/sse +docker rm -f wassette-test +``` + +## Building from Pre-Built Binaries + +For faster builds, you can create a Dockerfile that uses pre-built Wassette binaries: + +```dockerfile +FROM debian:bookworm-slim + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + libssl3 \ + curl && \ + rm -rf /var/lib/apt/lists/* + +# Download and install Wassette binary +ARG WASSETTE_VERSION=latest +RUN curl -fsSL https://github.com/microsoft/wassette/releases/download/${WASSETTE_VERSION}/wassette-linux-x86_64 -o /usr/local/bin/wassette && \ + chmod +x /usr/local/bin/wassette + +# Create non-root user and directories +RUN useradd -m -u 1000 -s /bin/bash wassette && \ + mkdir -p /home/wassette/.local/share/wassette/components && \ + mkdir -p /home/wassette/.config/wassette/secrets && \ + chown -R wassette:wassette /home/wassette + +ENV HOME=/home/wassette +ENV XDG_DATA_HOME=/home/wassette/.local/share +ENV XDG_CONFIG_HOME=/home/wassette/.config + +USER wassette +WORKDIR /home/wassette + +EXPOSE 9001 + +CMD ["wassette", "serve", "--stdio"] +``` + +This approach is faster as it doesn't require compiling from source. + +## Next Steps + +- Learn about [Wassette's permission system](../using/permissions.md) +- Explore [component examples](https://github.com/microsoft/wassette/tree/main/examples) +- Read the [CLI reference](../reference/cli.md) for all available commands +- Check the [FAQ](../faq.md) for common questions + +## Resources + +- [Docker Documentation](https://docs.docker.com/) +- [Docker Security Best Practices](https://docs.docker.com/engine/security/) +- [Wassette GitHub Repository](https://github.com/microsoft/wassette) From a4a4cfad28db9216a8cc662584626fdd5101533b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 03:02:36 +0000 Subject: [PATCH 2/5] Add Docker deployment section to README Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index ba67c65e..3e658f40 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,28 @@ Available installation methods: - **[Homebrew](./docs/installation.md#homebrew)** for macOS and Linux - **[WinGet](./docs/installation.md#windows)** for Windows - **[Nix flakes](./docs/installation.md#nix-all-platforms)** for reproducible environments +- **[Docker](./docs/deployment/docker.md)** for containerized deployments - **[Manual download](https://github.com/microsoft/wassette/releases)** from GitHub Releases +### Docker Deployment + +For enhanced security isolation and reproducible environments, Wassette can run in Docker containers: + +```bash +# Build the image +docker build -t wassette:latest . + +# Run with stdio transport (recommended) +docker run -i --rm wassette:latest + +# Mount components directory +docker run -i --rm \ + -v ./components:/home/wassette/.local/share/wassette/components:ro \ + wassette:latest +``` + +See the **[Docker deployment guide](./docs/deployment/docker.md)** for comprehensive documentation on running Wassette in containers, including security best practices, component mounting, and production deployment patterns. + ## Using Wassette With Wassette installed, the next step is to register it with your agent of From b2c51425f9a9f4868bf6e2a2f60f3a4131f8b3a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 03:04:05 +0000 Subject: [PATCH 3/5] Fix wording in README Docker section Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e658f40..e34977ff 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ docker run -i --rm \ wassette:latest ``` -See the **[Docker deployment guide](./docs/deployment/docker.md)** for comprehensive documentation on running Wassette in containers, including security best practices, component mounting, and production deployment patterns. +See the **[Docker deployment guide](./docs/deployment/docker.md)** for detailed documentation on running Wassette in containers, including security best practices, component mounting, and production deployment patterns. ## Using Wassette From 1451c886d123ca049c8560fd0006777bf7cf4f85 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 07:25:03 +0000 Subject: [PATCH 4/5] Address review feedback: use Rust 1.90, streamable-http default, merge Docker docs with Installation Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- Dockerfile | 6 +++--- Dockerfile.prebuilt | 4 ++-- docs/SUMMARY.md | 5 +---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 18884d7e..d2aa6d0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # This Dockerfile provides a containerized runtime for Wassette with additional security isolation # Stage 1: Build the Wassette binary -FROM rust:1.83-bookworm AS builder +FROM rust:1.90-bookworm AS builder # Install ca-certificates for HTTPS support during build RUN apt-get update && \ @@ -53,6 +53,6 @@ WORKDIR /home/wassette # Expose the default HTTP port (when using --http or --sse) EXPOSE 9001 -# Default command: start Wassette with stdio transport +# Default command: start Wassette with streamable-http transport # Override this in docker run or docker-compose for different transports -CMD ["wassette", "serve", "--stdio"] +CMD ["wassette", "serve", "--streamable-http"] diff --git a/Dockerfile.prebuilt b/Dockerfile.prebuilt index 876b3357..b7a5893b 100644 --- a/Dockerfile.prebuilt +++ b/Dockerfile.prebuilt @@ -37,6 +37,6 @@ WORKDIR /home/wassette # Expose the default HTTP port (when using --http or --sse) EXPOSE 9001 -# Default command: start Wassette with stdio transport +# Default command: start Wassette with streamable-http transport # Override this in docker run or docker-compose for different transports -CMD ["wassette", "serve", "--stdio"] +CMD ["wassette", "serve", "--streamable-http"] diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index c7543b75..c95101f9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -2,6 +2,7 @@ - [Overview](./overview.md) - [Installation](./installation.md) + - [Docker](./deployment/docker.md) - [MCP Clients](./mcp-clients.md) - [FAQ](./faq.md) @@ -19,10 +20,6 @@ - [CLI](./reference/cli.md) - [Permissions](./reference/permissions.md) -# Deployment - -- [Docker](./deployment/docker.md) - # Design & Architecture - [Architecture](./design/architecture.md) From a3e3208e1f95e8cd0ff3f8ad664e6108005976b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 07:43:57 +0000 Subject: [PATCH 5/5] Update Docker documentation to reflect streamable-http as default transport Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- README.md | 6 ++-- docker-compose.example.yml | 14 ++++---- docs/deployment/docker.md | 72 +++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index e34977ff..97a913c7 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,11 @@ For enhanced security isolation and reproducible environments, Wassette can run # Build the image docker build -t wassette:latest . -# Run with stdio transport (recommended) -docker run -i --rm wassette:latest +# Run with streamable-http transport (default) +docker run --rm -p 9001:9001 wassette:latest # Mount components directory -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v ./components:/home/wassette/.local/share/wassette/components:ro \ wassette:latest ``` diff --git a/docker-compose.example.yml b/docker-compose.example.yml index c60d3012..5457332b 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -8,7 +8,7 @@ services: build: . image: wassette:latest - # Expose port 9001 for HTTP/SSE access + # Expose port 9001 for streamable-http transport (default) ports: - "9001:9001" @@ -38,14 +38,16 @@ services: # - OPENWEATHER_API_KEY=your_api_key_here # Command to run (override the default CMD from Dockerfile) - # Note: stdio is the default and recommended for MCP clients + # Note: Default is streamable-http, but you can override it - # Option 1: Stdio transport (default, recommended) - command: ["wassette", "serve", "--stdio"] + # Default: Streamable HTTP transport (uses port 9001) + # Uses the default CMD from Dockerfile - no need to specify - # Option 2: SSE transport (requires host networking on Linux) + # Option 1: Override with stdio transport + # command: ["wassette", "serve", "--stdio"] + + # Option 2: Override with SSE transport # command: ["wassette", "serve", "--sse"] - # network_mode: host # Uncomment for SSE/HTTP access # Security: Limit container resources deploy: diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 7cecb27d..bf4f6271 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -31,26 +31,33 @@ This builds a multi-stage Docker image that: 2. Creates a minimal runtime image with only necessary dependencies 3. Runs as a non-root user for enhanced security -### Run with Stdio Transport +### Run with Streamable HTTP Transport (Default) -For use with MCP clients that expect stdio: +The Docker image defaults to streamable-http transport: ```bash -docker run -i --rm wassette:latest +docker run --rm -p 9001:9001 wassette:latest ``` -### Run with HTTP/SSE Transport +Then connect to `http://localhost:9001` from your MCP client. + +### Run with Stdio Transport + +For use with MCP clients that expect stdio, override the default command: + +```bash +docker run -i --rm wassette:latest wassette serve --stdio +``` -**Note**: The current version of Wassette binds to `127.0.0.1:9001`, which doesn't work directly with Docker port forwarding. The stdio transport is recommended for Docker deployments. HTTP/SSE support for Docker will be improved in a future release. +### Run with SSE Transport -If you need HTTP/SSE access in Docker, you can use a workaround with host networking: +For SSE transport, override the default command: ```bash -# Using host network mode (Linux only) -docker run --rm --network host wassette:latest wassette serve --sse +docker run --rm -p 9001:9001 wassette:latest wassette serve --sse ``` -Then connect to `http://localhost:9001/sse` from your MCP client on the host. +Then connect to `http://localhost:9001/sse` from your MCP client. ## Mounting Components @@ -74,15 +81,15 @@ docker run -i --rm \ cd examples/filesystem-rs cargo build --release --target wasm32-wasip2 -# Run Wassette with the example component mounted (stdio transport) -docker run -i --rm \ +# Run Wassette with the example component mounted (streamable-http transport) +docker run --rm -p 9001:9001 \ -v $(pwd)/examples/filesystem-rs/target/wasm32-wasip2/release:/home/wassette/.local/share/wassette/components:ro \ wassette:latest -# If you need SSE transport on Linux, use host networking: -# docker run --rm --network host \ +# For stdio transport, override the default: +# docker run -i --rm \ # -v $(pwd)/examples/filesystem-rs/target/wasm32-wasip2/release:/home/wassette/.local/share/wassette/components:ro \ -# wassette:latest wassette serve --sse +# wassette:latest wassette serve --stdio ``` ### Example: Running with Multiple Component Directories @@ -90,7 +97,7 @@ docker run -i --rm \ You can mount multiple component directories using multiple `-v` flags: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v /path/to/components1:/home/wassette/.local/share/wassette/components:ro \ -v /path/to/data:/data:rw \ wassette:latest @@ -101,7 +108,7 @@ docker run -i --rm \ If your components require secrets (API keys, credentials, etc.), mount the secrets directory: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v /path/to/secrets:/home/wassette/.config/wassette/secrets:ro \ -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ wassette:latest @@ -116,7 +123,7 @@ docker run -i --rm \ Pass environment variables to the container: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -e RUST_LOG=debug \ -e OPENWEATHER_API_KEY=your_api_key \ wassette:latest @@ -127,7 +134,7 @@ docker run -i --rm \ Mount a custom configuration file: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v /path/to/config.toml:/home/wassette/.config/wassette/config.toml:ro \ wassette:latest ``` @@ -156,10 +163,8 @@ services: wassette: build: . image: wassette:latest - # Note: Port mapping works best with --network host on Linux - # or use stdio transport without port mapping - # ports: - # - "9001:9001" + ports: + - "9001:9001" volumes: # Mount component directory (read-only) - ./components:/home/wassette/.local/share/wassette/components:ro @@ -169,8 +174,9 @@ services: - ./config.toml:/home/wassette/.config/wassette/config.toml:ro environment: - RUST_LOG=info - # Use SSE transport for network access - command: ["wassette", "serve", "--sse"] + # Default is streamable-http, but you can override: + # command: ["wassette", "serve", "--sse"] + # command: ["wassette", "serve", "--stdio"] # Security: Run with limited resources deploy: resources: @@ -193,7 +199,7 @@ The Dockerfile already configures Wassette to run as a non-root user (`wassette: ```bash # Good: Uses default non-root user -docker run -i --rm wassette:latest +docker run --rm -p 9001:9001 wassette:latest # Bad: Don't do this! # docker run -i --rm --user root wassette:latest @@ -204,7 +210,7 @@ docker run -i --rm wassette:latest Mount component and secret directories as read-only when possible: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ wassette:latest ``` @@ -214,7 +220,7 @@ docker run -i --rm \ Prevent resource exhaustion by setting limits: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ --memory="512m" \ --cpus="1.0" \ --pids-limit=100 \ @@ -226,7 +232,7 @@ docker run -i --rm \ For maximum security, run with a read-only root filesystem: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid,size=50m \ -v /path/to/components:/home/wassette/.local/share/wassette/components:ro \ @@ -238,7 +244,7 @@ docker run -i --rm \ Drop Linux capabilities that Wassette doesn't need: ```bash -docker run -i --rm \ +docker run --rm -p 9001:9001 \ --cap-drop=ALL \ --security-opt=no-new-privileges:true \ wassette:latest @@ -250,12 +256,12 @@ Use AppArmor or SELinux for additional security: ```bash # With AppArmor -docker run -i --rm \ +docker run --rm -p 9001:9001 \ --security-opt apparmor=docker-default \ wassette:latest # With SELinux -docker run -i --rm \ +docker run --rm -p 9001:9001 \ --security-opt label=type:container_runtime_t \ wassette:latest ``` @@ -267,7 +273,7 @@ docker run -i --rm \ If you need a custom base image: ```dockerfile -FROM rust:1.83-bookworm AS builder +FROM rust:1.90-bookworm AS builder # ... build stage ... FROM your-custom-base:latest @@ -300,7 +306,7 @@ For persistent component storage across container restarts: docker volume create wassette-components # Use the volume -docker run -i --rm \ +docker run --rm -p 9001:9001 \ -v wassette-components:/home/wassette/.local/share/wassette/components \ wassette:latest ```