title
Python Flask Tutorial: Deploying Your Application (Option #1) - Deploy to a Linux Server
description
In this Python Flask Tutorial, we will be learning how to deploy our application to a Linux Server from scratch using Linode.
If you would like $20 of free credit towards a Linode account, then you can use my link here to sign up:
https://linode.com/coreyschafer
We will be covering the entire deployment of a Flask application. This includes spinning up a new Linux Server and tightening its security with SSH keys and firewalls. Then we will install Nginx and Gunicorn so that we can get our Flask App running. Let's get started...
To skip the server setup, jump to 26:48
How to Run Linux/Bash on Windows: https://youtu.be/xzgwDbe7foQ
SSH Key-Based Authentication Tutorial: https://youtu.be/vpk_1gldOAE
SSH Keys on Windows: https://www.linode.com/docs/security/authentication/use-public-key-authentication-with-ssh/#windows
NGINX config used in this video:
https://github.com/CoreyMSchafer/code_snippets/blob/master/Python/Flask_Blog/snippets/nginx.conf
Supervisor config used in this video:
https://github.com/CoreyMSchafer/code_snippets/blob/master/Python/Flask_Blog/snippets/supervisor.conf
✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms
✅ Become a Channel Member:
https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join
✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY
✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot
✅ Corey's Public Amazon Wishlist
http://a.co/inIyro1
✅ Equipment I Use and Books I Recommend:
https://www.amazon.com/shop/coreyschafer
▶️ You Can Find Me On:
My Website - http://coreyms.com/
My Second Channel - https://www.youtube.com/c/coreymschafer
Facebook - https://www.facebook.com/CoreyMSchafer
Twitter - https://twitter.com/CoreyMSchafer
Instagram - https://www.instagram.com/coreymschafer/
#Python #Flask
detail
{'title': 'Python Flask Tutorial: Deploying Your Application (Option #1) - Deploy to a Linux Server', 'heatmap': [{'end': 676.417, 'start': 583.397, 'weight': 0.908}, {'end': 2662.463, 'start': 2608.975, 'weight': 0.706}, {'end': 2925.82, 'start': 2878.362, 'weight': 0.89}, {'end': 3069.003, 'start': 3013.859, 'weight': 0.739}, {'end': 3332.257, 'start': 3239.901, 'weight': 0.74}, {'end': 3555.335, 'start': 3509.884, 'weight': 1}, {'end': 3654.692, 'start': 3596.192, 'weight': 0.721}, {'end': 3960.508, 'start': 3911.195, 'weight': 0.729}], 'summary': "This tutorial covers deploying a flask application to a web server, including setting up a linode server, configuring user permissions, ssh key authentication, and service setup. it also details deploying the flask application, configuring flask, testing functionality, and setting up nginx and gunicorn for high traffic performance, along with managing web processes using supervisor on linux and linode's cloud management system.", 'chapters': [{'end': 292.613, 'segs': [{'end': 30.228, 'src': 'embed', 'start': 0.229, 'weight': 0, 'content': [{'end': 1.271, 'text': "Hey there, how's it going everybody?", 'start': 0.229, 'duration': 1.042}, {'end': 2.132, 'text': 'In this video,', 'start': 1.591, 'duration': 0.541}, {'end': 10.182, 'text': "we're going to be continuing the Flask series and learning how to deploy our Flask application to a web server so that anyone with internet access can use it within a browser.", 'start': 2.132, 'duration': 8.05}, {'end': 16.309, 'text': "So, so far we've created this application with some good functionality, but the site still only lives on our local machine.", 'start': 10.602, 'duration': 5.707}, {'end': 21.977, 'text': 'Right now this is just running in my browser on my local machine, but no one else can access this.', 'start': 16.911, 'duration': 5.066}, {'end': 26.984, 'text': "So the point of building these sites is to deploy them so that they're accessible over the internet.", 'start': 22.418, 'duration': 4.566}, {'end': 30.228, 'text': "Now I'm not going to lie to you, deploying can be a bit tricky.", 'start': 27.284, 'duration': 2.944}], 'summary': 'Continuing flask series, learning to deploy application for internet access.', 'duration': 29.999, 'max_score': 0.229, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co229.jpg'}, {'end': 65.004, 'src': 'embed', 'start': 34.594, 'weight': 2, 'content': [{'end': 38.015, 'text': "and it's hard to know exactly what's best for your specific application.", 'start': 34.594, 'duration': 3.421}, {'end': 41.116, 'text': "So we're going to look at several deployment options in this series.", 'start': 38.375, 'duration': 2.741}, {'end': 47.038, 'text': "So we're going to look at how to deploy to our own Linux server, how to deploy to Heroku, and possibly some others.", 'start': 41.436, 'duration': 5.602}, {'end': 54, 'text': "So in this video, we're going to be learning how to deploy our application to our own Linux server using Nginx and GUnicorn.", 'start': 47.418, 'duration': 6.582}, {'end': 59.522, 'text': 'Now, if you watched my Django series, then I deployed the Django application using Apache and ModWhiskey.', 'start': 54.34, 'duration': 5.182}, {'end': 65.004, 'text': "But the reason I used Apache and ModWhiskey in that video is because it's recommended on Django's site.", 'start': 59.863, 'duration': 5.141}], 'summary': 'Explore deployment options like linux server, heroku; deploy app to linux server using nginx and gunicorn.', 'duration': 30.41, 'max_score': 34.594, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co34594.jpg'}, {'end': 109.811, 'src': 'embed', 'start': 85.495, 'weight': 3, 'content': [{'end': 93.56, 'text': 'And Linode was actually kind enough to sponsor this video as well and has provided me with a link where you all can get $20 of free credit towards an account.', 'start': 85.495, 'duration': 8.065}, {'end': 97.943, 'text': "So if you want to follow along with this video, then I'll leave that link in the description section below,", 'start': 93.921, 'duration': 4.022}, {'end': 100.665, 'text': 'where you can sign up for an account and get enough credit to follow along.', 'start': 97.943, 'duration': 2.722}, {'end': 107.37, 'text': "I've been using their services for my own personal website for years, so I was really happy when they contacted me about sponsoring a video.", 'start': 101.025, 'duration': 6.345}, {'end': 109.811, 'text': "So with that said, let's go ahead and get started.", 'start': 107.87, 'duration': 1.941}], 'summary': 'Linode sponsored the video, offering $20 free credit for account sign-ups.', 'duration': 24.316, 'max_score': 85.495, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co85495.jpg'}, {'end': 190.522, 'src': 'embed', 'start': 156.944, 'weight': 4, 'content': [{'end': 158.524, 'text': 'So there definitely are some trade-offs there.', 'start': 156.944, 'duration': 1.58}, {'end': 163.106, 'text': "So like I said, I'm going to be using Linode to deploy this application to a Linux server.", 'start': 158.904, 'duration': 4.202}, {'end': 169.189, 'text': "So that's my personal preference, but you can do the same deployment with any Linux server that you can access via SSH.", 'start': 163.406, 'duration': 5.783}, {'end': 173.391, 'text': "Now, I already have an account with Linode, so I'm going to pull that up here in the browser.", 'start': 169.589, 'duration': 3.802}, {'end': 176.532, 'text': "So let me reload this page to make sure I'm still logged in.", 'start': 173.711, 'duration': 2.821}, {'end': 181.636, 'text': "Now I'm going to show you how to create and set up a Linux server from scratch because that's what a lot of you have requested.", 'start': 176.992, 'duration': 4.644}, {'end': 186.88, 'text': 'But if you already have a server ready to go and want to skip directly to the Flask specific deployment,', 'start': 181.996, 'duration': 4.884}, {'end': 190.522, 'text': "then I'll put a timestamp in the description section below where you can jump to that part.", 'start': 186.88, 'duration': 3.642}], 'summary': 'Using linode to deploy application to a linux server with ssh access, demonstrating server setup from scratch.', 'duration': 33.578, 'max_score': 156.944, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co156944.jpg'}, {'end': 282.086, 'src': 'embed', 'start': 254.65, 'weight': 6, 'content': [{'end': 258.252, 'text': 'so you probably want to choose a server that is going to be close to your audience.', 'start': 254.65, 'duration': 3.602}, {'end': 262.174, 'text': "so i'm going to choose dallas, texas because it's a nice midpoint in the united states.", 'start': 258.252, 'duration': 3.922}, {'end': 264.575, 'text': 'okay, so now we can choose our linode plan.', 'start': 262.174, 'duration': 2.401}, {'end': 265.876, 'text': 'so these are the standard plans.', 'start': 264.575, 'duration': 1.301}, {'end': 269.558, 'text': 'here you can see some of the computer specs and the prices.', 'start': 265.876, 'duration': 3.682}, {'end': 270.998, 'text': 'so this is ten dollars a month.', 'start': 269.558, 'duration': 1.44}, {'end': 275.401, 'text': 'twenty dollars a month One CPU, 50 gigs of storage, 2 gigs of RAM.', 'start': 270.998, 'duration': 4.403}, {'end': 278.103, 'text': 'They also have something here called a Nano.', 'start': 276.202, 'duration': 1.901}, {'end': 282.086, 'text': "Now, this is a low-performance machine, but it's also a cheaper option.", 'start': 278.483, 'duration': 3.603}], 'summary': 'Choose dallas, texas server for proximity. $20 plan: 1 cpu, 50gb storage, 2gb ram', 'duration': 27.436, 'max_score': 254.65, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co254650.jpg'}], 'start': 0.229, 'title': 'Flask application deployment', 'summary': 'Focuses on deploying a flask application to a web server, highlighting challenges and deployment options, including deploying to a linux server using nginx and gunicorn. it also discusses deploying to a linux server using linode, which offers $20 free credit for sign-up, and provides detailed guidance on server setup.', 'chapters': [{'end': 69.226, 'start': 0.229, 'title': 'Flask application deployment', 'summary': 'Focuses on deploying a flask application to a web server to make it accessible over the internet, highlighting the challenges and different deployment options, including deploying to a linux server using nginx and gunicorn.', 'duration': 68.997, 'highlights': ['The chapter emphasizes the importance of deploying a Flask application to make it accessible over the internet, addressing the challenges and complexities of deployment with multiple options discussed. It emphasizes the focus on deploying to a Linux server using Nginx and GUnicorn.', 'Deploying a Flask application to a web server is essential for making it accessible over the internet, with the video aiming to provide guidance on deploying to a Linux server using Nginx and GUnicorn, emphasizing the differences from deploying a Django application.', 'The video discusses the challenges and overwhelming nature of deployment, highlighting the various ways to deploy an application and the difficulty in determining the best approach for a specific application, setting the stage for exploring different deployment options including deploying to a Linux server and Heroku.']}, {'end': 292.613, 'start': 69.686, 'title': 'Deploying to a linux server with linode', 'summary': 'Discusses deploying to a linux server using linode, which offers $20 free credit for sign-up, and provides detailed guidance on setting up a linux server from scratch, including choosing an image, region, and plan.', 'duration': 222.927, 'highlights': ['Linode offers $20 of free credit towards an account for signing up, and the speaker personally uses Linode for web applications.', 'Detailed guidance is provided on creating and setting up a Linux server from scratch, including choosing an image, region, and plan.', 'The chapter emphasizes the flexibility and control offered by deploying to a Linux server, highlighting the trade-offs and benefits compared to other deployment methods.', 'The speaker discusses the standard plans offered by Linode, including the pricing and specifications of each plan.']}], 'duration': 292.384, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co229.jpg', 'highlights': ['The chapter emphasizes the importance of deploying a Flask application to make it accessible over the internet, addressing the challenges and complexities of deployment with multiple options discussed.', 'Deploying a Flask application to a web server is essential for making it accessible over the internet, with the video aiming to provide guidance on deploying to a Linux server using Nginx and GUnicorn, emphasizing the differences from deploying a Django application.', 'The video discusses the challenges and overwhelming nature of deployment, highlighting the various ways to deploy an application and the difficulty in determining the best approach for a specific application, setting the stage for exploring different deployment options including deploying to a Linux server and Heroku.', 'Linode offers $20 of free credit towards an account for signing up, and the speaker personally uses Linode for web applications.', 'Detailed guidance is provided on creating and setting up a Linux server from scratch, including choosing an image, region, and plan.', 'The chapter emphasizes the flexibility and control offered by deploying to a Linux server, highlighting the trade-offs and benefits compared to other deployment methods.', 'The speaker discusses the standard plans offered by Linode, including the pricing and specifications of each plan.']}, {'end': 676.417, 'segs': [{'end': 329.383, 'src': 'embed', 'start': 292.613, 'weight': 4, 'content': [{'end': 296.055, 'text': "I'm just going to choose this cheapest option because it's not going to take a lot of resources.", 'start': 292.613, 'duration': 3.442}, {'end': 298.036, 'text': "Okay, so now let's choose a label.", 'start': 296.435, 'duration': 1.601}, {'end': 301.719, 'text': "So I'm just going to call this Flask-Server.", 'start': 298.357, 'duration': 3.362}, {'end': 305.062, 'text': "And I'm going to skip and not add any tags here.", 'start': 302.419, 'duration': 2.643}, {'end': 307.264, 'text': "And now we're going to add a root password.", 'start': 305.442, 'duration': 1.822}, {'end': 313.529, 'text': "So I'm going to add a root password of just this is a test with some capitalization in there.", 'start': 307.564, 'duration': 5.965}, {'end': 318.553, 'text': "But you're going to want a stronger root password, obviously, for your own server.", 'start': 314.37, 'duration': 4.183}, {'end': 324.979, 'text': "Now, you're definitely going to want to remember this password as well, because this is what you're going to use to first log in to the system.", 'start': 318.894, 'duration': 6.085}, {'end': 329.383, 'text': 'Now you can see that they have some optional add-ons here such as backups and private IP.', 'start': 325.279, 'duration': 4.104}], 'summary': 'Choosing the cheapest option, setting a root password, considering optional add-ons.', 'duration': 36.77, 'max_score': 292.613, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co292613.jpg'}, {'end': 392.517, 'src': 'embed', 'start': 348.736, 'weight': 0, 'content': [{'end': 351.917, 'text': 'And after it provisions it, then it will boot the server up.', 'start': 348.736, 'duration': 3.181}, {'end': 355.198, 'text': "So I'm going to skip forward to where this is complete.", 'start': 352.337, 'duration': 2.861}, {'end': 358.359, 'text': 'So I will resume once this is finished.', 'start': 355.958, 'duration': 2.401}, {'end': 362.681, 'text': 'Okay, so our new server has finished booting up and that only took a couple of minutes.', 'start': 359.019, 'duration': 3.662}, {'end': 366.082, 'text': 'So now we can see it here in our list of Linodes.', 'start': 363.381, 'duration': 2.701}, {'end': 371.165, 'text': 'If we go to dashboard, then we can also see the Linode server listed there as well.', 'start': 366.403, 'duration': 4.762}, {'end': 377.548, 'text': 'So now all we need to do is click on this server and then go to the networking tab.', 'start': 372.045, 'duration': 5.503}, {'end': 381.87, 'text': "And once you're in the networking tab, you can see here that we have this SSH command.", 'start': 378.008, 'duration': 3.862}, {'end': 385.892, 'text': "So this SSH command is how we're going to first access our machine.", 'start': 382.25, 'duration': 3.642}, {'end': 392.517, 'text': "Now you're going to want to write down this IP address because we're going to be using that a lot throughout this video.", 'start': 386.753, 'duration': 5.764}], 'summary': 'New server booted up in a few minutes, accessed via ssh command with ip address.', 'duration': 43.781, 'max_score': 348.736, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co348736.jpg'}, {'end': 561.774, 'src': 'embed', 'start': 537.926, 'weight': 1, 'content': [{'end': 544.51, 'text': "I'm going to minimize this terminal here on the right and expand this over to where we have some more room to work with here.", 'start': 537.926, 'duration': 6.584}, {'end': 547.811, 'text': "Okay, so now we're working with a bare bones Ubuntu server.", 'start': 544.93, 'duration': 2.881}, {'end': 551.311, 'text': "So we're going to want to do a couple of things to get this set up first.", 'start': 548.111, 'duration': 3.2}, {'end': 557.493, 'text': "So first of all, let's upgrade the software and this is going to be like security updates and stuff like that.", 'start': 551.732, 'duration': 5.761}, {'end': 561.774, 'text': "You're going to want to always do this the first time you log into a Linux system.", 'start': 557.733, 'duration': 4.041}], 'summary': 'Setting up a bare bones ubuntu server, upgrading software for security.', 'duration': 23.848, 'max_score': 537.926, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co537926.jpg'}, {'end': 676.417, 'src': 'heatmap', 'start': 583.397, 'weight': 0.908, 'content': [{'end': 589.459, 'text': 'okay. so i fast forward to where those updates and upgrades were complete and that took a couple of minutes.', 'start': 583.397, 'duration': 6.062}, {'end': 593.04, 'text': "so now we're going to want to set our host name on this machine.", 'start': 589.459, 'duration': 3.581}, {'end': 596.442, 'text': "so i'm going to clear my screen here and now to set this host name.", 'start': 593.04, 'duration': 3.402}, {'end': 600.783, 'text': "i'm going to say host name, ctl.", 'start': 596.442, 'duration': 4.341}, {'end': 606.245, 'text': "set dash host name and i'm just going to call this flask dash server.", 'start': 600.783, 'duration': 5.462}, {'end': 610.969, 'text': 'so now, if i actually type in a host name, then it should say flask server there.', 'start': 606.245, 'duration': 4.724}, {'end': 611.71, 'text': "So that's good.", 'start': 611.049, 'duration': 0.661}, {'end': 616.036, 'text': 'So now we also need to set this host name and our host file.', 'start': 612.491, 'duration': 3.545}, {'end': 622.885, 'text': "So to do that, I'm just going to use the program nano since nano is an easy editor that a lot of people know how to use.", 'start': 616.416, 'duration': 6.469}, {'end': 625.688, 'text': "So I'm just going to say nano forward slash etc.", 'start': 623.225, 'duration': 2.463}, {'end': 634.376, 'text': "forward slash host and within this host file we're going to want right under our 127.0.", 'start': 626.309, 'duration': 8.067}, {'end': 639.04, 'text': "0.1. we're going to want to put in our IP address of this machine.", 'start': 634.376, 'duration': 4.664}, {'end': 642.623, 'text': "so I said to write that down because you're going to be using it a lot.", 'start': 639.04, 'duration': 3.583}, {'end': 645.936, 'text': 'mine was 45.33..', 'start': 642.623, 'duration': 3.313}, {'end': 653.35, 'text': "123.214 And after that, then we're going to want to hit tab and then put in our host name again.", 'start': 645.936, 'duration': 7.414}, {'end': 656.211, 'text': 'So I called mine flask-server.', 'start': 653.69, 'duration': 2.521}, {'end': 660.132, 'text': 'And now to save this in nano, you hit control X to exit.', 'start': 656.631, 'duration': 3.501}, {'end': 661.952, 'text': "And then it's going to ask you if you want to save.", 'start': 660.532, 'duration': 1.42}, {'end': 664.193, 'text': "So I'm going to hit Y for a yes.", 'start': 662.092, 'duration': 2.101}, {'end': 666.414, 'text': 'And then the file name that you want to write.', 'start': 664.613, 'duration': 1.801}, {'end': 669.055, 'text': 'If you just want to keep the same file name, then you just hit enter.', 'start': 666.494, 'duration': 2.561}, {'end': 673.836, 'text': 'So now that saved that host name to our host file.', 'start': 669.555, 'duration': 4.281}, {'end': 676.417, 'text': 'Okay, so now let me clear my screen here.', 'start': 674.196, 'duration': 2.221}], 'summary': "Set host name to 'flask-server' and ip address to 45.33.123.214 using nano editor.", 'duration': 93.02, 'max_score': 583.397, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co583397.jpg'}, {'end': 625.688, 'src': 'embed', 'start': 600.783, 'weight': 2, 'content': [{'end': 606.245, 'text': "set dash host name and i'm just going to call this flask dash server.", 'start': 600.783, 'duration': 5.462}, {'end': 610.969, 'text': 'so now, if i actually type in a host name, then it should say flask server there.', 'start': 606.245, 'duration': 4.724}, {'end': 611.71, 'text': "So that's good.", 'start': 611.049, 'duration': 0.661}, {'end': 616.036, 'text': 'So now we also need to set this host name and our host file.', 'start': 612.491, 'duration': 3.545}, {'end': 622.885, 'text': "So to do that, I'm just going to use the program nano since nano is an easy editor that a lot of people know how to use.", 'start': 616.416, 'duration': 6.469}, {'end': 625.688, 'text': "So I'm just going to say nano forward slash etc.", 'start': 623.225, 'duration': 2.463}], 'summary': "Setting up the host name as 'flask dash server' using nano editor.", 'duration': 24.905, 'max_score': 600.783, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co600783.jpg'}], 'start': 292.613, 'title': 'Setting up server with flask and linode', 'summary': 'Covers setting up a server with flask, including naming the server as flask-server, and creating a linode server, from provisioning to upgrading software, highlighting ssh command, server boot-up time, and host name configuration.', 'chapters': [{'end': 329.383, 'start': 292.613, 'title': 'Setting up a server with flask', 'summary': 'Details the process of setting up a server with flask, including choosing the cheapest option, naming the server as flask-server, setting a root password, and considering optional add-ons like backups and private ip.', 'duration': 36.77, 'highlights': ['Choosing the cheapest option to minimize resource usage.', 'Naming the server as Flask-Server.', 'Adding a root password for server security.', 'Considering optional add-ons like backups and private IP.']}, {'end': 676.417, 'start': 329.943, 'title': 'Creating and setting up a linode server', 'summary': 'Details the process of creating a linode server, from provisioning and booting up to setting up the host name and upgrading software, highlighting the ssh command, server boot-up time, and host name configuration.', 'duration': 346.474, 'highlights': ['The new server finished booting up in just a couple of minutes, demonstrating the efficient provisioning process.', 'The SSH command provided in the networking tab is essential for accessing the machine and should be written down for frequent use.', 'The process of updating and upgrading the software on the server was completed in a couple of minutes, emphasizing the importance of this initial setup step.', "Setting the host name using 'hostnamectl set-hostname' and editing the host file using 'nano' to include the IP address and host name are crucial steps in configuring the server for use."]}], 'duration': 383.804, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co292613.jpg', 'highlights': ['The new server finished booting up in just a couple of minutes, demonstrating the efficient provisioning process.', 'The process of updating and upgrading the software on the server was completed in a couple of minutes, emphasizing the importance of this initial setup step.', "Setting the host name using 'hostnamectl set-hostname' and editing the host file using 'nano' to include the IP address and host name are crucial steps in configuring the server for use.", 'The SSH command provided in the networking tab is essential for accessing the machine and should be written down for frequent use.', 'Choosing the cheapest option to minimize resource usage.', 'Naming the server as Flask-Server.', 'Adding a root password for server security.', 'Considering optional add-ons like backups and private IP.']}, {'end': 1259.62, 'segs': [{'end': 725.165, 'src': 'embed', 'start': 676.957, 'weight': 0, 'content': [{'end': 680.14, 'text': "Now we're going to want to add a limited user to our machine.", 'start': 676.957, 'duration': 3.183}, {'end': 683.182, 'text': "So right now we're logged in as the root user.", 'start': 680.52, 'duration': 2.662}, {'end': 688.667, 'text': 'Now the root user has unlimited privileges and can execute any command.', 'start': 683.542, 'duration': 5.125}, {'end': 697.314, 'text': "Now that might sound nice, but it's best practice to add a new user that has limited privileges that you use as your main account,", 'start': 689.007, 'duration': 8.307}, {'end': 700.356, 'text': "and you'll still be able to run admin commands using sudo.", 'start': 697.314, 'duration': 3.042}, {'end': 703.599, 'text': "It's just a lot more safe than running everything as root.", 'start': 700.656, 'duration': 2.943}, {'end': 710.301, 'text': 'so to do this, we can just say add user and now the username of the user that you want to add.', 'start': 704.119, 'duration': 6.182}, {'end': 717.283, 'text': "i'm going to add mine as core ems, but you want to add whatever yours is here now again.", 'start': 710.301, 'duration': 6.982}, {'end': 725.165, 'text': "okay, so now it's asking us for our password, so i'm just going to put in something like this is a test.", 'start': 717.283, 'duration': 7.882}], 'summary': "Adding a limited user for safety; root user has unlimited privileges; new user 'core ems' created", 'duration': 48.208, 'max_score': 676.957, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co676957.jpg'}, {'end': 816.462, 'src': 'embed', 'start': 768.23, 'weight': 3, 'content': [{'end': 775.516, 'text': "So I'm going to do add user Cori, ms., and then after that do sudo and that will add them.", 'start': 768.23, 'duration': 7.286}, {'end': 778.838, 'text': 'it says here adding core ems to the group sudo.', 'start': 775.516, 'duration': 3.322}, {'end': 780.019, 'text': "so that's good, okay.", 'start': 778.838, 'duration': 1.181}, {'end': 787.786, 'text': "so now that we've created this new user, now we're going to want to log out of the our server and log back in as that user,", 'start': 780.019, 'duration': 7.767}, {'end': 792.029, 'text': "because we don't want to be logged in as root longer than we have to.", 'start': 787.786, 'duration': 4.243}, {'end': 795.452, 'text': "it's just best practice to be logged in as a limited user.", 'start': 792.029, 'duration': 3.423}, {'end': 800.635, 'text': "so i'm going to exit out of our server And now I'm back on my local machine.", 'start': 795.452, 'duration': 5.183}, {'end': 806.457, 'text': "So I'm just going to hit the up arrow to run that same SSH command that we ran before.", 'start': 800.955, 'duration': 5.502}, {'end': 811.72, 'text': 'But instead of root, we are going to log in as the user that we created.', 'start': 806.858, 'duration': 4.862}, {'end': 816.462, 'text': "So I'm going to log in as Corey MS. And it's going to ask us for a password.", 'start': 812.02, 'duration': 4.442}], 'summary': 'Added user corey ms to the sudo group and logged in as the new user.', 'duration': 48.232, 'max_score': 768.23, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co768230.jpg'}, {'end': 899.322, 'src': 'embed', 'start': 872.289, 'weight': 6, 'content': [{'end': 879.773, 'text': "So when it comes to these SSH keys, By default, we're using a password to log into our web server, just like we just now did.", 'start': 872.289, 'duration': 7.484}, {'end': 882.655, 'text': 'We instead want to use key-based authentication.', 'start': 880.194, 'duration': 2.461}, {'end': 889.157, 'text': "So this is more secure and also more convenient because it uses keys that can't be brute forced.", 'start': 883.095, 'duration': 6.062}, {'end': 899.322, 'text': 'And it also allows us to log in without putting in our password every time, which is great for running remote scripts that connect to your web server.', 'start': 889.678, 'duration': 9.644}], 'summary': 'Switch to ssh key authentication for more security and convenience.', 'duration': 27.033, 'max_score': 872.289, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co872289.jpg'}, {'end': 1066.311, 'src': 'embed', 'start': 1039.666, 'weight': 4, 'content': [{'end': 1044.351, 'text': "Okay, so now that we've created that, it says that your identification has been saved.", 'start': 1039.666, 'duration': 4.685}, {'end': 1047.414, 'text': 'And we got this ID RSA file.', 'start': 1044.771, 'duration': 2.643}, {'end': 1052.139, 'text': 'And we also got this ID RSA dot pub, that is our public key.', 'start': 1047.714, 'duration': 4.425}, {'end': 1056.623, 'text': "Now we're going to want to move our public key to our server.", 'start': 1052.539, 'duration': 4.084}, {'end': 1059.686, 'text': "So to do this, I'm going to clear my screen here.", 'start': 1056.983, 'duration': 2.703}, {'end': 1066.311, 'text': "To do this on Bash, I'm going to use the scp command, which I believe stands for secure copy.", 'start': 1060.306, 'duration': 6.005}], 'summary': 'Created id rsa file and id rsa dot pub for secure copy to server', 'duration': 26.645, 'max_score': 1039.666, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1039665.jpg'}], 'start': 676.957, 'title': 'User configuration and ssh key authentication', 'summary': 'Covers adding a limited user with sudo privileges for security and details the process of setting up ssh key-based authentication on ubuntu, emphasizing its importance for deploying real-world applications on a web server.', 'chapters': [{'end': 747.477, 'start': 676.957, 'title': 'Adding limited user to machine', 'summary': 'Covers the process of adding a limited user to the machine, emphasizing the importance of using a new user with limited privileges for better security, and the use of sudo for admin commands. it also details the steps involved in adding a new user and providing optional user information.', 'duration': 70.52, 'highlights': ["The root user has unlimited privileges and can execute any command, but it's best practice to add a new user with limited privileges for increased safety.", 'Adding a new user with limited privileges and using sudo for admin commands is a safer practice than running everything as root.', "The process involves using the 'add user' command followed by the desired username and providing optional user information such as full name."]}, {'end': 1259.62, 'start': 747.857, 'title': 'Setting up ssh key-based authentication', 'summary': 'Covers setting up ssh key-based authentication on ubuntu, including adding a user to the sudo group, logging in as the new user, and copying the public key to the server, emphasizing the importance of these security measures for deploying a real-world application on a web server.', 'duration': 511.763, 'highlights': ["Creating a new user 'Corey MS' and adding them to the sudo group for admin privileges. User 'Corey MS' added to the sudo group for admin privileges.", 'Emphasizing best practice of logging in as a limited user instead of root and the significance of setting up SSH key-based authentication for security measures. Importance of logging in as a limited user and setting up SSH key-based authentication for security measures.', 'Demonstrating the process of creating and copying SSH keys to the server using the scp command. Demonstration of creating and copying SSH keys to the server using the scp command.']}], 'duration': 582.663, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co676957.jpg', 'highlights': ['Adding a new user with limited privileges and using sudo for admin commands is a safer practice than running everything as root.', "The root user has unlimited privileges and can execute any command, but it's best practice to add a new user with limited privileges for increased safety.", "The process involves using the 'add user' command followed by the desired username and providing optional user information such as full name.", 'Emphasizing best practice of logging in as a limited user instead of root and the significance of setting up SSH key-based authentication for security measures.', 'Demonstration of creating and copying SSH keys to the server using the scp command.', "Creating a new user 'Corey MS' and adding them to the sudo group for admin privileges. User 'Corey MS' added to the sudo group for admin privileges.", 'Importance of logging in as a limited user and setting up SSH key-based authentication for security measures.']}, {'end': 1598.816, 'segs': [{'end': 1288.715, 'src': 'embed', 'start': 1260.341, 'weight': 0, 'content': [{'end': 1263.122, 'text': "And the last one here is for everyone else, and that's a 0 as well.", 'start': 1260.341, 'duration': 2.781}, {'end': 1268.944, 'text': "And here we're saying that we want 600 permissions for the owner,", 'start': 1264.782, 'duration': 4.162}, {'end': 1273.726, 'text': 'zero permissions for the group and zero permissions for everyone else on the files in that directory.', 'start': 1268.944, 'duration': 4.782}, {'end': 1280.329, 'text': 'Okay, so, with those changes in place, we should now be able to log in to this server without a password,', 'start': 1274.126, 'duration': 6.203}, {'end': 1284.151, 'text': "and instead it's going to use our public and private SSH keys.", 'start': 1280.329, 'duration': 3.822}, {'end': 1288.715, 'text': "So if I exit out of the server here, now we're back on our local machine.", 'start': 1284.552, 'duration': 4.163}], 'summary': 'Directory permissions set to 600 for owner, 0 for group and others. ssh keys used for passwordless login.', 'duration': 28.374, 'max_score': 1260.341, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1260341.jpg'}, {'end': 1341.777, 'src': 'embed', 'start': 1304.888, 'weight': 1, 'content': [{'end': 1306.99, 'text': "That means that we're using our SSH keys.", 'start': 1304.888, 'duration': 2.102}, {'end': 1313.157, 'text': "Okay, so we're just about ready to start moving up our Flask application, but there's just a couple more things that we need to do here.", 'start': 1307.431, 'duration': 5.726}, {'end': 1320.204, 'text': 'So now that we have our SSH keys working, we also need to disallow root logins over SSH.', 'start': 1313.557, 'duration': 6.647}, {'end': 1329.189, 'text': "So now that we're logged in as our user, let's do an update on this SSH config file.", 'start': 1320.604, 'duration': 8.585}, {'end': 1341.777, 'text': "So I'm going to do a sudo nano, and this is within forward slash etc, forward slash ssh, forward slash sshd underscore config.", 'start': 1329.469, 'duration': 12.308}], 'summary': 'Configuring ssh keys and disallowing root logins over ssh for flask application deployment.', 'duration': 36.889, 'max_score': 1304.888, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1304888.jpg'}, {'end': 1447.279, 'src': 'embed', 'start': 1398.133, 'weight': 2, 'content': [{'end': 1406.499, 'text': 'So the reason behind this is that now that we have our SSH keys working, Sometimes hackers will just, you know, simply try to brute force passwords.', 'start': 1398.133, 'duration': 8.366}, {'end': 1413.707, 'text': "But since we have our SSH keys, we shouldn't have the need to log into our system with a password.", 'start': 1406.779, 'duration': 6.928}, {'end': 1416.69, 'text': "So I'm going to put password authentication to no.", 'start': 1414.027, 'duration': 2.663}, {'end': 1419.814, 'text': "So now to save this, I'm just going to hit control X.", 'start': 1417.031, 'duration': 2.783}, {'end': 1424.058, 'text': 'and then a y to save and then enter to keep the same file name.', 'start': 1420.334, 'duration': 3.724}, {'end': 1426.721, 'text': 'And now we want to restart our SSH service.', 'start': 1424.318, 'duration': 2.403}, {'end': 1433.908, 'text': "So to do that we can say sudo systemctl restart and that's sshd.", 'start': 1426.901, 'duration': 7.007}, {'end': 1437.572, 'text': "So let's run that and that restarts our SSH service.", 'start': 1434.308, 'duration': 3.264}, {'end': 1446.038, 'text': 'Okay, so now before we get to the flask deployment, we are going to set up a firewall, but this is going to be very quick here.', 'start': 1438.212, 'duration': 7.826}, {'end': 1447.279, 'text': 'This is pretty simple.', 'start': 1446.099, 'duration': 1.18}], 'summary': 'Configured ssh keys to prevent password brute force attacks and restarted ssh service. setting up firewall next.', 'duration': 49.146, 'max_score': 1398.133, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1398133.jpg'}, {'end': 1548.764, 'src': 'embed', 'start': 1502.904, 'weight': 4, 'content': [{'end': 1510.727, 'text': 'because configuring a default deny rule, like we just did, can lock you out of your server unless you use explicit allow rules.', 'start': 1502.904, 'duration': 7.823}, {'end': 1522.87, 'text': 'So we want to be sure that we have configured these next allow rules to allow for SSH and HTTP and things like that and any port that we want to access from the outside of our server.', 'start': 1511.127, 'duration': 11.743}, {'end': 1527.832, 'text': "So I'm going to say sudo ufw allow ssh.", 'start': 1523.21, 'duration': 4.622}, {'end': 1534.253, 'text': "Now this one is definitely important because if we don't allow SSH, then we're not going to be able to SSH into our server.", 'start': 1527.932, 'duration': 6.321}, {'end': 1536.034, 'text': 'So you definitely want to do that one.', 'start': 1534.293, 'duration': 1.741}, {'end': 1541.398, 'text': "So now let's also allow access to port 5000 for now.", 'start': 1536.814, 'duration': 4.584}, {'end': 1548.764, 'text': 'Now port 5000, if you remember from earlier in the series, is the port that FLAS development server runs on.', 'start': 1541.719, 'duration': 7.045}], 'summary': 'Configured default deny rule, allowed ssh and port 5000 for server access.', 'duration': 45.86, 'max_score': 1502.904, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1502904.jpg'}, {'end': 1604.401, 'src': 'embed', 'start': 1576.54, 'weight': 5, 'content': [{'end': 1580.581, 'text': "So right now I'm going to enable everything that we have just set.", 'start': 1576.54, 'duration': 4.041}, {'end': 1583.782, 'text': "So I'm going to do a sudo ufw enable and run that.", 'start': 1580.721, 'duration': 3.061}, {'end': 1587.345, 'text': 'and it says that the command may disrupt existing connections.', 'start': 1584.262, 'duration': 3.083}, {'end': 1592.39, 'text': "Hopefully, we remembered to allow SSH connections, so I'm just going to say yes.", 'start': 1587.685, 'duration': 4.705}, {'end': 1594.532, 'text': "Okay, so we're still logged in, so that's good.", 'start': 1592.93, 'duration': 1.602}, {'end': 1598.816, 'text': "Now, if you want to see the status of the things that you've allowed and disallowed,", 'start': 1594.912, 'duration': 3.904}, {'end': 1604.401, 'text': "you can go to sudo ufw status and that'll show you everything that we've allowed.", 'start': 1598.816, 'duration': 5.585}], 'summary': 'Enabling firewall using sudo ufw, ensuring ssh connections allowed.', 'duration': 27.861, 'max_score': 1576.54, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1576540.jpg'}], 'start': 1260.341, 'title': 'Ssh key configuration and service setup', 'summary': "Covers configuring ssh keys with 600 owner permissions, allowing passwordless login, and disallowing root logins. it also includes setting up the ssh service with 'sudo systemctl restart sshd' and configuring the ufw to allow outgoing traffic and specific ports.", 'chapters': [{'end': 1419.814, 'start': 1260.341, 'title': 'Configuring ssh keys and disallowing root logins', 'summary': "Covers configuring ssh keys for 600 permissions for the owner and 0 permissions for group and others, allowing login without a password, and disallowing root logins over ssh by updating ssh config file with 'permit root login' set to 'no' and 'password authentication' set to 'no'.", 'duration': 159.473, 'highlights': ['Configuring SSH keys with 600 permissions for owner and 0 permissions for group and others Specifies the permission settings for the owner, group, and others on the files in the directory as 600 for the owner and 0 for the group and others.', 'Allowing login without a password using SSH keys Demonstrates the successful login to the server without a password using public and private SSH keys.', "Disallowing root logins over SSH by updating SSH config file Updates the SSH configuration file to disallow root logins by setting 'permit root login' to 'no' and 'password authentication' to 'no' to enhance security and prevent unauthorized access."]}, {'end': 1598.816, 'start': 1420.334, 'title': 'Setting up ssh service and firewall', 'summary': "Covers setting up the ssh service with 'sudo systemctl restart sshd' and configuring the uncomplicated firewall (ufw) to allow outgoing traffic and specific ports like ssh and port 5000 for flask development server.", 'duration': 178.482, 'highlights': ["Setting up SSH service with 'sudo systemctl restart sshd' is crucial for establishing secure connections to the server.", 'Configuring the uncomplicated firewall (UFW) to allow outgoing traffic is essential for enabling communication from the server to external sources.', 'Allowing access to port 5000 for the flask development server is important for testing before going live on port 80.', "Enabling specific ports like SSH and port 5000 using 'sudo ufw allow' commands ensures that the server allows connections through these designated ports.", "Using 'sudo ufw enable' command to activate the configured rules and enable the firewall to protect the server from unauthorized access."]}], 'duration': 338.475, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1260341.jpg', 'highlights': ['Configuring SSH keys with 600 permissions for owner and 0 permissions for group and others', 'Disallowing root logins over SSH by updating SSH config file', 'Allowing login without a password using SSH keys', "Setting up SSH service with 'sudo systemctl restart sshd' is crucial for establishing secure connections to the server", 'Configuring the uncomplicated firewall (UFW) to allow outgoing traffic is essential for enabling communication from the server to external sources', "Using 'sudo ufw enable' command to activate the configured rules and enable the firewall to protect the server from unauthorized access", "Enabling specific ports like SSH and port 5000 using 'sudo ufw allow' commands ensures that the server allows connections through these designated ports", 'Allowing access to port 5000 for the flask development server is important for testing before going live on port 80']}, {'end': 2031.919, 'segs': [{'end': 1665.679, 'src': 'embed', 'start': 1622.836, 'weight': 0, 'content': [{'end': 1629.902, 'text': 'So if we have it checked into a Git repository, then we could simply do a Git clone here into our server.', 'start': 1622.836, 'duration': 7.066}, {'end': 1637.35, 'text': "If you're using an FTP client like FileZilla, then you can just simply copy it over to your server.", 'start': 1631.043, 'duration': 6.307}, {'end': 1644.057, 'text': "Since we're already using the command line in this video, I'm just going to use the bash terminal to do this.", 'start': 1638.091, 'duration': 5.966}, {'end': 1647.201, 'text': "So I'm going to clear my screen here on my server.", 'start': 1644.418, 'duration': 2.783}, {'end': 1651.506, 'text': 'And now let me open up my terminal here on my local machine.', 'start': 1647.601, 'duration': 3.905}, {'end': 1655.349, 'text': 'Now, before we push our Flask application to our server.', 'start': 1651.926, 'duration': 3.423}, {'end': 1660.735, 'text': "if we're using a virtual environment, then we're going to want to create a requirements.txt.", 'start': 1655.349, 'duration': 5.386}, {'end': 1665.679, 'text': 'file that captures everything that we need to install for our Flash project to work.', 'start': 1660.735, 'duration': 4.944}], 'summary': 'Using git or ftp to transfer files, creating requirements.txt for flask project.', 'duration': 42.843, 'max_score': 1622.836, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1622836.jpg'}, {'end': 1714.621, 'src': 'embed', 'start': 1687.434, 'weight': 2, 'content': [{'end': 1692.798, 'text': "If we run pip freeze, then this shows us all of the dependencies for our project that we've installed.", 'start': 1687.434, 'duration': 5.364}, {'end': 1696.061, 'text': 'so you can see here we have bcrypt, we have flask.', 'start': 1693.098, 'duration': 2.963}, {'end': 1704.13, 'text': 'obviously we have flask wtf, which is the forms, genja2, which is the templating pillow which does our images,', 'start': 1696.061, 'duration': 8.069}, {'end': 1708.775, 'text': 'and these also give us the exact versions of those packages as well,', 'start': 1704.13, 'duration': 4.645}, {'end': 1714.621, 'text': "so that we're sure that everything on our server matches every package version in development.", 'start': 1708.775, 'duration': 5.846}], 'summary': "Running 'pip freeze' lists project dependencies, including bcrypt, flask, flask wtf, jinja2, and pillow with exact versions for server matching.", 'duration': 27.187, 'max_score': 1687.434, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1687434.jpg'}, {'end': 1801.789, 'src': 'embed', 'start': 1776.182, 'weight': 4, 'content': [{'end': 1782.95, 'text': "Now, since I'm using bash, I'm going to use the same SCP command that I used earlier to copy up our keys.", 'start': 1776.182, 'duration': 6.768}, {'end': 1790.659, 'text': "But if you're not using bash, then again, you can use something like FileZilla or Git to get your project folder onto your server.", 'start': 1783.31, 'duration': 7.349}, {'end': 1795.703, 'text': "But for me, I'm simply going to say scp-r.", 'start': 1791.079, 'duration': 4.624}, {'end': 1796.985, 'text': "That's for recursive.", 'start': 1795.864, 'duration': 1.121}, {'end': 1799.587, 'text': "That means that we're going to move over an entire directory.", 'start': 1797.005, 'duration': 2.582}, {'end': 1801.789, 'text': "So I'm going to say dash r.", 'start': 1799.987, 'duration': 1.802}], 'summary': 'Using scp command to copy keys and project folder onto the server.', 'duration': 25.607, 'max_score': 1776.182, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1776182.jpg'}, {'end': 1965.189, 'src': 'embed', 'start': 1931.566, 'weight': 3, 'content': [{'end': 1932.747, 'text': "So let's run that.", 'start': 1931.566, 'duration': 1.181}, {'end': 1934.729, 'text': 'And this should install fairly quickly.', 'start': 1932.968, 'duration': 1.761}, {'end': 1941.146, 'text': 'Okay, so now that we have those two packages installed, now we can create our virtual environment.', 'start': 1935.959, 'duration': 5.187}, {'end': 1946.193, 'text': "So I'm just going to create this virtual environment inside of our Flask project.", 'start': 1941.547, 'duration': 4.646}, {'end': 1955.943, 'text': "So I'm going to say python3-m, venv, and this will create a new virtual environment.", 'start': 1946.513, 'duration': 9.43}, {'end': 1959.585, 'text': 'now we just have to specify where we want that virtual environment.', 'start': 1955.943, 'duration': 3.642}, {'end': 1965.189, 'text': "so I'm going to put this within flask blog and I'm going to call this virtual environment venv.", 'start': 1959.585, 'duration': 5.604}], 'summary': 'Installing packages and creating a virtual environment for flask project.', 'duration': 33.623, 'max_score': 1931.566, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1931566.jpg'}], 'start': 1598.816, 'title': 'Deploying flask application on a web server', 'summary': 'Covers setting up a server, deploying the flask application using different methods, creating a requirements.txt file, using scp to copy the project folder, setting up a virtual environment, and installing dependencies using python 3-pip and venv.', 'chapters': [{'end': 1775.181, 'start': 1598.816, 'title': 'Deploying flask application to web server', 'summary': "Covers setting up a server including allowing ports, deploying the flask application to the web server using different methods and creating a requirements.txt file for the project's dependencies.", 'duration': 176.365, 'highlights': ['Creating a requirements.txt file captures all dependencies needed for the Flask project to work, ensuring that everything on the server matches every package version in development. Capturing all dependencies for the Flask project, ensuring package versions match in development.', 'Explaining the process of pushing the Flask application to the server, including the methods of using Git, FTP, or the command line for deployment. Detailing the methods of pushing the Flask application to the server.', 'Showing the use of pip freeze to display all the dependencies installed for the project, including specific packages and their versions. Demonstrating the use of pip freeze to display installed dependencies and their versions.']}, {'end': 2031.919, 'start': 1776.182, 'title': 'Deploying flask application on a web server', 'summary': 'Discusses deploying a flask application on a web server using scp to copy the project folder, setting up a virtual environment on the server, and installing dependencies using python 3-pip and venv.', 'duration': 255.737, 'highlights': ['Setting up a virtual environment on the server The speaker explains the process of creating a virtual environment on the server using Python 3-venv and creating a new virtual environment within the Flask project folder.', 'Copying the project folder using SCP The speaker demonstrates using SCP to copy the entire Flask project folder to the server using the recursive flag, enabling the movement of an entire directory.', 'Installing Python 3-pip and venv The process of installing Python 3-pip and venv on the server is explained, emphasizing the importance of using Python 3-pip and creating a virtual environment for running the Flask application.']}], 'duration': 433.103, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co1598816.jpg', 'highlights': ['Creating a requirements.txt file captures all dependencies needed for the Flask project to work, ensuring that everything on the server matches every package version in development.', 'Explaining the process of pushing the Flask application to the server, including the methods of using Git, FTP, or the command line for deployment.', 'Showing the use of pip freeze to display all the dependencies installed for the project, including specific packages and their versions.', 'Setting up a virtual environment on the server using Python 3-venv and creating a new virtual environment within the Flask project folder.', 'Copying the project folder using SCP to copy the entire Flask project folder to the server using the recursive flag, enabling the movement of an entire directory.', 'Installing Python 3-pip and venv on the server is explained, emphasizing the importance of using Python 3-pip and creating a virtual environment for running the Flask application.']}, {'end': 2694.386, 'segs': [{'end': 2059.001, 'src': 'embed', 'start': 2032.299, 'weight': 2, 'content': [{'end': 2036.8, 'text': "So if I run that, then it's going to install everything that we need for our application.", 'start': 2032.299, 'duration': 4.501}, {'end': 2043.754, 'text': 'Okay, so that should have installed all of the Python packages that we need for our application.', 'start': 2038.792, 'duration': 4.962}, {'end': 2054.259, 'text': 'So now we want to test our website using the development server and make sure that it works using that development server before we install nginx and gunicorn.', 'start': 2044.234, 'duration': 10.025}, {'end': 2059.001, 'text': 'But before we test this, there are a couple of variables that we first need to set.', 'start': 2054.739, 'duration': 4.262}], 'summary': 'Installing python packages for application and setting up variables before testing website.', 'duration': 26.702, 'max_score': 2032.299, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2032299.jpg'}, {'end': 2116.304, 'src': 'embed', 'start': 2075.514, 'weight': 1, 'content': [{'end': 2081.121, 'text': 'now, on our local machine, we used environment variables and we could use environment variables here as well,', 'start': 2075.514, 'duration': 5.607}, {'end': 2087.027, 'text': 'but i think that sometimes environment variables can be a little tricky when working with different web servers.', 'start': 2081.121, 'duration': 5.906}, {'end': 2088.668, 'text': 'So instead,', 'start': 2087.447, 'duration': 1.221}, {'end': 2096.391, 'text': "let's just create a configuration file with all of our sensitive information and we'll load that into our application instead of our environment variables.", 'start': 2088.668, 'duration': 7.723}, {'end': 2104.356, 'text': "So first, I'm going to go back to my local machine and grab the values of those environment variables so that we can add them to our server.", 'start': 2096.851, 'duration': 7.505}, {'end': 2112.701, 'text': "So I'm going to clear my screen here on the server and now I'm going to open back up my local machine here.", 'start': 2104.697, 'duration': 8.004}, {'end': 2116.304, 'text': 'Now there are a couple of different ways that we can get those environment variables.', 'start': 2113.121, 'duration': 3.183}], 'summary': 'Suggests using a configuration file for sensitive information instead of environment variables, and plans to transfer environment variables from the local machine to the server.', 'duration': 40.79, 'max_score': 2075.514, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2075514.jpg'}, {'end': 2191.796, 'src': 'embed', 'start': 2164.245, 'weight': 0, 'content': [{'end': 2170.106, 'text': "So if you look in that Flask configuration file, you should be able to see where you're using these environment variables.", 'start': 2164.245, 'duration': 5.861}, {'end': 2176.588, 'text': 'It should say os.environment.get and then secret key, SQLAlchemy, database, URI, and etc.', 'start': 2170.186, 'duration': 6.402}, {'end': 2181.971, 'text': 'Now we also need to grab our email user.', 'start': 2177.328, 'duration': 4.643}, {'end': 2188.014, 'text': 'So email underscore user and also our email underscore pass.', 'start': 2182.271, 'duration': 5.743}, {'end': 2191.796, 'text': 'So my email user is just my email address.', 'start': 2188.414, 'duration': 3.382}], 'summary': 'Flask configuration file uses environment variables for secret key, sqlalchemy, database uri, email user, and email pass.', 'duration': 27.551, 'max_score': 2164.245, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2164245.jpg'}, {'end': 2456.595, 'src': 'embed', 'start': 2422.792, 'weight': 4, 'content': [{'end': 2424.533, 'text': "so I'm going to edit that file.", 'start': 2422.792, 'duration': 1.741}, {'end': 2435.079, 'text': "so I'm gonna do a sudo nano flaskblog config.py and within this file here at the top, I'm going to import JSON,", 'start': 2424.533, 'duration': 10.546}, {'end': 2437.981, 'text': "since we're now using JSON instead of environment variables.", 'start': 2435.079, 'duration': 2.902}, {'end': 2443.505, 'text': "And also here at the top, I'm going to load in those values.", 'start': 2438.601, 'duration': 4.904}, {'end': 2448.449, 'text': "So I'm going to say with open, and we're going to open that file that we just created.", 'start': 2443.805, 'duration': 4.644}, {'end': 2450.55, 'text': 'And so this is the path.', 'start': 2448.949, 'duration': 1.601}, {'end': 2456.595, 'text': 'So it was in forward slash etc, forward slash config dot JSON.', 'start': 2450.871, 'duration': 5.724}], 'summary': 'Editing flaskblog config.py to import and load json values.', 'duration': 33.803, 'max_score': 2422.792, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2422792.jpg'}, {'end': 2668.547, 'src': 'heatmap', 'start': 2608.975, 'weight': 5, 'content': [{'end': 2614.516, 'text': "So I'll say export flask underscore app is equal to, and there's no spaces here.", 'start': 2608.975, 'duration': 5.541}, {'end': 2619.097, 'text': 'so is equal to run.py, because that is what contains our application.', 'start': 2614.516, 'duration': 4.581}, {'end': 2625.541, 'text': "So now that we've done that export flask app equals run.py, now I can simply do flask run.", 'start': 2619.637, 'duration': 5.904}, {'end': 2626.882, 'text': "Now don't hit enter yet.", 'start': 2625.901, 'duration': 0.981}, {'end': 2630.704, 'text': 'Instead of doing flask run, we also want to set the host.', 'start': 2627.522, 'duration': 3.182}, {'end': 2634.336, 'text': "So I'm going to set the host equal to 0.0.", 'start': 2630.724, 'duration': 3.612}, {'end': 2639.049, 'text': '0.0 And that will allow us to access this development server.', 'start': 2634.336, 'duration': 4.713}, {'end': 2641.951, 'text': 'from the outside, so from our browser.', 'start': 2639.549, 'duration': 2.402}, {'end': 2652.977, 'text': "So I'm going to run that, and it should spin up our server so we can see that it's running on our IP address on port 5000.", 'start': 2642.371, 'duration': 10.606}, {'end': 2662.463, 'text': 'So now, if I open my browser here, then, oops, let me actually open up my other browser here.', 'start': 2652.977, 'duration': 9.486}, {'end': 2668.547, 'text': 'So now I want to go to my IP address at port 5000.', 'start': 2663.643, 'duration': 4.904}], 'summary': 'Setting host to 0.0 allows access to server from outside, running on ip address on port 5000.', 'duration': 34.211, 'max_score': 2608.975, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2608975.jpg'}], 'start': 2032.299, 'title': 'Setting up and configuring flask', 'summary': 'Covers setting up environment variables and creating a configuration file for a flask application, as well as configuring the project to use json instead of environment variables, ensuring proper functionality and external accessibility.', 'chapters': [{'end': 2394.265, 'start': 2032.299, 'title': 'Setting up configuration for flask application', 'summary': 'Discusses setting up environment variables and creating a configuration file with sensitive information for a flask application, including secret key, database uri, email user, and email password, to ensure proper functionality, before testing the application using a development server.', 'duration': 361.966, 'highlights': ['Creating a configuration file with sensitive information such as secret key, database URI, email user, and email password is necessary for the proper functionality of the Flask application on the server. Necessary sensitive information includes secret key, database URI, email user, and email password for the Flask application.', 'Testing the application using a development server is essential before installing nginx and gunicorn. Testing the application using a development server is essential before proceeding to install nginx and gunicorn.', 'Using a configuration file is suggested over environment variables for managing sensitive information due to potential issues when working with different web servers. Suggests using a configuration file over environment variables due to potential issues when working with different web servers.', 'Obtaining values of environment variables from the local machine and transferring them to the server for secure configuration. Transferring values of environment variables from the local machine to the server for secure configuration is demonstrated.']}, {'end': 2694.386, 'start': 2395.125, 'title': 'Configuring flask project with json', 'summary': "Demonstrates how to edit the flask project's config file to utilize json instead of environment variables, enabling the server to run and be accessed externally through the specified host and port.", 'duration': 299.261, 'highlights': ["Demonstrate how to edit the Flask project's config file to use JSON instead of environment variables. Updating the config file to utilize JSON instead of environment variables, enabling the server to access configuration values as a Python dictionary.", 'Setting the host to 0.0.0.0 to expose the server to the outside world and accessing the server via Flask run on port 5000. Setting the host to 0.0.0.0 to allow external access to the server, accessing the server via Flask run on port 5000.']}], 'duration': 662.087, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2032299.jpg', 'highlights': ['Creating a configuration file with sensitive information such as secret key, database URI, email user, and email password is necessary for the proper functionality of the Flask application on the server.', 'Using a configuration file is suggested over environment variables for managing sensitive information due to potential issues when working with different web servers.', 'Testing the application using a development server is essential before installing nginx and gunicorn.', 'Obtaining values of environment variables from the local machine and transferring them to the server for secure configuration.', "Demonstrate how to edit the Flask project's config file to use JSON instead of environment variables.", 'Setting the host to 0.0.0.0 to expose the server to the outside world and accessing the server via Flask run on port 5000.']}, {'end': 3576.664, 'segs': [{'end': 2826.797, 'src': 'embed', 'start': 2718.322, 'weight': 0, 'content': [{'end': 2719.543, 'text': 'It looks like that worked.', 'start': 2718.322, 'duration': 1.221}, {'end': 2720.924, 'text': 'Log out.', 'start': 2720.363, 'duration': 0.561}, {'end': 2722.345, 'text': 'That seems to work.', 'start': 2721.644, 'duration': 0.701}, {'end': 2725.067, 'text': "Let's go to register and try to create a new user.", 'start': 2722.785, 'duration': 2.282}, {'end': 2729.051, 'text': "So I'm going to create a new user here and just call this deployed user.", 'start': 2725.368, 'duration': 3.683}, {'end': 2733.316, 'text': "For the email, I'll do deployed user at test.com.", 'start': 2730.012, 'duration': 3.304}, {'end': 2738, 'text': "Password, I'll just do testing, password testing, sign up.", 'start': 2734.076, 'duration': 3.924}, {'end': 2740.043, 'text': 'And that seemed to work.', 'start': 2739.082, 'duration': 0.961}, {'end': 2741.724, 'text': "So now let's try that.", 'start': 2740.243, 'duration': 1.481}, {'end': 2747.55, 'text': 'So deployed user at test.com testing to log in.', 'start': 2741.804, 'duration': 5.746}, {'end': 2748.951, 'text': 'That seems to work.', 'start': 2748.131, 'duration': 0.82}, {'end': 2750.513, 'text': "Let's try to create a new post.", 'start': 2749.032, 'duration': 1.481}, {'end': 2757.52, 'text': 'Deployed post and I will copy that and post that.', 'start': 2752.455, 'duration': 5.065}, {'end': 2758.881, 'text': 'So it looks like that worked.', 'start': 2757.86, 'duration': 1.021}, {'end': 2760.363, 'text': 'See if we can update a post.', 'start': 2759.222, 'duration': 1.141}, {'end': 2764.39, 'text': 'Updated deployed post that works.', 'start': 2762.208, 'duration': 2.182}, {'end': 2766.732, 'text': "Let's try to delete a post.", 'start': 2765.211, 'duration': 1.521}, {'end': 2772.998, 'text': "So if I delete a post that seems to work as well Let's see if we can change our profile picture.", 'start': 2766.952, 'duration': 6.046}, {'end': 2780.885, 'text': 'So right now we just have this default profile picture I will try to choose a new picture here.', 'start': 2773.058, 'duration': 7.827}, {'end': 2785.069, 'text': 'Just choose one from my desktop update that and And that seemed to work.', 'start': 2780.945, 'duration': 4.124}, {'end': 2786.05, 'text': "Okay, that's good.", 'start': 2785.229, 'duration': 0.821}, {'end': 2789.834, 'text': "And let's also test that our email is working.", 'start': 2787.151, 'duration': 2.683}, {'end': 2795.579, 'text': 'So if I go to login, forgot password.', 'start': 2790.214, 'duration': 5.365}, {'end': 2799.062, 'text': 'If I say that I forgot my password for my Corey M.', 'start': 2796.079, 'duration': 2.983}, {'end': 2801.344, 'text': 'Schaefer email, Gmail account.', 'start': 2799.062, 'duration': 2.282}, {'end': 2805.806, 'text': 'If I run that, then it says an email has been sent with the instructions to reset your password.', 'start': 2801.864, 'duration': 3.942}, {'end': 2813.329, 'text': 'I actually have my Gmail opened up here and we can see that I got the password reset request here.', 'start': 2805.826, 'duration': 7.503}, {'end': 2819.052, 'text': 'So if I click on that, then we can see that I got my password reset link.', 'start': 2813.729, 'duration': 5.323}, {'end': 2822.472, 'text': 'and I can now change my password.', 'start': 2820.53, 'duration': 1.942}, {'end': 2826.797, 'text': "So instead, I'll change that to testing123 instead of just testing.", 'start': 2822.532, 'duration': 4.265}], 'summary': 'Successfully tested user registration, login, post creation, update, deletion, profile picture change, and email reset functionality.', 'duration': 108.475, 'max_score': 2718.322, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2718322.jpg'}, {'end': 2877.941, 'src': 'embed', 'start': 2851.336, 'weight': 1, 'content': [{'end': 2859.643, 'text': "This is great for testing, but you don't want to go live with this and send this URL out using a development server.", 'start': 2851.336, 'duration': 8.307}, {'end': 2861.785, 'text': "It's a development server for a reason.", 'start': 2859.984, 'duration': 1.801}, {'end': 2867.01, 'text': "It's not meant for a lot of performance and to be hit by a lot of people.", 'start': 2861.885, 'duration': 5.125}, {'end': 2877.941, 'text': "So that's why you use something like Nginx and G Unicorn because those applications do allow for high traffic and for good performance.", 'start': 2867.43, 'duration': 10.511}], 'summary': 'Development server not suitable for high traffic; nginx and g unicorn enable high performance.', 'duration': 26.605, 'max_score': 2851.336, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2851336.jpg'}, {'end': 2925.82, 'src': 'heatmap', 'start': 2878.362, 'weight': 0.89, 'content': [{'end': 2882.907, 'text': "So now we're going to want to get our application working with Nginx and G Unicorn.", 'start': 2878.362, 'duration': 4.545}, {'end': 2886.791, 'text': "But this is a very good sign that it's currently working in our development server.", 'start': 2883.247, 'duration': 3.544}, {'end': 2892.537, 'text': "So now I'm going to kill this by hitting Control-C and clearing my screen here.", 'start': 2887.151, 'duration': 5.386}, {'end': 2895.801, 'text': "And now let's install Nginx and gunicorn.", 'start': 2892.977, 'duration': 2.824}, {'end': 2901.266, 'text': "So I'm going to cd back to my home directory just so I have more room here to work with.", 'start': 2896.141, 'duration': 5.125}, {'end': 2904.97, 'text': "And now I'm going to say sudo apt install.", 'start': 2901.787, 'duration': 3.183}, {'end': 2908.114, 'text': "And we're going to want to install Nginx.", 'start': 2905.431, 'duration': 2.683}, {'end': 2909.155, 'text': "So let's run that.", 'start': 2908.374, 'duration': 0.781}, {'end': 2914.315, 'text': 'And once Nginx is installed, then I will clear my screen here.', 'start': 2911.374, 'duration': 2.941}, {'end': 2916.496, 'text': 'And now we want to install G Unicorn.', 'start': 2914.735, 'duration': 1.761}, {'end': 2919.457, 'text': 'So we can actually install G Unicorn with pip.', 'start': 2916.856, 'duration': 2.601}, {'end': 2920.938, 'text': 'So I can do pip install.', 'start': 2919.577, 'duration': 1.361}, {'end': 2925.82, 'text': "Now you're going to want to make sure that you are still within your virtual environment here.", 'start': 2921.338, 'duration': 4.482}], 'summary': 'Installing nginx and g unicorn for application deployment.', 'duration': 47.458, 'max_score': 2878.362, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2878362.jpg'}, {'end': 3069.003, 'src': 'heatmap', 'start': 3013.859, 'weight': 0.739, 'content': [{'end': 3016.76, 'text': 'so this is going to be in forward slash etc.', 'start': 3013.859, 'duration': 2.901}, {'end': 3023.923, 'text': 'forward slash, nginx, forward slash sites, dash enabled, and we will call this flask blog.', 'start': 3016.76, 'duration': 7.163}, {'end': 3024.963, 'text': "so let's run that.", 'start': 3023.923, 'duration': 1.04}, {'end': 3026.184, 'text': 'this is a new file.', 'start': 3024.963, 'duration': 1.221}, {'end': 3028.565, 'text': "this doesn't exist yet, so it's going to be completely blank.", 'start': 3026.184, 'duration': 2.381}, {'end': 3040.829, 'text': "So now to create an Nginx configuration file, we're just going to say server and then in these curly braces here, we will say listen on port 80,", 'start': 3029.185, 'duration': 11.644}, {'end': 3043.47, 'text': "and you're going to want to remember these semicolons here.", 'start': 3040.829, 'duration': 2.641}, {'end': 3048.432, 'text': "I know that writing Python code, we're not used to putting in semicolons, but here you have to remember that.", 'start': 3043.49, 'duration': 4.942}, {'end': 3054.675, 'text': 'so now we need server underscore name and that is going to be equal to for now.', 'start': 3048.912, 'duration': 5.763}, {'end': 3056.736, 'text': "it's just going to be our ip address.", 'start': 3054.675, 'duration': 2.061}, {'end': 3059.137, 'text': "so my ip address you're going to want to put in yours.", 'start': 3056.736, 'duration': 2.401}, {'end': 3059.597, 'text': 'mine is 45.33..', 'start': 3059.137, 'duration': 0.46}, {'end': 3069.003, 'text': "123.214 semicolon And now we're going to forward all of our static files.", 'start': 3059.597, 'duration': 9.406}], 'summary': 'Creating an nginx configuration file for flask blog on port 80.', 'duration': 55.144, 'max_score': 3013.859, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3013859.jpg'}, {'end': 3332.257, 'src': 'heatmap', 'start': 3239.901, 'weight': 0.74, 'content': [{'end': 3244.402, 'text': "So since I'm using nano, I'll hit control X, Y to save and then hit enter.", 'start': 3239.901, 'duration': 4.501}, {'end': 3249.804, 'text': 'Okay, so in our NGINX configuration file, we said that we were listening on port 80.', 'start': 3244.723, 'duration': 5.081}, {'end': 3254.005, 'text': "So if you remember, we haven't actually opened up that port on our firewall yet.", 'start': 3249.804, 'duration': 4.201}, {'end': 3255.685, 'text': "So let's go ahead and do that now.", 'start': 3254.405, 'duration': 1.28}, {'end': 3259.606, 'text': "So I'm going to say sudo ufw, our uncomplicated firewall.", 'start': 3255.705, 'duration': 3.901}, {'end': 3265.429, 'text': 'allow and we will allow http tcp traffic.', 'start': 3260.186, 'duration': 5.243}, {'end': 3273.034, 'text': 'so it said that it added those rules and since we are done with our testing, we will also disallow any traffic on port 5000,', 'start': 3265.429, 'duration': 7.605}, {'end': 3274.514, 'text': 'since that was our testing port.', 'start': 3273.034, 'duration': 1.48}, {'end': 3280.917, 'text': "so i'm going to say a sudo ufw delete and i will delete the allow of port 5000.", 'start': 3274.514, 'duration': 6.403}, {'end': 3283.318, 'text': "so again i'll make sure that that is enabled.", 'start': 3280.917, 'duration': 2.401}, {'end': 3292.561, 'text': 'so sudo ufw enable and hit y for yes, okay, and now we want to restart our nginx server.', 'start': 3283.318, 'duration': 9.243}, {'end': 3300.904, 'text': "so i'm going to say sudo system ctl restart nginx.", 'start': 3292.561, 'duration': 8.343}, {'end': 3305.065, 'text': "okay, so that restarted our nginx server, so i'm going to clear my screen.", 'start': 3300.904, 'duration': 4.161}, {'end': 3309.707, 'text': 'So now our nginx server is running but gunicorn is not running.', 'start': 3305.465, 'duration': 4.242}, {'end': 3314.008, 'text': 'So our server is not going to know how to handle that Python code.', 'start': 3309.887, 'duration': 4.121}, {'end': 3322.871, 'text': "So if I go back to my browser here, and I try to reload this page, then it's not going to work.", 'start': 3314.368, 'duration': 8.503}, {'end': 3327.993, 'text': "So if I just let this spin up here, it'll give me an nginx error eventually.", 'start': 3323.271, 'duration': 4.722}, {'end': 3332.257, 'text': "And I'm actually still on port 5000 here, so that's not going to work at all.", 'start': 3328.773, 'duration': 3.484}], 'summary': 'Configuring nginx to listen on port 80, setting up firewall rules, and restarting the server.', 'duration': 92.356, 'max_score': 3239.901, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3239901.jpg'}, {'end': 3555.335, 'src': 'heatmap', 'start': 3509.884, 'weight': 1, 'content': [{'end': 3511.927, 'text': "And that's what creates our Flask application.", 'start': 3509.884, 'duration': 2.043}, {'end': 3520.118, 'text': "So to run that gunicorn code again, again, it's gunicorn, and I'm going to use three workers.", 'start': 3512.428, 'duration': 7.69}, {'end': 3522.261, 'text': 'And that is within the run module.', 'start': 3520.519, 'duration': 1.742}, {'end': 3526.307, 'text': 'And that variable for our application is app.', 'start': 3522.762, 'duration': 3.545}, {'end': 3528.107, 'text': 'So if I run that,', 'start': 3526.847, 'duration': 1.26}, {'end': 3538.17, 'text': "then we can see that it says that it's listening on our local host at port 8000 and that it booted up three workers for three different processes.", 'start': 3528.107, 'duration': 10.063}, {'end': 3545.332, 'text': 'So now, if we go back to our browser here and reopen this in our browser,', 'start': 3538.57, 'duration': 6.762}, {'end': 3555.335, 'text': 'you can see that now we are just going to our IP address and Nginx is forwarding that traffic to gunicorn, and gunicorn is handling this Python code.', 'start': 3545.332, 'duration': 10.003}], 'summary': 'Flask app runs with 3 gunicorn workers, handling traffic via nginx.', 'duration': 45.451, 'max_score': 3509.884, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3509884.jpg'}], 'start': 2694.386, 'title': 'Testing application functionality and setting up nginx and gunicorn', 'summary': "Demonstrates testing the application's functionality including logging in, user management, and post operations. it also covers setting up nginx and gunicorn for high traffic performance and running gunicorn with multiple workers.", 'chapters': [{'end': 2772.998, 'start': 2694.386, 'title': 'Testing application functionality', 'summary': "Demonstrates testing the application's functionality by successfully logging in as a user, creating a new user, logging in with the new user, creating a new post, updating the post, deleting the post, and changing the profile picture.", 'duration': 78.612, 'highlights': ['Successfully logged in as a user, created a new user, and tested logging in with the new user.', 'Tested creating a new post, updating the post, and deleting the post.', 'Demonstrated changing the profile picture.', 'Verified the functionality of the application by performing various actions such as logging in, creating, updating, and deleting posts.']}, {'end': 3576.664, 'start': 2773.058, 'title': 'Setting up nginx and gunicorn', 'summary': 'Covers setting up a new profile picture, testing email functionality, transitioning from a development server to nginx and gunicorn for high traffic performance, and running gunicorn with multiple workers.', 'duration': 803.606, 'highlights': ['Transitioning from a development server to Nginx and Gunicorn for high traffic performance, ensuring good performance and handling high traffic (e.g., using Nginx and Gunicorn for high performance and traffic).', 'Testing email functionality by receiving a password reset request, changing the password, and successfully logging in with the new password (e.g., receiving and resetting password through email, successful login with new password).', 'Setting up a new profile picture by choosing an image from the desktop and updating it (e.g., updating profile picture from desktop).']}], 'duration': 882.278, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co2694386.jpg', 'highlights': ['Successfully logged in as a user, created a new user, and tested logging in with the new user.', 'Transitioning from a development server to Nginx and Gunicorn for high traffic performance, ensuring good performance and handling high traffic (e.g., using Nginx and Gunicorn for high performance and traffic).', 'Tested creating a new post, updating the post, and deleting the post.', 'Testing email functionality by receiving a password reset request, changing the password, and successfully logging in with the new password (e.g., receiving and resetting password through email, successful login with new password).', 'Demonstrated changing the profile picture.', 'Setting up a new profile picture by choosing an image from the desktop and updating it (e.g., updating profile picture from desktop).', 'Verified the functionality of the application by performing various actions such as logging in, creating, updating, and deleting posts.']}, {'end': 4487.186, 'segs': [{'end': 3654.692, 'src': 'heatmap', 'start': 3596.192, 'weight': 0.721, 'content': [{'end': 3602.24, 'text': "We just killed G Unicorn and if I try to reload the page, this isn't working anymore.", 'start': 3596.192, 'duration': 6.048}, {'end': 3614.434, 'text': "So what we need is something that is constantly monitoring G Unicorn and making sure that it's running and will auto start it and auto restart it if it crashes,", 'start': 3602.72, 'duration': 11.714}, {'end': 3615.295, 'text': 'and things like that.', 'start': 3614.434, 'duration': 0.861}, {'end': 3619.998, 'text': "So in order to do that, we're going to use some software called Supervisor.", 'start': 3615.916, 'duration': 4.082}, {'end': 3622.659, 'text': 'And this is very easy to use on Linux.', 'start': 3620.138, 'duration': 2.521}, {'end': 3627.421, 'text': "So to install Supervisor, I'm just going to say sudo apt install.", 'start': 3623.019, 'duration': 4.402}, {'end': 3629.803, 'text': 'And this is called Supervisor.', 'start': 3627.962, 'duration': 1.841}, {'end': 3631.904, 'text': "So let's run that and install that.", 'start': 3630.003, 'duration': 1.901}, {'end': 3632.744, 'text': "I'll say yes.", 'start': 3631.924, 'duration': 0.82}, {'end': 3640.748, 'text': 'Okay, and once that is installed, we just need to set up a quick and easy configuration file for Supervisor.', 'start': 3634.426, 'duration': 6.322}, {'end': 3646.749, 'text': "So to do this we'll say sudo nano, and this is going to be in ford slash, etc.", 'start': 3641.188, 'duration': 5.561}, {'end': 3654.692, 'text': "ford slash Supervisor conf dot d and within conf dot d we're going to create a configuration file.", 'start': 3646.749, 'duration': 7.943}], 'summary': 'Implemented supervisor to monitor and auto restart g unicorn on linux.', 'duration': 58.5, 'max_score': 3596.192, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3596192.jpg'}, {'end': 3629.803, 'src': 'embed', 'start': 3602.72, 'weight': 1, 'content': [{'end': 3614.434, 'text': "So what we need is something that is constantly monitoring G Unicorn and making sure that it's running and will auto start it and auto restart it if it crashes,", 'start': 3602.72, 'duration': 11.714}, {'end': 3615.295, 'text': 'and things like that.', 'start': 3614.434, 'duration': 0.861}, {'end': 3619.998, 'text': "So in order to do that, we're going to use some software called Supervisor.", 'start': 3615.916, 'duration': 4.082}, {'end': 3622.659, 'text': 'And this is very easy to use on Linux.', 'start': 3620.138, 'duration': 2.521}, {'end': 3627.421, 'text': "So to install Supervisor, I'm just going to say sudo apt install.", 'start': 3623.019, 'duration': 4.402}, {'end': 3629.803, 'text': 'And this is called Supervisor.', 'start': 3627.962, 'duration': 1.841}], 'summary': 'Implement supervisor to monitor and auto restart g unicorn on linux.', 'duration': 27.083, 'max_score': 3602.72, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3602720.jpg'}, {'end': 3960.508, 'src': 'heatmap', 'start': 3911.195, 'weight': 0.729, 'content': [{'end': 3918.382, 'text': 'we called those that was within forward slash var slash log, flask blog.', 'start': 3911.195, 'duration': 7.187}, {'end': 3922.987, 'text': 'we called that flask blog dot e r r dot log.', 'start': 3918.382, 'duration': 4.605}, {'end': 3925.309, 'text': "so I'll run that And I'll hit the up error here.", 'start': 3922.987, 'duration': 2.322}, {'end': 3929.653, 'text': 'We also want to do flaskblog.out.log.', 'start': 3925.429, 'duration': 4.224}, {'end': 3930.573, 'text': "So I'll run that.", 'start': 3929.953, 'duration': 0.62}, {'end': 3937.039, 'text': "Okay, so now that I have all of that in place, I'm just going to restart our supervisor.", 'start': 3930.934, 'duration': 6.105}, {'end': 3942.763, 'text': "So in order to do that, I'll just do sudo supervisorctl.", 'start': 3937.379, 'duration': 5.384}, {'end': 3948.451, 'text': 'reload So if I run that we can see that it restarted Supervisor.', 'start': 3943.624, 'duration': 4.827}, {'end': 3957.143, 'text': 'So now if we reload our page in the browser here sometimes it can take a while for Supervisor to start up that process.', 'start': 3949.032, 'duration': 8.111}, {'end': 3960.508, 'text': "If I run that now we can see that it's already working.", 'start': 3957.604, 'duration': 2.904}], 'summary': "Restarted supervisor, reloaded page, and verified it's working.", 'duration': 49.313, 'max_score': 3911.195, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3911195.jpg'}, {'end': 4032.019, 'src': 'embed', 'start': 4004.688, 'weight': 3, 'content': [{'end': 4009.652, 'text': "So you could get some unexpected things with your application, and that's just kind of knowing your web server.", 'start': 4004.688, 'duration': 4.964}, {'end': 4016.092, 'text': 'So for example, if I choose a really large file here, So I have a file on my desktop called large.jpg.', 'start': 4010.252, 'duration': 5.84}, {'end': 4023.936, 'text': "If I open that and I try to update that as my profile picture, if I do that, you can see it's going to spin here for a little bit.", 'start': 4016.612, 'duration': 7.324}, {'end': 4026.237, 'text': "And then it's going to give me an Nginx error.", 'start': 4024.396, 'duration': 1.841}, {'end': 4029.338, 'text': 'And it says 413 request entity too large.', 'start': 4026.357, 'duration': 2.981}, {'end': 4032.019, 'text': 'Now this is an Nginx default.', 'start': 4029.838, 'duration': 2.181}], 'summary': 'Unexpected issues may arise due to large file sizes, leading to nginx error 413.', 'duration': 27.331, 'max_score': 4004.688, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co4004688.jpg'}, {'end': 4255.338, 'src': 'embed', 'start': 4212.177, 'weight': 2, 'content': [{'end': 4214.939, 'text': 'And this is all still working.', 'start': 4212.177, 'duration': 2.762}, {'end': 4221.844, 'text': 'So we have a completely functional website that is working on our IP address that is fully deployed at this point.', 'start': 4215.279, 'duration': 6.565}, {'end': 4225.286, 'text': "Now there's still a lot more that we could do in future videos if you're interested.", 'start': 4222.224, 'duration': 3.062}, {'end': 4228.229, 'text': 'So right now we only have an IP address.', 'start': 4225.627, 'duration': 2.602}, {'end': 4229.429, 'text': 'But if you want,', 'start': 4228.749, 'duration': 0.68}, {'end': 4237.175, 'text': "then I could also walk through the process of buying a domain name and how to get that domain name to go to this server that we've set up.", 'start': 4229.429, 'duration': 7.746}, {'end': 4244.063, 'text': 'We could also see how to add SSL certificates so that we can have an HTTPS domain name.', 'start': 4237.755, 'duration': 6.308}, {'end': 4248.149, 'text': "That's actually something that I still need to do for my personal website as well.", 'start': 4244.664, 'duration': 3.485}, {'end': 4249.651, 'text': "I'm still using HTTP.", 'start': 4248.169, 'duration': 1.482}, {'end': 4255.338, 'text': "Now I'm actually going to delete this server after this video.", 'start': 4250.852, 'duration': 4.486}], 'summary': 'Fully functional website deployed on ip address, future plans for domain name, ssl certificates, and server deletion.', 'duration': 43.161, 'max_score': 4212.177, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co4212177.jpg'}, {'end': 4358.093, 'src': 'embed', 'start': 4332.937, 'weight': 0, 'content': [{'end': 4340.662, 'text': "Linode was actually kind enough to sponsor this video and I've used them for many years and have recommended them to people long before I even had any sponsors.", 'start': 4332.937, 'duration': 7.725}, {'end': 4344.145, 'text': 'So if you get a chance, I would highly recommend giving them a shot.', 'start': 4341.063, 'duration': 3.082}, {'end': 4352.09, 'text': 'So like we saw earlier in the video, they have this new and improved cloud management system that makes spinning up a server fast and easy.', 'start': 4344.525, 'duration': 7.565}, {'end': 4358.093, 'text': "You can choose from available images and you can even upload your own custom image if you'd like.", 'start': 4352.83, 'duration': 5.263}], 'summary': 'Linode sponsors the video, recommends their cloud management system for fast server setup.', 'duration': 25.156, 'max_score': 4332.937, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co4332937.jpg'}, {'end': 4461.717, 'src': 'embed', 'start': 4432.736, 'weight': 5, 'content': [{'end': 4438.382, 'text': 'Hopefully now you have a good idea of how you can deploy your Flask application to your own Linux server.', 'start': 4432.736, 'duration': 5.646}, {'end': 4444.669, 'text': 'Like I said before, this option takes a little more effort than some of the other options out there,', 'start': 4439.023, 'duration': 5.646}, {'end': 4450.594, 'text': 'but having your own virtual private server gives you so much more flexibility and room to grow with your application.', 'start': 4444.669, 'duration': 5.925}, {'end': 4455.136, 'text': 'And it also provides some terrific knowledge for learning more about backend and Linux systems.', 'start': 4450.915, 'duration': 4.221}, {'end': 4461.717, 'text': "And that's something that employers really look for nowadays and something that would really shine on a resume.", 'start': 4455.476, 'duration': 6.241}], 'summary': 'Deploying flask app to own linux server provides flexibility, growth, and valuable backend/linux knowledge for employers.', 'duration': 28.981, 'max_score': 4432.736, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co4432736.jpg'}], 'start': 3577.524, 'title': 'Setting up and managing web processes with supervisor and linode', 'summary': "Covers setting up supervisor for process monitoring and management on linux, configuring flask blog with supervisor, deploying a functional website, and highlights linode's cloud management system, including features like fast server deployment, availability of stack scripts, and referral offer of $20 free credit.", 'chapters': [{'end': 3766.346, 'start': 3577.524, 'title': 'Using supervisor for process monitoring', 'summary': 'Discusses the need for process monitoring, introduces supervisor for auto-restarting processes, and provides a step-by-step guide for setting up supervisor on linux to monitor and manage g unicorn for a flask project.', 'duration': 188.822, 'highlights': ['Supervisor is introduced as a tool for constantly monitoring and auto-restarting processes like G Unicorn, ensuring they remain running and auto-restarting if they crash.', "Step-by-step guide is provided for installing Supervisor on Linux using the command 'sudo apt install Supervisor'.", 'The process of setting up a configuration file for Supervisor, specifically for a Flask project, is detailed, including defining the program, directory, and command to run G Unicorn with three workers.', 'Explanation is given on providing the full path to the G Unicorn command within the virtual environment and specifying the number of workers to run.']}, {'end': 4211.477, 'start': 3767.067, 'title': 'Setting up flask blog with supervisor', 'summary': 'Highlights setting up a flask blog with supervisor, including configuring auto start, stop as group, error and log files, and dealing with nginx default settings. it also includes testing functionalities such as profile picture upload, password reset, and logging out of the server.', 'duration': 444.41, 'highlights': ["Configuring auto start and restart to ensure the application restarts if it crashes, with an example of setting 'auto start' to true.", 'Configuring error and log files for the application, including standard error log file and standard out log file, with detailed file paths and names.', 'Dealing with Nginx default settings, such as client upload size limit, and providing steps to update the client_max_body_size in Nginx configuration file.', 'Testing functionalities such as profile picture upload, password reset, and logging out of the server, with examples of troubleshooting and resolving issues.', "Using Supervisor to restart the application and ensuring its successful restart, including the command 'sudo supervisorctl reload' and verifying the application's functionality post-restart."]}, {'end': 4332.937, 'start': 4212.177, 'title': 'Setting up a functional website', 'summary': 'Demonstrates the process of setting up a fully deployed website on an ip address, with potential future videos covering domain name purchase, ssl certificate addition, and server management.', 'duration': 120.76, 'highlights': ['The chapter demonstrates the process of setting up a fully deployed website on an IP address.', 'Potential future videos could cover domain name purchase and how to get the domain name to go to the server.', 'Potential future videos could cover adding SSL certificates to have an HTTPS domain name.', 'Instructions on how to delete or power off the server to avoid charges are provided.']}, {'end': 4487.186, 'start': 4332.937, 'title': 'Linode cloud management system', 'summary': "Highlights linode's cloud management system, including features like fast server deployment, availability of stack scripts for common tasks like wordpress installation, and the presence of nine worldwide data centers, with two more set to open in 2019, as well as a referral offer of $20 free credit. they also emphasize the benefits of deploying flask applications to a virtual private server for flexibility, growth, and learning opportunities in backend and linux systems.", 'duration': 154.249, 'highlights': ['Linode offers a new and improved cloud management system that enables fast and easy server deployment, with the availability of stack scripts for common tasks like WordPress installation.', 'Linode has nine worldwide data centers and two more are set to open in 2019, providing users with the ability to spin up a server close to their audience.', "A referral link is provided in the description section, offering $20 of free credit to try Linode's services.", 'Deploying Flask applications to a virtual private server provides users with more flexibility and room to grow, as well as valuable learning opportunities in backend and Linux systems, which can be beneficial for career prospects.', 'Ways to support the tutorials include liking the video, sharing it with others, and contributing through Patreon, with a link provided in the description section.']}], 'duration': 909.662, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/goToXTC96Co/pics/goToXTC96Co3577524.jpg', 'highlights': ['Linode offers fast and easy server deployment with worldwide data centers and $20 free credit.', 'Supervisor constantly monitors and auto-restarts processes like G Unicorn on Linux.', 'Setting up a fully deployed website on an IP address is demonstrated.', 'Configuring auto start and restart for application, error and log files, and Nginx settings.', 'Potential future videos could cover domain name purchase, SSL certificates, and server management.', 'Deploying Flask applications to a virtual private server provides flexibility and learning opportunities.']}], 'highlights': ['Deploying a Flask application to a web server is essential for making it accessible over the internet, with the video aiming to provide guidance on deploying to a Linux server using Nginx and GUnicorn, emphasizing the differences from deploying a Django application.', 'The chapter emphasizes the importance of deploying a Flask application to make it accessible over the internet, addressing the challenges and complexities of deployment with multiple options discussed.', 'The video discusses the challenges and overwhelming nature of deployment, highlighting the various ways to deploy an application and the difficulty in determining the best approach for a specific application, setting the stage for exploring different deployment options including deploying to a Linux server and Heroku.', 'Detailed guidance is provided on creating and setting up a Linux server from scratch, including choosing an image, region, and plan.', 'The chapter emphasizes the flexibility and control offered by deploying to a Linux server, highlighting the trade-offs and benefits compared to other deployment methods.', 'The process of updating and upgrading the software on the server was completed in a couple of minutes, emphasizing the importance of this initial setup step.', 'Adding a new user with limited privileges and using sudo for admin commands is a safer practice than running everything as root.', 'Configuring SSH keys with 600 permissions for owner and 0 permissions for group and others', 'Creating a requirements.txt file captures all dependencies needed for the Flask project to work, ensuring that everything on the server matches every package version in development.', 'Creating a configuration file with sensitive information such as secret key, database URI, email user, and email password is necessary for the proper functionality of the Flask application on the server.', 'Transitioning from a development server to Nginx and Gunicorn for high traffic performance, ensuring good performance and handling high traffic (e.g., using Nginx and Gunicorn for high performance and traffic).', 'Linode offers fast and easy server deployment with worldwide data centers and $20 free credit.', 'Supervisor constantly monitors and auto-restarts processes like G Unicorn on Linux.', 'Deploying Flask applications to a virtual private server provides flexibility and learning opportunities.']}