英文:
How to create correct endpoints within an isolated network in Docker, NextJS and Nginx
问题
Nginx配置:
worker_processes 1;
events {
  worker_connections 1024;
}
http {
  sendfile on;
  upstream api {
    server nextjs-app:3000;
  }
  server {
    listen 80 default_server;
    location / {
      proxy_pass http://api;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
docker-compose:
version: '3.8'
services:
  nginx:
    image: nginx:latest
    restart: always
    depends_on:
      - rust-server
      - nextjs-app
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
    networks:
      - app_network
  nextjs-app:
    build:
      context: ./client
      dockerfile: Dockerfile
    container_name: nextjs-app
    environment:
      - CHOKIDAR_USEPOLLING=true
      - DB_USER=${DB_USER}
      - DB_PASS=${DB_PASS}
    expose:
      - "3000"
    networks:
      - app_network
  rust-server:
    build:
      context: ./userserver
      dockerfile: Dockerfile
    container_name: rustserver-dc
    expose:
      - "10000"
    networks:
      - app_network
    volumes:
      - './userserver:/usr/src/userserver'
      - '/usr/src/userserver/target'
    environment:
      - MY_LOG_LEVEL=info
      - MY_LOG_STYLE=Always
      - DATABASE_URL=${DATABASE_URL}
      - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
      - STRIPE_PUBLISH_KEY=${STRIPE_PUBLISH_KEY}
      - ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
      - REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
      - RESET_PASSWORD_SECRET=${RESET_PASSWORD_SECRET}
      - REDIS_URL=${REDIS_URL}
  surrealdb:
    image: surrealdb/surrealdb
    environment:
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
    expose:
      - "8000"
    networks:
      - app_network
    volumes:
      - data:/var/lib/surrealdb/data
    command: "start --user ${DB_USER} --pass {DB_PASSWORD} --log full file://var/lib/surreal/data"
networks:
  app_network:
    driver: bridge
volumes:
  data:
Next.js首页页面:
import Head from 'next/head';
import axios from 'axios';
import { useState, useEffect } from 'react';
export default function Home() {
  const [data, setData] = useState(null);
  useEffect(() => {
    axios.get('http://rustserver-dc:10000')
      .then(res => {
        setData(res.data);
      })
      .catch(err => {
        console.log(err);
      })
  }, []);
  console.log(data);
  return (
    <>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <div>Welcome to the app</div>
      </main>
    </>
  )
}
控制台中出现的错误:
Failed to load resource: net::ERR_NAME_NOT_RESOLVED rustserver-dc:10000/:1
以上为您提供的翻译内容,不包括代码部分。
英文:
I have a Docker network that is an isolated network and reverse proxy that serves the NextJS app to the localhost. Unfortunately, fetch to the backend gets failed whenever I open the browser. However, curl http://rustserver-dc:10000/ responds with the data. I do not want the DB and backend to get exposed, only is available from NextJS app when browsing.
Nginx conf:
worker_processes 1;
events {
  worker_connections 1024;
}
http {
  sendfile on;
  upstream api {
    server nextjs-app:3000;
  }
  server {
    listen 80 default_server;
    location / {
      proxy_pass http://api;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
docker-compose:
version: '3.8'
services:
  nginx:
    image: nginx:latest
    restart: always
    depends_on:
      - rust-server
      - nextjs-app
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
    networks:
      - app_network
 
  nextjs-app:
    build: 
      context: ./client
      dockerfile: Dockerfile
    container_name: nextjs-app
    environment:
      - CHOKIDAR_USEPOLLING=true
      - DB_USER=${DB_USER}
      - DB_PASS=${DB_PASS}
    expose:
      - "3000"
    networks:
      - app_network
  rust-server:
    build:
      context: ./userserver
      dockerfile: Dockerfile
    container_name: rustserver-dc
    expose:
      - "10000"
    networks:
      - app_network
    volumes:
      - './userserver:/usr/src/userserver'
      - '/usr/src/userserver/target'
    environment:
      - MY_LOG_LEVEL=info
      - MY_LOG_STYLE=Always
      - DATABASE_URL=${DATABASE_URL}
      - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
      - STRIPE_PUBLISH_KEY=${STRIPE_PUBLISH_KEY}
      - ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
      - REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
      - RESET_PASSWORD_SECRET=${RESET_PASSWORD_SECRET}
      - REDIS_URL=${REDIS_URL}
  surrealdb:
    image: surrealdb/surrealdb
    environment:
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
    expose:
      - "8000"
    networks:
      - app_network
    volumes:
      - data:/var/lib/surrealdb/data
    command: "start --user ${DB_USER} --pass {DB_PASSWORD} --log full 
file://var/lib/surreal/data"
networks:
  app_network:
    driver: bridge
    
volumes:
  data:
Next js index page:
import Head from 'next/head'
import axios from 'axios';
import { useState, useEffect } from 'react';
export default function Home() {
  const [data, setData] = useState(null);
  useEffect(() => {
    axios.get('http://rustserver-dc:10000')
      .then(res => {
        setData(res.data);
      })
      .catch(err => {
        console.log(err);
      })
  }, []);
  console.log(data);
  return (
    <>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <div>Welcome to the app</div>
      </main>
    </>
  )
}
Error occurring in console:
Failed to load resource: net::ERR_NAME_NOT_RESOLVED rustserver-dc:10000/:1
Had the same issue when I was trying to connect two nodes in Kubernetes, and exposing only NextJS app via Nginx reverse proxy
答案1
得分: 1
如果您希望在 Docker 网络上获取数据并将其发送给客户端,您可以使用 getServerSideProps 来在页面请求时获取数据,或者使用 getStaticProps 在构建时检索数据。
export async function getServerSideProps(context) {
  const res = await axios.get('http://rustserver-dc:10000')
  return {
    props: res.data, // 作为 props 传递给页面组件
  }
}
如果您需要客户端在这些时间之外请求 rustserver-dc,您可以添加一个 API 路由 到 Next.js,以将请求代理到 rustserver-dc 服务。
英文:
If you want next to fetch the data on the docker network and send it to the client you could use getServerSideProps to fetch the data when the page is requested, or getStaticProps to retrieve the data build time.
export async function getServerSideProps(context) {
  const res = await axios.get('http://rustserver-dc:10000')
  return {
    props: res.data, // will be passed to the page component as props
  }
}
If you need the client to make requests for rustserver-dc outside of those times, you could add an API route to next that proxies the request onto the rustserver-dc service.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论