Following the blog posts of Robert and Stefan, today I want to give you an overview of our thoughts concerning the deployment of the REST based Storefront.
The defiance of the current state
Deploying a single page application leads to many new challenges compared to classic web applications. Those challenges can on the other hand be turned into advantages. For example, as stated before we use Angular Universal for server-side rendering to tackle SEO concerns. The response to an incoming request for a specific URL is composed on the server and rendered using the REST endpoint of the in close vicinity deployed ICM instance. All used responses are then appended to the resulting HTML to be used as a startup enhancer for the client side application, which already has all the required information and only has to query for user-specific content.
As the ICM REST endpoint follows RESTful principles, any computation without any user-dependent data is also RESTful. Hence the initial response composed in the server side application is also RESTful, it can be cached for a reasonable amount of time. Imagine a cache enabled reverse proxy like nginx to be your first line of defence handling all incoming client requests and forwarding requests only in case of cache misses. To assure flexibility for different scenarios, we decided to decouple the deployments. One basic setup could look like the following scenario:
Of course it is not as easy as it sounds. To get this concept running some additional problems have to be addressed. First of all we have to get rid of any server side session state. Such a relic of the old way of doing things has no place in RESTful applications. If we want any user-specific data to be persisted we have to hold it in the client application via cookies or we have to allocate resource objects on REST endpoints which in turn are persisted in the database. Everything in between has to be resilient and replaceable.
As we are practically re-inventing the inSPIRED demo store in the process of developing, we are strongly adhering to those principles and every feature added has to follow them.
All those thoughts emerged while setting up a demo store. As you all know Intershop has a SCRUM enabled research and development department. That’s why we always experiment with new and current ways of doing things and we had to find a way to enable our product owner to do regular story acceptance testing. We did it by setting up a build pipeline of our current development version to a demo server with GitLab, our current development platform.
Following a GitFlow-like development workflow we commit to feature branches and merge them back to the develop branch. Every time the develop branch gets updated a Docker image for the current application is built. As you know we are using Angular Universal which needs a node.js environment to run. What could be easier than packaging up the whole build result in a node:alpine image and running it against a supplied REST endpoint of an ICM application?!
Turn up the volume!
To take this approach even one step further, our demo server hosting the REST based Storefront is part of a Docker Swarm. The build slave is publishing a new version of the development state by updating the service of the orchestrator. This is continuous delivery at its purest. Resilient! Replaceable! Rollback-enabled?! You name it!
Some of you might think that the ‘Docker, Docker, Docker!’ meme is a one-hit wonder and we’ll hit the ground harder than anticipated, but be informed that all major cloud service providers have made it part of their service offering. If you follow basic security concerns of Docker images like small footprint and narrow attack surface you will get all the advantages of it. Besides this, setting up an on-premise orchestrator for Docker containers is as easy as one-two-three.
I hope I could convince you that DevOps is not merely a buzzword for us but a way of doing things. Our development setup can easily be adapted in real world scenarios. Currently our runtime productive image has a footprint of 80 MB (including all of node.js and webpack optimized packaging of our REST based Storefront including dependencies). EAT THIS!
Deploying the REST based Storefront