Skip to content

Fix: backend port mapping#66

Merged
ejfine merged 10 commits intomainfrom
port-mapping
Aug 21, 2025
Merged

Fix: backend port mapping#66
ejfine merged 10 commits intomainfrom
port-mapping

Conversation

@ejfine
Copy link
Contributor

@ejfine ejfine commented Aug 21, 2025

Why is this change necessary?

When deploying the backend at a different port, it can't just be mapped at the docker level, it should be running on that port in the container in order to work on Windows Rancher Desktop

How does this change address the issue?

Runs it there

What side effects does this change have?

🤷

How is this change tested?

Downstream repo

Summary by CodeRabbit

  • New Features
    • Backend and frontend ports are now configurable at deployment so service ports align dynamically.
  • Documentation
    • README conditionally shows the Backend section and fixes code-block rendering.
    • Startup instruction updated to “Start the API server on port 4000.”
    • Added Copier update command: copier update --trust --conflict rej --defaults.
  • Chores
    • CI frontend script invocation updated to use pnpm --dir syntax.

@ejfine ejfine requested a review from Copilot August 21, 2025 16:27
@ejfine ejfine self-assigned this Aug 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 21, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Templates updated to make backend and frontend ports configurable, add conditional rendering for the Backend README block with adjusted raw/code-fence placement, change pnpm invocation style in CI, and add a Copier update example. Dockerfile, docker-compose, and Nginx templates now wire ports through environment/template variables.

Changes

Cohort / File(s) Summary
README template
template/README.md.jinja
Wrap Backend section in has_backend conditional, adjust {% raw %}/{% endraw %} fence boundaries, rename the backend instruction to “Start the API server on port 4000:” and update the uvicorn command, and add copier update --trust --conflict rej --defaults example.
Backend Dockerfile template
template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja
Make container port dynamic via {{ backend_deployed_port_number }}: update EXPOSE, add ENV API_PORT={{ backend_deployed_port_number }}, change CMD to use $API_PORT, and update docker run mapping examples; add note about host-network behavior on Rancher Desktop/WSL.
docker-compose template
template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja
Change backend port mapping to {{ backend_deployed_port_number }}:{{ backend_deployed_port_number }} and add API_PORT env; add FRONTEND_PORT env for frontend service.
Frontend Dockerfile template
template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja
Replace pnpm run generate with pnpm generate in build step; add FRONTEND_PORT={{ frontend_deployed_port_number }} to production ENV and include $FRONTEND_PORT in envsubst within CMD.
Frontend Nginx template
template/frontend/{% if not deploy_as_executable %}default.conf.template{% endif %}.jinja
Change Nginx listen from {{ frontend_deployed_port_number }} to environment variable ${FRONTEND_PORT}.
CI workflow template
template/.github/workflows/ci.yaml.jinja
Replace pnpm run --dir=frontend <script> with pnpm --dir=frontend <script> for frontend tasks (unit, generate, test-compiled, e2e); no control-flow changes.
Nuxt config comments
template/frontend/nuxt.config.ts.jinja
Update comments to refer to pnpm dev instead of pnpm run dev in devProxy/proxy notes (comment-only changes).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant Compose as docker-compose / Docker CLI
  participant Image as Image (frontend/backend)
  participant Proc as Process (uvicorn/nginx)

  Dev->>Compose: docker-compose up / docker run
  Compose->>Image: start container with port mapping\nHOST:${backend_deployed_port_number} -> CONTAINER:${backend_deployed_port_number}
  Note right of Image: ENV API_PORT=${backend_deployed_port_number}\nENV FRONTEND_PORT=${frontend_deployed_port_number}
  Image->>Proc: CMD uses $API_PORT or runs envsubst($FRONTEND_PORT)
  Proc-->>Image: listen on provided env port (API_PORT / FRONTEND_PORT)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I’m a rabbit in the config lair,
Swapping ports with careful care.
Docker hums and Nginx sings,
Env vars flutter on my springs.
Copier updates — I hop and share! 🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch port-mapping

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

This comment was marked as outdated.

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)
template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja (1)

7-11: Host networking makes the backend ports: mapping ineffective; consider gating or removing it

With network_mode: host (Line 10), Docker/Compose ignores ports: on that service. Keeping the mapping can confuse readers and, depending on Compose version, may emit a warning. Since the fix here is to run the backend on the deployed port inside the container, the ports: stanza isn’t needed for backend when network_mode: host is enabled.

