Skip to content

Add GitHub Actions workflow for container image builds#2

Merged
kelleyblackmore merged 6 commits into
mainfrom
copilot/add-github-action-for-container-image
Oct 31, 2025
Merged

Add GitHub Actions workflow for container image builds#2
kelleyblackmore merged 6 commits into
mainfrom
copilot/add-github-action-for-container-image

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 31, 2025

Create GitHub Action for building container image

Plan:

  • Explore repository structure and understand the project
  • Verify Dockerfile exists and builds successfully
  • Test npm build process
  • Create .github/workflows directory
  • Create GitHub Action workflow for building and publishing container image
    • Build on push to main branch and on pull requests
    • Build on version tags (v*)
    • Push to GitHub Container Registry (ghcr.io)
    • Support multi-platform builds (linux/amd64, linux/arm64)
  • Test the workflow file syntax with yamllint
  • Verify the workflow is correctly configured
  • Update README documentation with:
    • Instructions for pulling pre-built images from GHCR
    • CI/CD workflow information
    • Updated Claude Desktop configuration example
  • Run code review and address feedback
  • Improve README formatting for better readability
  • Fix invalid Docker tag format issue
    • Removed prefix={{branch}}- from SHA tag which was creating invalid tags like :-80796be
    • Changed to simple type=sha which creates valid tags like sha-80796be
  • Fix npm ci build failure
    • Changed npm ci to npm install in Dockerfile since package-lock.json is not committed
    • Added migration documentation for users switching from local builds to GHCR images

Complete! The workflow now correctly builds Docker images without errors.

Original prompt

create a github action for creating the containe image to the repo


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits October 31, 2025 06:01
Co-authored-by: kelleyblackmore <16111250+kelleyblackmore@users.noreply.github.com>
Co-authored-by: kelleyblackmore <16111250+kelleyblackmore@users.noreply.github.com>
Co-authored-by: kelleyblackmore <16111250+kelleyblackmore@users.noreply.github.com>
Copilot AI changed the title [WIP] Create GitHub Action for building container image Add GitHub Actions workflow for container image builds Oct 31, 2025
Copilot AI requested a review from kelleyblackmore October 31, 2025 06:05
@kelleyblackmore kelleyblackmore marked this pull request as ready for review October 31, 2025 06:09
Copilot AI review requested due to automatic review settings October 31, 2025 06:09
@kelleyblackmore
Copy link
Copy Markdown
Owner

@copilot 1s
Run docker/build-push-action@v5
GitHub Actions runtime token ACs
Docker info
Proxy configuration
Buildx version
Builder info
/usr/bin/docker buildx build --cache-from type=gha --cache-to type=gha,mode=max --iidfile /home/runner/work/_temp/docker-actions-toolkit-3Q5KXI/build-iidfile-1aaa44ef16.txt --label org.opencontainers.image.created=2025-10-31T06:07:11.248Z --label org.opencontainers.image.description=vault-mcp service --label org.opencontainers.image.licenses= --label org.opencontainers.image.revision=80796be52b05c50f4aeac4fd8d88b461ca431392 --label org.opencontainers.image.source=https://github.com/kelleyblackmore/vault-mcp --label org.opencontainers.image.title=vault-mcp --label org.opencontainers.image.url=https://github.com/kelleyblackmore/vault-mcp --label org.opencontainers.image.version=pr-2 --platform linux/amd64,linux/arm64 --attest type=provenance,mode=max,builder-id=https://github.com/kelleyblackmore/vault-mcp/actions/runs/18964246450 --tag ghcr.io/kelleyblackmore/vault-mcp:pr-2 --tag ghcr.io/kelleyblackmore/vault-mcp:-80796be --metadata-file /home/runner/work/_temp/docker-actions-toolkit-3Q5KXI/build-metadata-53b20cffc2.json .
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
ERROR: failed to build: invalid tag "ghcr.io/kelleyblackmore/vault-mcp:-80796be": invalid reference format
Error: buildx failed with: ERROR: failed to build: invalid tag "ghcr.io/kelleyblackmore/vault-mcp:-80796be": invalid

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds automated Docker image building and publishing to GitHub Container Registry (GHCR) using GitHub Actions, along with comprehensive documentation updates.

  • Implements a CI/CD workflow that builds multi-platform Docker images (amd64 and arm64) and publishes them to GHCR
  • Updates README with instructions for using pre-built images from GHCR
  • Documents the CI/CD process and adds project structure details including the new workflow file

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/docker-build-publish.yml New GitHub Actions workflow for building and publishing multi-platform Docker images to GHCR on push to main, tags, and pull requests
README.md Adds documentation for pre-built images, updates Claude Desktop config to use GHCR images, documents CI/CD workflow, and updates project structure

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
"-e",
"VAULT_TOKEN=your-vault-token",
"vault-mcp"
"ghcr.io/kelleyblackmore/vault-mcp:latest"
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The image reference change from vault-mcp to ghcr.io/kelleyblackmore/vault-mcp:latest is a breaking change for existing users who have built the image locally. Consider documenting a migration note for users upgrading from a local setup to the GHCR images, or provide both examples side-by-side initially.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added migration documentation to help users understand their options when switching from local builds to GHCR images. The note now clearly explains both approaches. (730a4ae)

