I am new to angular and I would like to put the application on Nginx
server on a docker container.
To do that, I did the following steps:
sudo npm install -g @angular/cli
ng new angular4-on-nginx-with-docker
npm start
The angular application is working correctly through
npm start
Now, I want to avoid the command npm start
because I am thinking about developing a dockerized application. To do that, below is:
Dockerfile
file for nginxFROM debian:jessie
MAINTAINER NGINX Docker Maintainers "[email protected]"
ENV NGINX_VERSION 1.11.9-1~jessie
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \
&& echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
ca-certificates \
nginx=${NGINX_VERSION} \
&& rm -rf /var/lib/apt/lists/*
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
server {
server_name angular4.dev;
root /var/www/frontend/src;
try_files $uri $uri/ index.html;
error_log /var/log/nginx/angular4_error.log;
access_log /var/log/nginx/angular4_access.log;
}
docker-compose.yml
version: '2'
services:
nginx:
build: nginx
ports:
- 88:80
volumes:
- ./nginx/frontend:/var/www/frontend
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/logs/nginx/:/var/log/nginx
docker-compose up -d --build
docker inspect angular4onnginxwithdocker_nginx_1 | grep IPA
#"SecondaryIPAddresses": null,
#"IPAddress": "",
# "IPAMConfig": null,
# "IPAddress": "172.18.0.2",
Open your browser on 172.18.0.2
I think that npm packages are not accessible... I am not sure what is wrong exactly. But, what I can say is that the page is empty and without having any error message in the console.
Below is the code obtained when using nginx
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular4 on nginx with docker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
This the code of the page obtained by the use of the command npm start
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular4 on nginx with docker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="polyfills.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>
</html>
So, what is wrong???
A repo for that example is available on github
NGINX serving static files If we look at the above diagram, Angular builds the app and place the static assets in the /dist folder. We place these assets in the NGINX default location /usr/share/nginx/html where it serves the web content from.
By default, the configuration file is named nginx. conf and placed in the directory /usr/local/nginx/conf , /etc/nginx , or /usr/local/etc/nginx .
If anyone still struggling with production setup of angular 2/4/5 app + Nginx(i.e. Without Docker), then here is the complete solution:
Suppose you want to deploy your angular app at HOST: http://example.com
and PORT: 8080
Note - HOST and PORT might be different in your case.
Make sure you have <base href="/">
in you index.html head tag.
Firstly, go to your angular repo (i.e. /home/user/helloWorld) path at your machine.
Then build /dist for your production server using the following command:
ng build --prod --base-href http://example.com:8080
Now copy /dist (i.e. /home/user/helloWorld/dist) folder from your machine's angular repo to the remote machine where you want to host your production server.
Now login to your remote server and add following nginx server configuration.
server {
listen 8080;
server_name http://example.com;
root /path/to/your/dist/location;
# eg. root /home/admin/helloWorld/dist
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
# This will allow you to refresh page in your angular app. Which will not give error 404.
}
}
Now restart nginx.
That's it !! Now you can access your angular app at http://example.com:8080
Hope it will be helpful.
One thing that's wrong is that you are trying to publish your source files, instead of doing a production build using the cli and publish the output of these files. ng start
is used for local development. When you are happy with your outcome, you can use ng build --prod
to build your application, and whatever resides in your /dist
folder should be placed in the docker.
If you want to have everything in your docker, you should ng build --prod
after creating your new project, and then point the root of your nginx
to /var/www/frontend/dist;
. This will highly increase the boot time of your docker though. Obviously depending on the size of your project
If anyone still have problems serving angular with docker and ssl.
Dockerfile
FROM nginx:stable
## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /app/dist/my-app /usr/share/nginx/html/
## Skip this if you are using kubernetes config map
COPY nginx.conf /etc/nginx/nginx.conf
## Serve
CMD ["nginx", "-g", "daemon off;"]
Provide nginx.conf via kubernetes config map definition as follows:
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
name: config
subPath: nginx.conf
volumes:
- configMap:
defaultMode: 420
name: config-map-name
nginx.conf
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# this is necessary for us to be able to disable request buffering in all cases
include /etc/nginx/mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
log_format timed_combined 'remote_addr - '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
access_log /dev/stdout timed_combined;
server {
listen 0.0.0.0:443 ssl;
listen [::]:443 ssl default_server;
server_tokens off;
root /usr/share/nginx/html;
# SSL
ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411:
chunked_transfer_encoding on;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With