let's gather around take take your seats and let's continue talking about nginx
unit and how that system can launch and run your applications it's a very
interesting title slide I prepared for you this is literally the only slide for
this talk and I want to introduce first I want to introduce the engineering team
of nginx unit and the whole engineering team is here at the conference it's eager Valentin Maxime and I I just
talked about this all right
basically what we are going to be doing is looking at how nginx unit works in
this in in our environment I will guide you through a creation of I will guide
you through the configuration of unit through the compilation process through
modifying and the change in your go applications to run through the nginx
unit and also I'll show you how to run multiple versions of the application and
multiple versions of application language here all right I already
downloaded the source code you can do that using github mercurial repository
or using just a simple terrible link from our website first let's clean it up
all right and what we have here is our configure
script usually when I launch a configure script first thing I do is launch in the
help and see what we can configure in this in the source code the most important parts here will be the
configuration options for each of our languages before going into the language
configuration first thing I'm gonna do is configure nginx unit itself the
prerequisites for that are quite easy you just need the C tools and
for the languages themselves you will need the the library is the development
kits for PHP Python and languages and forego language you just need the go
package all right now we have it configured and now let's start
configuring our languages we got PHP here and we see that it's been
configured for PHP version 7.0 that is really good and now let's configure it
for Python okay so for python it found a version 2.7 which is installed in the
system but i do know that i installed not only python 2 but also python 3 in
this same environment let's see what I have here lets me let me press tab here I see Python to Python 3 and so on let
me take a look on how configure Python
will show me the options of what I can configure you see we need the Python
config that we can provide directly and the Python config for the version 3 here
will be this one python 3.5 - config which means i can configure this with with the configuration file this one and
now we see that we have a unit module prepared for us for python 3.5 it does
not delete the previous one it just adds another module now we have configured
the sources for PHP version 7 for Python 2.7 and Python 3.5 ok in addition to
that we need to do that for the go language as well let's first take a look
at the parameters we will build it with the default go package which is which
comes with the system which is go 1.6 and if you want to use newer versions
you can specify the parameters here alright let's go with with let's
configure go and that works just well so the first the first thing I want to
build here well let's do make all and compile in the next unit of with the
configuration that we just defined this is not a very long process it just takes
less than a minute to compile it and let's see what we have here now in our
build directory we see a unit daemon which is a binary right here and we got the objects the modules compiled in that
same directory and as I said we got one for Python for the default version for
the version 3.5 and the PHP module all of those modules will be discovered
automatically when a unit runs all right let's do that let's run unit but before
running it let me see what what other options can we do and we can specify for
unit to be non demonized which is important if you want to run it in a
container you can give it the PD log files directory where you put the modules user names and so on another
important parameter that I want to use today will be the control socket since
we talked that unit is fully api controlled and it's it doesn't require a
configuration file the thing we want to use we want to actually connect to a
unit the ways how our infrastructure likes it okay
by default there's going to be a socket file in a file system let's open an HTTP
pool let's open a TCP port and the let's make the API available via HTTP on port
let's say 8 4 4 3 so we're going to use the control parameter and I will put the
IP address in here
because I don't want it to listen on the API on every available public address of the system all right so we just started
the unit daemon with this API control socket okay in the process list on the
bottom of the screen you can easily see that unit launched with launched the
main process and directly in the process line you see where you will be able to
connect for controlling and modifying its configuration it's going to be this
IP and port right here unit immediately creates the controller and router
processes you'll went to the keynote a few minutes ago and we discussed at
length how controller and router processes work together in the unit okay
well the first the first thing we're gonna do is let's see what this API
gives us alright it just gave us an JSON object with listeners and applications
which are not defined at at this point of time it launched empty with a very
fresh and clean configuration and it doesn't listen on any ports and hasn't
launched any application at this moment all right I prepared a a file here with the
configuration and this file has a very very simple very simple listener and
very simple one application defined the application is just PHP info and that
PHP info file is available right here let's let's see the file itself I
haven't I wasn't making any modifications to the PHP file I wasn't
making any modifications to the PHP packages themselves just took them to
the way they are and launching it with the unit
alright well let's let's upload this file using the put method directly into
this API control port well the curl put request we need to specify the file and
our API port alright the first the first thing that we see is the response from
unit that reconfiguration was performed all right let's see what was performed
let's curl the configuration again let's see what's in there and yes we can see
all of that information that we just put into that API directly available okay so
we define the application we define the workers and everything but we are not seeing any application processes here
let's take a look at how our application works and let's open a new tab for that and we have it on port 80 300 here we go
here's our PHP info and we see that our server API is unit right here okay in
the process list you immediately can see that we don't only have the controller
and router process but also this new application process the number of those
application workers the maximum number is what we defined in our adjacent file
in our configuration that we uploaded ok that was pretty easy right let's let's
look at another another application that we prepared here and that application is
a Python app
okay so this JSON file it doesn't have a name of the application it defines a
Python application with a version 3 of Python language a couple of workers and
also you can see that it lists a different user and the end different group parameters here ok let me show you
the application itself the application is really easy all it does here it's just showing us the very simple the
system version ok let's have this demo this Python application that file let's
put this file into our API right here
okay it's port 8 443 now where do we put this file without the full definition of the configuration we need to put it into
the applications and let's give it a name alright we just
defined it as a Python underscore sample and this application is now right there
let's see what we have in our list of applications right now we have our port
80 300 listener we got the application PHP info we got the Python sample our
PHP info application worker it's still there the PHP info page is working
perfectly but now we define some new entity right here okay so what we can do
right now for this application we can either create a different listener and
have it listening on a different port or we can redefine this existing listener
which is part 8300 and see this application the way it works in this environment dynamically without change
in the listener okay let's have a show of hands who wants that application to
run on a new port okay and who wants to redefine the existing port for this new
application okay we redefining the existing port to see the newer to see
how the new application works for that we're gonna do regular under this we're
going to access this object the listeners 8,300 and we're going to
access this parameter application and change its value from PHP info to fight
an underscore sample okay let's do that that's going to be some tricky command
here it's going to be a put request the data of the put request will be a string which is Python underscore sample and
the URL where we will put that will be our listeners URL with the with the ID
of with the ID of the listener and then the parameter will be application
alright we just got that money in here all right we see reconfiguration is done
let's take a look what we have here and yes our application was redefined for this same listener what's interesting in
the process list is that nothing changed here we haven't removed the PHP application
it's just not bound to any listeners at this point and now the thing that we're
gonna do we're gonna refresh the page and here we go we can see that the Python app is running and we can see
that python worker process has been created right here okay at this point
you can see the Python app and PHP are onion at the same time in that same
system and all of those all of them both of
them are onion under different users the PHP user and Python user in this in this
Linux system and we can dynamically manage and dynamically change whatever
whatever we want about this listener and application the there are interesting
use cases for that let's say you want to update your application with a new
version just put the code in a different directory and change the route using
this API or change the listener into a completely new instance of application
or create a new application object in this API test it out with a separate listener just put some minor amounts of
traffic into that a new version of the application once it's ready just swap
the listeners using one API call all of the changes are graceful the connections
are not broken connections are not reset and the listener the listening sockets
are still open it at any point of time if you're changing it so this is this is
fully truly dynamic alright let's let's see what else we have here I prepared a longer file and in this
file what we what we see right here is a bunch of different listeners we got a
PHP application of an application defined in Python version 2 in Python
version 3 and also a very interesting one which is the go hello world
application okay now the goal occations are really really interesting to build
let's go directly into this directory and let's see what we have here as our
hello go app what we did we created the package the go package which is called
unit and we need to add a unit as as the package right here in the code of
our application now instead of using HTTP listen and serve I will use unit
listen and serve right here with the same parameters how that will work if
the application is launched directly it will fall back to the HTTP functionality
of go and it will listen on the port it will be available right now it will be
available the way you usually launch the go applications however if unit will
launch the application if unit will take that binary and and
start it the application will not open an HTTP port instead of that it will be
communicating with unit or router using the shared memory that Iger explained in
the keynote and that system will provide you a consistent HTTP stack across your
applications regardless of the language and the platform that you are using for
these applications alright we already have this hello application compiled
it's a very simple app we have more complicated applications or Iranian in
the demo booth where you can see apps like graph Anna Iranian of with nginx
unit and some other apps as well all right we have it right there and we had
the full JSON file that I'm going to upload the full JSON file that I'm going to upload through the API and it will be
able to launch for different applications PHP two versions of Python
and go alright let's do that I will use the put method I will specify the file
curl command requires the @ symbol before specifying the file and let's put
that in our one two seven zero zero one and the port at which shows right here all right we
got the configuration going since I renamed the applications our Python
sample application was removed and the workers of the Python sample
applications are not there however our PHP application in the full
JSON file was exactly the same PHP application that we started from since
that wasn't a change unit didn't kill any PHP processes it kept them live it
kept them accessible on that same port because that wasn't hurt
that wasn't a change only the Python applications and go applications were
changed in this environment all right let's see all of those applications how
they are working so a port 8300 that's going to be our PHP application here we
go that's PHP seven zero PHP info let's go to the next port which was 8400 8400
was the Python application defined as Python 2.7 version and I had almost
exactly the copy of that at the next port 8401 which is exactly the same
application running in a different version of python you see now the once
we started launching those applications we see the processes coming in and we
got the PI 2 and PI 3 and application now let's open the last one of those
which is the go app and this is a completely different application right
here we can see it in the process list directly all right now what happens if we want to delete some of those apps
well it's very easy you can use the same the same API for cleaning things up we
can use the delete method and we'll apply that delete method directed to the
application and which which application do you want do you want to do
to be to delete right here PHP okay yep what what do you think will happen right now it's invalid we cannot delete it
right now because we have a listener socket bound right now to the same
application let's clean up the listen socket first all right so our PHP
application was leased was listening on the socket that was 8300 this one all
right what happened here is quite interesting as well we deleted the
socket now our port 8300 will not be accessible here we go
the site can be reached the port is not there however in the list of processes
below you can still see the PHP application we only deleted the listener
we only deleted that part that was changed and we were not touching the
rest of the system that is still supposed to be live maybe you want to
run that same PHP application on a different port you just create another
different listener bind it to that same application and your life without
changes and without restarts even of a single app alright now let's try to
delete our PHP application and here we go PHP application is out of here
[Applause] all right so this is this is a really fun system right here and you can create
delete update parts of the application parts of configuration using any any of
those requests that I've shown you really easy to use and really
configurable all of those things are available on on any modern Linux system
and with all of the modern versions of PHP Python and go languages so here's
the thing we started to get a lot of comments and a lot of questions on
social media and even on github and everywhere else so for this session we
wanted to leave more time for your questions and we want to answer all of
those questions right here so we have the whole engineering team as eager Valentin and Maxime right here and
myself for answering the questions all right
let's ask the questions so yes the question was about heaven the the
variables passed from nginx into into unit similar to the PHP fpm similar the
fancy GI params right all right let's let's have the the engineering
team up here and let's let's help answer this question I I must say that many of
your questions will be answered with the words yes we have this planned all right
can we have a portable microphone here
all right well we'll get the microphone right now for because we're getting a
lot of questions let's let's have a microphone here for that oh this this
one is working so it should be configurable of course and we will provide a way how to pass additional
variables using HTTP headers from and the next to unit of course and for now
it populates environment variables according to HTTP requests so if you
want to pass for example IP address from the client connection to nginx you have
to use custom I should be header but eventually I think that you know you
will be able to put nginx unit to the external environment so and don't have
nginx behind unit and in this case there is really no problem at all to populate
all the environment variables it's yes go ahead
yes that's right and they as you can see they use different user and group and
they're isolated and if one process dies so only the request that is served by
this process will be in a failed everything else will be protested is and
what I should mention that and unit rotor process it's not iterated but each
thread is asynchronous like nginx worker process so you have as many traits as
you have course in your system and each thread can handle thousands of
connections like nginx worker process
so the question was how we monitor the health of the workers and how they shut
down at what conditions and how we can control that this is one of the things
that we are planning in a very short term a roadmap right now as having the
pre fork module to pre for pre fork model for creating the workers and
monitoring them using the pretty much standard system level tools as for
memory timeouts and so on this is plan this is a short-term road map yes
sorry I didn't quite and send the question okay so what happens to the
existing configuration okay for now it will just it disappeared but we are
going to add persistence in the short term I think it will be ready in a week
or so so if the main router process or work or master process will die you can
restart unit and it will start with the previous working configuration yes as of
as of right now what you can do is when when you are just when you are making
changes to your configuration it is completely dynamic that the changes
might come from different sources for different reasons
but it gives you a fully consistent view on what the configuration is you can simply a dump that configuration JSON
into a file and that will be your last non-working config of course the
persistence features are very important and that we have them we will have them
done very quickly
[Music]
so we expect users to interact with nginx unit only using this API so we
don't expect them to edit our persistent storage of course you can because it
will be simple JSON and but soon all right yes yep yeah the question was
about securing the API access what I did in this demo I enabled API access only
on localhost on one to seven zero zero one and only through only on one
specific port by default it launches the API in a UNIX domain socket which is only accessible locally in the system
now here's what you can do in addition to that if you go to our website in to
integration with nginx article right here we actually defined how you can see
secure your API using nginx tools we already know how to deliver secure
websites and secure API is in the world and what you can do here you can install
nginx configure access lists configure proxy in into the control socket
directly you can configure client certificate authentication you can have
basic authentication and all of the nginx security tools right in front of
the unit naturally as you would have in front of any API
yeah for now we recommend to use UNIX domain circuits with root credentials
but eventually we are going to add TLS support and client certificates of
terrorization and other whereas other methods of terrorization
to be able to control the privileges and who can manipulate it with this API interface all right all right we got
another question here sorry I couldn't hear this oh chroot environments are we
playing this the chroot environments
and to also watch shall in for Python applications of course