Apply one of the options below:

Option A — Drop ports: for backend:

   backend:
     build:
       context: ./backend
       dockerfile: Dockerfile
     container_name: {{ repo_name }}-backend
-    ports:
-      - "{{ backend_deployed_port_number }}:{{ backend_deployed_port_number }}"
     restart: unless-stopped
     network_mode: host

Option B — Gate by a template flag so you can switch between bridge/host easily:

   backend:
     build:
       context: ./backend
       dockerfile: Dockerfile
     container_name: {{ repo_name }}-backend
-{% raw %}    ports:
-      - "{% endraw %}{{ backend_deployed_port_number }}{% raw %}:{% endraw %}{{ backend_deployed_port_number }}{% raw %}"{% endraw %}
+{% if not backend_use_host_network_mode %}{% raw %}
+    ports:
+      - "{% endraw %}{{ backend_deployed_port_number }}{% raw %}:{% endraw %}{{ backend_deployed_port_number }}{% raw %}"{% endraw %}
+{% endif %}
-    restart: unless-stopped
-    network_mode: host
+    restart: unless-stopped
+{% if backend_use_host_network_mode %}{% raw %}
+    network_mode: host
+{% endif %}{% raw %}

If you want, I can follow up with a small defaults.yml addition for backend_use_host_network_mode and docs to explain when to toggle it.

template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1)

28-28: Consider making the port overridable via an env var for operator ergonomics

Hardcoding the port via ARGs/templating is fine for generated projects. For day‑2 ops, allowing override via PORT (or similar) improves flexibility without re-templating. Example:

-# By default, run the entrypoint to serve the GraphQL app
-CMD ["python", "src/entrypoint.py", "--host", "0.0.0.0", "--port", "{{ backend_deployed_port_number }}"]
+# By default, run the entrypoint to serve the GraphQL app
+ENV PORT={{ backend_deployed_port_number }}
+# Use a shell form so $PORT can be overridden at runtime without re-templating
+CMD ["sh", "-c", "python src/entrypoint.py --host 0.0.0.0 --port ${PORT}"]

If you prefer to keep exec form, we can add a tiny wrapper script to parse $PORT and exec Python.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 80e0051 and 80b81f9.

📒 Files selected for processing (3)
  • template/README.md.jinja (1 hunks)
  • template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2 hunks)
  • template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja (1 hunks)
🔇 Additional comments (3)
template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2)

4-4: Good: example run command now mirrors the dynamic deployed port

The example docker run -p <host>:<container> reflects {{ backend_deployed_port_number }} on both sides, aligning with the Compose template and README intent.


24-26: Comment and EXPOSE align with the Rancher Desktop host networking constraint

The explanatory comment and EXPOSE {{ backend_deployed_port_number }} match the change to have the app listen on the final deployed port inside the container. This aids discoverability (e.g., docker inspect/metadata) even if EXPOSE isn’t enforced.

template/README.md.jinja (1)

33-33: Nice: fixed code-fence/raw/conditional interplay

Closing the preview fence before entering the has_backend block avoids malformed markdown when the backend is disabled.

Comment on lines +36 to +39
Start the API server on port 4000:
```bash
uv --directory=backend run uvicorn src.entrypoint:app --reload --host '::' --port 4000
```
```{% endraw %}{% endif %}{% raw %}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Docs should reflect the dynamic backend port; avoid hardcoding 4000

The project now parameterizes the backend port, and the container listens on that port. The README still instructs to run on 4000, which can mislead when {{ backend_deployed_port_number }} ≠ 4000.

Apply this diff to keep the docs consistent with the templates:

-Start the API server on port 4000:
+Start the API server on port {% endraw %}{{ backend_deployed_port_number }}{% raw %}:
 ```bash
-uv --directory=backend run uvicorn src.entrypoint:app --reload --host '::' --port 4000
+uv --directory=backend run uvicorn src.entrypoint:app --reload --host 0.0.0.0 --port {% endraw %}{{ backend_deployed_port_number }}{% raw %}

Notes:
- Switched `--host` to `0.0.0.0` to mirror the Dockerfile default and avoid potential IPv6-only binding surprises on some hosts. If you want dual‑stack, we can document `--host ::` as an alternative.

<details>
<summary>🤖 Prompt for AI Agents</summary>

