feat: add Dockerfile + .dockerignore - #5
Merged
Merged
Conversation
…er deploys Two-stage Dockerfile (node:20-alpine) that builds the TypeScript source with tsup, prunes devDependencies, and copies the result into a lean runtime image. Final container runs `node /app/dist/index.js`, speaking MCP over stdio. Local verification with MCP Inspector CLI: - docker build . succeeds (image: 224 MB) - tools/list returns 4 tools - orcarouter_chat.max_tokens.default = 10000 (matches v1.1.3) - orcarouter_models_list (no API key) returns 159 models Primary motivation: Glama indexes by spawning each server in a Firecracker microVM and running MCP introspection. With a hand-authored Dockerfile in the repo, Glama uses ours instead of inferring one via their AI heuristic — faster scan, fewer surprises. Bonus: any user who prefers container deploys can now `docker run -i --rm <image> --rm -e ORCAROUTER_API_KEY=...` instead of npx. .dockerignore keeps the build context lean (no node_modules / dist / test / examples / READMEs / locale files / vitest config in the image layers).
Member
Author
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
2 tasks
fengyat
added a commit
that referenced
this pull request
May 26, 2026
`npm ci` requires a package-lock.json. This repo uses bun as its
primary package manager and only commits bun.lock, so the v1.1.4 tag
push triggered a CI failure at the Install dependencies step:
npm error The `npm ci` command can only install with an existing
package-lock.json or npm-shrinkwrap.json
PR #3 originally chose `npm ci` from the official MCP Registry docs
example — that example assumes an npm-managed project. Our Dockerfile
(merged in #5) already uses `npm install --no-audit --no-fund` against
the same package.json with no issues; this commit aligns the publish
workflow with that pattern.
We accept the trade-off of non-pinned transitive deps in CI: deps are
pinned to caret ranges in package.json that have been stable across
releases, the build is bundled by tsup so transitive shape doesn't
leak into the published artifact, and tag-gated runs are infrequent
enough that drift detection is moot.
After this merges, the existing v1.1.4 tag needs to be re-pointed at
the new commit (delete + recreate) to retrigger publish — there is no
v1.1.4 on npm or MCP Registry yet, since the failed run aborted before
either publish step.
Co-authored-by: fengyat <fengya.tian@continuum01.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Glama indexes MCP servers by spawning each one in a Firecracker microVM, running build, and then doing MCP protocol introspection. They prefer a hand-authored Dockerfile in the repo; otherwise they fall back to an AI-inferred one which can fail in non-obvious ways. Our glama submission has been pending for hours — adding a proper Dockerfile should unblock it (and by extension our
punkpeye/awesome-mcp-serversPR #6878, which is gated on the glama badge).What's in the Dockerfile
Two-stage build:
node:20-alpine): copy manifest + source,npm install,npm run build(tsup →dist/index.js), thennpm prune --omit=devnode:20-alpine): copydist/, prunednode_modules, andpackage.json. Run asnodeuser.ENTRYPOINT ["node", "/app/dist/index.js"]Final image: 224 MB (typical alpine + node_modules baseline).
Local verification
Container behavior is identical to bare
node dist/index.js— same tools, same defaults, sameno API key needed for catalogsemantics..dockerignoreExcludes from the build context:
.git,.github,.claude,node_modules,dist,test,examples,assets, locale READMEs,bun.lock(we use npm in the image),vitest.config.ts, etc. Keeps the build fast and the image clean.Out of scope
Test plan
docker buildsucceeds locallytools/listandtools/call