From 9026ec5ef208bb4617530abd59ae6bb851ad604c Mon Sep 17 00:00:00 2001 From: Aaron Yordanyan Date: Fri, 6 Jun 2025 17:15:16 +0400 Subject: [PATCH] Add Docker support with GitHub Actions workflow and updated configurations - Introduced `.github/workflows/docker.yml` for building and pushing Docker images. - Updated `Dockerfile` to split stages for `base`, `development`, and `production`. - Added `compose.yaml` for Docker Compose setups. - Enhanced `README.md` with Docker usage instructions. --- .github/workflows/docker.yml | 68 ++++++++++++++++++++++++++++++++++++ Dockerfile | 30 ++++++++++++---- README.md | 29 ++++++++++++--- compose.yaml | 22 ++++++++++++ 4 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/docker.yml create mode 100644 compose.yaml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..7e15e4c --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,68 @@ +name: Build and Push Docker Images + +on: + push: + branches: [ main ] + tags: [ 'v*' ] + pull_request: + branches: [ main ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push production image + uses: docker/build-push-action@v5 + with: + context: . + target: production + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Build and push development image + uses: docker/build-push-action@v5 + with: + context: . + target: development + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 4521867..d88d4e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -# Use the official Python image for the base image. -FROM python:3.11-slim +# Base stage with common dependencies +FROM python:3.11-slim AS base SHELL ["/bin/bash", "-c"] # Set environment variables to make Python print directly to the terminal and avoid .pyc files. @@ -21,18 +21,18 @@ RUN python3 -m pip install --no-cache-dir pipx \ # Add local bin to the path ENV PATH="${PATH}:/root/.local/bin" - # Install the latest version of uv RUN curl -LsSf https://astral.sh/uv/install.sh | sh # Set the working directory WORKDIR /workspaces/serena -# Copy required files into the image -COPY pyproject.toml /workspaces/serena/ -COPY README.md /workspaces/serena/ +# Development target +FROM base AS development +# Copy all files for development +COPY . /workspaces/serena/ -# Create virtual environment and install dependencies +# Create virtual environment and install dependencies with dev extras RUN uv venv RUN . .venv/bin/activate RUN uv pip install --all-extras -r pyproject.toml -e . @@ -41,3 +41,19 @@ ENV PATH="/workspaces/serena/.venv/bin:${PATH}" # Entrypoint to ensure environment is activated ENTRYPOINT ["/bin/bash", "-c", "source .venv/bin/activate && $0 $@"] +# Production target +FROM base AS production +# Copy only necessary files for production +COPY pyproject.toml /workspaces/serena/ +COPY README.md /workspaces/serena/ +COPY src/ /workspaces/serena/src/ + +# Create virtual environment and install dependencies (production only) +RUN uv venv +RUN . .venv/bin/activate +RUN uv pip install -r pyproject.toml -e . +ENV PATH="/workspaces/serena/.venv/bin:${PATH}" + +# Entrypoint to ensure environment is activated +ENTRYPOINT ["/bin/bash", "-c", "source .venv/bin/activate && $0 $@"] + diff --git a/README.md b/README.md index 6d48de7..fd07825 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,8 @@ Configure the MCP server in your client. For [Claude Desktop](https://claude.ai/download) (available for Windows and macOS), go to File / Settings / Developer / MCP Servers / Edit Config, which will let you open the JSON file `claude_desktop_config.json`. Add the following (with adjusted paths) to enable Serena: +#### Local Installation + ```json { "mcpServers": { @@ -254,6 +256,23 @@ which will let you open the JSON file `claude_desktop_config.json`. Add the foll } ``` +#### Docker Installation + +Alternatively, you can run Serena using Docker: + +```json +{ + "mcpServers": { + "serena": { + "command": "docker", + "args": ["run", "--rm", "-i", "--network", "host", "-v", "/path/to/your/projects:/workspaces/projects", "ghcr.io/oraios/serena:latest", "serena-mcp-server", "--transport", "stdio"] + } + } +} +``` + +Replace `/path/to/your/projects` with the absolute path to your projects directory. The Docker approach has the advantage of not requiring local installation of dependencies. + If you are using paths containing backslashes for paths on Windows (note that you can also just use forward slashes), be sure to escape them correctly (`\\`). @@ -265,16 +284,18 @@ That's it! Save the config and then restart Claude Desktop. You are ready for ac uv run serena-mcp-server --help ``` -ℹ️ You can use Serena without cloning or configuring it explicitly by +ℹ️ You can use Serena without cloning or configuring it explicitly by using the Docker image above or: +```json { "mcpServers": { "serena": { - "command": "/abs/path/to/uv", - "args": ["run", "--directory", "/abs/path/to/serena", "serena-mcp-server"] + "command": "uvx", + "args": ["--from", "git+https://github.com/oraios/serena", "serena-mcp-server"] } } } +``` #### Troubleshooting @@ -399,7 +420,7 @@ Here's how it works (see also [Agno's documentation](https://docs.agno.com/intro 3. Copy `.env.example` to `.env` and fill in the API keys for the provider(s) you intend to use. -5. Start the agno agent app with +4. Start the agno agent app with ```shell uv run python scripts/agno_agent.py ``` diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..5150442 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,22 @@ +services: + serena: + image: serena:latest + build: + context: ./ + dockerfile: Dockerfile + target: production + tty: true + stdin_open: true + + serena-dev: + image: serena:dev + build: + context: ./ + dockerfile: Dockerfile + target: development + tty: true + stdin_open: true + volumes: + - .:/workspaces/serena + command: + - "uv run --directory . serena-mcp-server"