Skip to content

chore: docker examples#1030

Merged
belgattitude merged 4 commits intomainfrom
add-distroless-example
Mar 24, 2026
Merged

chore: docker examples#1030
belgattitude merged 4 commits intomainfrom
add-distroless-example

Conversation

@belgattitude
Copy link
Copy Markdown
Owner

@belgattitude belgattitude commented Mar 24, 2026

Summary by CodeRabbit

  • New Features

    • Added distroless Docker image support for the Next.js example with optimized multi-stage builds.
    • New Docker Compose configuration for distroless deployment.
  • Chores

    • Expanded Docker and Git ignore patterns to exclude more build outputs, caches, and editor artifacts.
    • Updated Docker build prune output references.
    • Removed commented-out WebAssembly-related config snippets.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 24, 2026

⚠️ No Changeset found

Latest commit: 82561f9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flowblade-next-app Ready Ready Preview Mar 24, 2026 6:00pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Warning

Rate limit exceeded

@belgattitude has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 6 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: adb45efb-5c23-4d0d-a555-c91873998d99

📥 Commits

Reviewing files that changed from the base of the PR and between 51cfb37 and 82561f9.

📒 Files selected for processing (3)
  • .dockerignore
  • examples/apps/nextjs-app/docker/.dockerignore
  • examples/apps/nextjs-app/docker/Dockerfile.distroless
📝 Walkthrough

Walkthrough

This PR expands repository Docker ignore patterns, switches Turbo prune output to ./.turbo-pruned/, adds a distroless multi-stage Dockerfile and Compose for the Next.js example, updates the example Dockerfile, and removes commented WASM loader blocks from Next.js config.

Changes

Cohort / File(s) Summary
Root Dockerignore
/.dockerignore
Expanded ignore patterns to include VCS metadata, additional dependency/cache paths (Yarn, .pnp.*, node_modules variants), build artifacts (tsbuildinfo, eslintcache, coverage, .out), and common OS/IDE/debug files.
Example Dockerignore
examples/apps/nextjs-app/docker/.dockerignore
Replaced minimal list with comprehensive ignore patterns mirroring root .dockerignore, covering caches, build outputs, dependency directories, and editor/tooling files.
Gitignore
/.gitignore
Replaced out with .turbo-pruned to match the new Turbo prune output directory naming.
Next.js Dockerfile (example)
examples/apps/nextjs-app/docker/Dockerfile
Changed prune output path from ./out/nextjs-app/ to ./.turbo-pruned/nextjs-app/; updated COPY paths and consolidated runner-stage setup; corepack install commented out.
Distroless Dockerfile & Compose
examples/apps/nextjs-app/docker/Dockerfile.distroless, examples/apps/nextjs-app/docker/docker-compose.distroless.yml
Added a distroless multi-stage Dockerfile (prepare, builder, runner) with build args and pruned dependency flow, plus a Compose file to run the distroless image.
Next.js Config
examples/apps/nextjs-app/next.config.mjs
Removed two commented-out WASM-related configuration blocks (turbopack rules and webpack override).

Sequence Diagram(s)

mermaid
sequenceDiagram
rect rgba(200,220,255,0.5)
participant Dev as Developer/CI
end
rect rgba(200,255,220,0.5)
participant Prep as Prepare stage
participant Build as Builder stage
participant Run as Runner (distroless)
end
Dev->>Prep: copy manifests, install corepack, run turbo prune
Prep-->>Dev: .turbo-pruned/ (pruned outputs + json/yarn.lock)
Dev->>Build: COPY pruned outputs, install deps, run build (turbo/yarn)
Build-->>Dev: standalone Next.js build, node_modules subset, static files
Dev->>Run: COPY standalone output, static, public; set env, expose port
Run-->>Users: serve via node examples/apps/nextjs-app/server.js

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Improve docker #1027 — Overlapping Docker and .dockerignore updates across root and example directories.
  • fix: docker #616 — Related edits to the Next.js example Dockerfile and build/prune handling.

Poem

🐰 I pruned the paths and hid the cache,
Dockerfiles lean for a speedy dash.
Distroless boots, a silent little clap,
Builds hop along — no bulky extra map.
thump — the rabbit tidies up the app.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'chore: docker examples' is vague and generic, using a non-descriptive term 'docker examples' that doesn't convey specific information about the changeset. Consider a more specific title such as 'chore: add distroless Docker example and expand dockerignore patterns' to better reflect the actual changes made.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-distroless-example

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.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 24, 2026

Open in StackBlitz

@flowblade/core

npm i https://pkg.pr.new/@flowblade/core@1030

@flowblade/source-duckdb

npm i https://pkg.pr.new/@flowblade/source-duckdb@1030

@flowblade/source-kysely

npm i https://pkg.pr.new/@flowblade/source-kysely@1030

@flowblade/sql-tag

npm i https://pkg.pr.new/@flowblade/sql-tag@1030

@flowblade/sql-tag-format

npm i https://pkg.pr.new/@flowblade/sql-tag-format@1030