In template/README.md.jinja around lines 36 to 39, the README hardcodes port
4000 and uses --host '::', which conflicts with the parameterized backend port
and Docker default; update the example command to use the template variable for
the port and switch the host to 0.0.0.0. Replace the hardcoded "--port 4000"
with "--port {{ backend_deployed_port_number }}" (respecting the surrounding
Jinja raw/endraw blocks as in the template) and change "--host '::'" to "--host
0.0.0.0" so the docs reflect the dynamic configuration and match container
networking.


</details>

<!-- fingerprinting:phantom:poseidon:chinchilla -->

<!-- This is an auto-generated comment by CodeRabbit -->

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 (3)
template/frontend/{% if not deploy_as_executable %}default.conf.template{% endif %}.jinja (1)

2-2: Consider marking this as the default server.

If multiple server blocks ever get introduced, explicitly setting default_server avoids ambiguity.

Apply this diff:

-    listen ${FRONTEND_PORT};
+    listen ${FRONTEND_PORT} default_server;
template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2)

40-40: Harden envsubst and shell behavior (brace variables + fail on unset).

Use brace-delimited variables to avoid partial-name collisions and enable -eu so the container fails fast if a variable is missing.

Apply this diff:

-CMD ["sh", "-c", "envsubst '$BACKEND_HOST $BACKEND_PORT $FRONTEND_PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
+CMD ["sh", "-eu", "-c", "envsubst '${BACKEND_HOST} ${BACKEND_PORT} ${FRONTEND_PORT}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]

4-6: Update the inline run example to reflect Nginx’s port (no longer 3000).

The container serves via Nginx on FRONTEND_PORT; the example mapping to 3000 is stale.

Apply this diff:

-# docker run -p {{ frontend_deployed_port_number }}:3000 my-nuxt-app
+# docker run -p {{ frontend_deployed_port_number }}:{{ frontend_deployed_port_number }} my-nuxt-app
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 80b81f9 and 9d5923d.

📒 Files selected for processing (4)
  • template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1 hunks)
  • template/frontend/{% if not deploy_as_executable %}default.conf.template{% endif %}.jinja (1 hunks)
  • template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2 hunks)
  • template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja
  • template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja
🔇 Additional comments (2)
template/frontend/{% if not deploy_as_executable %}default.conf.template{% endif %}.jinja (1)

2-2: Switching Nginx listen to an env var is correct and aligns with runtime port configurability.

This makes the container actually listen on the configured port (esp. helpful on Windows/Rancher Desktop) and matches the Dockerfile’s envsubst flow.

template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1)

33-34: ENV FRONTEND_PORT addition looks good.

Providing a default FRONTEND_PORT ensures the Nginx config renders even if the runtime environment doesn’t override it.

