简体   繁体   English

NGINX上的Angular 2

[英]Angular 2 on NGINX

I am trying to host an Angular 2 seed on an NGINX server. 我试图在NGINX服务器上托管Angular 2种子。

I am able to clone the seed, npm install it and npm start it and it works just fine off of the embedded web server. 我能够克隆种子, npm install它和npm start它,它可以很好地从嵌入式Web服务器。

I then try to move the content of the same src directory of the seed (with the index.html file and all the other Angular components in it under the default root of my nginx server ( /usr/share/nginx/html ). 然后我尝试移动种子的同一个src目录的内容(使用index.html文件和其中所有其他Angular组件在我的nginx服务器的默认根目录下( /usr/share/nginx/html )。

My Angular index.html looks like this: 我的Angular index.html如下所示:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Clarity Seed App</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico?v=2">
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>  

The structure of inside the src directory (which is copied over to /usr/share/nginx/html ) is this: src目录内部的结构(复制到/usr/share/nginx/html )是这样的:

drwxr-xr-x 14 root root   476 May 26 11:47 .
drwxr-xr-x  3 root root  4096 Nov  8  2016 ..
drwxr-xr-x 11 root root   374 May 26 10:40 app
drwxr-xr-x  4 root root   136 May 26 10:40 environments
-rw-r--r--  1 root root 15086 May 26 10:40 favicon.ico
drwxr-xr-x  3 root root   102 May 26 10:40 images
-rw-r--r--  1 root root   310 May 26 10:40 index.html
-rw-r--r--  1 root root   351 May 26 10:40 main.ts
drwxr-xr-x  2 root root    68 May 26 11:47 node_modules
-rw-r--r--  1 root root   604 May 26 10:40 polyfills.ts
-rw-r--r--  1 root root    80 May 26 10:40 styles.css
-rw-r--r--  1 root root  1005 May 26 10:40 test.ts
-rw-r--r--  1 root root   702 May 26 10:40 tsconfig.json
-rw-r--r--  1 root root   147 May 26 10:40 typings.d.ts

Inside the app directory there is my actual Angular application. app目录中有我的实际Angular应用程序。

When I try to connect to the nginx server the index.html file is loaded properly but then, instead of loading the angular application, it just stays there (forever) at the "Loading" message per the <my-app>Loading...</my-app> code. 当我尝试连接到nginx服务器时, index.html文件被正确加载但是,然后,它只是(永远)停留在“加载”消息的<my-app>Loading...</my-app>代码。

I have not changed the default nginx configuration (given that I am dropping my angular app right into the default root for the web server). 我没有更改默认的nginx配置(假设我将我的角度应用程序直接放入Web服务器的默认根目录)。 The configuration files for the nginx server are as follows. nginx服务器的配置文件如下。

Main nginx config file: 主nginx配置文件:

cat /etc/nginx/nginx.conf 

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;
   }

Nginx config file imported into the main config: Nginx配置文件导入主配置:

cat /etc/nginx/conf.d/default.conf 

server {
    listen       80;
    server_name  localhost;

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

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

I can't figure out whether this problem is due to some nginx configurations missing, whether this is due to some runtime components that are required to run the angular app or whether this problem is due to some compilation problems (but again if I take the same directory and I npm start it the app renders just fine). 我无法弄清楚这个问题是否是由于某些nginx配置丢失造成的,这是否是由于运行角度应用程序所需的某些运行时组件或者是否是由于某些编译问题导致的问题(但是如果我采取了同一个目录,我npm start它应用程序渲染就好了)。

Thanks. 谢谢。

UPDATE: I did not mention this before as I thought that it would confuse stuff even more but when I said I moved the files from src to /usr/share/nginx/html what I have really done was to start nginx as a container and mapping my src directory to the /usr/share/nginx/html inside the container. 更新:之前我没有提到这个,因为我认为它会让事情更加混乱但是当我说我将文件从src移动到/usr/share/nginx/html我真正做的就是将nginx作为容器启动将我的src目录映射到容器内的/usr/share/nginx/html So when I am working on my local host I npm install and npm start in the src directory and it's working fine. 因此,当我在我的本地主机上工作时,我在npm installnpm startsrc目录中运行正常。 Then I start the container mapping to the exact same directory (under /usr/share/nginx/html ) and I see the problem as described above. 然后我开始容器映射到完全相同的目录(在/usr/share/nginx/html ),我看到如上所述的问题。 I want to assume that when you do the npm install the first time you are actually compiling the app and downloading all dependencies and when you then use the same app (in src ) in the context of the nginx container the app is ready to be run? 我想假设当你第一次编译应用程序并下载所有依赖项时执行npm install ,然后当你在nginx容器的上下文中使用相同的应用程序(在src )时,应用程序就可以运行了?

UPDATE #2: I think this was getting a bit fluffy on my side so I decided to codify what I am trying to do. 更新#2:我认为这对我来说有点蓬松,所以我决定编写我想要做的事情。 I think discussing around an actual piece of code is better than assuming. 我认为围绕一段实际代码讨论比假设更好。 You can recreate my problem using this Dockerfile: 您可以使用此Dockerfile重新创建我的问题:

FROM nginx:1.11.5

RUN apt-get update
RUN apt-get -y install git

RUN git clone https://github.com/vmware/clarity-seed.git

RUN apt-get -y install build-essential
RUN apt-get -y install curl
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -
RUN apt-get -y install nodejs
RUN npm install -g @angular/cli

RUN sed -i -- 's#/usr/share/nginx/html#/clarity-seed/src#g' /etc/nginx/conf.d/default.conf

WORKDIR /clarity-seed/src

RUN npm install  

RUN ng build --prod 

You can build and run it as follows: 您可以按如下方式构建和运行它:

docker build -t mreferre/nginxangular .

docker run -d -p 8080:80 mreferre/nginxangular

if you point your browser to the docker host (port 8080) where the container is running ... you will see the Loading page I was referring to and the Angular app will never start. 如果您将浏览器指向运行容器的docker主机(端口8080)...您将看到我所指的Loading页面,而Angular应用程序将永远不会启动。

Sure thing there is a mistake in the Dockerfile somewhere (or on the NGINX config?). 当然,Dockerfile中的某个地方(或NGINX配置?)有错误。

UPDATE #3: kind of getting closer now.. but not quite there yet. 更新#3:现在越来越近了......但还没到那里。 If you try to get inside the container above you can do a curl localhost:80 and you get your static html page served by nginx (which is running on port 80 of the container). 如果你试图进入上面的容器,你可以做一个curl localhost:80 ,你得到你的静态html页面由nginx服务(它在容器的端口80上运行)。 Interesting to note this part of the response: 有意思注意这部分回复:

<body>
<my-app>Loading...</my-app>
</body>

If I then try to bring up the ng web server ( ng serve ) this comes up and start listening on port 4200. Now you can do curl localhost:4200 . 如果我然后尝试启动ng web服务器( ng serve ),则会启动并开始侦听端口4200.现在你可以做curl localhost:4200 The response is almost identical except for ... 响应几乎完全相同,除了......

<body>
<my-app>Loading...</my-app>
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="scripts.bundle.js"></script><script type="text/javascript" src="styles.bundle.js"></script><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>

Unfortunately I don't have a real browser to test it but I 'd bet this is working (as I see the Javascript code being returned). 不幸的是我没有真正的浏览器来测试它,但我敢打赌这是有效的(因为我看到返回的Javascript代码)。

The problem seems to be due to the fact that, for some reasons, the nginx server doesn't provide the Javascript app content in the response. 问题似乎是由于某些原因,nginx服务器不在响应中提供Javascript应用程序内容。

Mh... MH ...

I eventually figured what I was doing wrong. 我最终想到了我做错了什么。 I am not very familiar with Angular and I wasn't sure where the artifacts of the build were being built. 我对Angular不太熟悉,我不确定构建的工件在哪里构建。 I kept pointing my NGINX instance to the src directory and I was missing that the production artifacts were being created in the dist directory. 我一直将我的NGINX实例指向src目录,但我错过了在dist目录中创建的生产工件。

As soon as I pointed the nginx web server root to the dist directory the application start working. 只要我将nginx Web服务器根指向dist目录,应用程序就会开始工作。

This is a sample (and definitely not optimized) working Dockerfile for reference: 这是一个示例(并且绝对不是优化的)工作Dockerfile供参考:

FROM nginx:1.11.5

RUN apt-get update
RUN apt-get -y install git

RUN git clone https://github.com/vmware/clarity-seed.git

RUN apt-get -y install build-essential
RUN apt-get -y install curl
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -
RUN apt-get -y install nodejs
RUN npm install -g @angular/cli

RUN sed -i -- 's#/usr/share/nginx/html#/clarity-seed/dist#g' /etc/nginx/conf.d/default.conf

WORKDIR /clarity-seed/src

RUN npm install  

RUN ng build --prod 

For future reference I would like to add my production nginx-angular builder Dockerfile in response to your file. 为了将来参考,我想添加我的生产nginx-angular构建器Dockerfile以响应您的文件。 Since docker added a feature called multi-stage builds, it's possible to create really small images very easily without the use of a container builder pipeline. 由于docker添加了一个称为多阶段构建的功能,因此可以非常轻松地创建非常小的图像,而无需使用容器构建器管道。

FROM node:alpine as builder
COPY frontend /app

# build the app
RUN npm install
RUN npm run build


# now the fun part
FROM nginx:stable-alpine

# copy nginx configs
COPY nginx.conf /etc/nginx/nginx.conf
COPY dhparams.pem /etc/nginx/dhparams.pem
COPY example.com.crt /etc/nginx/example.com.crt
COPY example.com.key /etc/nginx/example.com.key

# copy the prebuild frontend from the previous build stage
COPY --from=builder /app/dist /app/dist

# expose both http and https port that nginx listens on
EXPOSE 80
EXPOSE 443

# because the nginx:stable-alpine image already has an CMD, nginx automatically starts up

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM