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