Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Nginx Angular2/Angular routes

Tags:

I have an Angular2/Angular app running inside a docker container and using nginx to serve it. So my app base = /myapp/. Everything works correctly when hitting the app using the base url i.e. www.server.com/myapp or www.server.com/myapp/

events {   worker_connections  4096;  ## Default: 1024 }  http {   include /etc/nginx/conf/*.conf;    server {     listen       80 default_server;      root   /usr/share/nginx/html;     index  index.html index.htm;     include /etc/nginx/mime.types;     underscores_in_headers on;      location /myapp {       # If you want to enable html5Mode(true) in your angularjs app for pretty URL       # then all request for your angularJS app will be through index.html       try_files $uri /myapp/index.html;      }      #Static File Caching. All static files with the following extension will be cached for 1 day     location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {       expires 1d;     }      ## PROXIES ##     # location matcher for get requests. Any query params will be proxied using this location block     location = /myapp/api {        proxy_pass http://$hostname/api$is_args$query_string;       proxy_http_version 1.1;       proxy_set_header Upgrade $http_upgrade;       proxy_set_header Connection 'upgrade';       proxy_set_header Host $host;       proxy_cache_bypass $http_upgrade;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_connect_timeout       120;       proxy_send_timeout          120;       proxy_read_timeout          120;       send_timeout                120;     }      # location matcher for post requests i.e. updateAsset. Any request with additional path params will be proxied using this location block     location ~ ^/myapp/api/(?<section>.*) {        proxy_pass http://$hostname/api/$section;       proxy_http_version 1.1;       proxy_set_header Upgrade $http_upgrade;       proxy_set_header Connection 'upgrade';       proxy_set_header Host $host;       proxy_cache_bypass $http_upgrade;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_connect_timeout       120;       proxy_send_timeout          120;       proxy_read_timeout          120;       send_timeout                120;     }   } } 

My app has several other routes e.g. /myapp/page1 or /myapp/page2. These routes can be hit when serving the app in dev mode using nodejs. However once i containerize it (containerization isn't the issue) and serve using nginx then i get a 404 not found when trying to access /myapp/page1 or /myapp/page2. The error log outputs

2017/02/27 12:15:01 [error] 5#5: *3 open() "/usr/share/nginx/html/myapp/page1" failed (2: No such file or directory), client: 172.17.0.1, server: , request: "GET /myapp/page1 HTTP/1.1", host: "localhost"

I have tried mapping all my app urls in the nginx conf file but nothing seems to work. How do I get this to work?

Update 1

Added angular routes

Main app route:

import { Route } from '@angular/router'; import { MyAppComponent } from './index';  export const MyAppRoutes: Route[] = [   {     path: '',     component: MyAppComponent   } ]; 

Page 1 route:

import { Route } from '@angular/router'; import { Page1Component } from './index';  export const Page1Routes: Route[] = [   {     path:'page1',     component: Page1Component   } ]; 
like image 540
Steve Fitzsimons Avatar asked Feb 27 '17 12:02

Steve Fitzsimons


People also ask

What is Nginx in angular?

NGINX can be used as a web server or reverse proxy to serve the static content. All the NGINX configuration can be placed in this file nginx. conf . We need to build the angular app and place all the static files in the root location of the NGINX to serve the web. Docker is used as the container runtime.

Where is Nginx setup?

NGINX Configuration: Understanding Directives. Every NGINX configuration file will be found in the /etc/nginx/ directory, with the main configuration file located in /etc/nginx/nginx. conf .


2 Answers

Here is my nginx sites-available/myapp

server {     listen 80;     listen 80 [::]:80;     root /my/root/path;     server_name www.mysite.com mysite.com;      location /app1/ {         alias /my/root/path/app1/;         try_files $uri$args $uri$args/ $uri/ /app1/index.html;     }      location /app2/ {          ...     }     } 

After setting up the config you want to make your site enabled, run:

sudo ln -s /pathtonginx/sites-available/myapp /pathtonginx/sites-enabled/myapp 

The basehref on my index.html

<base href="./"> 

Hope this helps!

like image 134
David Pascoal Avatar answered Sep 19 '22 18:09

David Pascoal


The nginx Docker image includes a base configuration file, /etc/nginx/nginx.conf. This configuration file sets up various items to values that the image maintainers (presumably) know to be good values for a Docker container, so it is tempting to make use of that configuration file as much as possible when serving Angular. Anticipating that users might want to do that, the base configuration file includes the directive

http { ...     include /etc/nginx/conf.d/*.conf; } 

so, you can put your Angular specific configuration in a file /etc/nginx/conf.d/ng.conf, and get the benefit of using the base configuration file.

That file can be nice and simple. As recommended by the Angular documentation and the Nginx documentation, it just uses the try_files directive to serve your index.html for all deep-link paths:

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

and your Dockerfile just needs to copy that file from the build context into the Docker image:

COPY src/etc/nginx/conf.d/ng.conf /etc/nginx/conf.d/ 

I did that, but it didn't work, because there is also one snag. The nginx Docker image also includes a file /etc/nginx/conf.d/default.conf. That file is suitable for serving static content (from /usr/share/nginx/html), and if Nginx uses that configuration in preference to your configuration (which can happen), your try_files will be useless. Your Dockerfile should therefore also remove that default configuration:

RUN rm /etc/nginx/conf.d/default.conf 
like image 33
Raedwald Avatar answered Sep 23 '22 18:09

Raedwald