Home > Enterprise >  How to redirect to index.html when using proxy_pass
How to redirect to index.html when using proxy_pass

Time:04-02

I'm trying to setup a Angular/NestJS project that uses docker. It's all working except if I reload the Angular frontend (admin) on any url other than / it gives me a 404. I believe I need the try_files $uri $uri/ /index.html =404; in location / part of the default.config file, but I can't figure out how to get it to work with proxy_pass. Anyone get this to work or know the secret?

Folder Structure

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/(.*) /$1 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"]

CodePudding user response:

The try_files directive needs to be set in the Angular apps Nginx Docker component. The first Nginx instance does not have access to the Angular containers' filesystem, which it needs to check whether a file exists or not.

Create a Nginx configuration file, 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;
  }
}

Copy the file into your admin app container:

# 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

You might have to change the ./nginx-config.conf filename and path to match the one you created in your project.

  • Related