使用 Angular 7、NGINX 和 Docker 刷新页面时出现 404 错误

And*_*ris 14 nginx docker angular

我有一个用 Angular 7 编写的应用程序,我将它部署到带有 NGINX 的 Docker 容器中。当我运行容器时,一切正常,除非我在浏览器中刷新页面 (F5) 我得到一个 NGINX 404 错误页面。

这是我的 nginx.conf 文件,您可以从中看到我尝试过的“try_files”

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 80; 

        location / {
            root /usr/share/nginx/html;
            index index.html;
            try_files $uri /index.html;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的 Dockerfile:

FROM node:alpine as builder
RUN apk update && apk add --no-cache make git

WORKDIR /app

COPY package.json package-lock.json /app/
RUN cd /app && npm install

COPY .  /app
RUN cd /app && npm run build

FROM nginx:alpine

RUN rm -rf /usr/share/nginx/html/* && rm -rf /etc/nginx/nginx.conf
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /app/dist/hyper-client-admin /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Run Code Online (Sandbox Code Playgroud)

部署容器上的目录是:

/usr/share/nginx/html # ls -la
total 23564
drwxr-xr-x    1 root     root          4096 May 20 00:18 .
drwxr-xr-x    1 root     root          4096 Mar  8 03:05 ..
drwxr-xr-x    2 root     root          4096 May 20 00:18 assets
-rw-r--r--    1 root     root        290728 May 20 00:18 es2015-polyfills.js
-rw-r--r--    1 root     root        211178 May 20 00:18 es2015-polyfills.js.map
-rw-r--r--    1 root     root           997 May 20 00:18 favicon.png
-rw-r--r--    1 root     root           770 May 20 00:18 index.html
-rw-r--r--    1 root     root        114749 May 20 00:18 main.js
-rw-r--r--    1 root     root        115163 May 20 00:18 main.js.map
-rw-r--r--    1 root     root        241546 May 20 00:18 polyfills.js
-rw-r--r--    1 root     root        240220 May 20 00:18 polyfills.js.map
-rw-r--r--    1 root     root          6224 May 20 00:18 runtime.js
-rw-r--r--    1 root     root          6214 May 20 00:18 runtime.js.map
-rw-r--r--    1 root     root       1117457 May 20 00:18 styles.js
-rw-r--r--    1 root     root       1191427 May 20 00:18 styles.js.map
-rw-r--r--    1 root     root      10048515 May 20 00:18 vendor.js
-rw-r--r--    1 root     root      10505601 May 20 00:18 vendor.js.map
Run Code Online (Sandbox Code Playgroud)

这是控制台输出:

172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET / HTTP/1.1" 200 371 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"lopment\hyper-client-admin>
172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET /runtime.js HTTP/1.1" 200 6224 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET /polyfills.js HTTP/1.1" 200 241546 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET /main.js HTTP/1.1" 200 114749 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET /styles.js HTTP/1.1" 200 1117457 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:30 +0000] "GET /vendor.js HTTP/1.1" 200 10048515 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:31 +0000] "GET /assets/logo-white.svg HTTP/1.1" 200 4519 "http://localhost:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:31 +0000] "GET /favicon.png HTTP/1.1" 200 997 "http://localhost:81/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
172.17.0.1 - - [20/May/2019:00:18:35 +0000] "GET /login HTTP/1.1" 404 188 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" "-"
2019/05/20 00:18:35 [error] 6#6: *4 open() "/usr/share/nginx/html/login" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /login HTTP/1.1", host: "localhost:81"
Run Code Online (Sandbox Code Playgroud)

任何想法这里发生了什么?

更新:对此的实际答案在于@Rajesh 的答案的评论中。问题是我正在处理 /etc/nginx/nginx.conf 而我需要处理 /etc/nginx/conf.d/default.conf

Raj*_*pta 27

通过刷新 Angular 应用程序,我们需要告诉 nginx Web 服务器index.html在显示错误页面之前首先查看请求的路由是否存在。这对我来说很好用:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 将 `try_files $uri $uri/ =404;` 更改为 `try_files $uri $uri/ /index.html;` 对我有用 (4认同)
  • 刚刚得出了完全相同的结论。问题是我正在处理 /etc/nginx/nginx.conf 而我需要处理 /etc/nginx/conf.d/default.conf (2认同)

Ric*_*ick 12

只需使用 useHash: true 标志即可快速修复此问题。由于某些未知的原因,Angular 不会将此设置默认为 true。

确保您的 app-routing-module.ts 文件包含 useHash,如下所示:

@NgModule({
  imports: [RouterModule.forRoot(routes, { useHash: true })],
  exports: [RouterModule]
})
Run Code Online (Sandbox Code Playgroud)