Http2 setup for Spring Boot, Angular with nginx (containerized)
Tags: spring, http2, webdev, github
Published: 2022-03-22 18:51:23

###### This is my first post
**This demo is just to scratch the surface with Http2 using Spring.**

**You can find code at [Github](https://github.com/venkatsgithub1/http2-with-spring-angular)
Kindly follow the code to understand the API requests in Spring and Angular.**

To enable Http2 with Spring, we need SSL enabled on Spring.
With nginx, we need to add which port is needed to be used with Http2.

I used docker compose to easily startup the entire application.

### Here is what I tried and worked:

#### To enable http2 in Spring, we need to enable https first.
 * Create a self signed certificate, since this is a demo
 * Use following properties in application.properties for ssl: 
   * `server.ssl.key-store-type=PKCS12`
   * `server.ssl.key-store=/etc/ssl/certs/https2_test.p12`
   * `server.ssl.key-store-password=https2_test`
   * `server.ssl.key-alias=https2_test`
   * `server.ssl.enabled=true`
 * Enable http2 using the following:
   * `server.http2.enabled=true`
 * I am using 8443 as embedded tomcat server port.
 * Application code is self explanatory, has two endpoints.

### For UI, Angular is used and code is being deployed into nginx.
* UI code is simple, and has two API calls in ngOnInit.

### Docker compose is used to start up both backend and frontend.
 * Backend dockerfile steps:
   * ![Backend Dockerfile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdqto58q4extjm19j4wp.png)
   * Dockerfile on the backend side is straightforward:
   * It uses maven java image as builder
   * Copies code into workdir
   * Runs mvn clean install
   * Uses jdk14 image, copies jar, certificates there
   * Importing certificate to cacerts
   * Finally run jar.
 * Frontend dockerfile steps:
   * ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0fob51j6llghssmstwc.png)
   * Uses node lts image as builder
   * Copy all code
   * Run npm install and build
   * Use nginx alpine image to copy build files
   * I created a custom default.conf and copied it to `/etc/nginx/conf.d/`
     * The custom default.conf has settings related to http2 and ssl certs
   * Add certs into nginx locations:
     * `/etc/ssl/private/`
     * `/etc/ssl/certs/`
   * Start nginx with daemon off.

### Changes to default.conf of nginx
 * Add following below default 80 port localhost:
   * `listen 443 ssl http2 default_server;`
   * `listen [::]:443 ssl http2 default_server;`
   * `ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;`
   * `ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;`
   * These steps are saying, here are my certs, use 443 for http2 with ssl.

### Docker compose
 * ![Docker compose yml](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bno2yg10e7efvwvdvsm.png)
 * Compose is pretty simple, it has steps in yml to build backend and frontend:
 * Backend:
   * sbh2 is spring boot http2 service, we just have container name here and build from current path.
 * Frontend:
   * fengh2 is frontend nginx http2 service, it exposes 80 and 443 on 8080 and 8443 respectively, build location and container name.
 * To build and start, we use: `docker compose up`

### Demonstration
  ![Requests with Network](https://github.com/venkatsgithub1/http2-with-spring-angular/blob/master/images/requests1.png?raw=true)
**In the network tab, we see that the hello and random-quote API calls are showing protocol h2 indicating Http2.**
  ![Console](https://github.com/venkatsgithub1/http2-with-spring-angular/blob/master/images/requests2.png?raw=true)