If you want to deploy your beautiful Angular project on Heroku, the first thing you do is ... using Google.
Most people will tell you to use an ExpressJS instance to send the Angular bundle.
For example, some results from Google:
Why not using ExpressJS?
Is it a good idea to deploy a node instance to serve the Angular bundle?
I don't think so.
This is why:
- Less code === less problem
- Tools exist to serve static HTML like web servers
- ExpressJS is made to build dynamic websites or APIs
- ExpressJS uses a lot of CPU to serve static files
Here is a discussion on Stackoverflow that compares ExpressJS and Nginx for serving static files: link
The solution
To serve static HTML, like an Angular bundle, we can use Nginx
To use Nginx, we will build a Docker image with the Angular bundle and Nginx.
Create a Dockerfile
At the root of your project, create a file named Dockerfile with this content.
⚠️ In the file, replace your_app_name by the name value in your package.json file.
### STAGE 1:BUILD ###
FROM node:16.13.2-alpine AS build
WORKDIR /dist/src/app
RUN npm cache clean --force
COPY . .
RUN npm install
RUN npm run build --prod
FROM nginx:latest AS ngi
COPY --from=build /dist/src/app/dist/your_app_name>/usr/share/nginx/html
COPY /nginx.conf /etc/nginx/conf.d/default.conf
CMD sed -i -e 's/$PORT/'"$PORT"'/g'/etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'
EXPOSE $PORT
Create the Nginx configuration file
At the root of your project, create a file named nginx.conf
server {
listen $PORT;
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 / {
try_files $uri $uri/ /index.html =404;
}
}
Create a .dockerignore file
If you want to do things properly 😎, you can create a file named .dockerignore at the root of your project.
Files and directories listed in the file will not be copied when we create the Docker image.
You can add all files that are not required to the project like your IDE files.
.git
.editorconfig
/.vscode/*
/node_modules
/e2e
/docs
.gitignore
*.zip
.angular
.history
dist
Set the stack of your app to container
Here is some documentation about the stacks: link
In your terminal with the Heroku client execute this:
heroku stack:set container -a your_heroku_app_name
And?
Push your project on Heroku (or another git hosting service connected to Heroku) and wait for Docker magic to do its work.
Top comments (0)