title: Angular 2 on NGINX
body: <p>I am trying to host an Angular 2 seed on an NGINX server. </p>
  
  <p>I am able to clone the seed, <code>npm install</code> it and <code>npm start</code> it and it works just fine off of the embedded web server. </p>
  
  <p>I then try to move the content of the same <code>src</code> directory of the seed (with the <code>index.html</code> file and all the other Angular components in it under the default root of my nginx server (<code>/usr/share/nginx/html</code>). </p>
  
  <p>My Angular index.html looks like this:</p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta charset="utf-8"&gt;
      &lt;title&gt;Clarity Seed App&lt;/title&gt;
      &lt;base href="/"&gt;
      &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
      &lt;link rel="icon" type="image/x-icon" href="favicon.ico?v=2"&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;my-app&gt;Loading...&lt;/my-app&gt;
  &lt;/body&gt;
  &lt;/html&gt;  
  </code></pre>
  
  <p>The structure of inside the <code>src</code> directory (which is copied over to <code>/usr/share/nginx/html</code>) is this:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Inside the <code>app</code> directory there is my actual Angular application. </p>
  
  <p>When I try to connect to the nginx server the <code>index.html</code> file is loaded properly but then, instead of loading the angular application, it just stays there (forever) at the "Loading" message per the <code>&lt;my-app&gt;Loading...&lt;/my-app&gt;</code> code. </p>
  
  <p>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). The configuration files for the nginx server are as follows. </p>
  
  <p>Main nginx config file:</p>
  
  <pre><code>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;
     }
  </code></pre>
  
  <p>Nginx config file imported into the main config:</p>
  
  <pre><code>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;
      }
  }
  </code></pre>
  
  <p>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 <code>npm start</code> it the app renders just fine). </p>
  
  <p>Thanks.  </p>
  
  <p>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 <code>src</code> to <code>/usr/share/nginx/html</code> what I have really done was to start nginx as a container and mapping my <code>src</code> directory to the <code>/usr/share/nginx/html</code> inside the container. So when I am working on my local host I <code>npm install</code> and <code>npm start</code> in the <code>src</code> directory and it's working fine. Then I start the container mapping to the exact same directory (under <code>/usr/share/nginx/html</code>) and I see the problem as described above. I want to assume that when you do the <code>npm install</code> the first time you are actually compiling the app and downloading all dependencies and when you then use the same app (in <code>src</code>) in the context of the nginx container the app is ready to be run? </p>
  
  <p>UPDATE #2: I think this was getting a bit fluffy on my side so I decided to codify what I am trying to do. I think discussing around an actual piece of code is better than assuming. You can recreate my problem using this Dockerfile:</p>
  
  <pre><code>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 
  </code></pre>
  
  <p>You can build and run it as follows:</p>
  
  <pre><code>docker build -t mreferre/nginxangular .
  
  docker run -d -p 8080:80 mreferre/nginxangular
  </code></pre>
  
  <p>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. </p>
  
  <p>Sure thing there is a mistake in the Dockerfile somewhere (or on the NGINX config?). </p>
  
  <p>UPDATE #3: kind of getting closer now.. but not quite there yet. If you try to get inside the container above you can do a <code>curl localhost:80</code> and you get your static html page served by nginx (which is running on port 80 of the container). Interesting to note this part of the response:</p>
  
  <pre><code>&lt;body&gt;
  &lt;my-app&gt;Loading...&lt;/my-app&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>If I then try to bring up the ng web server (<code>ng serve</code>) this comes up and start listening on port 4200. Now you can do <code>curl localhost:4200</code>. The response is almost identical except for ... </p>
  
  <pre><code>&lt;body&gt;
  &lt;my-app&gt;Loading...&lt;/my-app&gt;
  &lt;script type="text/javascript" src="inline.bundle.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="scripts.bundle.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="styles.bundle.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="vendor.bundle.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="main.bundle.js"&gt;&lt;/script&gt;&lt;/body&gt;
  </code></pre>
  
  <p>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). </p>
  
  <p>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. </p>
  
  <p>Mh... </p>