type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The SHA tag generation using prefix={{branch}}- may produce unexpected results. For pull requests, this will use the PR branch name rather than the base branch. Consider using a static prefix like sha- or removing the branch prefix for cleaner tag naming: type=sha.

Suggested change
type=sha,prefix={{branch}}-
type=sha,prefix=sha-

Copilot uses AI. Check for mistakes.
Co-authored-by: kelleyblackmore <16111250+kelleyblackmore@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 31, 2025

@copilot 1s
Run docker/build-push-action@v5
GitHub Actions runtime token ACs...

Fixed the invalid tag format error. The issue was caused by type=sha,prefix={{branch}}- which created malformed tags like :-80796be when the branch name was empty in PR contexts. Changed to type=sha which generates valid tags like sha-80796be. (3e2043d)

@kelleyblackmore
Copy link
Copy Markdown
Owner

@copilot Run docker/build-push-action@v5
GitHub Actions runtime token ACs
Docker info
Proxy configuration
Buildx version
Builder info
/usr/bin/docker buildx build --cache-from type=gha --cache-to type=gha,mode=max --iidfile /home/runner/work/_temp/docker-actions-toolkit-OW3n2b/build-iidfile-9507bcec2c.txt --label org.opencontainers.image.created=2025-10-31T06:24:25.287Z --label org.opencontainers.image.description=vault-mcp service --label org.opencontainers.image.licenses= --label org.opencontainers.image.revision=67f19af90ea5cf2b17a0eeef08ad763e0cea7c3d --label org.opencontainers.image.source=https://github.com/kelleyblackmore/vault-mcp --label org.opencontainers.image.title=vault-mcp --label org.opencontainers.image.url=https://github.com/kelleyblackmore/vault-mcp --label org.opencontainers.image.version=pr-2 --platform linux/amd64,linux/arm64 --attest type=provenance,mode=max,builder-id=https://github.com/kelleyblackmore/vault-mcp/actions/runs/18964389499 --tag ghcr.io/kelleyblackmore/vault-mcp:pr-2 --tag ghcr.io/kelleyblackmore/vault-mcp:sha-67f19af --metadata-file /home/runner/work/_temp/docker-actions-toolkit-OW3n2b/build-metadata-520584a129.json .
#0 building with "builder-f1b36697-54ba-44bc-8137-3c679147e3f9" instance using docker-container driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 1.07kB done
#1 DONE 0.0s

#2 [linux/amd64 internal] load metadata for docker.io/library/node:20-alpine
#2 ...

#3 [auth] library/node:pull token for registry-1.docker.io
#3 DONE 0.0s

#4 [linux/arm64 internal] load metadata for docker.io/library/node:20-alpine
#4 ...

#2 [linux/amd64 internal] load metadata for docker.io/library/node:20-alpine
#2 DONE 1.0s

#5 [internal] load .dockerignore
#5 transferring context: 2B done
#5 DONE 0.0s

#4 [linux/arm64 internal] load metadata for docker.io/library/node:20-alpine
#4 DONE 1.1s

