我的问题
我想用 docker 容器部署我的 angular 应用程序。不幸的是,我很难路由特定的 uri。
前端图像包含 nginx 和我编译的 angular 应用程序。为了在容器内执行路由,nginx 将所有 uri 指向我编译的应用程序 try_files $uri $uri/ myapplication/index.html =404
然后 Angular 路由器负责一切。
但是,当我运行前端容器时。我只能访问我的应用程序,而 Angular 路由根本不起作用。
另一方面,如果我在没有 docker 的情况下使用 nginx 为我编译的应用程序提供服务,则路由可以完美运行。
鉴于此,我想知道:
how to route angular app properly inside a docker container ?
您可以在 Tl;dr 下方找到所有详细信息
整个搭建过程
我的应用程序由三个服务组成:
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 镜像。
在这一点上,应用程序正在构建没有问题。我控制了我的服务的状态:
3)前端路由问题
所以在这一点上,数据库和后端正在协同工作。我的应用程序在 localhost/myapplication/index.html 上提供服务,但 Angular 路由不起作用,而是浏览器告诉我他无法访问我的应用程序。我发现有人有类似的问题 here .
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 路由完美运行!6) 结论
总而言之,我尝试运行 docker-compose 文件,但前端容器存在路由问题。然后我隔离了这个容器,它有相同的结果。最后,我直接使用 nginx 为我的应用程序提供服务,并且成功了,因为路由工作正常。
最佳答案
终于,经过15天的劳动,我修好了!
它是 listen [::]:80
nginx 配置中的那一行是谁的问题。
此外,前端容器的端口设置不正确。
这就是我实现它的方式:
前端 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"
如您所见,我重命名了上下文的文件。
使用 nginx 服务器容器化 angular 应用程序是一团糟,因为文档是不同的。
如果你想部署一个 Angular 应用程序
检查此链接:
关于angular - 如何在 Nginx 容器内路由 Angular 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61800182/