@flowblade/sqlduck

npm i https://pkg.pr.new/@flowblade/sqlduck@1030

commit: 82561f9

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR adds Docker examples for the nextjs-app monorepo application, introducing both a standard Debian-based runner and a new distroless variant, while also cleaning up the .dockerignore files and renaming the turbo prune output directory from out to .turbo-pruned.

  • Critical bug in Dockerfile runner stage: adduser, mkdir, and chown are chained with bare \ line continuations instead of &&, so all three commands are passed as extra arguments to addgroup rather than running independently. The nextjs user and .next directory are never actually created, and USER nextjs will fail or silently use an unintended user.
  • New Dockerfile.distroless: Structurally sound, but the runner stage runs as root because the USER directive is commented out. The distroless image ships a nonroot user (UID 65532) or a :nonroot tag that should be used.
  • .turbo cache exclusion removed: Both updated .dockerignore files dropped the **/.turbo entry that was present before, potentially pulling Turborepo's local build cache into the Docker context unnecessarily.
  • Typo in comment: # Bort PORT / HOSTNAME should be # Both PORT / HOSTNAME in both Dockerfiles.
  • Cleaned up next.config.mjs: Removed stale commented-out webpack/turbopack WASM loader blocks — no functional impact.

Confidence Score: 1/5

  • Not safe to merge — the primary Dockerfile runner stage has a critical shell syntax bug that will break the production image at runtime.
  • The missing && operators in the runner-stage RUN block of Dockerfile means the nextjs user is never created, .next is never created/owned, and the subsequent USER nextjs line will either fail or silently run as an unintended user. This is a build-breaking bug in the main Dockerfile. The distroless variant also runs as root, which is a security concern.
  • examples/apps/nextjs-app/docker/Dockerfile (lines 113–116) requires immediate attention before this PR is merged.

Important Files Changed

Filename Overview
examples/apps/nextjs-app/docker/Dockerfile Runner stage has a critical shell syntax bug: adduser, mkdir, and chown are missing && operators and will be passed as arguments to addgroup instead of running as separate commands, breaking the nextjs user setup entirely.
examples/apps/nextjs-app/docker/Dockerfile.distroless New distroless variant Dockerfile; build stages are correct. Runner stage runs as root (USER directive is commented out) — the distroless image's built-in nonroot user should be used instead.
.dockerignore Expanded with many standard exclusions; the **/.turbo cache exclusion from the previous version was accidentally removed, which may slightly increase build-context size.
examples/apps/nextjs-app/docker/.dockerignore Previously had most entries commented out; now properly mirrors the root .dockerignore. Same omission of **/.turbo as the root file.
examples/apps/nextjs-app/docker/docker-compose.distroless.yml New compose file for the distroless variant; straightforward and correct.
.gitignore Renamed out to .turbo-pruned to match the updated turbo prune output directory used in the Dockerfiles.
examples/apps/nextjs-app/next.config.mjs Removed commented-out turbopack and webpack WASM loader config blocks; no functional change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Docker Build Context\nfiltered by .dockerignore] --> B

    subgraph Stage1["Stage 1 — prepare (node:debian)"]
        B[Install git, jq, corepack, turbo] --> C[COPY monorepo sources]
        C --> D["turbo prune → .turbo-pruned/nextjs-app/"]
    end

    subgraph Stage2["Stage 2 — builder (FROM prepare)"]
        E[COPY pruned json + yarn.lock] --> F[yarn install with cache mount]
        F --> G[COPY pruned full sources]
        G --> H[yarn turbo run build\nnext.js standalone output]
    end

    subgraph Stage3_Standard["Stage 3 — runner (node:debian)"]
        I[addgroup / adduser / mkdir / chown\n⚠️ missing && operators] --> J[COPY standalone artefacts]
        J --> K["CMD node server.js\n(runs as nextjs user — if setup works)"]
    end

    subgraph Stage3_Distroless["Stage 3 — runner (distroless)"]
        L[COPY standalone artefacts] --> M["CMD node server.js\n⚠️ runs as root"]
    end

    D --> E
    H --> I
    H --> L
Loading

Comments Outside Diff (1)

  1. examples/apps/nextjs-app/docker/Dockerfile, line 96 (link)

    P2 Typo: "Bort" → "Both"

    The same typo exists at line 98 in Dockerfile.distroless.

Reviews (1): Last reviewed commit: "chore: docker examples" | Re-trigger Greptile

Comment on lines +113 to +116
RUN addgroup --system --gid 1001 nodejs \
adduser --system --uid 1001 nextjs \
mkdir .next \
chown nextjs:nodejs .next
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0 Missing && operators — commands won't run

The line-continuation backslashes \ here do NOT separate shell commands; they simply continue a single shell command. As written, adduser, mkdir, and chown are passed as extra positional arguments to addgroup, which will either reject them or silently ignore them. As a result, the nextjs user is never created, the .next directory is never created/owned, and USER nextjs on the next line will cause the container to fail to start (or run as an unintended user on some runtimes).