#6 [internal] load build context
#6 DONE 0.0s

#7 [linux/arm64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#7 resolve docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435 done
#7 DONE 0.0s

#8 importing cache manifest from gha:1700154126132761330
#8 DONE 0.2s

#6 [internal] load build context
#6 transferring context: 5.98kB done
#6 DONE 0.0s

#9 [linux/amd64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#9 resolve docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435 0.0s done
#9 sha256:da04d522c98fe12816b2bcddf8413fca73645f8fa60f287c672f58bcc7f0fa38 0B / 444B 0.2s
#9 sha256:da04d522c98fe12816b2bcddf8413fca73645f8fa60f287c672f58bcc7f0fa38 444B / 444B 0.2s done
#9 sha256:e74e4ed823e9560b3fe51c0cab47dbfdfc4b12453604319408ec58708fb9e720 1.26MB / 1.26MB 0.2s done
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 2.10MB / 42.75MB 0.2s
#9 sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b 3.80MB / 3.80MB 0.3s done
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 6.29MB / 42.75MB 0.3s
#9 extracting sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b 0.1s done
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 13.41MB / 42.75MB 0.5s
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 19.92MB / 42.75MB 0.6s
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 27.26MB / 42.75MB 0.8s
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 34.60MB / 42.75MB 0.9s
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 40.89MB / 42.75MB 1.1s
#9 ...

#7 [linux/arm64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#7 sha256:6dbf56a7feaf43fe338cd74317fda62608ec88dfd616dd5bff62f6f11b631692 1.26MB / 1.26MB 0.1s done
#7 sha256:f3dae84293a5e75bd15077274b31b14eaec6c0fc94e035b36febae220198d1f2 443B / 443B 0.1s done
#7 sha256:6b59a28fa20117e6048ad0616b8d8c901877ef15ff4c7f18db04e4f01f43bc39 4.14MB / 4.14MB 0.3s done
#7 sha256:ae67534e7d0aa8a27cfb7e3ecb9727f2ce2a6dd5b721d5392c27b91fc68b7f13 42.43MB / 42.43MB 0.5s done
#7 extracting sha256:6b59a28fa20117e6048ad0616b8d8c901877ef15ff4c7f18db04e4f01f43bc39 0.1s done
#7 extracting sha256:ae67534e7d0aa8a27cfb7e3ecb9727f2ce2a6dd5b721d5392c27b91fc68b7f13 0.9s done
#7 extracting sha256:6dbf56a7feaf43fe338cd74317fda62608ec88dfd616dd5bff62f6f11b631692 0.0s done
#7 DONE 1.5s

#9 [linux/amd64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#9 sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 42.75MB / 42.75MB 1.1s done
#9 extracting sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64
#9 ...

#7 [linux/arm64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#7 extracting sha256:f3dae84293a5e75bd15077274b31b14eaec6c0fc94e035b36febae220198d1f2 done
#7 DONE 1.5s

#10 [linux/arm64 builder 2/6] WORKDIR /app
#10 DONE 0.2s

#9 [linux/amd64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#9 ...

#11 [linux/arm64 builder 3/6] COPY package*.json ./
#11 DONE 0.1s

#12 [linux/arm64 builder 4/6] COPY tsconfig.json ./
#12 DONE 0.0s

#13 [linux/arm64 builder 5/6] COPY src ./src
#13 DONE 0.0s

#14 [linux/arm64 builder 6/6] RUN npm config set strict-ssl false && npm install
#14 ...

#9 [linux/amd64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#9 extracting sha256:60e45a9660cfaebbbac9bba98180aa28b3966b7f2462d132c46f51a1f5b25a64 1.2s done
#9 DONE 2.6s

#9 [linux/amd64 builder 1/6] FROM docker.io/library/node:20-alpine@sha256:6178e78b972f79c335df281f4b7674a2d85071aae2af020ffa39f0a770265435
#9 extracting sha256:e74e4ed823e9560b3fe51c0cab47dbfdfc4b12453604319408ec58708fb9e720 0.0s done
#9 extracting sha256:da04d522c98fe12816b2bcddf8413fca73645f8fa60f287c672f58bcc7f0fa38 done
#9 DONE 2.7s

