seanmt13
seanmt13

Reputation: 422

How to deploy Angular 4 app with Docker and Azure Web App on Linux

I am trying to follow this documentation on deploying my angular 4 web app with docker.

Azure Web App on Linux Documentation

Below is what my Docker File currently looks like:

# Create image based on the official Node 6 image from dockerhub
FROM node:6
# Create a directory where our app will be placed
RUN mkdir -p /usr/src/app
# Change directory so that our commands run inside this new directory
WORKDIR /usr/src/app
# Copy dependency definitions
COPY package.json /usr/src/app
# Install dependecies
RUN npm install
# Get all the code needed to run the app
COPY . /usr/src/app
# Expose the port the app runs in
EXPOSE 80 
# Serve the app
CMD ["npm", "start"]

My package.json currenly has this under scripts "start": "ng serve -H 0.0.0.0",

I am able to create the Web App on Linux and push my image but i am getting the following when trying to browse the web application:

Invalid Host header

Am I missing something in my docker file? I am kinda stuck at this point so any help would be appreciated.

Upvotes: 1

Views: 3183

Answers (2)

Grimmy
Grimmy

Reputation: 4137

If you are just serving the generated app, make it as simple as possible. Do you really need ng-cli in the container and all the node modules in the image? The node modules alone is at least 200 MB.

Build the app locally with ng-build --prod. This generates the dist folder and this is the only thing you need.

You end up with a very simple Dockerfile:

FROM nginx:stable-alpine
ADD dist /usr/share/nginx/html
ADD default.conf /etc/nginx/conf.d/

The basic nginx conf to handle urls in angular default.conf:

server {
    listen       80;
    server_name  localhost;
    root /usr/share/nginx/html;
    charset utf-8;

    location / {
        try_files $uri /index.html;
    }
}

This gives you a tiny image of maybe 30 MB based on the size of your app instead of 250 MB+ with all the tools and dependencies.

Upvotes: 2

Thomas
Thomas

Reputation: 12029

I assume that the built in webserver expects a different host. You can try to use "ng serve -host 0.0.0.0" instead of the npm-start command. For production use I suggest to take a different approach, though: I would use nginx (or any other) production webserver to serve the angular application and build an image containing just the final application delivery. If you want to use docker as built container, I would separate these reponsibilities and consider docker multi-stage builds. Example for a docker multi-stage build

FROM trion/ng-cli:latest AS ngcli
WORKDIR /app
COPY . .                          
RUN npm install
RUN ng build --prod --aot --progress=false

FROM nginx:alpine AS app           
ENV PORT=8080
EXPOSE 8080
COPY --from=ngcli dist /usr/share/nginx/html/ 
COPY nginx/default.conf /etc/nginx/conf.d/default.conf.template
RUN chown -R nginx /etc/nginx

CMD ["/bin/sh","-c",\
"cp /etc/nginx/conf.d/default.conf.template \
 /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]

The nginx config (from nginx/default.conf) could look like this

server {
  listen 8080;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
  }
}

So you get two distinct containers: One just for building the app, one just for serving the app.

Upvotes: 1

Related Questions