Skip to content

Add Docker support with multi-stage Dockerfile and compose config#111

Merged
Harish-Naruto merged 2 commits into
mainfrom
fuck/local-dev
Jun 23, 2026
Merged

Add Docker support with multi-stage Dockerfile and compose config#111
Harish-Naruto merged 2 commits into
mainfrom
fuck/local-dev

Conversation

@Harish-Naruto

@Harish-Naruto Harish-Naruto commented Jun 23, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Release Notes

  • Documentation

    • Expanded README with tech stack details, prerequisites, and local development setup instructions.
    • Added comprehensive Docker local development guide with environment configuration steps and troubleshooting.
  • Chores

    • Added GitHub Actions workflow for automated Docker image CI/CD.
    • Added Docker Compose configuration for multi-service local development environment.
    • Added multi-stage Dockerfile for application containerization.
    • Added environment variable example files for Docker services.
    • Updated application start script with explicit port configuration.

…ompose configuration, and updated dev scripts
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Harish-Naruto, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 32 minutes. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: da2b6fa6-aa2f-47ba-87a4-e118fd757684

📥 Commits

Reviewing files that changed from the base of the PR and between 980aaaf and 74b8849.

📒 Files selected for processing (2)
  • .github/workflows/docker-image.yml
  • Dockerfile
📝 Walkthrough

Walkthrough

Adds a complete Docker-based local development setup: a multi-stage Dockerfile (deps/builder/runner), a docker-compose.yml with a health-checked coc-api service and a hot-reload frontend service, environment example files, .gitignore protection for local secrets, a GitHub Actions CI workflow to build and push the image, and comprehensive DOCKER.md and README.md documentation.

Changes

Docker Local Development Infrastructure

Layer / File(s) Summary
Multi-stage Dockerfile and port binding
package.json, Dockerfile
Defines deps (npm ci), builder (npm run build with API_BASE_URL ARG), and runner (production, port 3001) stages; updates start script to bind explicitly to -p 3001.
Compose services, env templates, and .gitignore
.gitignore, docker/.env.local.coc-api.example, docker/.env.local.frontend.example, docker-compose.yml
Adds coc-api service (pre-built image, /health healthcheck, port 3000) and frontend service (local builder-stage build, depends_on coc-api healthy, develop.watch hot-reload) on the coc-local network; adds env example files and ignores local secret files while tracking .example variants.
GitHub Actions Docker image CI
.github/workflows/docker-image.yml
Workflow triggers on push/PR to main, conditionally logs in to Docker Hub on push only, builds from ./Dockerfile, and pushes callofcode07/callofcode:latest on push events.
DOCKER.md guide and README updates
DOCKER.md, README.md
Adds a full DOCKER.md (stack overview, quick-start, env variable tables, hot-reload paths, Dockerfile stages, commands, health-check details, troubleshooting); rewrites README.md with a tech-stack table, local dev setup, Docker section, available scripts table, and updated contributing/license/contact sections.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hippity-hop, a Dockerfile's born,
Three stages tall on a bright Docker morn!
The frontend waits — health-check says "go!" —
Hot-reload syncs files with a cottontail glow.
Secrets stay hidden, examples shine true,
Happy coding, dear devs — from me to you! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes in the PR—adding Docker support including a multi-stage Dockerfile and docker-compose configuration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 fuck/local-dev

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.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploying call-of-code with  Cloudflare Pages  Cloudflare Pages

Latest commit: 74b8849
Status: ✅  Deploy successful!
Preview URL: https://4a64c099.call-of-code.pages.dev
Branch Preview URL: https://fuck-local-dev.call-of-code.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
docker-compose.yml (1)

21-35: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: Simplify API_BASE_URL configuration — build arg is unused for runtime.

The frontend service passes API_BASE_URL both as a build arg (line 27) and as a runtime environment variable (line 35). For Next.js, private env vars (those without the NEXT_PUBLIC_ prefix) are not baked into the build — they are only used at runtime. The build arg is effectively ignored.

Recommendation: Remove the build arg from the frontend service's build.args section. Keeping only the environment variable (line 35) is clearer and sufficient.

♻️ Proposed simplification
     build:
       context: .
       dockerfile: Dockerfile
       target: builder