#15 [linux/amd64 builder 2/6] WORKDIR /app
#15 DONE 0.1s

#16 [linux/arm64 stage-1 4/5] RUN npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts
#16 ...

#17 [linux/amd64 builder 3/6] COPY package*.json ./
#17 DONE 0.0s

#18 [linux/amd64 builder 4/6] COPY tsconfig.json ./
#18 DONE 0.0s

#19 [linux/amd64 builder 5/6] COPY src ./src
#19 DONE 0.0s

#20 [linux/amd64 builder 6/6] RUN npm config set strict-ssl false && npm install
#20 CANCELED

#21 [linux/amd64 stage-1 4/5] RUN npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts
#21 1.337 npm error code EUSAGE
#21 1.338 npm error
#21 1.338 npm error The npm ci command can only install with an existing package-lock.json or
#21 1.338 npm error npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or
#21 1.338 npm error later to generate a package-lock.json file, then try again.
#21 1.338 npm error
#21 1.338 npm error Clean install a project
#21 1.338 npm error
#21 1.338 npm error Usage:
#21 1.338 npm error npm ci
#21 1.338 npm error
#21 1.338 npm error Options:
#21 1.338 npm error [--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundling]
#21 1.338 npm error [--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
#21 1.338 npm error [--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
#21 1.338 npm error [--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
#21 1.338 npm error [--no-bin-links] [--no-fund] [--dry-run]
#21 1.338 npm error [-w|--workspace [-w|--workspace ...]]
#21 1.338 npm error [-ws|--workspaces] [--include-workspace-root] [--install-links]
#21 1.338 npm error
#21 1.338 npm error aliases: clean-install, ic, install-clean, isntall-clean
#21 1.338 npm error
#21 1.338 npm error Run "npm help ci" for more info
#21 1.341 npm error A complete log of this run can be found in: /root/.npm/_logs/2025-10-31T06_24_31_245Z-debug-0.log
#21 ERROR: process "/bin/sh -c npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts" did not complete successfully: exit code: 1

#16 [linux/arm64 stage-1 4/5] RUN npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts
#16 CANCELED

#14 [linux/arm64 builder 6/6] RUN npm config set strict-ssl false && npm install
#14 CANCELED

[linux/amd64 stage-1 4/5] RUN npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts:
1.338 npm error [--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
1.338 npm error [--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
1.338 npm error [--no-bin-links] [--no-fund] [--dry-run]
1.338 npm error [-w|--workspace [-w|--workspace ...]]
1.338 npm error [-ws|--workspaces] [--include-workspace-root] [--install-links]
1.338 npm error
1.338 npm error aliases: clean-install, ic, install-clean, isntall-clean
1.338 npm error
1.338 npm error Run "npm help ci" for more info
1.341 npm error A complete log of this run can be found in: /root/.npm/_logs/2025-10-31T06_24_31_245Z-debug-0.log


WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
Dockerfile:27

25 | # Install production dependencies only (skip scripts to avoid running prepare/build)
26 | # Note: strict-ssl is disabled for build environments with self-signed certificates
27 | >>> RUN npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts
28 |
29 | # Copy built files from builder

ERROR: failed to build: failed to solve: process "/bin/sh -c npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts" did not complete successfully: exit code: 1
Error: buildx failed with: ERROR: failed to build: failed to solve: process "/bin/sh -c npm config set strict-ssl false && npm ci --omit=dev --ignore-scripts" did not complete successfully: exit code: 1

Co-authored-by: kelleyblackmore <16111250+kelleyblackmore@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 31, 2025

@copilot Run docker/build-push-action@v5
GitHub Actions runtime token ACs
Docker info...

Fixed the npm ci error by changing to npm install in the Dockerfile. The issue was that npm ci requires package-lock.json, which is excluded from the repository via .gitignore. The Dockerfile now uses npm install --omit=dev --ignore-scripts which works without the lock file. (730a4ae)

@kelleyblackmore kelleyblackmore merged commit 6fbddb5 into main Oct 31, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants