簡體   English   中英

如何在 Nginx 容器內路由 Angular 應用程序?

[英]How to route Angular app inside Nginx container?

我的問題

我想用 docker 容器部署我的 angular 應用程序。 不幸的是,我很難路由特定的 uri。

前端圖像包含 nginx 和我編譯的 angular 應用程序。 為了在容器內執行路由,nginx 將所有 uris 指向我編譯的應用程序, try_files $uri $uri/ myapplication/index.html =404然后 ZD18B8624A0F5F721DA7B823655 路由器負責一切。

但是,當我運行前端容器時。 我只能訪問我的應用程序,並且 angular 路由根本不起作用。

另一方面,如果我在沒有 docker 的情況下使用 nginx 為我編譯的應用程序提供服務,則路由可以完美運行。

鑒於此,我想知道:

如何在 docker 容器內正確路由 angular 應用程序?

您可以在下面找到所有詳細信息 Tl;dr


整個構建過程

我的應用由三個服務組成:

  1. Angular 前端(Nginx + Angular)
  2. 后端 API(NodeJs + Express)
  3. 數據庫(MongoDB)

1) 上下文

我有以下文件樹:

|frontend
||package.json
||nginx.conf
||frontend.dockerfile
||Jumble
|backend
||package.json
||backend.dockerfile
||server.js
||Jumble
|docker-compose.yml

Docker-compose.yml 文件:

services:
  frontend:
    container_name: clockmachine-frontend
    build:
      context: ./frontend
      dockerfile: clockmachine-frontend.dockerfile

  database:
    container_name: mongo
    image: mongo
    ports:
    - "27017:27017"

  backend:
    container_name: clockmachine-api
    image: clockmachine-api
    build:
      context: ./backend
      dockerfile: clockmachine-api.dockerfile
    environment:
      - NODE_ENV=production
    ports:
      - "3000:3000"

我的前端 Dockerfile:

#### Stage 0, Build Angular frontend
FROM node:latest as build
WORKDIR /app
COPY package.json package.json
RUN npm install
COPY . .
RUN npm run build -- --prod

####Stage 1, Build Nginx backend
FROM nginx:alpine
COPY --from=build /app/dist/ /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

nginx.conf 文件:

server {
  listen 0.0.0.0:80;
  listen [::]:80;
  default_type application/octet-stream;
  client_max_body_size  256M;

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

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

后端 dockerfile:

#### Stage 0, Build API
FROM node:alpine
LABEL author="Olivier D'Ancona"
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node","server.js"]

2) 構建

我在主文件夾中構建了我的應用程序,如下所示:

sudo docker-compose build
sudo docker-compose up

前端將被編譯並在 nginx 服務器中提供服務。 后端將使用 nodejs 和 express 部署。 數據庫將從 dockerhub 中提取一個 mongo 圖像。

此時,應用程序正在構建沒有問題。 我控制了我的服務的狀態:

  1. http://localhost:27017/與 Mongo 數據庫實例連接(看起來您正試圖通過 HTTP 在本機驅動程序端口上訪問 MongoDB)。
  2. http://localhost:3000/api/工作正常(我成功連接到 mongo)
  3. http://localhost:8080無法連接(Firefox 無法在 localhost:8080 建立與服務器的連接。)
  4. http://localhost/student this is a static route of my app (Welcome to nginx, If you see this page. the nginx web server is successfully installed and working. Further configuration is required.)

3)前端路由問題

所以此時,數據庫和后端正在協同工作。 我的應用程序在 localhost/myapplication/index.html 上提供,但 angular 路由不起作用,而是瀏覽器告訴我他無法訪問我的應用程序。 我發現有人在這里有類似的問題。


4) 隔離容器

所以我嘗試單獨構建和運行前端容器:

我將目錄更改為文件夾 /frontend 並輸入:

sudo docker build -t mytag -f clockmachine-frontend.dockerfile .
sudo docker run mytag

構建過程大約需要 10 分鍾並成功完成。 這一次,當我到達http://localhost/myapplication時,應用程序工作正常,但又遇到了這個路由問題。


5) 無容器運行 nginx

因此,我嘗試直接在我的機器上運行 nginx。 我編譯了我的前端應用程序:

ng build --prod

並將其移至/usr/share/nginx/html/myapplication

我使用相同的 nginx.conf 配置文件並將其放入/etc/nginx/conf.d/default.conf ,我什至嘗試更改文件名而不覆蓋 default.conf 文件。

結果是我的應用程序在localhost/myapplication上正常運行,angular 路由工作完美!


六,結論

總而言之,我嘗試運行 docker-compose 文件,前端容器出現路由問題。 然后我隔離了這個容器,結果也一樣。 最后,我直接使用 nginx 為我的應用程序提供服務,並且它是成功的,因為路由工作正常。

終於,經過15天的勞動,我修好了!

問題出在 nginx 配置中的listen [::]:80行。 此外,前端容器的端口設置不正確。

這就是我實現它的方式:

前端 Dockerfile:

# Stage 0: compile angular frontend
FROM node:latest as build
WORKDIR /app
COPY . . 
RUN npm install
RUN npm run build --prod


# Stage 1: serve app with nginx server
FROM nginx:latest
COPY --from=build /app/dist/pointeuse  /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

Nginx配置:

server {
  listen 80;
  sendfile on;
  default_type application/octet-stream;

  gzip on;
  gzip_http_version 1.1;
  gzip_disable      "MSIE [1-6]\.";
  gzip_min_length   256;
  gzip_vary         on;
  gzip_proxied      expired no-cache no-store private auth;
  gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level   9;

  root /usr/share/nginx/html;

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

Docker-compose 文件:

version: '3.1'

services:
        frontend:
                container_name: clockmachine-frontend
                depends_on:
                        - database 
                        - backend
                image: clockmachine-frontend
                build:
                        context: ./frontend
                        dockerfile: frontend.dockerfile
                ports:
                        - "80:80"
        database:
                container_name: mongo
                image: mongo
                ports:
                        - "27017:27017"

        backend:
                container_name: clockmachine-api
                image: clockmachine-api
                build:
                        context: ./backend
                        dockerfile: backend.dockerfile
                environment:
                        - NODE_ENV=production
                ports:
                        - "3000:3000"

如您所見,我重命名了上下文文件。

將 angular 應用程序與 nginx 服務器容器化是一團糟,因為文檔是不同的。

如果您想部署 Angular 應用程序

檢查此鏈接:

  1. Angular 部署文檔
  2. 丹·瓦林示例
  3. 使用 nginx 提供 static 內容
  4. Nginx.org 文檔

我認為問題在於您將 /myapplication 前綴用於前端應用程序。
最好是直接在根 url 上托管應用程序而不使用“虛擬目錄”。

但是,如果您仍然需要使用它,則需要在 Angular 索引中設置。html Base href ( https://angular.io/guide-deployment ) 中您將使用的#thebase “/我的應用程序”。

其次, try_files $uri $uri/ myapplication/index.html =404應該是try_files myapplication/$uri myapplication/$uri/ myapplication/index.html =404因為你不想重定向不以myapplication開頭的元素.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM