Skip to content

fix: resolve CORS and remote Docker access issues#681

Open
srbhr wants to merge 3 commits intomainfrom
fix/docker-remote-access-cors
Open

fix: resolve CORS and remote Docker access issues#681
srbhr wants to merge 3 commits intomainfrom
fix/docker-remote-access-cors

Conversation

@srbhr
Copy link
Copy Markdown
Owner

@srbhr srbhr commented Feb 19, 2026

Problem

Users running the app on a remote Docker server and accessing from a different machine encountered two issues:

  1. CORS errors — The backend only allowed localhost:3000 by default, blocking requests from remote origins
  2. PDF download brokenNEXT_PUBLIC_API_URL was baked into the JS bundle as http://localhost:8000, so the browser on a remote machine tried to fetch from its own localhost instead of the server

Root Cause

The frontend was making cross-origin requests directly from the browser to the backend (http://SERVER_IP:8000). This requires CORS headers and the correct server IP baked at build time — both of which are painful to configure for self-hosted deployments.

Fix

Route all browser API calls through the Next.js proxy rewrite that was already configured in next.config.ts but unused:

Browser → /api_be/api/v1/* (same-origin)
       → Next.js rewrite (server-side)
       → http://localhost:8000/* (internal)

apps/frontend/lib/api/client.ts

  • API_BASE is now context-aware:
    • Client-side (browser): /api_be/api/v1 — same-origin proxy path, zero CORS
    • Server-side (print pages/Server Components): http://localhost:8000/api/v1 — direct internal URL
  • apiFetch updated to avoid double-prepending the base when given a full proxy path

docker-compose.yml

  • Clarifies that NEXT_PUBLIC_API_URL is the internal backend URL for the proxy rewrite, not the external server IP
  • Wires CORS_ORIGINS and FRONTEND_BASE_URL as overridable env vars (kept for non-Docker / edge-case use)

apps/backend/.env.example

  • Documents that CORS_ORIGINS is not needed for standard Docker or npm dev setups

Result

  • Remote Docker deployments work out of the box — no server IP configuration, no image rebuild required
  • PDF download works from any machine
  • Works identically on Windows, macOS, and Linux Docker hosts

Summary by cubic

Proxy browser API calls through Next.js to remove CORS errors and fix PDF downloads when accessing a remote Docker host. Remote deployments now work without server IP config or image rebuilds.

  • Bug Fixes
    • Route browser requests to /api_be/api/v1 (same-origin) and rewrite server-side to http://localhost:8000.
    • Keep server-side code using the absolute backend URL inside the container for print/PDF pages.
    • docker-compose: expose CORS_ORIGINS and FRONTEND_BASE_URL as overridable env vars; clarify NEXT_PUBLIC_API_URL is internal.
    • backend .env.example: document that CORS_ORIGINS isn’t needed for standard Docker/npm setups and FRONTEND_BASE_URL should stay localhost.

Written for commit 36bd1ce. Summary will update on new commits.

Adds CORS_ORIGINS and FRONTEND_BASE_URL as configurable environment
variables in docker-compose.yml so users can override them without
editing source files.

Clarifies that NEXT_PUBLIC_API_URL is the internal backend URL used
by the Next.js server-side proxy rewrite, not the external server IP.
Browser requests are proxied through Next.js, so CORS and IP config
are not required for remote Docker deployments.
Changes API_BASE to use the /api_be/api/v1 proxy path on the client
side, routing browser requests through the Next.js rewrite rule
(next.config.ts) instead of directly to the backend.

- Browser requests go to /api_be/api/v1/* (same-origin, no CORS)
- Next.js server-side rewrite forwards to http://localhost:8000/*
- Server Components (print pages) continue using the absolute URL

This fixes CORS errors for remote Docker deployments and makes PDF
download work when accessing from a different machine, with no IP
configuration or image rebuild required.
Adds notes explaining that CORS_ORIGINS is not needed for standard
Docker or npm dev setups since browser requests are proxied through
Next.js. Documents that FRONTEND_BASE_URL should remain localhost
(Playwright runs inside the container).
Copilot AI review requested due to automatic review settings February 19, 2026 09:03
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot bot commented Feb 19, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Overview

This PR implements a clean solution for Docker remote access by routing client-side API requests through a Next.js proxy rewrite (/api_be/* → backend). This eliminates CORS issues for remote deployments without requiring IP configuration.

Key Changes Reviewed:

  1. API Client (apps/frontend/lib/api/client.ts):

    • API_BASE now returns a relative proxy path (/api_be/api/v1) on client-side
    • Server-side continues using the absolute URL for container-to-container communication
    • apiFetch() correctly handles both URL types
  2. Docker Configuration (docker-compose.yml):

    • Added CORS_ORIGINS and FRONTEND_BASE_URL environment variables with sensible defaults
    • Documentation clearly explains when/why to modify these values
  3. Environment Example (.env.example):

    • Updated documentation to clarify Playwright/PDF generation requirements

Focus Areas Checked:

  • API Breaking Changes: None - backend endpoints unchanged, only frontend routing modified
  • Prompts Flow: Not affected by this PR
  • LiteLLM Configurations: Not affected by this PR
  • Security: No vulnerabilities introduced
  • Runtime Errors: Logic is sound, handles edge cases properly
Files Reviewed (3 files)
  • apps/backend/.env.example - Documentation updates only
  • apps/frontend/lib/api/client.ts - API routing changes
  • docker-compose.yml - Environment variable additions

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

Copy link
Copy Markdown

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 adjusts the deployment/networking model so the browser talks to the backend via a same-origin Next.js proxy rewrite, avoiding CORS issues and preventing PDF downloads from being tied to localhost on the end user’s machine in remote Docker deployments.

Changes:

  • Switch frontend client-side API base to the Next.js rewrite path (/api_be/api/v1) while keeping server-side fetches pointed at the internal backend URL.
  • Update apiFetch to avoid double-prepending the base when given an already-prefixed proxy URL.
  • Clarify Docker/ENV configuration for proxying, CORS, and Playwright PDF generation base URL.

Reviewed changes

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

File Description
docker-compose.yml Documents proxy-based access and adds overridable CORS_ORIGINS / FRONTEND_BASE_URL env vars for Docker deployments.
apps/frontend/lib/api/client.ts Makes API base context-aware (browser uses rewrite path; server uses absolute internal URL) and updates apiFetch base handling.
apps/backend/.env.example Improves documentation around FRONTEND_BASE_URL and when CORS_ORIGINS is actually needed.

# Browser requests are proxied through Next.js - they never contact the
# backend directly, so no CORS or IP configuration is needed for remote use.
args:
- NEXT_PUBLIC_API_URL=http://localhost:${BACKEND_PORT:-8000}
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

The comments here say the Next.js rewrite backend URL should always be reachable from inside the container (i.e., always localhost:8000), but the build arg still uses ${BACKEND_PORT}. If a user overrides BACKEND_PORT (e.g., to change the exposed host port), this will bake a different port into the frontend rewrite target and can break proxying inside the container. Consider hardcoding the internal backend port (http://localhost:8000) for NEXT_PUBLIC_API_URL, or otherwise make internal port selection/mappings consistent (rewrite target, uvicorn port, and compose port mappings all aligned).

Suggested change
- NEXT_PUBLIC_API_URL=http://localhost:${BACKEND_PORT:-8000}
- NEXT_PUBLIC_API_URL=http://localhost:8000

Copilot uses AI. Check for mistakes.
@webysther
Copy link
Copy Markdown
Contributor

@srbhr I already fixed this is a better way, this can be closed:

Test with this:

ghcr.io/webysther/resume-matcher

only need this:

services:
  resume-matcher:
    image: ghcr.io/webysther/resume-matcher
    container_name: resume-matcher
    ports:
      - "3000:3000"
    volumes:
      - resume-data:/app/backend/data
    restart: unless-stopped

volumes:
  resume-data:
    driver: local

I will sent the PR in few minutes, just adjusting docs and making more tests

@srbhr
Copy link
Copy Markdown
Owner Author

srbhr commented Feb 20, 2026

Hey @webysther I've asked Docker to add me to the Docker Open Source, so is there a way we can also push this image to Docker? Whenever there's a new release?

@webysther
Copy link
Copy Markdown
Contributor

Hey @webysther I've asked Docker to add me to the Docker Open Source, so is there a way we can also push this image to Docker? Whenever there's a new release?

My suggestion as I see people on others projects, skip docker hub for now (mean, just comment the push to docker hub in actions), they take months to get back to you. Send only to ghcr, are the best because not api rate limit.

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.

3 participants