Micro Frontend app with Reverse Proxy (Part 1)

Mohammad Taheri
5 min readOct 16, 2024

--

I like afterglow honestly, enjoy it.

As web applications grow more complex, micro frontends offer a solution by breaking down a monolithic frontend into smaller, manageable pieces, each developed and maintained independently. To efficiently manage these components, this article explores how integrating micro frontends with Nginx can streamline your application architecture, enhancing scalability and performance. We’ll cover the basics and provide practical tips for implementation.

Introduction

This way of implementation is called route distribution, and I want to show how to implement it with reverse proxy. In this project.

I don’t want to talk about pros and cons of micro frontend, you can search about it in other articles. But in this article which is part 1, you are going to run just a simple route distribution, load different apps in different routes and in part2 (I am currently writing it) I will talk about communications. Also, you can see full code in GitHub.

Architecture Overview

First, It is better to think about proxy, then talk about reverse proxy. A forward proxy, often just called a proxy, is a server that acts as an intermediary between a group of clients and the internet. Without it, clients send requests directly to the target server. With a forward proxy, clients send their requests to the proxy server, which then forwards them to the main server on their behalf.

Forward Proxy
Forward Proxy from Cloudflare

On the other hand, a Reverse Proxy is a server that sits in front of one or more web servers, intercepting requests from clients. This is different from a forward proxy, where the proxy sits in front of the clients. With a reverse proxy, when clients send requests to the origin server of a website, those requests are intercepted at the network edge by the reverse proxy server.

Reverse Proxy
Reverse Proxy from Cloudflare

Also, you can read more about it in bytebytego.

If we want to add a reverse proxy we should use Nginx, if you are not familiar, you can check practical-nginx-a-beginners-step-by-step-project-guide.

Now we start project with very basic one, we load two different project named blog and posts in different ports, and we use Nginx configuration. In the Micro frontend app, We have a container/shell project that load other apps, and also it is a place that connects many apps, in this sample, we go on with mono repo structure, but it is possible to make it multi repo:

/blogs
/posts
/container
docker-compose.yml
README.md

Implementation

We are using docker compose, and we have a basic configuration for it, you can check it in repo, and each project, they have their own docker, nginx file, then the important part is to add proxy to nginx of container app:

upstream posts_upstream {
server posts_hostname:8081;
}

upstream blog_upstream {
server blog_hostname:8082;
}
server {
....
location ~ ^/posts/(.*)$ {
# $1 in the proxy_pass directive is used to refer to the part of
# the URL that matched the capture group in the regular expression
# within the location block.
proxy_pass http://posts_upstream/$1;
}

location ~ ^/blog/(.*)$ {
proxy_pass http://blog_upstream/$1;
}
}

And this is a part of the docker-compose config, we define hostname to use it:

  blog: 
hostname: blog_hostname
build: blog
networks:
- mfe
ports:
- "8082:8082"

The container app now is responsible to just show some links and has the main Nginx config, but later we can add state management to it.

Now if you run the app with docker-compose up then check localhost:8000 you will see application and if you redirect to http://localhost:8000/posts/ you will see posts app, each app they are up in their ports, for instance in http://localhost:8082 you will see the blog app.

But wait, maybe you ask, so I don’t want to load just a HTML file, what is the point of that, you are right 😁, we keep going…

Add Modern Frontend App

Now I have changed those apps to modern web apps, Now we have two react apps. For the modern frontend apps, we should pay attention to configuration. When we build a React app (or other frameworks) we see a new build folder is generated, and we have many files in it and when we load a React app, the browser loads all related files, like CSS, icons, and others.

In proxy, because we are serving many javascript and CSS files with hash names, we don’t know which file is for which micro app, so to solve it, I change the docker file of each micro app and I copy build folder in a new folder with the name of the project:

COPY --from=builder /app/build .
COPY --from=builder /app/build /usr/share/nginx/html/blog #/posts

Now we should add config for files, to load static files correctly for each project, for instance, we request to /[project_name]/file[hasId].js so when we copy to a folder with the name of the project it is easier to separate them:

location ~* ^/(blog|posts)/(.*\.(css|js|png|jpg|jpeg|gif|ico|svg))$ {
set $project $1;
proxy_pass http://${project}_upstream/$2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

Now it is time to add config for any URL to proxy to the micro-app.

location ~ ^/(blog|posts)/(.*)$ {
set $project $1;
proxy_pass http://${project}_upstream/$2;
proxy_set_header Host $host;
# It's useful for logging and application logic that relies on
# the client's actual IP address
proxy_set_header X-Real-IP $remote_addr;
}

Congregation, We are done, we can see projects in a main project or main port (8000). You can see the full version of the second part in this branch and run with docker-compose up and check 8000 of localhost.

Problems

Now the problem is we have just separated pages, but in some cases, we need to load two apps on a single page, also communication is an important concern of micro frontend apps, so in part 2 I will talk about these concerns.

Thanks.

--

--

No responses yet