From 2244248f4ac3a466c9aef415a2e01013b76bee6f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 07:46:25 +0000 Subject: [PATCH] feat: Add Docker support and GitHub Container Registry CI/CD - Add multi-stage Dockerfile for optimized container builds - Add GitHub Actions workflow for building and pushing to ghcr.io - Add docker-compose.yml for easy local development and testing - Add comprehensive Docker usage documentation in docs/DOCKER.md - Add .dockerignore to optimize build context Features: - Multi-platform support (linux/amd64, linux/arm64) - Non-root container user for security - Automatic semantic versioning and tagging - Build provenance attestation - Caching for faster builds - Ready for MCP server integration The container can be used as: 1. Standalone CLI tool in containerized environments 2. Base image for custom MCP server implementations 3. CI/CD integration for flashback operations --- .dockerignore | 49 +++++ .github/workflows/docker-build-push.yml | 102 +++++++++ Dockerfile | 65 ++++++ docker-compose.yml | 59 +++++ docs/DOCKER.md | 275 ++++++++++++++++++++++++ 5 files changed, 550 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/docker-build-push.yml create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 docs/DOCKER.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b7122a6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,49 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build artifacts +lib/ +*.tsbuildinfo + +# Tests +tests/ +coverage/ +*.test.js +*.test.ts + +# Documentation +docs/ +*.md +!README.md + +# Git +.git/ +.gitignore +.gitattributes + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# CI/CD +.github/ +.travis.yml +.gitlab-ci.yml + +# Misc +.DS_Store +.env +.env.* +*.log +tmp/ +temp/ +.cache/ + +# Claude Code specific (not needed in container) +.claude/ diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml new file mode 100644 index 0000000..cee71d5 --- /dev/null +++ b/.github/workflows/docker-build-push.yml @@ -0,0 +1,102 @@ +name: Build and Push Docker Image to GHCR + +on: + push: + branches: + - main + - master + - 'claude/**' + tags: + - 'v*' + pull_request: + branches: + - main + - master + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub 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 (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + # Tag with version for release tags + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + # Tag with branch name + type=ref,event=branch + # Tag with PR number for pull requests + type=ref,event=pr + # Tag with 'latest' for main/master branch + type=raw,value=latest,enable={{is_default_branch}} + # Tag with git sha + type=sha,prefix={{branch}}- + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + 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 + build-args: | + BUILD_DATE=${{ github.event.head_commit.timestamp }} + VCS_REF=${{ github.sha }} + VERSION=${{ steps.meta.outputs.version }} + + - name: Generate artifact attestation + if: github.event_name != 'pull_request' + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + + - name: Output image details + if: github.event_name != 'pull_request' + run: | + echo "### Docker Image Published :rocket:" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Registry:** \`${{ env.REGISTRY }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Image:** \`${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tags:**" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5061748 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,65 @@ +# Multi-stage build for flashbacker MCP server +# Stage 1: Build +FROM node:22-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache python3 make g++ git + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies (including dev dependencies for build) +RUN npm ci + +# Copy source code +COPY . . + +# Build TypeScript and copy templates +RUN npm run build + +# Stage 2: Runtime +FROM node:22-alpine + +# Install runtime dependencies only +RUN apk add --no-cache git + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install production dependencies only +RUN npm ci --only=production + +# Copy built files from builder stage +COPY --from=builder /app/lib ./lib +COPY --from=builder /app/bin ./bin +COPY --from=builder /app/templates ./templates +COPY README.md ./ + +# Create a non-root user +RUN addgroup -g 1001 flashback && \ + adduser -D -u 1001 -G flashback flashback && \ + chown -R flashback:flashback /app + +# Switch to non-root user +USER flashback + +# Make the CLI executable globally available +ENV PATH="/app/bin:${PATH}" + +# Set up entrypoint +ENTRYPOINT ["node", "/app/lib/cli.js"] + +# Default command (shows help) +CMD ["--help"] + +# Labels for container metadata +LABEL org.opencontainers.image.title="Flashbacker" +LABEL org.opencontainers.image.description="Claude Code state management with session continuity and AI personas" +LABEL org.opencontainers.image.source="https://github.com/agentsea/flashbacker" +LABEL org.opencontainers.image.licenses="MIT" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6c6acc2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,59 @@ +version: '3.8' + +services: + flashbacker: + build: + context: . + dockerfile: Dockerfile + image: ghcr.io/agentsea/flashbacker:latest + container_name: flashbacker-mcp + volumes: + # Mount your project directory to work with flashback commands + - ./:/workspace + working_dir: /workspace + # Override entrypoint to keep container running for interactive use + entrypoint: ["/bin/sh"] + stdin_open: true + tty: true + environment: + # Set any environment variables needed + - NODE_ENV=production + networks: + - flashback-network + + # Example: Using flashbacker with an MCP server setup + flashbacker-mcp-server: + build: + context: . + dockerfile: Dockerfile + image: ghcr.io/agentsea/flashbacker:latest + container_name: flashbacker-mcp-stdio + volumes: + - ./:/workspace + working_dir: /workspace + # For MCP server mode, you'd typically run a specific command + # This is a placeholder - adjust based on your MCP server implementation + command: ["--version"] + stdin_open: true + tty: true + networks: + - flashback-network + +networks: + flashback-network: + driver: bridge + +# Usage examples: +# +# 1. Build the image: +# docker-compose build +# +# 2. Run flashback commands: +# docker-compose run --rm flashbacker flashback --version +# docker-compose run --rm flashbacker flashback init --mcp +# +# 3. Interactive shell in container: +# docker-compose run --rm flashbacker /bin/sh +# +# 4. Start MCP server (adjust command as needed): +# docker-compose up flashbacker-mcp-server diff --git a/docs/DOCKER.md b/docs/DOCKER.md new file mode 100644 index 0000000..d4768c4 --- /dev/null +++ b/docs/DOCKER.md @@ -0,0 +1,275 @@ +# Docker Usage Guide + +This guide explains how to use Flashbacker with Docker and how to integrate it with MCP (Model Context Protocol) servers. + +## Quick Start + +### Pull from GitHub Container Registry + +```bash +docker pull ghcr.io/agentsea/flashbacker:latest +``` + +### Build Locally + +```bash +# Build the Docker image +docker build -t flashbacker:local . + +# Or use docker-compose +docker-compose build +``` + +## Running Flashbacker in Docker + +### Basic Commands + +```bash +# Check version +docker run --rm ghcr.io/agentsea/flashbacker:latest --version + +# Show help +docker run --rm ghcr.io/agentsea/flashbacker:latest --help + +# Initialize flashback in a project +docker run --rm -v $(pwd):/workspace -w /workspace \ + ghcr.io/agentsea/flashbacker:latest init --mcp +``` + +### Using Docker Compose + +The repository includes a `docker-compose.yml` for easier management: + +```bash +# Run flashback commands +docker-compose run --rm flashbacker flashback --version +docker-compose run --rm flashbacker flashback init --mcp +docker-compose run --rm flashbacker flashback status + +# Interactive shell +docker-compose run --rm flashbacker /bin/sh +``` + +## MCP Server Integration + +Flashbacker works with MCP servers for enhanced AI capabilities. When running in Docker, you can configure MCP servers in several ways: + +### Option 1: Initialize with MCP Servers + +```bash +# Initialize flashback with built-in MCP server support +docker run --rm -v $(pwd):/workspace -w /workspace \ + ghcr.io/agentsea/flashbacker:latest init --mcp +``` + +This will set up the following MCP servers in your project: +- **context7**: Up-to-date documentation and library context +- **playwright**: Browser automation and testing +- **sequential-thinking**: Advanced reasoning chains + +### Option 2: Using as an MCP Server Base + +You can use the Flashbacker Docker image as a base for creating your own MCP server: + +```dockerfile +FROM ghcr.io/agentsea/flashbacker:latest + +# Add your MCP server implementation +COPY your-mcp-server.js /app/ + +# Configure to run as MCP server +ENTRYPOINT ["node", "/app/your-mcp-server.js"] +``` + +### Option 3: stdio MCP Server Mode + +For stdio-based MCP servers (common pattern): + +```bash +# Run flashbacker in stdio mode for MCP integration +docker run -i --rm \ + -v $(pwd):/workspace \ + -w /workspace \ + ghcr.io/agentsea/flashbacker:latest \ + agent --context +``` + +## Volume Mounting + +To work with your project files, mount them as volumes: + +```bash +# Mount current directory +docker run --rm -v $(pwd):/workspace -w /workspace \ + ghcr.io/agentsea/flashbacker:latest init + +# Mount specific project directory +docker run --rm -v /path/to/project:/workspace -w /workspace \ + ghcr.io/agentsea/flashbacker:latest status +``` + +## Environment Variables + +Configure Flashbacker behavior with environment variables: + +```bash +docker run --rm \ + -e NODE_ENV=production \ + -v $(pwd):/workspace \ + -w /workspace \ + ghcr.io/agentsea/flashbacker:latest init +``` + +## Multi-Platform Support + +The Docker image is built for multiple platforms: +- `linux/amd64` (x86_64) +- `linux/arm64` (ARM64/Apple Silicon) + +Docker will automatically pull the correct platform for your system. + +## Container Image Details + +### Image Tags + +- `latest`: Latest stable release from main branch +- `v2.4.1`, `v2.4`, `v2`: Semantic version tags +- `main`: Latest from main branch +- `claude/branch-name`: Development branches +- `sha-`: Specific commit SHA + +### Example Tag Usage + +```bash +# Latest stable +docker pull ghcr.io/agentsea/flashbacker:latest + +# Specific version +docker pull ghcr.io/agentsea/flashbacker:v2.4.1 + +# Development branch +docker pull ghcr.io/agentsea/flashbacker:claude/feature-branch +``` + +## Advanced Usage + +### Running in Kubernetes + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: flashbacker-init +spec: + containers: + - name: flashbacker + image: ghcr.io/agentsea/flashbacker:latest + command: ["flashback", "init", "--mcp"] + volumeMounts: + - name: project-volume + mountPath: /workspace + workingDir: /workspace + volumes: + - name: project-volume + persistentVolumeClaim: + claimName: project-pvc +``` + +### CI/CD Integration + +Use in GitHub Actions: + +```yaml +jobs: + setup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Initialize Flashbacker + run: | + docker run --rm \ + -v ${{ github.workspace }}:/workspace \ + -w /workspace \ + ghcr.io/agentsea/flashbacker:latest \ + init --mcp +``` + +## Building Custom Images + +### Extending the Base Image + +```dockerfile +FROM ghcr.io/agentsea/flashbacker:latest + +# Install additional dependencies +USER root +RUN apk add --no-cache bash curl jq + +# Copy custom configuration +COPY custom-config.json /app/config/ + +# Switch back to non-root user +USER flashback + +# Set custom entrypoint +ENTRYPOINT ["flashback"] +``` + +### Multi-Stage Custom Build + +```dockerfile +FROM ghcr.io/agentsea/flashbacker:latest AS base + +FROM node:22-alpine +COPY --from=base /app /app +ENV PATH="/app/bin:${PATH}" + +# Add your customizations +RUN apk add --no-cache git bash + +ENTRYPOINT ["flashback"] +``` + +## Troubleshooting + +### Permission Issues + +If you encounter permission issues with mounted volumes: + +```bash +# Run as current user +docker run --rm --user $(id -u):$(id -g) \ + -v $(pwd):/workspace \ + -w /workspace \ + ghcr.io/agentsea/flashbacker:latest init +``` + +### Node.js Version Compatibility + +The Docker image uses Node.js 22 (LTS) which is compatible with Flashbacker's requirements (Node.js 18-24). + +### Git Configuration + +For commands that require git: + +```bash +docker run --rm \ + -v $(pwd):/workspace \ + -v ~/.gitconfig:/home/flashback/.gitconfig:ro \ + -w /workspace \ + ghcr.io/agentsea/flashbacker:latest status +``` + +## Security Considerations + +- The container runs as a non-root user (`flashback` - UID 1001) +- Only necessary dependencies are included in the production image +- Multi-stage build minimizes attack surface +- Build provenance attestation is generated for all images + +## Support + +For issues or questions: +- GitHub Issues: https://github.com/agentsea/flashbacker/issues +- Documentation: https://github.com/agentsea/flashbacker#readme