DEV Community

Damien Marchand
Damien Marchand

Posted on • Updated on

Angular on Heroku with ExpressJS

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

Enter fullscreen mode Exit fullscreen mode




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;
}
}

Enter fullscreen mode Exit fullscreen mode




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
Enter fullscreen mode Exit fullscreen mode




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)