Search code examples
angulardockernginx

Docker: showing nginx index instead of angular homepage


I built an Angular 17 application using Docker Compose, but it was not loading correctly on localhost. It only showed the base Nginx template. After some testing, I tried to use the base template of Angular (ng new frontend) with a simple Dockerfile, but it still did not load the Angular application. I used the command docker build -t.

Here is the Dockerfile I used with the base Angular template:

FROM node:alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist/frontend /usr/share/nginx/html

Furthermore, I tried to list the contents of the path /usr/share/nginx/html and here is the result:

/ # ls
bin                   etc                   mnt                   run                   tmp
dev                   home                  opt                   sbin                  usr
docker-entrypoint.d   lib                   proc                  srv                   var
docker-entrypoint.sh  media                 root                  sys
/ # ls -l usr/share/nginx/html
total 28
-rw-r--r--    1 root     root         13753 Mar  9 01:30 3rdpartylicenses.txt
-rw-r--r--    1 root     root           497 Feb 14 16:20 50x.html
drwxr-xr-x    2 root     root          4096 Mar  9 01:30 browser
-rw-r--r--    1 root     root           615 Feb 14 16:20 index.html

I suppose the COPY command in the Dockerfile is not working, but I don’t have enough Docker knowledge to be sure about that.

I also tried to reinstall Docker, but it did not work.

Interestingly, my friend on Discord tried to help me and ran the same project with the same Dockerfile. On his computer, it ran normally. That's the reasoning I created this post.

This is my first Stack Overflow post. If you guys need more information, I’m glad to help.


Solution

  • Aparently there is an issue with Angular 17. The real output is /app/dist/frontend/browser, even though the angular.json states "outputPath": "dist/frontend",

    # Stage 1
    FROM node:alpine AS build
    WORKDIR /app
    COPY package.json package-lock.json ./
    RUN npm install
    COPY . .
    RUN npm run build
    
    # Stage 2
    FROM nginx:alpine
    COPY --from=build /app/dist/frontend/browser /usr/share/nginx/html
    COPY ./nginx.conf /etc/nginx/conf.d/default.conf
    

    Also, I'm now using this nginx.conf:

    server {
      listen 80;
    
      gzip on;
      gzip_http_version 1.1;
      gzip_disable      "MSIE [1-6]\.";
      gzip_min_length   256;
      gzip_vary         on;
      gzip_proxied      expired no-cache no-store private auth;
      gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
      gzip_comp_level   9;
      client_max_body_size 5M;
      proxy_read_timeout 200s;
      index index.html;
    
      location / {
        include /etc/nginx/mime.types;
        root /usr/share/nginx/html;
        add_header Cache-Control "public, max-age=1M";
        try_files $uri $uri/ /index.html =404;
      }
    
      location /healthcheck {
            access_log off;
            add_header 'Content-Type' 'text/plain';
            return 200 "Healthy\n";
        
      }
    }
    

    Whitout this nginx.conf, it does not properly access /index.html

    I also had to clear my browser history/cache after all that, this step was very important (I don't exactly know the reasoning, but it worked after doing this).

    You can learn more information about that with this Issue: https://github.com/angular/angular-cli/issues/26304

    This post also helped me: Docker for angular: Build result is not being copied in the /usr/share/nginx/html folder