@@ -1,5 +1,5 @@
{% raw %}server {
listen {% endraw %}{{ frontend_deployed_port_number }}{% raw %};
listen ${FRONTEND_PORT};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify end-to-end: FRONTEND_PORT is provided and port mappings are consistent.

Ensure docker-compose/K8s manifests provide FRONTEND_PORT and map host:container to the same value to avoid “listen ;” or mismatched publishing.

Run:


🏁 Script executed:

#!/bin/bash
# 1) Confirm FRONTEND_PORT is set where services are defined
rg -nP -C2 '\bFRONTEND_PORT\b' -g '!**/node_modules/**'

# 2) Sanity-check for any lingering 3000 port mappings that could be outdated
rg -nP -C2 '(:|=)\s*3000\b' -g '!**/node_modules/**'

# 3) If you use docker-compose templates, confirm ports mapping mirrors FRONTEND_PORT
rg -nP -C2 'ports:|FRONTEND_PORT' -g '*docker-compose*.jinja'

Length of output: 8809


Align container port mapping with FRONTEND_PORT in production deployment

Your local compose template correctly maps FRONTEND_PORT end-to-end (host⇄container) and sets FRONTEND_PORT for Nginx, but the production deployment template hard-codes the container port to 3000 while still exposing a variable host port. This will break routing whenever frontend_deployed_port_number ≠ 3000.

• In template/deployment/docker-compose.yaml.jinja around lines 15–17:

ports:
- "{{ frontend_deployed_port_number }}:3000"
+ "{{ frontend_deployed_port_number }}:{{ frontend_deployed_port_number }}"

(Change the right-hand side of the mapping from 3000 to the same variable.)

• (Optional) To improve clarity, you can also add an explicit environment section:

environment:
  - FRONTEND_PORT={{ frontend_deployed_port_number }}

so it’s clear at runtime which port Nginx will listen on.

With this change, Nginx’s listen ${FRONTEND_PORT} will always match the container port you’ve exposed.

🤖 Prompt for AI Agents
In template/frontend/{% if not deploy_as_executable %}default.conf.template{%
endif %}.jinja around line 2, Nginx is configured to listen on ${FRONTEND_PORT}
but the production docker-compose template hard-codes the container side of the
port mapping to 3000; update template/deployment/docker-compose.yaml.jinja
(around lines 15–17) to map host port to the same variable (replace the
right-hand-side 3000 with {{ frontend_deployed_port_number }}) so container port
matches FRONTEND_PORT, and optionally add an environment section to the service:
include FRONTEND_PORT={{ frontend_deployed_port_number }} to make the runtime
port explicit.

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 (3)
template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (3)

4-4: Clarify the docker run example to show overriding API_PORT explicitly

Showing -e makes it obvious the service must listen on the same port inside the container. Also add a host-networking example for Rancher Desktop users.

-# docker run -p {{ backend_deployed_port_number }}:{{ backend_deployed_port_number }} my-graphql-backend
+# docker run -e API_PORT={{ backend_deployed_port_number }} -p {{ backend_deployed_port_number }}:{{ backend_deployed_port_number }} my-graphql-backend
+# (Rancher Desktop host networking) docker run --network=host -e API_PORT={{ backend_deployed_port_number }} my-graphql-backend

24-26: ENV default LGTM; consider PORT fallback for broader runtime compatibility

Nice: defaulting API_PORT to the deployed port and allowing -e overrides at runtime matches the PR intent. As an optional enhancement, many PaaS set PORT (not API_PORT). You can keep ENV as-is and add a fallback to PORT in the CMD (see suggestion on Line 31).


31-31: Prefer falling back to $PORT when $API_PORT is unset

This preserves the existing behavior (uses API_PORT if provided) but also “just works” on platforms that inject PORT. No runtime change when API_PORT is set.

• Replace in template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja:

-CMD ["sh", "-c", "python src/entrypoint.py --host 0.0.0.0 --port $API_PORT"]
+CMD ["sh", "-c", "python src/entrypoint.py --host 0.0.0.0 --port ${API_PORT:-${PORT:-{{ backend_deployed_port_number }}}}"]

• Verify that the CLI accepts --host and --port flags:

#!/bin/bash
# Confirm CLI defines --host and --port
rg -n -C1 'parser\.add_argument\("--(host|port)"' --type=py template/backend/src/backend_api/cli.py
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9d5923d and 7eb173f.

📒 Files selected for processing (2)
  • template/{% if has_backend %}backend{% endif %}/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2 hunks)
  • template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • template/{% if not deploy_as_executable %}docker-compose.yaml{% endif %}.jinja

Comment on lines +27 to +28
# When deployed with network-mode=host on Rancher Desktop on Windows (for WSL-compatibility), there's no actual port mapping, so we need to have it running on the deployed port within the container itself
EXPOSE {% endraw %}{{ backend_deployed_port_number }}{% raw %}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

EXPOSE is documentation-only; ensure compose/k8s also wire containerPort to the same value

EXPOSE helps tooling but doesn’t publish ports. Double-check docker-compose.yaml.jinja (and any Helm/k8s templates, if present) map {{ backend_deployed_port_number }} on both host and container, and pass API_PORT in environment. If already done in this PR, you’re good.


🏁 Script executed:

#!/bin/bash
# Verify compose and templates map the same container port and set API_PORT
rg -n -C2 -P '(ports:|EXPOSE|API_PORT|backend_deployed_port_number)' --type=yaml --type=dockerfile --type=jinja

Length of output: 148


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List all Jinja templates
echo "Listing all Jinja templates:"
fd --type f -e jinja || true

# Identify compose-related templates
echo -e "\nCompose-related templates:"
fd --type f -e jinja | grep -i 'compose' || true

# Verify backend_deployed_port_number usage in compose templates
echo -e "\nVerify backend_deployed_port_number in compose templates:"
fd --type f -e jinja | grep -i 'compose' | xargs -r rg -n -C2 'backend_deployed_port_number' || true

