Building a Docker Image for your Angular App with Nginx
This was created on November 2, 2021. This is based on an Angular 12.x application.
Creating the Dockerfile
In the root of your Angular app's project directory, create a Dockerfile
.
We will use a multi-stage build. Choose a version of the node
base image that is closest to your locally installed version.
$ node --versionv14.17.6
In the below Dockerfile you will need to change the COPY --from...
line so that is uses the right path for your built application.
FROM node:14.17.6-slim AS buildWORKDIR /dist/src/appRUN npm cache clean --forceCOPY package*.json ./RUN npm installCOPY . .RUN npm run buildFROM nginx:latest AS ngiCOPY --from=build /dist/src/app/dist/courses-front-end /usr/share/nginx/htmlCOPY /nginx.conf /etc/nginx/conf.d/default.confEXPOSE 80
Docker Ignore
Create a .dockerignore
file in the root of your project that has at a minimum the following:
.git.editorconfig/.vscode/*/node_modules.gitignore
Nginx Configuration
Also in the root of your project, create an nginx.conf
file, with content similiar to the following:
server { listen 80; sendfile on; default_type application/octet-stream; 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; root /usr/share/nginx/html; location ~ /index.html|.*\.json$ { expires -1; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; } location ~ .*\.css$|.*\.js$ { add_header Cache-Control 'max-age=31449600'; # one year } location / { try_files $uri $uri/ /index.html =404; }}
This adds gzip compression, and adds cache headers for the javascript and css files for one year.
The last portion is particularly important (the location / {...}
) as this tells NginX that instead of sending a 404 for any bad requests, just send index.html
. This will make it so a load or a refesh on a url that containers Angular routing information will be ignored.
Build the Image
Run the following (in the directory with your Dockerfile):
docker build -t jeffrygonzalez/super-angular-app:v1 .
Provide your own tag name and version, and don't forget the period at the end.
To run it:
docker run -d -p 8080:80 jeffrygonzalez/super-angular-app:v1
And hit that sucker with your browsah at http://localhost:8080
. Your magnifcent Angular app should appear. Check out the network tab for all good caching goodness.
Build Early, Build Often
Remember you should be rebuilding and redistributing your images often, even if none of the code changes. When you build an Angular app, it uses "relative" information for browser support.