Skip to content

Comments

feat: Add Docker build and publish CI for web app#418

Merged
elie222 merged 4 commits intoelie222:mainfrom
vishalmakwana111:feat/docker-publish-ci
May 4, 2025
Merged

feat: Add Docker build and publish CI for web app#418
elie222 merged 4 commits intoelie222:mainfrom
vishalmakwana111:feat/docker-publish-ci

Conversation

@vishalmakwana111
Copy link
Contributor

@vishalmakwana111 vishalmakwana111 commented Apr 26, 2025

This PR adds Docker support for the apps/web application and a GitHub Actions workflow to automatically build and publish images to GHCR.

Changes:

  1. docker/Dockerfile.prod: New Dockerfile to build the web application production image.
  2. .github/workflows/publish-docker.yml: New GitHub Action workflow that:
    • Triggers on version tag pushes (v*.*.*).
    • Builds the image using Dockerfile.prod.
    • Pushes the tagged image to GHCR.
    • Note for Maintainers: Please update the images path in this workflow to ghcr.io/${{ github.repository_owner }}/inbox-zero after merging.
  3. Code Changes (apps/web/...): Modified blog/sitemap components to correctly handle dummy Sanity credentials during the Docker build process (next build).

Testing & Local Usage:

  • CI Workflow: Successfully tested in fork (vishalmakwana111/inbox-zero). Pushing a version tag built and pushed a working image. You can test this specific image: docker pull ghcr.io/vishalmakwana111/inbox-zero:v0.0.11
  • Local Build: You can build the image locally using docker build -t inbox-zero-test -f docker/Dockerfile.prod .
  • Running Pre-Built Image with Docker Compose:
    • To run the pre-built images from GHCR (after this PR is merged and images are published to the main repo's registry), modify your local docker-compose.yml file:
      1. Comment out or remove the build: section for the web service (if present).
      2. Set the image: line for the web service to point to the desired image tag, e.g., image: ghcr.io/elie222/inbox-zero:vX.Y.Z (replace elie222 and vX.Y.Z as needed). Use the tag mentioned above for testing from the fork.
    • Ensure your local ./apps/web/.env file contains the necessary runtime environment variables.
    • Run docker compose up -d.

Addresses the request for an official Docker image raised in #389.

Summary by CodeRabbit

  • New Features
    • Introduced automated publishing of Docker images to GitHub Container Registry on version tag pushes.
    • Added a production-ready Dockerfile for optimized and reproducible builds.
  • Bug Fixes
    • Improved blog and sitemap build reliability by skipping Sanity data fetches when dummy credentials are detected.
    • Added a user-facing message when blog post content is unavailable.
  • Chores
    • Updated Docker Compose to use a pre-built image from a remote registry.
    • Added Prettier Tailwind CSS plugin as a development dependency.

@vercel
Copy link

vercel bot commented Apr 26, 2025

@vishalmakwana111 is attempting to deploy a commit to the Inbox Zero Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLAassistant commented Apr 26, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 26, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces a new GitHub Actions workflow for automated Docker image publishing to GHCR on pushes to the main branch and semantic version tags. A new production Dockerfile is added to build the application container with Node 22 Alpine, pnpm, Prisma, Next.js, and dummy environment variables for build-time. The Docker Compose configuration is updated to use the published image from GHCR instead of building locally. Application code changes detect a dummy Sanity project ID to conditionally skip data fetching and static parameter generation during builds. Additionally, a Prettier plugin for Tailwind CSS is added as a development dependency. Minor stylistic and formatting improvements were made in several React components and TypeScript files.

Changes

File(s) Change Summary
.github/workflows/publish-docker.yml Added a new GitHub Actions workflow to build and publish Docker images to GHCR on pushes to main branch and semantic version tag pushes.
docker/Dockerfile.prod Added a production Dockerfile based on Node 22 Alpine with pnpm, Prisma client generation, Next.js build, dummy environment variables, and setup for production runtime.
docker-compose.yml Modified web service to comment out local Docker build and use a pre-built image from GHCR instead.
apps/web/app/blog/page.tsx
apps/web/app/blog/post/[slug]/page.tsx
apps/web/app/sitemap.ts
Updated to conditionally skip Sanity data fetching and static parameter generation when the environment variable NEXT_PUBLIC_SANITY_PROJECT_ID equals 'dummy-sanity-project-id-for-build', preventing fetches during certain build scenarios.
package.json Added prettier-plugin-tailwindcss version 0.6.11 as a new development dependency.
apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeBase.tsx Reordered CSS class names in two paragraph elements for styling consistency; no logic changes.
apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeForm.tsx Reformatted call to updateKnowledgeAction to multi-line argument style; no logic changes.
apps/web/app/(app)/[emailAccountId]/clean/helpers.ts Reformatted TypeScript type annotation for getLastJob function parameter to multi-line for readability; no logic changes.
apps/web/app/(app)/[emailAccountId]/settings/LabelsSection.tsx Reformatted argument object passed to updateLabelsAction with explicit line breaks and trailing commas; no logic changes.
apps/web/app/api/google/threads/basic/route.ts Removed trailing whitespace line after variable declaration; no functional changes.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant GitHub
    participant GitHubActions
    participant DockerBuild
    participant GHCR
    participant DockerCompose
    participant Application

    Developer->>GitHub: Push to main branch or tag vX.Y.Z
    GitHub->>GitHubActions: Trigger publish-docker workflow
    GitHubActions->>DockerBuild: Build Docker image using Dockerfile.prod
    DockerBuild->>GHCR: Push image with tags (latest, semantic version)
    GitHubActions->>GitHub: Complete workflow
    Developer->>DockerCompose: Use docker-compose.yml to run container
    DockerCompose->>Application: Pull and run image from GHCR
Loading

Possibly related PRs

Poem

🐇
A Docker hop, a workflow leap,
To GHCR our images creep.
Dummy IDs keep fetches at bay,
Ensuring smooth builds, night or day.
Tailwind Prettier joins the show,
Compose pulls images—off we go!
The rabbit cheers this tidy feat,
With every change, our build’s complete!
🌱

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeBase.tsx

Oops! Something went wrong! :(

ESLint: 9.24.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

apps/web/app/(app)/[emailAccountId]/clean/helpers.ts

Oops! Something went wrong! :(

ESLint: 9.24.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeForm.tsx

Oops! Something went wrong! :(

ESLint: 9.24.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

  • 2 others

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d17916 and 9382812.

📒 Files selected for processing (6)
  • .github/workflows/publish-docker.yml (1 hunks)
  • apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeBase.tsx (2 hunks)
  • apps/web/app/(app)/[emailAccountId]/automation/knowledge/KnowledgeForm.tsx (1 hunks)
  • apps/web/app/(app)/[emailAccountId]/clean/helpers.ts (1 hunks)
  • apps/web/app/(app)/[emailAccountId]/settings/LabelsSection.tsx (1 hunks)
  • apps/web/app/api/google/threads/basic/route.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 1

🧹 Nitpick comments (4)
docker/Dockerfile.prod (1)

21-26: Consider using multi-stage build for a smaller production image

The current approach installs all dependencies including dev dependencies without pruning them after the build, which results in a larger final image.

- # Copy the rest of the application code FIRST
- COPY . .
- 
- # Install ALL dependencies (including dev, no pruning)
- # This will now run postinstall scripts *after* source code is copied
- RUN pnpm install --frozen-lockfile
+ # Copy the rest of the application code
+ COPY . .
+ 
+ # Install dependencies and run postinstall scripts
+ RUN pnpm install --frozen-lockfile && \
+     pnpm --filter inbox-zero-ai exec -- prisma generate && \
+     pnpm --filter inbox-zero-ai exec -- next build && \
+     pnpm install --frozen-lockfile --prod
apps/web/app/blog/post/[slug]/page.tsx (1)

13-13: Consider using consistent quote style across files.

Minor consistency note: this file uses single quotes for the dummy project ID string, while sitemap.ts uses double quotes for the same value.

-  if (process.env.NEXT_PUBLIC_SANITY_PROJECT_ID === 'dummy-sanity-project-id-for-build') {
+  if (process.env.NEXT_PUBLIC_SANITY_PROJECT_ID === "dummy-sanity-project-id-for-build") {
.github/workflows/publish-docker.yml (2)

4-4: Remove trailing whitespace.

There are trailing spaces at the end of these lines.

-name: Publish Docker Image 
+name: Publish Docker Image
-      - 'v*.*.*' # Trigger on tags like v1.0.0, v1.2.3, etc. 
+      - 'v*.*.*' # Trigger on tags like v1.0.0, v1.2.3, etc.

Also applies to: 9-9

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 4-4: trailing spaces

(trailing-spaces)


51-51: Consider removing no-cache: true.

You're using GitHub Actions cache with cache-from and cache-to, but no-cache: true disables the Docker build cache entirely, which could make builds slower. Unless you specifically need to ensure completely fresh builds every time, consider removing this line to benefit from both GHA and Docker caching.

-          no-cache: true
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b17a22e and 7e2bb3a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .github/workflows/publish-docker.yml (1 hunks)
  • apps/web/app/blog/page.tsx (1 hunks)
  • apps/web/app/blog/post/[slug]/page.tsx (2 hunks)
  • apps/web/app/sitemap.ts (1 hunks)
  • docker-compose.yml (1 hunks)
  • docker/Dockerfile.prod (1 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/app/blog/page.tsx (1)
apps/web/sanity/lib/fetch.ts (1)
  • sanityFetch (12-42)
🪛 YAMLlint (1.35.1)
.github/workflows/publish-docker.yml

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 9-9: trailing spaces

(trailing-spaces)

🪛 Checkov (3.2.334)
docker/Dockerfile.prod

[MEDIUM] 32-33: Basic Auth Credentials

(CKV_SECRET_4)

🔇 Additional comments (12)
package.json (1)

24-24: Good addition for consistent Tailwind CSS formatting

Adding the Tailwind CSS Prettier plugin will help maintain consistent formatting of Tailwind CSS classes throughout the codebase, which improves readability and makes styles more maintainable.

docker/Dockerfile.prod (5)

1-8: LGTM: Proper base image and setup

Using Node 22 Alpine as the base image is a good choice for minimizing image size while providing the latest Node.js version. The essential tools installation looks good.


9-20: LGTM: Optimized Docker layer caching

Copying package manager files first before the rest of the application code is a great practice for optimizing Docker build caching. When package.json files don't change, Docker can reuse the cached dependency installation layer.


31-52: Dummy environment variables are properly isolated for build-time only

The use of dummy environment variables during build is a reasonable approach to satisfy build-time requirements without exposing sensitive information. However, ensure that these variables are only used during build and not at runtime.

Note that lines 32-33 containing dummy database URLs were flagged by static analysis as potential basic auth credentials, but since these are just placeholders for build time only, they don't represent a security risk.

Consider adding a comment clarifying that these values are never used in runtime:

- # Provide dummy build-time ENV VARS (Still needed for build)
+ # Provide dummy build-time ENV VARS (Still needed for build, never used at runtime)
🧰 Tools
🪛 Checkov (3.2.334)

[MEDIUM] 32-33: Basic Auth Credentials

(CKV_SECRET_4)


53-58: LGTM: Proper build steps

Generating the Prisma client followed by building the Next.js application is the correct sequence for the production build.


59-64: LGTM: Container configuration

Exposing port 3000 and setting the default command for starting the production server looks good.

docker-compose.yml (1)

40-44: Update the image reference before merging

The image is currently set to use the contributor's personal GitHub Container Registry path. As noted in the PR objectives, maintainers should update this to use the organization's registry path after merging.

- image: ghcr.io/vishalmakwana111/inbox-zero:latest # Use pre-built image (updated tag)
+ image: ghcr.io/${{ github.repository_owner }}/inbox-zero:latest # Use pre-built image (updated tag)

It might be better to use a specific version tag instead of latest for better stability and reproducibility, e.g., v0.0.1.

apps/web/app/blog/page.tsx (1)

209-213: LGTM: Properly handling Sanity fetch during build

Good approach to conditionally skip Sanity fetches during builds with dummy credentials. This ensures that the Docker build process won't attempt to fetch from Sanity when using the dummy project ID, avoiding build-time errors.

This change aligns with the PR's objective to modify blog components to properly handle dummy Sanity credentials during the Docker build process.

apps/web/app/sitemap.ts (1)

7-13: Good addition to handle dummy Sanity credentials during Docker builds.

This conditional check prevents calling the Sanity API during build time when using placeholder credentials, which is exactly what's needed for Docker builds to succeed without real Sanity access. The early return with an empty array is an elegant solution.

apps/web/app/blog/post/[slug]/page.tsx (2)

13-15: Good addition for Docker build compatibility.

This condition correctly prevents fetching post paths during builds with dummy credentials, consistent with the approach used in sitemap.ts.


73-75: Nice defensive programming with fallback UI.

Adding this guard clause prevents potential runtime errors when post data is unavailable, improving the resilience of the application. The fallback message is clear and appropriate.

.github/workflows/publish-docker.yml (1)

1-52: Well-structured Docker publishing workflow.

This GitHub Actions workflow is well-organized and properly configured for building and publishing Docker images to GHCR on version tag pushes. The semantic versioning tag strategy is particularly good for maintaining versioned Docker images.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 9-9: trailing spaces

(trailing-spaces)

Copy link
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: 0

♻️ Duplicate comments (1)
.github/workflows/publish-docker.yml (1)

27-27: Update Docker image path after merging.

As noted in the PR description, once this lands, the image path should be parameterized to use the repository owner variable instead of the contributor’s namespace.

-          images: ghcr.io/vishalmakwana111/inbox-zero
+          images: ghcr.io/${{ github.repository_owner }}/inbox-zero
🧹 Nitpick comments (3)
.github/workflows/publish-docker.yml (3)

4-4: Remove trailing spaces.

YAMLlint flagged trailing spaces on this line—please remove them to ensure clean YAML syntax.

- name: Publish Docker Image␣
+ name: Publish Docker Image
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 4-4: trailing spaces

(trailing-spaces)


29-33: Clean up or fill out commented tag configurations.

There are several commented-out tag strategies (SHA, latest). Either remove these examples to declutter or enable the ones you intend to use.


49-51: Reconcile cache settings with no-cache.

You’ve configured both cache-from/cache-to and no-cache: true, which disables layer caching. If you intend to leverage GitHub Actions caching to speed up builds, remove the no-cache: true flag. Otherwise, drop the cache entries. For example:

-          cache-from: type=gha
-          cache-to: type=gha,mode=max
-          no-cache: true
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
# remove `no-cache: true` to enable caching
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e2bb3a and 2b15101.

📒 Files selected for processing (2)
  • .github/workflows/publish-docker.yml (1 hunks)
  • docker-compose.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker-compose.yml
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/publish-docker.yml

[error] 4-4: trailing spaces

(trailing-spaces)

🔇 Additional comments (1)
.github/workflows/publish-docker.yml (1)

1-3:

Details

✅ Verification successful

Verify linked documentation exists.

The header references CICD_PLAN.md for details—ensure this file is present at the repository root and up to date.


🏁 Script executed:

#!/bin/bash
# Check for the presence of CICD_PLAN.md in the repo root
if ! fd --hidden --max-depth 1 'CICD_PLAN\.md'; then
  echo "Error: CICD_PLAN.md not found in the repository root."
  exit 1
fi
echo "CICD_PLAN.md exists."

Length of output: 94


CICD_PLAN.md presence verified
The workflow header in .github/workflows/publish-docker.yml references CICD_PLAN.md, and the file exists at the repository root. No further action required.

@vishalmakwana111
Copy link
Contributor Author

Just a quick note on the workflow triggers in .github/workflows/publish-docker.yml:

The workflow runs on pushes to main in addition to version tags (v*.*.*). This is intentional to ensure the latest Docker tag is always automatically updated to reflect the current state of the main development branch.

@vishalmakwana111 vishalmakwana111 changed the title Feat/docker publish ci feat: Add Docker build and publish CI for web app Apr 26, 2025
    Adds a production Dockerfile (`docker/Dockerfile.prod`) for the `apps/web` Next.js application and a GitHub Actions workflow (`.github/workflows/publish-docker.yml`) to automatically build and publish images to GHCR.

    Includes dummy environment variables in the Dockerfile and modifications to Sanity components to ensure successful builds. Configures CI triggers and tagging for `main` branch (`latest`) and version tags (`vX.Y.Z`).

    Addresses the request in issue elie222#389.
@elie222
Copy link
Owner

elie222 commented Apr 29, 2025

Thanks so much for this!

I will be looking at this PR later this week. There was also this PR, any overlap?
#417

@vishalmakwana111
Copy link
Contributor Author

vishalmakwana111 commented Apr 30, 2025

I was actually working on this feature but forgot to add a comment on that issue, which caused the overlap. I suggest reviewing both PRs and accepting whichever seems better.
I've tested it locally, and it's working fine

Latest Image : https://github.com/vishalmakwana111/inbox-zero/pkgs/container/inbox-zero

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
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: 1

🧹 Nitpick comments (2)
docker/Dockerfile.prod (2)

1-8: Validate base image and tooling setup
Using node:22-alpine is a solid choice for a slim production image. Installing openssl via apk add --no-cache is correct. For pnpm, consider leveraging Node’s built-in Corepack (available since v16.9) instead of a global npm install to reduce the global footprint:

RUN corepack enable && corepack prepare pnpm@latest --activate

82-84: Expose application port
EXPOSE 3000 matches Next.js defaults. For improved resilience, consider adding a lightweight HEALTHCHECK instruction to verify the server is up.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8118c41 and 9d17916.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .github/workflows/publish-docker.yml (1 hunks)
  • apps/web/app/blog/page.tsx (1 hunks)
  • apps/web/app/blog/post/[slug]/page.tsx (2 hunks)
  • apps/web/app/sitemap.ts (1 hunks)
  • docker-compose.yml (1 hunks)
  • docker/Dockerfile.prod (1 hunks)
  • package.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docker-compose.yml
🚧 Files skipped from review as they are similar to previous changes (5)
  • package.json
  • apps/web/app/blog/post/[slug]/page.tsx
  • apps/web/app/blog/page.tsx
  • apps/web/app/sitemap.ts
  • .github/workflows/publish-docker.yml
🧰 Additional context used
🪛 Checkov (3.2.334)
docker/Dockerfile.prod

[MEDIUM] 32-33: Basic Auth Credentials

(CKV_SECRET_4)

🔇 Additional comments (6)
docker/Dockerfile.prod (6)

9-20: Efficient layer caching for dependencies
Copying only your workspace’s root package.json, lockfile, and individual package manifest files before running install steps is an excellent way to maximize Docker layer cache reuse. This hunk looks great.


21-27: Install dependencies without pruning
Running pnpm install --frozen-lockfile after copying the full source ensures reproducible builds and that any postinstall scripts have access to your code. This is the correct approach for the build stage.


29-29: Set NODE_ENV to production
Pinning NODE_ENV=production at build time can prune dev-only optimizations in some packages. In a single-stage build this is fine, but if you migrate to a multi-stage pattern, you may want to move this to the runtime stage to keep build-time tools intact.


53-55: Ensure Prisma client generation
You explicitly run prisma generate scoped to inbox-zero-ai, which is necessary. Please verify that this filter covers all Prisma schema locations in your monorepo (if there are others).


79-81: Build Next.js application
Building the Next.js app here is appropriate in a single-stage build. In a builder stage, ensure all build-time env (e.g. Sanity vars) are provided via ARG.


85-87: Default CMD for production start
pnpm --filter inbox-zero-ai start is consistent, but if you move to a runtime stage without a global pnpm, ensure the runtime image has access to the pnpm binary (either via Corepack or copying it over).

Comment on lines +31 to +52
# Provide dummy build-time ENV VARS (Still needed for build)
ENV DATABASE_URL="postgresql://dummy:dummy@dummy:5432/dummy?schema=public"
ENV DIRECT_URL="postgresql://dummy:dummy@dummy:5432/dummy?schema=public"
ENV NEXTAUTH_SECRET="dummy_secret_for_build_only"
ENV NEXTAUTH_URL="http://localhost:3000"
ENV GOOGLE_CLIENT_ID="dummy_id_for_build_only"
ENV GOOGLE_CLIENT_SECRET="dummy_secret_for_build_only"
ENV GOOGLE_ENCRYPT_SECRET="dummy_encrypt_secret_for_build_only"
ENV GOOGLE_ENCRYPT_SALT="dummy_encrypt_salt_for_build_only"
ENV GOOGLE_PUBSUB_TOPIC_NAME="dummy_topic_for_build_only"
ENV GOOGLE_PUBSUB_VERIFICATION_TOKEN="dummy_pubsub_token_for_build"
ENV INTERNAL_API_KEY="dummy_apikey_for_build_only"
ENV API_KEY_SALT="dummy_salt_for_build_only"
ENV UPSTASH_REDIS_URL="http://dummy-redis-for-build:6379"
ENV UPSTASH_REDIS_TOKEN="dummy_redis_token_for_build"
ENV REDIS_URL="redis://dummy:dummy@dummy:6379"
ENV QSTASH_TOKEN="dummy_qstash_token_for_build"
ENV QSTASH_CURRENT_SIGNING_KEY="dummy_qstash_curr_key_for_build"
ENV QSTASH_NEXT_SIGNING_KEY="dummy_qstash_next_key_for_build"
ENV NEXT_PUBLIC_SANITY_PROJECT_ID="dummy-sanity-project-id-for-build"
ENV NEXT_PUBLIC_SANITY_DATASET="dummy-sanity-dataset-for-build"

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consolidate and isolate dummy environment variables
There are multiple duplicated blocks of dummy credentials (lines 31–52, 57–67, 69–74, 76–78), which increases image size and risks retaining build-only values in the final artifact. Recommended refactor:

  1. Switch from ENV to ARG for build-time defaults to avoid persisting fake secrets.
  2. Use a multi-stage build:
    • builder stage with all ARG variables and full install+build
    • runtime stage that only copies built output, sets NODE_ENV=production, and does not include dummy envs

Example skeleton:

# Builder stage
FROM node:22-alpine AS builder
WORKDIR /app
RUN apk add --no-cache openssl
RUN corepack enable && corepack prepare pnpm@latest --activate
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
# ...copy individual package.json files...
RUN pnpm install --frozen-lockfile
ARG DATABASE_URL="postgresql://dummy:dummy@dummy:5432/dummy?schema=public"
ARG NEXT_PUBLIC_SANITY_PROJECT_ID="dummy-sanity-id-for-build"
# ...other build args...
RUN pnpm --filter inbox-zero-ai exec -- prisma generate \
 && pnpm --filter inbox-zero-ai exec -- next build

# Runtime stage
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
CMD ["pnpm", "--filter", "inbox-zero-ai", "start"]

This reduces final image size, confines dummy values to the builder, and suppresses false positives from Checkov (CKV_SECRET_4).

Also applies to: 57-67, 69-78

🧰 Tools
🪛 Checkov (3.2.334)

[MEDIUM] 32-33: Basic Auth Credentials

(CKV_SECRET_4)

@elie222
Copy link
Owner

elie222 commented May 4, 2025

@vishalmakwana111 could you sign the CLA please

@vishalmakwana111
Copy link
Contributor Author

@elie222 Done, just signed it.

@elie222 elie222 merged commit 041a4f7 into elie222:main May 4, 2025
2 of 3 checks passed
@elie222
Copy link
Owner

elie222 commented May 4, 2025

Thanks!

@rafaelsales
Copy link
Contributor

@elie222 I think we need your approval for this to really go live: https://github.com/elie222/inbox-zero/actions/runs/14678737529

@elie222
Copy link
Owner

elie222 commented May 10, 2025

Hey. I accepted the pr but then removed as it was breaking the build. I'll try look at it in the next day to make sure it's working as expected and not breaking the build either.

@coderabbitai coderabbitai bot mentioned this pull request Nov 19, 2025
infinitewatts pushed a commit to affordablesolar/inbox-zero that referenced this pull request Jan 18, 2026
Fixed React Error elie222#418 hydration mismatch in archive-queue.ts that was
causing infinite flickering on bulk-archive/analyze pages. The issue
occurred when atomWithStorage tried to access localStorage during SSR,
creating different initial values between server and client renders.

Changes:
- Modified createStorage() to return no-op storage during SSR
- Changed getOnInit from true to false to delay localStorage read
- Added optional chaining for safer null handling

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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.

4 participants