Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Build artifacts
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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/
Suggested change
# Build artifacts
# Build artifacts
# Build artifacts (built in Docker, not copied from host)

Copilot uses AI. Check for mistakes.
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/
102 changes: 102 additions & 0 deletions .github/workflows/docker-build-push.yml
Original file line number Diff line number Diff line change
@@ -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 }}
Comment on lines +63 to +76
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copilot uses AI. Check for mistakes.

Comment on lines +73 to +77
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Suggested change
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VCS_REF=${{ github.sha }}
VERSION=${{ steps.meta.outputs.version }}

Copilot uses AI. Check for mistakes.
- 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
65 changes: 65 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"
59 changes: 59 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
version: '3.8'

Comment on lines +1 to +2
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Suggested change
version: '3.8'

Copilot uses AI. Check for mistakes.
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
Loading