nitro icon indicating copy to clipboard operation
nitro copied to clipboard

refactor(presets/zeabur): match our current zbpack

Open pan93412 opened this issue 2 weeks ago β€’ 2 comments

πŸ”— Linked issue

A better implementation of #3122.

Fix ZEA-7651

❓ Type of change

  • [ ] πŸ“– Documentation (updates to the documentation, readme, or JSdoc annotations)
  • [x] 🐞 Bug fix (a non-breaking change that fixes an issue)
  • [x] πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • [ ] ✨ New feature (a non-breaking change that adds functionality)
  • [ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Zeabur now uses the general "node-server" to build the Dockerfile. Therefore, we simply extend "node-server" and "static".

πŸ“ Checklist

  • [x] I have linked an issue or discussion.
  • [x] I have updated the documentation accordingly.

Checks:

  • [x] Complete the tests of zeabur and zeabur-static.
  • [x] "nuxt build" selects the "zeabur" provider and generates the same output as "node". $ ZEABUR=1 pnpm build ● Nitro preset: zeabur [success] [nitro] You can preview this build using `node .output/server/index.mjs`
  • [x] "nuxt generate" selects the ~~"zeabur-static"~~ "zeabur" provider and generates the same output as "static" (?) $ ZEABUR=1 pnpm generate ● Nitro preset: zeabur [success] [nitro] Generated public .output/public [success] [nitro] You can preview this build using `node .output/server/index.mjs`

pan93412 avatar Dec 16 '25 18:12 pan93412

@pan93412 is attempting to deploy a commit to the Nitro Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Dec 16 '25 18:12 vercel[bot]

πŸ“ Walkthrough

Walkthrough

Renamed the Zeabur server preset to zeaburServer, replaced custom serverless/ISR/output hooks with extends: "node-server", updated default export to use zeaburServer, and added unit tests validating static and server preset output structures.

Changes

Cohort / File(s) Summary
Zeabur preset refactor
src/presets/zeabur/preset.ts
Renamed zeabur β†’ zeaburServer; removed legacy serverless/output hooks, ISR hookup, file-write and symlink side effects; simplified preset to extends: "node-server"; updated default export to use zeaburServer alongside zeaburStatic.
Zeabur preset tests
test/presets/zeabur.test.ts
Added tests asserting output layout: the static preset produces nitro.json, a public directory and public/favicon.ico; the server preset produces a server/index.mjs entry point.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review the new zeaburServer preset to ensure required server behaviors previously provided by removed hooks are still satisfied by node-server.
  • Confirm removal of ISR, file writes, and symlink logic does not break deployments or expected build outputs.
  • Validate the new tests cover critical output expectations and adapt if other output artifacts are required.

Pre-merge checks and finishing touches

βœ… Passed checks (3 passed)
Check name Status Explanation
Description check βœ… Passed The description is directly related to the changeset, providing context about the Zeabur preset refactoring, linked issues, type of changes, and verification steps.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check βœ… Passed The PR title follows conventional commits format with 'refactor' type and 'zeabur' scope, clearly summarizing the main change of updating the Zeabur preset.
✨ Finishing touches
  • [ ] πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Dec 16 '25 18:12 coderabbitai[bot]

Since both of your review comments point to the same underlying issue, I'd like to provide some additional context here to address them together.

Last year, after evaluating stability and necessity, Zeabur decided to deprecate serverless runtime support, as containerization effectively covers those use cases. Currently, all projects on Zeabur are wrapped in a Dockerfile and executed as containers. As a result, the current role of zbpack is limited to:

  • Determining if the project is a Nitro project (currently hardcoded via package.json):

    https://github.com/zeabur/zbpack/blob/b8d76b5758fed32203cbdbf0456a9bc5c948dfc0/internal/nodejs/plan.go#L339-L347

  • If it is, it simply starts Nitro's own node-server:

    https://github.com/zeabur/zbpack/blob/b8d76b5758fed32203cbdbf0456a9bc5c948dfc0/internal/nodejs/plan.go#L713-L719

  • The node-server then handles SSR and ISR. Users can choose to fully utilize SSG by specifying ZBPACK_OUTPUT_DIR and using nuxt generate as the ZBPACK_BUILD_COMMAND. We do not interfere with the build artifacts further.

You might also notice that we currently hardcode the NITRO_PRESET. Consequently, the specific build artifacts generated by the zeabur preset are actually no longer being used by our platform internally. However, this preset still impacts users who choose to write their own Dockerfiles. For example:

FROM node:25-slim AS builder
WORKDIR /src
COPY . .
RUN npm install -g pnpm && pnpm install --prod --frozen-lockfile
RUN pnpm run generate

FROM zeabur/caddy-static AS server
EXPOSE 8080
COPY --from=builder /src/.output/public /usr/share/caddy

Because Zeabur automatically injects ZEABUR=1 during CI, std-env defaults to the Zeabur preset. However, since the output path for the Zeabur preset differs from standard expectations (the artifacts end up in .zeabur/output instead of .output/public), the Dockerfile code above fails.

This has caused confusion for many users who wonder, "Why does my Dockerfile build fine locally (using node-server or static presets) but fail in the Zeabur environment?" Therefore, my goal is to align the zeabur preset behavior more closely with our current containerized environment.

If you have any better suggestions or thoughts on how to handle this, I'd love to hear them!

pan93412 avatar Dec 17 '25 03:12 pan93412

@pi0 sorry for pinging – what's your opinion?

pan93412 avatar Dec 19 '25 03:12 pan93412

Thanks for the explanations, @pan93412 ❀️. It makes sense if the platform is simplified by switching to a node-server–style preset that also works with Dockerfile templates.

My concern is that framework detection can easily fail. In plan.go, the "nitro" (v3) NPM package is not detected (this PR is also targeting nitro v3 btw. there is not even an official Nuxt version supporting it yet, not sure how you could test). There are meta-frameworks and tools (like undocs) that use Nitro as an internal dependency, and those will fail as well. Nuxt is not the only direct dep we should be checking for.

With the current preset implementation, when a Nitro build runs in Zeabur CI, it produces a predictable output that the deployment platform can consume. I am fine if the output directory becomes .output or something else, but it should be detectable from build artifacts rather than relying on dependency-name detection for special behavior.

pi0 avatar Dec 19 '25 12:12 pi0

Vercel CLI is also detect framework by matching package:

https://github.com/vercel/vercel/blob/d4490e7ffbf47a6efb87fe3b66b6368fb0ac9d3b/packages/frameworks/src/frameworks.ts#L2365-L2395 https://github.com/vercel/vercel/blob/d4490e7ffbf47a6efb87fe3b66b6368fb0ac9d3b/packages/frameworks/src/frameworks.ts#L1520-L1588 https://github.com/vercel/vercel/blob/d4490e7ffbf47a6efb87fe3b66b6368fb0ac9d3b/packages/frameworks/src/frameworks.ts#L1908-L1944

https://github.com/vercel/vercel/blob/d4490e7ffbf47a6efb87fe3b66b6368fb0ac9d3b/packages/fs-detectors/src/detect-framework.ts

gxres042 avatar Dec 19 '25 15:12 gxres042

My concern is that framework detection can easily fail. In plan.go, the "nitro" (v3) NPM package is not detected (this PR is also targeting nitro v3 btw. there is not even an official Nuxt version supporting it yet, not sure how you could test). There are meta-frameworks and tools (like undocs) that use Nitro as an internal dependency, and those will fail as well. Nuxt is not the only direct dep we should be checking for.

Currently, we can only list all frameworks based on Nitro and apply the same logic to them. Most zero-config application builders use this approach, including Vercel and Railway's Railpack. I think it is fine at the moment.

Nitro v3 will be implemented after I have cleaned up the logic in zbpack.

With the current preset implementation, when a Nitro build runs in Zeabur CI, it produces a predictable output that the deployment platform can consume. I am fine if the output directory becomes .output or something else, but it should be detectable from build artifacts rather than relying on dependency-name detection for special behavior.

Yes. Once we declare that a framework (e.g., Nuxt, Undocs, TanStack Start) is based on Nitro, they will all follow the same bundle logic in zbpack, as their outputs are predictable. The only thing we need to maintain is the list of Nitro frameworks.

pan93412 avatar Dec 20 '25 04:12 pan93412

Some providers also detect "some" Nitro based frameworks however zero config detection build output and docs are based on assumption that platform's framework detection is not a hard requirement.

Maintaining a list of known pkg names per each provider is not desired nor practical honestly. The fact that official "nitro" package itself(!) is missing today (and our e2e deploys failed without notice) is a proof of this. Anyone should be able to make a Nitro based tool that just works everywhere without waiting.

Regardless, i will properly review platform support as soon as could and likely defaulting to something guaranteed to work on zeabur even if detection fails.

Feel free to reach me out in discord (@pi0) to chat more.

pi0 avatar Dec 22 '25 09:12 pi0