# Verify ports: mapping in compose templates
echo -e "\nVerify ports: in compose templates:"
fd --type f -e jinja | grep -i 'compose' | xargs -r rg -n -C2 'ports:' || true

# Verify API_PORT environment variable in compose templates
echo -e "\nVerify API_PORT in compose templates:"
fd --type f -e jinja | grep -i 'compose' | xargs -r rg -n -C2 'API_PORT' || true

# Identify K8s/Helm-related templates
echo -e "\nK8s/Helm-related templates:"
fd --type f -e jinja | grep -Ei 'helm|k8s|deployment|service' || true

# Verify containerPort mapping in K8s templates
echo -e "\nVerify containerPort in K8s templates:"
fd --type f -e jinja | grep -Ei 'helm|k8s|deployment|service' | xargs -r rg -n -C2 'containerPort' || true

# Verify backend_deployed_port_number in K8s templates
echo -e "\nVerify backend_deployed_port_number in K8s templates:"
fd --type f -e jinja | grep -Ei 'helm|k8s|deployment|service' | xargs -r rg -n -C2 'backend_deployed_port_number' || true

Length of output: 5659


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all docker-compose Jinja templates
compose_files=$(fd --type f -e jinja | grep -i 'docker-compose.yaml')

# Print the first 200 lines of each to inspect ports and environment settings
for f in $compose_files; do
  echo "===== Inspecting $f ====="
  sed -n '1,200p' "$f" || true
  echo ""
done

Length of output: 3221


EXPOSE is documentation-only; compose template needs to wire up port and API_PORT

The Dockerfile’s EXPOSE {{ backend_deployed_port_number }} only informs tooling—it doesn’t actually publish the port at runtime or inject an environment variable. I verified in ​template/deployment/docker-compose.yaml.jinja that the backend service maps the port correctly (host {{ backend_deployed_port_number }} → container 4000), but there is no environment: block on the backend service to pass API_PORT. There are also no Kubernetes/Helm templates deploying the backend, so if you add any in the future you’ll need to wire containerPort and API_PORT there too.

• In template/deployment/docker-compose.yaml.jinja, under services.backend, add:

    ports:
      - "{{ backend_deployed_port_number }}:4000"
    environment:
      API_PORT: "{{ backend_deployed_port_number }}"

• If you introduce Kubernetes/Helm manifests for the backend, ensure they include:

        containerPort: {{ backend_deployed_port_number }}
        env:
          - name: API_PORT
            value: "{{ backend_deployed_port_number }}"
🤖 Prompt for AI Agents
In template/{% if has_backend %}backend{% endif %}/{% if not
deploy_as_executable %}Dockerfile{% endif %}.jinja around lines 27-28, the
Dockerfile only uses EXPOSE which is documentation-only; update the compose
deployment to actually publish the port and set API_PORT: in
template/deployment/docker-compose.yaml.jinja under services.backend add a ports
mapping from host {{ backend_deployed_port_number }} to container 4000 and add
an environment entry API_PORT with value {{ backend_deployed_port_number }};
also, if you later add Kubernetes/Helm manifests, ensure the backend container
spec includes containerPort: {{ backend_deployed_port_number }} and an env
variable name=API_PORT value={{ backend_deployed_port_number }}.

@ejfine ejfine requested a review from Copilot August 21, 2025 16:54

This comment was marked as outdated.

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)
template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1)

40-40: Validate ports before envsubst to reduce config-injection/misconfig risk (follow-up to prior comment)

Previous review already flagged envsubst-based templating risks. Adding FRONTEND_PORT increases surface a bit. At minimum, validate that BACKEND_PORT and FRONTEND_PORT are numeric before generating the nginx config.

