使用 proxy_pass 时如何重定向到 index.html

How to redirect to index.html when using proxy_pass

我正在尝试设置一个使用 docker 的 Angular/NestJS 项目。一切正常,除非我在除 / 以外的任何 url 上重新加载 Angular 前端(管理员),它会给我一个 404。我相信我需要 try_files $uri $uri/ /index.html =404;location /default.config 文件的一部分,但我不知道如何让它与 proxy_pass 一起工作。任何人都可以让它工作或知道秘密吗?

文件夹结构

my-project/ -> root
my-project/admin/ -> Angular Project
my-project/api/ -> NestJS API Project

my-project/default.config

upstream api {
  server api:3000;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Frontend
    location / {
        # root /usr/share/nginx/html;
        # index index.html index.htm;
        # try_files $uri $uri/ /index.html =404;
        proxy_pass http://admin;
    }

    # Backend
    location /api {
      rewrite /api/(.*) / break;
      proxy_pass http://api;
    }

    # You may need this to prevent return 404 recursion.
    location = /404.html {
        internal;
    }
}

my-project/docker-compose.yml

version: "3.8"

services:
  api:
    container_name: api
    build:
      context: ./api
      target: development
    volumes:
      - ./api:/usr/src/app
      - /usr/src/app/node_modules
    ports:
      - ${SERVER_PORT}:${SERVER_PORT}
      - 9229:9229
    command: npm run start:prod
    env_file:
      - .env
    networks:
      - webnet
    depends_on:
      - redis
      - postgres
  admin:
    container_name: admin
    build:
      context: ./admin
      # target: development
    # ports:
    #   - 80:80
    networks:
      - webnet
  nginx-proxy:
    depends_on:
      - admin
      - api
    image: nginx:alpine
    volumes:
      - $PWD/default.conf:/etc/nginx/conf.d/default.conf
    networks:
      webnet:
    ports:
      - 80:80
  redis:
    container_name: redis
    image: redis:6
    restart: always
    ports:
      - 6379:6379
    volumes:
      - redisdata:/data
    networks:
      - webnet
  postgres:
    container_name: postgres
    image: postgis/postgis
    networks:
      - webnet
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      PG_DATA: /var/lib/postgresql/data
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql/data
networks:
  webnet:
volumes:
  pgdata:
  redisdata:

my-project/admin/Dockerfile

# Stage 1: Compile and Build angular codebase

# Use official node image as the base image
FROM node:latest as build

# Set the working directory
WORKDIR /usr/local/app

# Add the source code to app
COPY ./ /usr/local/app/

# Install all the dependencies
RUN npm install

# Generate the build of the application
RUN npm run build


# Stage 2: Serve app with nginx server

# Use official nginx image as the base image
FROM nginx:latest

# Copy the build output to replace the default nginx contents.
COPY --from=build /usr/local/app/dist/my-project /usr/share/nginx/html

# Expose port 80
EXPOSE 80

my-project/api/Dockerfile

FROM node:12.13-alpine As development

WORKDIR /usr/src/app

COPY package*.json ./

RUN apk add --update python3 make g++ && rm -rf /var/cache/apk/*

RUN npm install

COPY . .

RUN npm run build

FROM node:12.13-alpine as production

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install --only=production

COPY . .

COPY --from=development /usr/src/app/dist ./dist

CMD ["node", "dist/main"]

需要在 Angular apps Nginx Docker 组件中设置 try_files 指令。第一个 Nginx 实例无法访问 Angular 容器的文件系统,它需要检查文件是否存在。

创建Nginx配置文件,admin/nginx-config.conf:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  root  /usr/share/nginx/html;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html =404;
  }
}

将文件复制到您的管理应用程序容器中:

# Stage 2: Serve app with nginx server

# Use official nginx image as the base image
FROM nginx:latest

# Set custom Nginx configuration
COPY ./nginx-config.conf /etc/nginx/conf.d/default.conf

# Copy the build output to replace the default nginx contents.
COPY --from=build /usr/local/app/dist/my-project /usr/share/nginx/html

# Expose port 80
EXPOSE 80

您可能需要更改 ./nginx-config.conf 文件名和路径以匹配您在项目中创建的文件名和路径。