Python for Entrepreneurs Transcripts
Chapter: Deploying to the cloud
Lecture: Using nginx as our web server

Login or purchase this course to watch this video and the rest of the course contents.
0:01 We already installed the package for nginx, as a part of the last video when we were configuring the let's encrypt certificate.
0:08 We need to now configure nginx to serve up traffic via https, and handle any request that come through our domain name.
0:16 In this chapter we're going to create a new yaml file, just for nginx and we're going to introduce a new concept which is known as a template file
0:23 in the template file will have an nginx configuration with a few tokens in it that our Ansible variables will replace,
0:30 and that file will then be copied over to a remote server where nginx can pick up that configuration and use it when responding to traffic.
0:39 First, we're going to create a new yaml file that will serve as a handler. Now a handler for Ansible is typically used
0:46 to stop, start and restart system services whenever we complete some task in one of our playbooks,
0:52 so rtaher than rewriting the same task over and over again to for example restart nginx, we just have a handler
0:59 with one task in that handler file that will restart nginx for us and then there's a special syntax
1:06 we can use at the end of our task to call that handler. Once we write the handler, we'll take a look at that syntax.
1:11 First, we're going to want to go back into our Ansible roles, common and handlers,
1:16 and create a new main.yml file, here we're going to give it a name of restart nginx, we'll use the service module, provide the name of nginx,
1:28 and we'll give it the state of restarted, and we are going to need super user privileges to do that;
1:35 save that file, then go back into tasks and we're going to create an nginx yaml file
1:40 this one will only have three tasks in it, because we've already done a lot of the configuration for nginx, give it a quick comment, close that off,
1:49 and then our first task is we're just going to double check that nginx is installed properly with the way that we've written this current playbook,
1:58 it should always be installed by this point, but I like to have it just in case
2:02 we remove the let's crypt and replaced it with another yaml file, for example.
2:10 We'll use the apt module, and again, we'll need Super User privileges just for this. Our second task is going to be to delete the default nginx file
2:21 that is served up as index.html, we don't want that to appear when users go to our website.
2:28 We are going to use a different module, this one is the file module, we're going to give it a specific path on our remote server,
2:34 and we're going to ensure that it's removed. The state should be absent, as opposed to present. Super User privileges because nginx files are protected
2:45 and then our third task is going to be to write a configuration file this is new with a template file, that we're going to write in a moment
2:53 what Ansible is going to do is to take this configuration template, insert variables where there are tokens,
3:01 and then ensure that that file is on the remote server we'll give it the template module and the source for that
3:08 is going to be nginx sll configuration and the .j2 is for Jinja 2 template. The destination, and this is for the remote server,
3:19 will be in the configuration directory for nginx, we're going to have a new variable that we'll define in a few moments, .configuration.
3:28 We are going to need Super User privileges for this, this is where we're going to use our handler, we'll use the notify syntax,
3:36 we're going to have restart nginx be the handler that we notify. So what does it mean restart nginx here? How does Ansible know what to do with that?
3:48 If we go back to our handler, we can see that the name was specified as a restart nginx, so it's a really expressive way
3:57 where you can give a specific name in your Ansible file, Ansible will fall back to the handler
4:03 and look for that appropriate name that you've specified. Alright, now we need to write our temple file
4:09 what I've done is rather than having me type a whole thing I've copied in the template file that we need and I am going to explain each piece.
4:16 What I recommend is to go to the course demos github repository, and copy this file into your project.
4:22 At first blush this can look like a really complicated file but there's really only three parts to it:
4:28 the first part is where we specify the upstream app server, the wsgi server. This is not running yet, but that's where
4:35 our pyramid application is going to be running, it's going to be running on a different port on our local host system,
4:40 only a service running on our local host is going to be able to access that wsgi server these first three lines set up nginx as a reverse proxy,
4:50 and it knows when certain requests come in, it will forward those requests over to the wsgi server and then it will return back the response
4:58 that is given from the wsgi server, pass that back to the web browser device that sent the request. The second part here is simply for
5:06 web browsers that try to contact our web application not through https, so if they're just using standard http
5:14 what we want to do here is rewrite the url so that they are contacting us via https. http runs on port 80, and that's why we're listening on port 80,
5:25 and then we're essentially just redirecting over to port 443 where we have the rest of our web server configuration running via https,
5:35 that is using the ssl certificate retrieved from let's encrypt. Here's the most complicated part of our nginx configuration
5:42 we have a server name, this is just going to be our fully qualified domain name
5:46 we're listening on port 443, these two lines specify where our SSL certificate lives,
5:51 we specify certain properties about our sessions, time outs and caches, which protocols we support and the ciphers
6:00 and then were specifying that .pem file that we created. We also have some logging that takes place as nginx is running
6:07 and these are the locations for where those log files are stored and then we have two bits down below,
6:13 the first one is how we configure nginx to do what web servers were originally intended to do, which is simply serve up static files.
6:19 Any url to our web server that has /static as the start of its url will not be forwarded to our wsgi server. This is really how we define whether we're
6:31 in web server mode serving up a static file or we're in reverse proxy mode, where we just simply pass on the request
6:38 to the wsgi server and then return the response that the wsgi server gives us.
6:43 That is only defined by if in the url, the url starts with after the domain name /static
6:50 then we're going to go look up and see if we have a file by that name we're going to have a new variable that defines where our application is stored
6:57 and we're going to go look up the static directory within that application and serve up those files.
7:02 Finally, we have the configuration for the reverse proxy where we forward on certain headers to the wsgi server
7:09 and we pass that through and this is what ties together the proxy passes what ties together this part of the configuration
7:15 with what we defined up front, which is the upstream wsgi application server. Ansible is going to take this template, insert the values of variables
7:24 where there are tokens, and then make sure that this file is saved on the remote server. There is one more bit we need to do before we run this,
7:33 and that's just update our variables file. We used a few new variables in this video, the first one is the wsgi server port
7:45 the wsgi server port is specified in our Pyramid configuration, so let's take a look how we can obtain that. Take a look at production.ini
7:56 we're going to have a port number in here, and that port is 6543. That's the port we want to specify for our wsgi server.
8:07 Next up, we're going to specify an application name, and this application name will be used as the directory
8:16 for where our application is going to be cloned once we do our git set up, we'll call it blue yellow,
8:22 and then the application directory, this is going to be an absolute path to where our application is stored on the remote server.
8:28 We'll say home deploy user, and then we'll use the app_name as well for where that source code is stored.
8:41 Those are the files we need, let's go back into the deploy directory, but there's one more thing that we forgot,
8:48 we need to specify that we want to include nginx.yml, as part of our deployment process. Let's go ahead and run the script, run this playbook,
9:01 and it looks like everything ran great, let's test our application. Alright, now at first blush that may seem like it's a really bad thing
9:08 that we get a 502 bad gateway, but that's actually really great we've got some great indicators here that everything worked well.
9:14 The first is that we're using https, and when we went to Python deployment example we were redirected from http to https, DNS records all worked,
9:24 we know that this is being served up from our application and the 502 bad gateway means that when nginx tried to access our web application
9:35 it wasn't up and running, so as soon as we put that in place our application will be served via the reverse proxy.
9:41 These are all good indicators that everything is up and running to this point,
9:44 once we get our source code and run our wsgi server, we'll be in business.

Talk Python's Mastodon Michael Kennedy's Mastodon