Suggested change
RUN addgroup --system --gid 1001 nodejs \
adduser --system --uid 1001 nextjs \
mkdir .next \
chown nextjs:nodejs .next
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs \
&& mkdir .next \
&& chown nextjs:nodejs .next

Comment on lines 1 to +49
# .dockerignore is used to exclude files and directories from being copied into the Docker image during the build process. This helps to reduce the size of the image and improve build times by only including necessary files.
# keep it at the root of the project to ensure that we don't copy unnecessary files into the Docker image.

node_modules
**/.turbo
# git (disable if needed in the container)
.git

# dependencies
**/node_modules

# caches
**/.cache
**/tsconfig.tsbuildinfo
**/tsconfig.*.tsbuildinfo
**/.eslintcache

# package managers
**/.yarn/*
!**/.yarn/patches
!**/.yarn/releases
!**/.yarn/plugins
.pnp.*

# testing
**/coverage
**/.out/

# Build directories
**/apps/*/.next
**/packages/*/dist
**/packages/*/docs
**/.eslintcache

# Misc
.DS_Store
*.pem

# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# IDE
.idea/*
.project
.classpath
*.launch
*.sublime-workspace
.vscode/


Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 .turbo cache directory no longer excluded

The previous .dockerignore explicitly excluded **/.turbo (Turborepo's local build-cache). This entry was removed in the new version. While the newly generated .turbo-pruned output is intentional, the .turbo cache directories on the host can be large and are never needed inside the image. Omitting this exclusion will increase Docker build-context transfer size on incremental builds.

Consider re-adding the exclusion:

# turbo cache
**/.turbo

The same entry is also missing from examples/apps/nextjs-app/docker/.dockerignore.

#RUN mkdir .next
#RUN chown nextjs:nodejs .next

#USER nextjs
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Distroless runner stage running as root

The addgroup/adduser/USER nextjs setup is entirely commented out in the distroless stage, meaning the container runs as root (UID 0) in production. The gcr.io/distroless/nodejs* images ship a built-in nonroot user (UID 65532). Running as root is unnecessary here and contradicts the security principle of least privilege.

Consider switching to the non-root user that the distroless image already provides:

USER nonroot

or, equivalently, use the :nonroot image variant:

ARG DISTROLESS_IMAGE=gcr.io/distroless/nodejs24-debian13:nonroot

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.dockerignore:
- Around line 10-15: Add an ignore pattern for the Turbo cache to the
.dockerignore by including the '**/.turbo' entry (matching the existing glob
style like '**/.cache'); update the .dockerignore file where other cache
patterns are listed (near '**/.cache', '**/.eslintcache', etc.) so the Turbo
cache directory is excluded from Docker build context.

In `@examples/apps/nextjs-app/docker/.dockerignore`:
- Around line 10-15: The .dockerignore is missing an entry to exclude the Turbo
cache; update the Docker ignore (examples/apps/nextjs-app/docker/.dockerignore)
to add an exclusion for the Turbo cache directory (add a pattern like **/.turbo)
so the Turbo cache is not included in the Docker build context and doesn't
inflate image builds.

In `@examples/apps/nextjs-app/docker/Dockerfile`:
- Around line 113-116: The RUN instruction in the Dockerfile chains multiple
shell commands (addgroup, adduser, mkdir, chown) but misses the required &&
operators between them; update the RUN line for the Dockerfile so each command
is joined with && (and retain trailing backslashes for line continuation) to
ensure commands execute sequentially and the build doesn't treat later tokens as
arguments—specifically modify the RUN that invokes addgroup, adduser, mkdir
.next, and chown nextjs:nodejs .next to use "&&" between each command.

In `@examples/apps/nextjs-app/docker/Dockerfile.distroless`:
- Around line 94-131: Add a non-root user and ensure files are owned by it in
the runner stage: set USER 65532:65532 in the runner stage (after WORKDIR or
after all COPYs as appropriate) and update the COPY --from=builder commands that
bring in files (the COPY of next.config.mjs and package.json, COPY of
.next/standalone, COPY of .next/static, and COPY of public) to use
--chown=65532:65532 so the runtime files are owned by the distroless nonroot
user and the container does not run as root.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ed60295c-1e60-4532-88d5-3a74a216e0ff

📥 Commits

Reviewing files that changed from the base of the PR and between 853f9d0 and 26e73ae.

📒 Files selected for processing (7)
  • .dockerignore
  • .gitignore
  • examples/apps/nextjs-app/docker/.dockerignore
  • examples/apps/nextjs-app/docker/Dockerfile
  • examples/apps/nextjs-app/docker/Dockerfile.distroless
  • examples/apps/nextjs-app/docker/docker-compose.distroless.yml
  • examples/apps/nextjs-app/next.config.mjs
💤 Files with no reviewable changes (1)
  • examples/apps/nextjs-app/next.config.mjs

@belgattitude belgattitude merged commit f3f8056 into main Mar 24, 2026
15 checks passed
@belgattitude belgattitude deleted the add-distroless-example branch March 24, 2026 18:04
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.

1 participant