We’ve now successfully deployed our app to PythonAnywhere, but it’s not really production-ready. In this video, we’ll provide some tips on making your app ready to share with the world.
In this video, I'm gonna take my deployed Django project and 0:00 make it more production ready. 0:03 So I'm gonna start by getting some production ready settings. 0:04 A common pattern in Django projects is to have a base settings file, 0:08 which is used for local development, things like that, and a production 0:12 settings file that pulls in the base settings and makes necessary changes. 0:16 To make everything a little easier later on, 0:20 I'm going to make the production settings importable as its own Python module. 0:23 So in my terminal, and I am here just inside 0:29 the deploying_django folder, I'm going to create a new directory and 0:34 then add an init file so that it's a Python module. 0:39 So I'm going to mkdir djangoal/djangoal/deploy_settings. 0:42 And then I'm gonna touch 0:49 djangoal/djangoal/deploy_settings/__init_- _.py. 0:52 So this creates the module directory for the deploy settings, and the init.py, 0:58 that tells Python that it's a module. 1:02 So now I'm going to open up the deploy settings __init__.py in my text editor. 1:05 And you can see this is empty. 1:12 So the first thing I'm gonna do is I'm gonna import all of these settings. 1:15 So I'm going to say from ..settings import *. 1:19 So that'll bring in all, since it's here, I go .. 1:24 to come up to this directory, and it'll bring in this settings.py. 1:27 It'll bring in all of the settings. 1:30 So then I need to turn off debug. 1:32 So we set DEBUG = False, and TEMPLATE_DEBUG is also gonna be, 1:34 it's gonna be set to DEBUG. 1:40 So what this does is, setting it to DEBUG False means that it's running in 1:42 production mode, not debug mode, not development mode. 1:47 And the TEMPLATE_DEBUG being set to whatever debug is set to makes sure that 1:50 the template is running in production mode as well. 1:54 If I deployed this at this point and 1:57 opened it up in the web browser, I would get a Bad Request error, 1:59 because in production mode, Django employs what's called host header validation. 2:04 And any request that's made to a domain that's not in the allowed host list 2:09 is rejected. 2:14 So if you don't put your domain name in the allowed hosts list and 2:15 your web app gets a request, then it goes, well, 2:19 I don't know where this is coming from, and it just ignores it or it rejects it. 2:22 So to make sure that the app can be accessed, 2:26 I'm going to update the ALLOWED_HOSTS setting. 2:30 And it's going to have two items in it. 2:34 So the first one is going to be the string localhost, 2:36 which will allow requests from on the same machine. 2:39 And the second one is going to be .pythonanywhere.com, 2:43 which will allow requests to any domain that end in pythonanywhere.com. 2:47 There's one other potential security issue that needs to be taken care of. 2:53 The base settings file has a secret key for the project, right? 2:58 Right there. 3:04 And that is not good, right? 3:04 That doesn't need to be there. 3:10 So that means that our, oops, sorry, no, it's right here. 3:11 That means that the secret key is on source control, and 3:15 I don't want the secret key to be available on source control. 3:17 So to fix that, I'm gonna use environment variables. 3:19 I've already gone ahead and added this function, but 3:22 I want to point out what the function is. 3:24 The function is right here, it's called get_env_variable. 3:27 So what it does is it tries to find a variable in the environment. 3:30 So in the environment that the web app is running in, it looks for a variable. 3:34 And it looks for whatever variable you've asked for. 3:39 So whatever var_name you put in. 3:41 If it can't find that, then it throws an error message. 3:42 If we're in debug, it just throws a warning, but otherwise, 3:45 it raises an actual configuration error. 3:48 Putting this here into settings.py makes it so iit's available for 3:51 all the other settings files. 3:54 And that includes this one, the deploy settings. 3:56 So in deploy settings, I'm going to add a new line here, 4:00 which is SECRET_KEY = get_env_variable("SECRET_KEY"). 4:05 So that'll go look up the secret key in the environment. 4:14 So while I'm changing the settings files, I want to add one more line. 4:17 This isn't about security, this is for static files. 4:21 In the base settings file, I'm gonna add one more line down at the bottom. 4:26 And I think it's already in there, yeah. 4:30 It's the STATIC_ROOT line. 4:32 So you'll want to go ahead and 4:34 add that STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles'). 4:36 And then, one more in the deploy settings, 4:41 which is STATICFILES_STORAGE= 4:47 "whitenoise.django.GzipManifestStaticFile- sStorage". 4:51 So setting a static route like I did in the settings file gives a place for 5:01 Django to collect our static assets to on the server. 5:05 And setting the static files storage like I've done here lets WhiteNoise make 5:09 some optimizations for us when it handles the static files. 5:14 So with those two changes in place, 5:19 it's time to redeploy the project to Python Anywhere. 5:20 So I will check the status. 5:24 And I will do git add. 5:27 And git commit -m "add deploy settings". 5:30 And then git push origin master. 5:38 And in the Python Anywhere console, I will do a git pull. 5:43 And now those changes are on there, so great. 5:53 But before I can deploy the app again, I need to make a couple of changes to files 5:56 that are already on Python Anywhere to make all of this work. 5:59 So first I need to handle the environment variables that we need, 6:03 the secret key generator, or the security key, rather. 6:08 So to do that, environment variables go into two places in Python Anywhere. 6:11 One of them is the post activate script for the virtualenv. 6:17 Anytime activate is called to step into our virtual EMV, 6:21 post activate gets called immediately after that. 6:23 So I can get a new secret key by going to this website, 6:27 miniwebtoolcom/django-secret-key-genera- tor. 6:30 And I can just click this button to generate a new Django secret key. 6:34 So there's a new key, I'll copy that. 6:39 And then back over here, I'm going to go to the Files tab. 6:43 And then I'm going to click the .virtualenvs directory. 6:47 And then I'm going to click the venv directory. 6:52 And then I'm going to click the bin directory. 6:54 And then there's a file over here named postactivate. 6:58 I'm gonna right-click and open that in a new tab, just so I can keep things up. 7:01 And you may have this line, you may not have this line, you probably won't. 7:06 But you wanna add a line that says export SECRET_KEY, and 7:10 then inside of quotes, you want to add whatever your new secret key is. 7:14 And then you want to hit Save. 7:18 And so what'll happen now is, any time you activate your environment, 7:20 it creates this new secret key. 7:23 So you can close that tab, come back over here to your console. 7:26 And if you type workon venv, it will reactivate the virtual environment. 7:29 And we can check that setting that key worked by doing echo $SECRET_KEY 7:36 all in caps and getting back the secret key that we put in. 7:41 Okay, so because of the way the Python Anywhere works, 7:45 we also need to add it to the WSGI file. 7:49 So I'm gonna go back over here I'm and gonna go back to the Web tab. 7:52 And I want to add the secret key to the OS environment and 7:56 then adjust the WSGI file to use the deploy settings. 8:01 So I need to come down here, I need edit this WSGI file. 8:06 So I'm gonna open that in a new tab as well. 8:11 I'm going to set the secret key. 8:14 So again, os.environ["SECRET_KEY"] = and then the secret key that I copied. 8:16 And then I'm gonna add another line here, which is, or rather, 8:23 I'm gonna change this line. 8:26 You'll have a line that says os.environ.setdefault 8:27 DJANGO_SETTINGS_MODULE. 8:30 And it will almost likely say djangoal.settings. 8:31 You want to change that to djangoal.deploy_settings, deploy_settings. 8:36 So save that. 8:42 And back over here in this tab, you should be able to hit Reload. 8:44 And then let's try refreshing the web app. 8:50 And we get a 500 error. 8:56 If we look down here in the errors. 8:57 Here, I'm gonna scroll all the way to the bottom. 9:03 We see this value error about, the CSS goal could not be found. 9:05 That's because the static files aren't set up correctly. 9:09 So let's see if we can fix that. 9:12 What I want to do is here in the console, I need to collect the static files. 9:15 So I'm at the top directory of the application. 9:20 And if I do an ls, I'll see the manage.py. 9:26 So I want to do Python manage.py collectstatic. 9:29 And then I'm gonna do --settiongs=djangoal.deploy_settings. 9:32 Press Return. 9:41 It's gonna to ask me if I want to collect the files to this location. 9:42 And I want to, so I'm gonna type in yes. 9:46 And it's gonna copy everything over. 9:48 Tons of stuff, 58 files. 9:51 And now, if I refresh this, the site loads, 9:53 because now it knows where the static files are. 9:57 So that wraps it up for this video. 10:02 The Django project that I've deployed is now much more production ready, and 10:04 there's really just one thing left to do. 10:07 So in the next video, I'm gonna be moving the project to use Python Anywhere as my 10:09 SQL database instead of using a SQLite database. 10:14
You need to sign up for Treehouse in order to download course files.Sign up