-CMD ["sh", "-c", "envsubst '$BACKEND_HOST $BACKEND_PORT $FRONTEND_PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
+CMD ["sh", "-c", "case \"$BACKEND_PORT\" in ''|*[!0-9]*) echo 'Invalid BACKEND_PORT: must be numeric' >&2; exit 64;; esac; \
+case \"$FRONTEND_PORT\" in ''|*[!0-9]*) echo 'Invalid FRONTEND_PORT: must be numeric' >&2; exit 64;; esac; \
+envsubst '$BACKEND_HOST $BACKEND_PORT $FRONTEND_PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]

If you want stricter hardening later, consider moving this logic into a small entrypoint script that also bounds-checks the port ranges (1–65535) and whitelists BACKEND_HOST characters.

🧹 Nitpick comments (1)
template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1)

21-21: Drop the ‘pnpm list’ to shave build time and logs (optional)

Listing deps during build is mostly noisy and adds a bit of time without build value.

-RUN pnpm list && pnpm generate
+RUN pnpm generate
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7eb173f and 2419d69.

📒 Files selected for processing (4)
  • template/.github/workflows/ci.yaml.jinja (4 hunks)
  • template/README.md.jinja (1 hunks)
  • template/frontend/nuxt.config.ts.jinja (2 hunks)
  • template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • template/frontend/nuxt.config.ts.jinja
🚧 Files skipped from review as they are similar to previous changes (1)
  • template/README.md.jinja
🔇 Additional comments (2)
template/.github/workflows/ci.yaml.jinja (1)

45-45: Confirm --dir flag support in pinned pnpm version

  • Template already pins PNPM via:
    • Dockerfile: RUN npm install -g pnpm@{{ pnpm_version }}
    • package.json: "packageManager": "pnpm@{{ pnpm_version }}"
  • The -C, --dir option is documented in PNPM v6.x (cuyl.github.io) and continues through v8.x (pnpm.io).
  • Please verify that your pnpm_version variable (in the template defaults, CI action, and any developer environment) is set to at least 6.0.0 to ensure --dir is available.
  • For extra safety, consider adding a CI step to echo the installed pnpm version:
       - name: Install dependencies
         uses: ./.github/actions/install_deps
         with:
           node-version: {{ node_version }}
+      - name: Confirm pnpm version
+        run: pnpm --version

Apply this check in your CI workflow at lines 45, 107, 187, and 235 in ci.yaml.jinja.

template/frontend/{% if not deploy_as_executable %}Dockerfile{% endif %}.jinja (1)

33-35: ENV defaults align with EXPOSE and template usage; please confirm Nginx template listens on $FRONTEND_PORT

The new FRONTEND_PORT default correctly matches the EXPOSE value and the intent to run Nginx on the target port inside the container (important for Rancher Desktop on Windows). Just double-check that default.conf.template’s listen directive is driven by $FRONTEND_PORT, or you’ll get a mismatch at runtime.

@ejfine ejfine requested a review from Copilot August 21, 2025 18:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR addresses backend port mapping configuration issues when deploying to Windows Rancher Desktop by ensuring the backend service runs on the correct port within the container rather than relying solely on Docker port mapping.

  • Modified backend configuration to use configurable port environment variables
  • Updated frontend nginx configuration to support dynamic port configuration
  • Standardized pnpm command syntax across documentation and CI files

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docker-compose.yaml Updated port mapping to use configurable ports and added environment variables for API_PORT and FRONTEND_PORT
backend/Dockerfile Changed from hardcoded port 4000 to configurable API_PORT environment variable
frontend/default.conf.template Modified nginx to listen on dynamic FRONTEND_PORT instead of hardcoded port
frontend/Dockerfile Added FRONTEND_PORT environment variable and updated envsubst command
frontend/nuxt.config.ts Updated comments to use standardized pnpm command syntax
README.md Updated pnpm commands and improved backend section documentation
.github/workflows/ci.yaml Standardized pnpm command syntax from pnpm run --dir to pnpm --dir

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


# build the Nuxt app (generates .output folder in Nuxt 3)
RUN pnpm list && pnpm run generate
RUN pnpm list && pnpm generate
Copy link

Copilot AI Aug 21, 2025

Choose a reason for hiding this comment

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

The command change from 'pnpm run generate' to 'pnpm generate' may not work as expected. In most npm/pnpm projects, 'generate' is a script defined in package.json that should be invoked with 'pnpm run generate' or 'pnpm generate' only if it's a built-in pnpm command. Verify that 'generate' works without the 'run' prefix.

Suggested change
RUN pnpm list && pnpm generate
RUN pnpm list && pnpm run generate

Copilot uses AI. Check for mistakes.
@ejfine ejfine merged commit 5ee1072 into main Aug 21, 2025
21 of 23 checks passed
@ejfine ejfine deleted the port-mapping branch August 21, 2025 18:31
@coderabbitai coderabbitai bot mentioned this pull request Jan 9, 2026
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