feat: Add Docker support and GitHub Container Registry CI/CD#8
Conversation
- 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
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive Docker support for Flashbacker, enabling containerized deployments and CI/CD automation through GitHub Container Registry. The implementation includes multi-stage builds for optimization, multi-platform support (amd64/arm64), security hardening with non-root user execution, and extensive documentation for various use cases including MCP server integration.
Key Changes:
- Multi-stage Dockerfile with build optimization and security best practices
- GitHub Actions workflow for automated building and publishing to ghcr.io with semantic versioning
- Docker Compose configuration for simplified local development and testing
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
Dockerfile |
Multi-stage build setup with Node.js 22, non-root user (UID 1001), and optimized layer caching |
.github/workflows/docker-build-push.yml |
CI/CD workflow for multi-platform builds, GHCR publishing, and build attestation |
docker-compose.yml |
Local development setup with two service configurations for CLI and MCP server usage |
.dockerignore |
Build context optimization excluding unnecessary files like tests, docs, and build artifacts |
docs/DOCKER.md |
Comprehensive usage guide covering CLI usage, MCP integration, volume mounting, and deployment patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - 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 }} |
There was a problem hiding this comment.
The attestation step references steps.build.outputs.digest, but the build step (line 63-76) doesn't have an id: build assigned to it. This will cause the attestation step to fail.
Add id: build to the "Build and push Docker image" step:
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5| yarn-debug.log* | ||
| yarn-error.log* | ||
|
|
||
| # Build artifacts |
There was a problem hiding this comment.
[nitpick] The .dockerignore file excludes lib/ (line 8), but the Dockerfile's runtime stage copies the built lib directory from the builder stage (line 39 in Dockerfile). Since the builder stage builds the project (line 21), this works correctly. However, excluding lib/ here could be confusing since it's explicitly copied in the Dockerfile.
Consider adding a comment to clarify:
# Build artifacts (built in Docker, not copied from host)
lib/
| # Build artifacts | |
| # Build artifacts | |
| # Build artifacts (built in Docker, not copied from host) |
| # 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: | ||
|
|
There was a problem hiding this comment.
[nitpick] The documentation uses the older docker-compose command syntax (with hyphen). While this still works, Docker Compose V2 (which is now bundled with Docker) uses docker compose (with a space) as the standard command.
Consider updating these examples to use the modern syntax:
# Run flashback commands
docker compose run --rm flashbacker flashback --version
docker compose run --rm flashbacker flashback init --mcpOr add a note mentioning both syntaxes are supported.
| -v $(pwd):/workspace \ | ||
| -w /workspace \ | ||
| ghcr.io/agentsea/flashbacker:latest \ | ||
| agent --context |
There was a problem hiding this comment.
The command agent --context appears inconsistent with the flashback CLI commands shown elsewhere in the documentation (e.g., init, status, --version).
Please verify this is a valid flashback command. If agent is not a valid subcommand, this example should be updated to use an appropriate command for stdio MCP integration.
| agent --context | |
| init --mcp |
| version: '3.8' | ||
|
|
There was a problem hiding this comment.
[nitpick] The version: '3.8' field in docker-compose.yml is deprecated as of Docker Compose v1.27.0 and is no longer required in Docker Compose V2. Modern best practice is to omit this field entirely.
Consider removing this line as it's no longer needed and the compose file will work without it.
| version: '3.8' |
| build-args: | | ||
| BUILD_DATE=${{ github.event.head_commit.timestamp }} | ||
| VCS_REF=${{ github.sha }} | ||
| VERSION=${{ steps.meta.outputs.version }} | ||
|
|
There was a problem hiding this comment.
[nitpick] The workflow passes build arguments (BUILD_DATE, VCS_REF, VERSION) to the Docker build, but the Dockerfile doesn't declare these with ARG instructions or use them anywhere. These arguments will be silently ignored.
If these are intended to be used in the image (e.g., in labels), add them to the Dockerfile:
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
LABEL org.opencontainers.image.created="${BUILD_DATE}"
LABEL org.opencontainers.image.revision="${VCS_REF}"
LABEL org.opencontainers.image.version="${VERSION}"Otherwise, remove the unused build-args from the workflow.
| build-args: | | |
| BUILD_DATE=${{ github.event.head_commit.timestamp }} | |
| VCS_REF=${{ github.sha }} | |
| VERSION=${{ steps.meta.outputs.version }} |
Features:
The container can be used as: