Reverse Proxying an angular-cli SPA with Apache and Tomcat
It’s always beneficial to have your development environment closely mirror your production one, and thanks to tools like Docker it’s quite easy to set it up nowadays. In this post we will learn how to set up a dev environment for an Angular 4 application, backed by an api served with Tomcat fronted by Apache. If my production Angular app was served available at http://www.production.com , and the backing api at http://www.production.com/api, my goal would be to replicate the same set up for my local dev environment, so have my
front-end being served at http://www.production.dev/app and
apiat http://www.production.dev/api. I would want to I will be making the following assumptions:
- an Apache-2.4 web server running on port 80, configured for the domain http://production.dev/, with the modules mod_proxy and mod_proxy_http enabled
- a Tomcat-8.5.27 api server running on port 8080 that is accessible on http://production.dev:8080/api.
- An angular-cli (v1.3.2) Angular 4 application running in dev with
ng servethat is normally available by default at http://localhost:4200.
As a developer I wanted both my Angular and API application to be able to be accessible from a production.dev domain when developing locally. There are three separate areas to configure to make it happen.
In order to be able to access the production.dev address, I set up a custom domain in my Mac’s
etc/hosts file. This maps my default localhost address to this custom domain:
The first thing you will need is to configure Apache to reverse proxy both the Angular (app)and the Tomcat (api)applications. A representative
httpd.conf would look like:
ProxyPass /api http://localhost:8090/api
ProxyPassReverse /api http://localhost:8090/api
ProxyPassReverseCookiePath /api /
ProxyPass /app http://localhost:4200/app/
ProxyPassReverse /app http://localhost:4200/app/
This sets up Apache to forward requests from
/api to our Tomcat api app instance. You can also set it up in the exact same way if you are using Virutal Hosts. You’ll notice that the Tomcat port is
8090 which is not the default Tomcat port, which leads me to the next configuration.
In my case I wanted my app to have the context path of
api since it would be served from the same domain as my front end app. So my
server.xml configuration was updated to contain a
Context entry. I will not add it here since it was done through configuring my IntelliJ configuration but my app was available after a local deploy at http://production.dev/api. You’ll need to create a new connector for your app for the proxying to work. A sample configuration would be :
proxyPort is the important configuration here, it allows you application to reflect the port being proxied (80) rather than the port it is running on (8090).
In order for this setup to work locally, I had to set up local proxying made enabled by the proxy feature of the webpack-dev-server that powers the angular-cli. I was getting 404s when using the
http://production.dev/app url to access my Angular app when it was served through
ng serve — host production.dev. In order to resolve this I had to add to add a proxy configuration for my app like this in a new
proxy.conf.json in my app’s root directory :
With that configuration in place, i ran my ng serve as
ng serve --host production.dev --proxy-config proxy.conf.json --base-href /app/
base-href option is important in this case it allows us to specify the base url of the application which is
app in this case.
This completes the local setup of a development environment to try and mirror production domain wise using Angular, Apache and Tomcat. In the case of Angular you might need the
deploy-url option to be specified with the
ng serve to get this to work.