Angular 2 на NGINX

Я пытаюсь разместить начальное число Angular 2 на сервере NGINX.

Я могу клонировать семя, npm install и npm start, и оно отлично работает со встроенным веб-сервером.

Затем я пытаюсь переместить содержимое той же директории src семени (с файлом index.html и всеми другими компонентами Angular в нем в корень по умолчанию моего сервера nginx (/usr/share/nginx/html).

Мой 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>  

Структура внутри каталога 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

Внутри каталога app находится мое собственное приложение Angular.

Когда я пытаюсь подключиться к серверу nginx, файл index.html загружается правильно, но затем вместо загрузки приложения angular он просто остается там (навсегда) в сообщении «Загрузка» в соответствии с кодом <my-app>Loading...</my-app>.

Я не менял конфигурацию nginx по умолчанию (учитывая, что я отбрасываю свое приложение angular прямо в корневой каталог по умолчанию для веб-сервера). Файлы конфигурации для сервера nginx следующие.

Основной файл конфигурации 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, импортированный в основную конфигурацию:

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

Я не могу понять, связана ли эта проблема с отсутствием некоторых конфигураций nginx, связано ли это с некоторыми компонентами времени выполнения, которые необходимы для запуска приложения angular, или эта проблема связана с некоторыми проблемами компиляции (но опять же, если я возьму в том же каталоге, и я npm start это приложение отлично отображает).

Спасибо.

ОБНОВЛЕНИЕ: я не упоминал об этом раньше, так как думал, что это еще больше запутает материал, но когда я сказал, что переместил файлы с src на /usr/share/nginx/html, я действительно сделал то, что запустил nginx как контейнер и сопоставил мой каталог src с /usr/share/nginx/html внутри контейнера. Поэтому, когда я работаю на своем локальном хосте, я npm install и npm start в каталоге src, и он работает нормально. Затем я запускаю сопоставление контейнера с тем же каталогом (под /usr/share/nginx/html) и вижу проблему, описанную выше. Я хочу предположить, что когда вы делаете npm install в первый раз, когда фактически компилируете приложение и загружаете все зависимости, и когда вы затем используете то же приложение (в src) в контексте контейнера nginx, приложение готово к запуску?

ОБНОВЛЕНИЕ № 2: Я думаю, что это становилось немного пушистым с моей стороны, поэтому я решил систематизировать то, что я пытаюсь сделать. Я думаю, что обсуждать реальный фрагмент кода лучше, чем предполагать. Вы можете воссоздать мою проблему, используя этот 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 

Вы можете собрать и запустить его следующим образом:

docker build -t mreferre/nginxangular .

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

если вы укажете в браузере хост докеров (порт 8080), на котором запущен контейнер ... вы увидите страницу загрузки, о которой я говорил, и приложение Angular никогда не запустится.

Конечно, где-то в Dockerfile (или в конфигурации NGINX?) Есть ошибка.

ОБНОВЛЕНИЕ №3: вроде приближается ... но еще не совсем. Если вы попытаетесь попасть внутрь контейнера выше, вы можете сделать curl localhost:80 и получить свою статическую html-страницу, обслуживаемую nginx (который работает на 80-м порту контейнера). Интересно отметить эту часть ответа:

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

Если я затем попытаюсь запустить веб-сервер ng (ng serve), он появится и начнет прослушивать порт 4200. Теперь вы можете сделать curl localhost:4200. Ответ практически идентичен, за исключением ...

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

К сожалению, у меня нет настоящего браузера для тестирования, но я уверен, что он работает (поскольку я вижу, что возвращается код Javascript).

Проблема, похоже, связана с тем, что по некоторым причинам сервер nginx не предоставляет содержимое приложения Javascript в ответе.

Mh...


person mreferre    schedule 26.05.2017    source источник
comment
проверьте консоль разработчика на наличие ошибок. Это было бы хорошим местом для начала. Опять же, проект angular должен быть опубликован с использованием ng build   -  person Poul Kruijt    schedule 26.05.2017
comment
Он сказал, что пытался переместить каталог src. Я предполагаю, что он действительно перемещает исходные TypeScript файлы! Как видите, main.ts все еще в рабочем состоянии.   -  person borislemke    schedule 26.05.2017
comment
@PierreDuc Консоль разработчика просто довольна отрисовкой страницы загрузки. Это ничего не говорит. Согласно сборке ng ... см. Мое ОБНОВЛЕНИЕ в потоке. Как я могу опубликовать на nginx с помощью ng build? Я так понимаю, что каталог src уже скомпилирован, учитывая, что я установил / запустил npm?   -  person mreferre    schedule 26.05.2017
comment
@borislemke, оказалось, что ты на что-то наткнулся со своим комментарием. Смотрите мой собственный ответ. Спасибо.   -  person mreferre    schedule 27.05.2017


Ответы (2)


В конце концов я понял, что делаю не так. Я не очень хорошо знаком с Angular и не был уверен, где были созданы артефакты сборки. Я продолжал указывать свой экземпляр NGINX на каталог src, и мне не хватало того, что производственные артефакты создавались в каталоге dist.

Как только я указал корень веб-сервера nginx в каталог dist, приложение начало работать.

Это образец (и определенно не оптимизированный) рабочий 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 
person mreferre    schedule 27.05.2017

Для справки в будущем я хотел бы добавить свой рабочий Dockerfile конструктора nginx-angular в ответ на ваш файл. Поскольку в 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
person Mark Peter Fejes    schedule 28.06.2018
comment
Спасибо, Марк. Да, многоступенчатые сборки помогли мне уменьшить размер финального контейнера. Вот что я использую в наши дни: - person mreferre; 03.07.2018