-      args:
-        API_BASE_URL: ${API_BASE_URL:-http://coc-api:3000}
     image: coc-frontend:dev
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose.yml` around lines 21 - 35, The frontend service in the
docker-compose.yml file currently passes API_BASE_URL as both a build argument
(in the build.args section) and as a runtime environment variable. Since Next.js
does not bake private environment variables (those without the NEXT_PUBLIC_
prefix) into the build, the build argument is redundant. Remove the API_BASE_URL
build arg from the build.args section under the frontend service, while keeping
the environment variable definition in the environment section, as this is where
the value is actually used at runtime.
.github/workflows/docker-image.yml (2)

14-27: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin third-party actions to commit SHAs.

zizmor flags the actions/checkout, docker/login-action, and docker/build-push-action references as unpinned. Pinning to a full commit SHA (with the version as a trailing comment) protects against supply-chain tag-mutation attacks.

For example:

uses: actions/checkout@<commit-sha> # v4
uses: docker/login-action@<commit-sha> # v3
uses: docker/build-push-action@<commit-sha> # v6
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-image.yml around lines 14 - 27, The workflow file
references third-party actions using version tags (v4, v3, v6) which are
vulnerable to supply-chain attacks. Replace the version tags with full commit
SHAs for the actions/checkout, docker/login-action, and docker/build-push-action
actions, and add the version numbers as trailing comments to maintain clarity
about which versions are being used.

Source: Linters/SAST tools


26-27: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider adding docker/setup-buildx-action before the build step.

docker/build-push-action@v6 relies on Buildx; while it's preinstalled on ubuntu-latest, explicitly running docker/setup-buildx-action is the documented setup and enables features like build caching (cache-from/cache-to) to speed up CI.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-image.yml around lines 26 - 27, The workflow is
missing an explicit setup step for Docker Buildx before the
docker/build-push-action@v6 step. Add a new step that uses
docker/setup-buildx-action before the "Build and push Docker image" step to
properly initialize Buildx and enable build caching features. This ensures the
documented setup is followed and allows you to leverage cache optimization in
subsequent build steps.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/docker-image.yml:
- Line 32: In the docker-image.yml workflow file, the tags property at line 32
currently specifies `callofcode07/callofcode:latest`, which does not align with
the image names referenced in docker-compose.yml (callofcode07/coc-api:latest
for the API service). Either update the published image name in the tags
property to match what the dev stack expects (callofcode07/coc-api), or add a
comment in the workflow explaining the intentional separation between the
published image and local development images. Additionally, replace the single
`:latest` tag with multiple tags including both a version-based immutable tag
(e.g., using git commit SHA or version number) and the `:latest` tag to enable
proper rollback and debugging of past deployments.

In `@Dockerfile`:
- Around line 1-41: In the runner stage of the Dockerfile, after setting ENV
NODE_ENV=production and before the EXPOSE instruction, create a non-root user
using RUN apk add --no-cache (if needed for your setup) and create the user with
appropriate commands. Then change the ownership of the /app directory to this
non-root user, and add a USER instruction to switch to that user before the CMD
instruction that runs npm run start. This ensures the application runs with
minimal privileges rather than as root.
- Around line 22-41: The runner stage in the Dockerfile does not declare the
API_BASE_URL environment variable, which is needed at runtime by the Next.js
application code in app/api/projects-with-members/route.ts and
app/achievements/page.tsx. After the ENV NODE_ENV=production line in the runner
stage (FROM node:20-alpine AS runner), add an ENV directive to declare
API_BASE_URL as an environment variable. This allows users to provide the value
at runtime via docker run -e API_BASE_URL=... or similar runtime mechanisms,
ensuring the variable is available when the container starts.

---

Nitpick comments:
In @.github/workflows/docker-image.yml:
- Around line 14-27: The workflow file references third-party actions using
version tags (v4, v3, v6) which are vulnerable to supply-chain attacks. Replace
the version tags with full commit SHAs for the actions/checkout,
docker/login-action, and docker/build-push-action actions, and add the version
numbers as trailing comments to maintain clarity about which versions are being
used.
- Around line 26-27: The workflow is missing an explicit setup step for Docker
Buildx before the docker/build-push-action@v6 step. Add a new step that uses
docker/setup-buildx-action before the "Build and push Docker image" step to
properly initialize Buildx and enable build caching features. This ensures the
documented setup is followed and allows you to leverage cache optimization in
subsequent build steps.

In `@docker-compose.yml`:
- Around line 21-35: The frontend service in the docker-compose.yml file
currently passes API_BASE_URL as both a build argument (in the build.args
section) and as a runtime environment variable. Since Next.js does not bake
private environment variables (those without the NEXT_PUBLIC_ prefix) into the
build, the build argument is redundant. Remove the API_BASE_URL build arg from
the build.args section under the frontend service, while keeping the environment
variable definition in the environment section, as this is where the value is
actually used at runtime.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 65353c26-42be-463b-adca-fe4464ef4b80

📥 Commits

Reviewing files that changed from the base of the PR and between b9ef9cb and 980aaaf.

📒 Files selected for processing (9)
  • .github/workflows/docker-image.yml
  • .gitignore
  • DOCKER.md
  • Dockerfile
  • README.md
  • docker-compose.yml
  • docker/.env.local.coc-api.example
  • docker/.env.local.frontend.example
  • package.json

context: .
file: ./Dockerfile
push: ${{ github.event_name == 'push' }}
tags: callofcode07/callofcode:latest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the docker-image.yml workflow file to see the full context
cat -n .github/workflows/docker-image.yml

Repository: call-0f-code/call-of-code

Length of output: 1155


🏁 Script executed:

# Now examine docker-compose.yml to see what images it references
cat -n docker-compose.yml

Repository: call-0f-code/call-of-code

Length of output: 2145


🏁 Script executed:

# Search for references to the image names across the repository
rg "callofcode07/callofcode|callofcode07/coc-api|coc-frontend" --type yaml --type yml -n

Repository: call-0f-code/call-of-code

Length of output: 191


🏁 Script executed:

# Search more broadly for image name references
rg "callofcode07|coc-api|coc-frontend" -n --no-heading | head -30

Repository: call-0f-code/call-of-code

Length of output: 163


🏁 Script executed:

# Check the Dockerfile to see what's being built
cat -n Dockerfile | head -50

Repository: call-0f-code/call-of-code

Length of output: 1481


🏁 Script executed:

# Search for any README or documentation that might explain the image naming
find . -name "README*" -o -name "*.md" | xargs grep -l "callofcode07\|docker" 2>/dev/null | head -5

Repository: call-0f-code/call-of-code

Length of output: 187


🏁 Script executed:

# Check DOCKER.md for documentation about the image naming and architecture
cat -n DOCKER.md

Repository: call-0f-code/call-of-code

Length of output: 7972


🏁 Script executed:

# Also check README.md for relevant information
cat README.md | grep -A 20 -B 5 "docker\|image" -i | head -60

Repository: call-0f-code/call-of-code

Length of output: 1655


Published image name doesn't match what the dev stack uses; align or document the separation.

The workflow publishes to callofcode07/callofcode:latest, but the dev stack in docker-compose.yml pulls callofcode07/coc-api:latest for the API and builds the frontend locally as coc-frontend:dev. The published callofcode07/callofcode image is unused in the local development workflow, making this an orphaned build artifact. Per DOCKER.md, the stack has no reference to this image.

Additionally, publishing only :latest leaves no immutable tag for rollbacks or debugging past deployments.

Consider either:

  • Aligning the published image name with what dev stack consumes, or
  • Adding a documentation comment explaining why the published image differs from local builds
🔧 Suggested tagging
-          tags: callofcode07/callofcode:latest
+          tags: |
+            callofcode07/callofcode:latest
+            callofcode07/callofcode:${{ github.sha }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tags: callofcode07/callofcode:latest
tags: |
callofcode07/callofcode:latest
callofcode07/callofcode:${{ github.sha }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-image.yml at line 32, In the docker-image.yml
workflow file, the tags property at line 32 currently specifies
`callofcode07/callofcode:latest`, which does not align with the image names
referenced in docker-compose.yml (callofcode07/coc-api:latest for the API
service). Either update the published image name in the tags property to match
what the dev stack expects (callofcode07/coc-api), or add a comment in the
workflow explaining the intentional separation between the published image and
local development images. Additionally, replace the single `:latest` tag with
multiple tags including both a version-based immutable tag (e.g., using git
commit SHA or version number) and the `:latest` tag to enable proper rollback
and debugging of past deployments.

Comment thread Dockerfile
Comment thread Dockerfile
Comment on lines +22 to +41
# Stage 3 – runner: lean production image
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production

# Next.js standalone output (enable in next.config if needed)
# COPY --from=builder /app/.next/standalone ./
# COPY --from=builder /app/.next/static ./.next/static
# COPY --from=builder /app/public ./public

# Standard (non-standalone) output
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 3001

CMD ["npm", "run", "start"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Runtime environment variable API_BASE_URL is not available in the runner stage.

The builder stage sets API_BASE_URL as an ARG and ENV (lines 17–18), but build-time ARGs are not inherited by subsequent stages. The runner stage has no corresponding ENV directive to make API_BASE_URL available at runtime.

The upstream code (app/api/projects-with-members/route.ts and app/achievements/page.tsx) requires process.env.API_BASE_URL at runtime. When the runner image is executed standalone (outside Compose), the app will fail with "API_BASE_URL not set" errors (HTTP 500).

Recommendation: Either:

  • Accept API_BASE_URL as a runtime ENV var in the runner stage (users provide it via docker run -e API_BASE_URL=... or in a .env file).
  • Or document that the runner image requires API_BASE_URL to be passed at container startup.
🔧 Proposed fix: Accept API_BASE_URL at runtime
 # Stage 3 – runner: lean production image
 FROM node:20-alpine AS runner
 WORKDIR /app
 
 ENV NODE_ENV=production
+ENV API_BASE_URL=""  # Set at runtime via -e or .env
 
 # Next.js standalone output (enable in next.config if needed)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile` around lines 22 - 41, The runner stage in the Dockerfile does not
declare the API_BASE_URL environment variable, which is needed at runtime by the
Next.js application code in app/api/projects-with-members/route.ts and
app/achievements/page.tsx. After the ENV NODE_ENV=production line in the runner
stage (FROM node:20-alpine AS runner), add an ENV directive to declare
API_BASE_URL as an environment variable. This allows users to provide the value
at runtime via docker run -e API_BASE_URL=... or similar runtime mechanisms,
ensuring the variable is available when the container starts.

@Harish-Naruto Harish-Naruto merged commit 48f2edc into main Jun 23, 2026
3 checks passed
@Harish-Naruto Harish-Naruto deleted the fuck/local-dev branch June 23, 2026 20:29
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.

2 participants