最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

docker - Next.js uses different URLs for fetch depending if in client or server component with FastApi when dockerized - Stack O

programmeradmin1浏览0评论

I have a dockerized app using Next.js and FastApi. Depending if fetch is called from client or server component different URLs need to be used.

Currently client components use http://localhost:8000/ and server components http://server:8000

How can this be fixed so the same URL can be used?

services:
  db:
    container_name: weatherdb
    image: postgres
    volumes:
      - ./db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: pass

  client:
    container_name: client
    build:
      context: ./client
      dockerfile: ./Dockerfile
    volumes:
      - ./client:/app
    ports:
      - 3000:3000
    environment:
      - NEXT_PUBLIC_PYTHON_API=http://server:8000

  server:
    container_name: server
    build:
      context: ./server
      dockerfile: ./Dockerfile
    volumes:
      - ./server:/usr/src/app
    ports:
      - "8000:8000"
    environment:
      DB_NAME: weatherdb
      DB_HOST: weatherdb
      DB_PORT: 5432
      DB_USER: postgres
      DB_PASS: pass
    depends_on:
      - db

volumes:
  db_data:

Client Dockerfile

FROM node:18-alpine
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable

WORKDIR /app
EXPOSE 3000

CMD ["pnpm", "run", "dev"]

Server Dockerfile

FROM python:3

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

I have tried to use same URL for both server and client components. http://server/ in client component causes ERR_NAME_NOT_RESOLVED.

http://localhost/ in client component results in the following stack trace

TypeError: fetch failed
    at node:internal/deps/undici/undici:12625:11
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Debug (/app/.next/server/chunks/ssr/_85a404._.js:55:21)

I have a dockerized app using Next.js and FastApi. Depending if fetch is called from client or server component different URLs need to be used.

Currently client components use http://localhost:8000/ and server components http://server:8000

How can this be fixed so the same URL can be used?

services:
  db:
    container_name: weatherdb
    image: postgres
    volumes:
      - ./db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: pass

  client:
    container_name: client
    build:
      context: ./client
      dockerfile: ./Dockerfile
    volumes:
      - ./client:/app
    ports:
      - 3000:3000
    environment:
      - NEXT_PUBLIC_PYTHON_API=http://server:8000

  server:
    container_name: server
    build:
      context: ./server
      dockerfile: ./Dockerfile
    volumes:
      - ./server:/usr/src/app
    ports:
      - "8000:8000"
    environment:
      DB_NAME: weatherdb
      DB_HOST: weatherdb
      DB_PORT: 5432
      DB_USER: postgres
      DB_PASS: pass
    depends_on:
      - db

volumes:
  db_data:

Client Dockerfile

FROM node:18-alpine
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable

WORKDIR /app
EXPOSE 3000

CMD ["pnpm", "run", "dev"]

Server Dockerfile

FROM python:3

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

I have tried to use same URL for both server and client components. http://server/ in client component causes ERR_NAME_NOT_RESOLVED.

http://localhost/ in client component results in the following stack trace

TypeError: fetch failed
    at node:internal/deps/undici/undici:12625:11
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Debug (/app/.next/server/chunks/ssr/_85a404._.js:55:21)
Share Improve this question asked Mar 14 at 9:21 jooviljoovil 31 bronze badge 2
  • Does Referencing Docker container from server-side (from another container) AND from client-side (browser) with same URL answer your question? You do intrinsically need different URLs for client- and server-originated calls, but it seems like there's a standard approach for setting that up. – David Maze Commented Mar 14 at 10:28
  • Thank you. Didn't realize that different URLs are needed when the Next application is dockerized. Did some more reading and got everything working. – joovil Commented Mar 14 at 12:20
Add a comment  | 

1 Answer 1

Reset to default 0

How about selecting the right url dynamically within your application. Sample say.

export const getApiUrl = () => {
  if (typeof window === 'undefined') {
    // Server
    return process.env.SERVER_PYTHON_API;
  } else {
    // Client
    return process.env.NEXT_PUBLIC_PYTHON_API;
  }
};

Then when making API calls, use the function to get the correct URL. Sample like

const fetchData = async () => {
  const apiUrl = getApiUrl();
  const response = await fetch(`${apiUrl}/your-endpoint`);
  const data = await response.json();
  return data;
};

With this you can work with both URL's. And update docker compose env with both url

 environment:
      - NEXT_PUBLIC_PYTHON_API=http://localhost:8000
      - SERVER_PYTHON_API=http://server:8000

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论