 Thank you Thank you very much So good morning. Good afternoon. Good evening to all of you depending from We have joined us. Um, I'm very glad to be here and Being your presenter today. I said my name is Timo Stark. I'm developer advocate for for engine X Working with with engine X and friends for like more than 12 years right now And I'm pretty pretty excited to give you a webinar today about a completely new Project at engine X called engine X unit and the agenda for this for today's webinar It's like I give you a brief overview about what engine X unit is and where we come from Then we will start with a common use case and configure engine X unit to host and Single-page as application created in react JS Then we will add some some API's to that to make make it more functional and At the end we will give or I will give you a short overview about how you can secure your applications What features that we have as I think you're doing the webinar. We have Q&A open. I have a colleague next to me To answering all your Q&A while I'm talking so feel free to put anything at the Q&A While I'm talking and we will make sure that all answers All questions will be answered accordingly Yeah, let's hop into introduction of engine X unit Yeah, most of you are very familiar with engine X as a web server as a reverse proxy and Igor Sasayev back in the days is the big the creator and founder of the engine X project and product and He tried to solve a very specific problem back in the days That he had and that was how can I handle more connections more customer on a single server instance, that was the whole reason why he invented engine X and It started as you can see here the green line it started Officially with it with one of the first releases back in 2001 like the invention and then 2004 with the first releases general 0.1 version was back in 2011 and Engine X was is today the most used web server on the market within with the market share of around 37 percent and This is a set you already know engine X as a web server as a reverse proxy. You probably have used it and Today I want to demonstrate what we have new and What is what what are the difference between engine X and engine X unit? The common engine X use cases are pretty clear. We can do local lancing for TCP UDP and HTTP We do reverse proxying a web server content cache web application firewall All that kind of things But with unit we try to solve a completely different problem and as said engine X unit is a completely new fully open source and free project That does not share any code with the engine X web server at all it is a set a completely new product and project and we try to attack the problem of All the complexity that we have in our today's application runtime in the application stack in the complexity of managing and serve Present or host our service for customers or users Because the today's application stack is a very complex ecosystem Let's start with a with a code on the very very bottom of this of this slide It depends on the language you're using it's a JavaScript. Is it Java is it Python PHP? You name it on top of that we add some runtime environment either an application server or Or a set of binaries like node.js or go Then we have something like a reverse proxy in front of it doing maybe HTTPS reverse proxy load balancing Then before the client we do some edge stuff stuff like Cloudflare or global load balancing things like that and then at the end we have the client in the browser Each and every layer adds complexity to the stack and it makes it complicated and hard for the engineers to manage all All of these different steps how to configure how to push configuration from one stick to another some config Depends on the application code some configuration has to be made in the application runtime The other one has to be made in the proxy layer So it's very very complicated to keep everything in sync and to configure everything accordingly it like an example I want to make here is With something that we have in the real world just to make it a little bit more easier to understand What is mobility for us today? I can buy a train or I can buy aircraft, but that is not mobility Right, so then I own a train. I own an airplane But that means Nusted that does not mean that I'm that I'm in some sort mobile or that I have mobility These two things are really think the train is the thing a aircraft is a thing Same applies to your application code. The code alone is not a service It does not represent a service if the application code is a thing in an ecosystem That we just saw and it's like a train in the aircraft. It's something that can carry things, right? But it's not mobility. It's nothing you can consume out of the box To make it consumable There is a lot more to it. You need a train station. You need an airport You need some folks managing and taking care of the folks at the airport the train station Maintains all that stuff. So it's a lot more to this picture to make Mobility or create mobility as the service based on a train or an aircraft and This is the reason why We created engine X unit because we believe that there is a better way and a more efficient way to manage and host your application stack and Create real end-to-end services for your users instead of just hosting application code So I come back to this picture with unit what we can do We combined all layers we saw in the previous slide from the very top that means from the listener part To the Proxying routing routing engine down into the application runtime. So with engine X unit We have a product and a project That combines all layers That's needed to serve and create like a real end-to-end experience You can run your Java code. You can run your note code your JavaScript code your Python code your PHP app on unit natively Then you can make configurations about routing Static file shares and on the very top We have the network stack that can expose listeners that can enable TLS termination and certificate management and all that so That is the real unique thing why unit exists because we believe that this can simplify the application stack a lot and Just to combine like to wrap this a little bit more up As that we can first of all run your application code Today we support seven different languages that will come to that in a minute. We can serve static assets That means we have a built-in web server That is the the use case we will see in the single page application Demo and we can proxy to back ends. So simple HTTP proxying is also part of the of engine X unit as a as a future and Again, because that was a common question during other what we know as it talks This product is a hundred percent open source and completely free Right and the use cases try to attack here is first simplify your microservice stack That means that we do not need an application run time and the reverse proxy And all that may be in a single container and deal with all the complex stuff of having multi-demonized containers and Manage all this all this stuff on on on kubernetes For example, we can have engine X unit that handles all that for us with a single configuration with a single configuration syntax without dealing with multiple products at the time Modernized mental monolith is that engine X unit can run in a container, but it can also run on a VM and On a VM we have all the capabilities we need to modernize our Currently existing applications to add features to them and to make it easier manageable for example to to enable a gdps to change environment variables and all that kind of stuff and on the very right This is a interesting thing here What can I say we secured the application run time that is because with engine X unit we added kind of the same Ideas and same implementations that you have with docker. We can isolate the namespaces and the linux namespaces We can isolate the network stack. We can isolate the process IDs and things Each and every process or application can run under its own run user So you can isolate your currently existing applications on a VM for example With a variety of features in engine X unit that makes it more isolated Therefore more secure to run more than one application at a time on a single on a single VM or server So, yeah, that's that's basically all set here Yeah, something I want to mention here I've talked about the Configuration syntax and that we have One configuration syntax that applies to all to all the application other languages and all kind of applications we host under a single unit instance and The unit configuration that this is something we will see in the demo as well is red We have a restful Configuration or an API that you can send JSON files on the one hand to send a JSON payload to an to an API That will reconfigure your unit instance or you can use The JSON the JSON objects and go to a very specific part of the configuration and change for example a single Environment variable or a single list in our single route and I will see this in the demo in a minute And this is all without restarting engine X without reloading the configuration manually. This is all Zero downtime fully integrated and automated. So send the config to the unit config endpoint Unit will pick up the configuration changes will reconfigure the server Without a downtime and without having a need of restart the process manually by hand, right? This is a wrap-up about security already Mentioned most of it and we have a more detailed Slide at the end of this presentation So make sure you keep your questions till then I probably will answer most of them All right, so enough for slides because I think we are here to see something real in action That's why I really want to show you now Demo about engine X Unit how that all works. All right So I'm connected to my Linux box here at the moment We support engine X unit for Linux operating systems details will be in the presentation limit and Mac OS so Windows is not supported at the moment All right, so we have unit already installed and up and running Let's grab that and show you we have The latest version 27 point zero and then we see here a couple of things first We have a controller a router and the main process All good. All right, so How to get started in general is we install unit the runtime and for the single-page application use case There is no need of the language module. This is something I would cover in a bit for this demo All you need to do is up install for example up to install a unit and then you're golden so Let's hope over to some source code. I've created a small demo application in react.js And That we can see in the browser here That's basically a weather service Couple of static assets with images we have CSS We do something like the react router stuff so that the react application takes care of Invalid locations in the URI and handles a 404 All right, so let's jump in and see How that works. Yes, we have a simple react-based application we have an Build output with an index HTML file and some static assets and Now what we need to do is we have to tell engine X unit that we want to share our static assets like the CSS JavaScript pictures all that and Anything that relates in and 404 not found Will be automatically directed to the index HTML so that the react router can take care of the request and Handles the incoming request and displays the 404 page for example Anything we need is a configuration that looks like like this and I would like to start with a very top with the network layer that is called a listener and We can have multiple listeners at the time So at this time we have a listener listening on port 80 Can do a listener report 8080 you can specify in specific IP address So star means we listen to all IP address is connected to that virtual machine to the server IP If you want to bring that down to for example local host, you're totally fine to put local host in here Or if you want to connect it to some some private IP addresses, whatever feel free to add them here as well so That means you can you can make a decision that you have the choice Who should be able to connect to that listener on on what interface? Is it just local host if it is it's anything or is it's a public IP? That's totally fine to you in this case. We're good with start 80 means any IP that's connected to that server will be able to connect to this listener Then we have a pass object and with the past object we tell and or we tell the engine X unit server What to do with an incoming request? We send a request to port 80 and Unit will pass it over to the router and The router is a very very powerful thing We have an engine X unit because what we do is we have a combination of actions and Matchers and match is for example. I can show you this here a match Will take care of incoming requests and look for specific parts of it of the host name the your eye We can match headers. We can match cookies. We can match HTTP options like get post put all kind of all kind of things and Based on a given match We can invoke in an action. So in this case what we have here is We match if a given host for example is local host and the your eye is anything with environment slash Star so anything that starts with environments If this is the case We will send or we will share a config.json file from this given directory Reason why I'm doing it is it is always a little bit tricky in react.js It's all client-side code to protect your API endpoints or the URLs the host names for you for the endpoints Based for example on an on a given host name So what we can do here with unit is we can define our environments. So this is for example the development environment and We can have the production environment as well and In react.js. I created some code that will reach out initially to environments and Receive the config.json file and I will configure my my environment Accordingly to this configuration. So there's no need of having your Production host names your staging host names development host names hard-coded in your react that even if it's client-side because nginx unit will be able to share some config files that you can configure your react app Based on based on this response But the only thing we need without without this extra add-on We would need to configure to make the single page application work after we have filled it Is we define an action. There's no need for a match In this case matches optional and action is always required and what we can do is we can tell unit share This is an array. We can say first try To find the given URI in this particular directory so given we use localhosts slash static slash CSS slash main A2 whatever dot CSS unit will be able to find this CSS file and Send it in a response If we send something for example, we already saw here something that does not exist and GenX unit will then send this request to the index.html file and the index.html file and the react router will take care of the request and display the custom 404 page we have created inside of our react application and This is the config is all we need to make nginx unit work for single page applications so as a wrap-up app install unit then create a config that looks like this listener and Arroute Array With an action share and that's it. No application needed at this time No other routes needed at this time. It's all you need to host your static your static Applicate your static files and your single page application alright So next is we will talk about nginx unit as the application runtime because what we can see here Back to the landing page We should see some Weather forecast favorite data in our reactor but say not implemented deployed the API and unit to see this future and The API endpoint which is local host API we want weather favorites is sending 405 not implemented Here we can see Our environment response that we already saw in the config that tells our react that hey The weather API is located under HTTP local host and for production. They will point out to another host a Great, so let's check what we can do to make a Python application in this case Running on on nginx unit the reason why I choose Python for this demo is because it's the simplest and most Efficient way to run and getting started application on unit because Python is the Python Bineries are part of like most or all operating system. We currently support. So that's why the Python three or two runtimes are already there and the only thing we need is a language module and a language module is our Implementation in that case of the WS GI or AS GI interface for PHP. We are talking to the server API so There's no need for example In the PHP term no need of creating or installing an FPM Which was the like the old way of doing it or using somewhat PHP Apache Unit implements something that is like an FPM. So we take care of the PHP processes. We take care of Handling the PHP requests Same with Python same with Ruby and all the other languages you can see here So the language modules as said are something you can install They are pre packed and pre built and there is a simple app to install unit Python unit Ruby Java and PHP And that will install the language module and the language module is represented in something that's called the type Type tells unit what kind of application is that is it Python Ruby Java PHP? and What you can see here on the right is an example That we can host all different languages all kind of languages and even more all different kind of different versions like Python two and three Java eight and eleven PHP five seven and eight all on the same unit instance There's no need of having multiple servers multiple Installations because of languages if you want to host your PHP five seven and eight applications on a single box Isolated no problem unit can definitely do this for you same applies to all the other application languages as well as the configuration syntax you see here on the right is For all application languages the same they are language specific config syntax In an application object. That's what we can see here So for example for Java, we have something that's called fast path For PHP we have something to tell unit what are the PHP options and so very specific things per per language But in 80% of the of the configuration syntax it is totally identical For all application languages so now Enough talking. So let's do some actual unit configuration Let me show you the application configuration first So Now we have we have learned we have a couple of objects. We know listeners We know routes and the third one is applications Applications are a wrapper for all applications. We have under a unit instance and the good thing What you already saw here is the applications are Coupled from the routes the listener is the coupled from the route and the application So you can configure application Independently of all the routes of the listener you have on top of it That means you can easily switch listeners route actions Between your between your application This is a very handy when it comes to a B testing when it comes to blue green deployments all that kind of all that kind of things so in this case our Python API hosts and an API endpoint that starts with slash API all the time So we create a new route Matcher that says anything that comes in with slash API at the beginning Star anything that's it's off to slash API slash Will be sent to applications unit weather then we define application unit weather and What we need here is we need the type with the type hotel engine next unit hate. This is Python version 3.10 We share a path Where unit can find the code the home is the Python virtual environment A callable is inside of the application the instance of the application object The module is the module name in Python I will show you this in the code And this is an example of how to modern like the modern to modify the environment We can define environment variables in the configuration and access inside of the of the Python code So let's have a quick look into the source code So we have the virtual environment. We have our module name called wsgi.py You have like free of choice. You can call it application. You can call it wsgi You can call it module star whatever just make sure you point it as the module The callable is this bit in this case It's the flask application and the application object of flask is mapped to app That's the callable we refer in unit configuration The default one will be application. So if you call this application and not app You have there's no need of defining the callable in here But as the flask defaults tutorials Are pointing that out as app I used app did not change it and use the callable syntax in my configuration so then we have a simple route that is API we want weather favorites and We have a weather service in here that is basically send weather favorites as an array and share it as a As a JSON output. So that is basically all we have For the simple Python API And now if we send this configuration to unit That means it will configure the application object Then we will see in the front end that we can reach out to this application object and we see the The weather favorites in our front. So let's do this. So this is a way you can send Configuration to the unit server. Let me explain this in in a little bit more detail We have two ways to for unit to listen for configuration changes the default way is a unique socket and This can be changed into in PCP port IP address and port combination as well So that means if you change that to localhost 9999 for example that you then you will add localhost 9999 slash config and you can get rid of the unique socket Then we have the put option get will read the configuration put will use the JSON file that we put here and send it to the To the unit and a config endpoint Let's do this So reconfiguration done if you have any errors it will say error While reconfiguring and then there is a unit log in bar log unit log Where I can trace down the the errors while sending updates to the conjugate point Okay, so now We reconfigured unit so that means that the 501 error not implemented error should go away now and it does so again We see The favorites here and that shares the JSON response from the from the API and Click on them with the data for Seattle on a core of San Francisco So that is that it that is because we have slash API and Unit now knows hey anything that is slash API Will directly be sent to the unit weather application if you want to host another application for example and V2 and you want to build this in Java or you want to build this in PHP. No problem change this from API V1 slash Duplicate this thing Create another object with V2 and send it to another part of the to another application object So that is how flexible that is it's all one configuration syntax one configuration file and It's all the same for all programming languages Again, the request router option is something we already saw. It's very powerful based on incoming Metadata of the request posting your eye could be said as methods arguments and your eye segments We can make our decisions. But this is one of the biggest differences against the engine X Because an engine X we most of the time use location based Matching and here with unit we have a router implementation that can match any Important meta information of the HTTP request and it evokes actions accordingly. So that's what we already discussed Just maybe as a little wrap up so you can take a screenshot from that and for like use it as a As a reference as said the router object in unit is very very powerful And and it can it can do a lot a lot of different things But it would take too much time to go into very Details in for the for the routing stuff. So that's why we covered here the real basics We have great examples on the website and the link will be in this presentation in a bit. So Make sure you check this out if you have more questions about the engine X router at the engines unit router Right. So this as a as a diagram To illustrate what we already saw in the demos just to wrap it up We saw the listeners on the very left Which is the layer for implementation on the network stack this opens some ports or Sockets to connect you then we can send it to an Upstream which is the reverse proxying capabilities. It can send requests to the router Or we can send it to the applications straight So the routes is an optional thing you can use which is very powerful, but there's no need to use routes You can send an incoming request directly to an application or if you wanted that's what we saw with the API if you want to like Disable some some parts of the oven of an host name or you or I Have a listener send it to routes and the routes can then return an HTTP response straight like anything that is API v1 is deprecated and that should return 502 right now 501 400 something that is possible with the router as well and Then we have the application objects and the file on disk which is this share array option We saw for their single-page application and the good thing is to come back to the very start of this presentation This illustrate the technique and the implementation we created because we believe that we can Host the services and we can manage this application stack in a single product and make it therefore very very easy Efficient and flexible to configure everything from your network to the routes and Handling of the routes and incoming requests to the application runtime or web server capabilities This is another representation of what we of this diagram We saw it just to wrap it up once more the configuration. We saw the rest config and I would like to show you One more thing because we we did some updates But let me do some Config tweaking here as we have time left and I would really like to demo things on the product instead of hopping through the PowerPoint stuff So this curl request will give us all the configuration we have currently loaded in unit So you see the application unit thing is here our routes are here All great good so As it is all JSON based what we can do is we can say localhost config I'm just interested in all the listeners. I have so this sir nurse So means if we say localhost config listeners, we can see all the listeners. I have if I want to see okay. What is for example Where is point 80 going to? That means it says okay it passes to routes in the same way I can query the configuration here I can update it. So that means if I would like to update the past object I do this it says routes if I want to go straight to an application. No problem. I can use put again or post to Curl this endpoint specify my input and update the configuration So same is for config routes So I can see all my I can see my route object and in this example We have one route array That have that has all the matches and actions and there's an alternative syntax to this That can create something that called named routes So we can give routes a name if you want to have multiple routes on the system You can call this whole thing this whole array will be named main And then we can point a listener to the main route instead of an global routes object, but that is well Documented in our on our website I said it's called named routes and this has the benefit that you have multiple routes from multiple Kind of applications and listeners Right, so that was routes and we can do the same thing with applications Um, so for example, this is now applications. We can do the same thing here unit weather We'll just give the Weather thing and if I want to change the environment environment V So let's change that actually um We can do put here HD So let's actually send something like 002 reconfiguration done when I query now the Let's query the whole application object again That prints now 002 That's a very handy way to reconfigure your application environment like database users passwords Some feature toggles if you want to enable a feature toggle No need of doing that On the server directly make sure you connect to the config endpoint securely And change the environment in any way you want curl is supported Curl is supported Any HTTP client? I mean I have another another test done here with an IntelliJ based implementation So that works Postmove work Any other HTTP client you have will will work in the In the exact same way. So that is the rest configuration here As said you can send config updates to the endpoint Very specific very fine gradated or use the whole json file to send configuration to unit True end to end tls Means that we have the opportunity to or the options to attach the tls to the listener So we decoupled it from all the application Objects and application runtime We support For example, it's java. It is now very very easy to host an HTTPS Encrypted java application or HTTPS enable java application on unit as we moved out the htp configuration Out of the like if you have spring boot Or head spring boot or any tomcat base Configuration it was always painful to do this and with nginx unit. We have the tls now on the router No need to change anything in the java app. No need to add sync to the java keystore. It's all on the router And last but not least I want to tell you a lot more about the nginx unit security capabilities This is for Applications that run on a vm for example, or if you want to run Multiple applications on a single virtual machine or a single server nginx unit can add a lot security capabilities to this to this runtime So first as we already heard end to end tls. We can manage the certificates So that means there is a there's a config endpoint for certificates We can upload certificates to nginx unit nginx unit will parse the certificates We'll read the certificates and there is a certificate endpoint in the api So you can query the cns. You will be able to query the expiration date How long it's valid you can see the root ca that was used to sign the certificate So it makes it very easy and transparent To see what certificates are loaded inside of your unit instance Multi-cert matching with sni Means unit no is based on the incoming host name if sna if if sni is enabled and sni is is a unit Enabled pretty fault You send an hdps request the host name will be in clear text We will read the host name and pick the right certificate Based out of the list of certificates config on unit based on the incoming host name automatically And it's all part of the api. So I said you can query the api the certificates with the config api Application isolation capabilities That sounds right now maybe a little bit too deep but to explain it it is in general the same Idea or the same concept that you will see with docker if you run a container The container is isolated from the Docker demon or the host system of the docker runtime or the container runtime and We apply the same techniques with nginx unit. So we can use The the very simple thing is we have a run user for application so that means you can create users and nginx unit will create processes for the applications that Then will listen or will operate under a given run user like dot dot dot data or unit or any other application user you want to You can think of Then see it root and see groups Is an isolation that we can isolate for example the file system That means that the application process just sees The configured file system as its root If you want so there's no way to step out of this of this isolated file system And the same is this namespaces Uh configuration means that we can isolate the network and process runtime on the on the linux box So given you would from inside of your application You would query the list of processes You will just be able to see the processes that are Under your created namespace. So you're not able to see the processes of all the other applications um On on that box so that adds a lot of security to your Back end in your hosting if you want to use nginx unit to host a lot of Applications of different kind of applications different versions of applications on a single VM because they're all isolated they're if if it's if it's Needed like this you can isolate each and every application in a way that it's not possible for for this application to let's say See other directories of of other applications at all Without having the need of containerize them you can you can put the things In the directory as they are today all right Yeah, that's basically a combination of two things I talked about this and now how to get started on all this as that nginx unit has a couple of resources nginx orchestration unit to see the installation instructions um code and issues are on github so Go to github.com nginx unit um Give us a star. Let's talk about features um issues if you want to try it out if you have any Problems or any questions regard Whatever we are round of github if we are totally appreciate your feedback So let us know what you think we are happy to jump on the conversation. Um We have a community slack Uh from from nginx within with our own channel unit uses there So let's hop over to slack and have a conversation there or if you prefer mailing lists Um, we still have a mailing list. It's the unit at nginx.org and the installation on if you're like very impatient what to do right now. Um If you're on a mac through install nginx unit, uh on linux Configure repository Then up install unit to get started or we have docker images available for the specific languages Like for python php no j s and they are on docker hub You can find them under nginx unit on docker hub and then see the tags Section to see what docker images and what tags are available for the given languages Detailed instructions for all this and we find found on unit nginx org slash installation And they are also a list of all the the docker images. I've just I've just mentioned So that brings me finally to the q&a section. Um, but I think I'll check this There's just one open open question Um, let me read that Will it be possible to configure the java runtime to use each oracle jdk in open jdk 11? Yes, that is possible um So given we have multiple java applications need different languages we can have the Java development or the java runtime environment sorry for 8 and 11 on the single on the same box and the language module will then Do the the mapping accordingly what version needs what java runtime environment? So that is totally possible. Um, you want to try that out feel free if you have any Trouble any problem with it find us on github post your configuration We are more than happy to do this and and show you how that how that works Great. No more open questions If there are no more open questions, um, we are right on time, which is good and Yeah, there are no more open questions. Thank you very much for joining and spending the Last 15 minutes with us and I would like to pass them back to the venice foundation Thank you so much teamo for your time today and thank you everyone for joining us As a reminder, this recording will be on the linux foundation youtube page later today We hope you will join us for future webinars and have a wonderful day