Deploying Flask App on AWS ec2 instance with Mysql without using elastic bean stalk



Your flask app works on your local machine and the code is hosted(Github).



Launch a Ec2 instance and log in using your key-pair or ssh keys. Make sure you store the key.pem file when you create the instance.

$ ssh -i key.pem ubuntu@  # (Your public IP)

If you get an error like:

Permissions 0644 for ‘Downloads/ishaan-key.pem’ are too open.

It is required that your private key files are NOT accessible by others.

This private key will be ignored.

Then change your permission on your key.pem file

$ chmod 700 key.pem


2. Before you can install python specific packages if you are using MYsql yo need to install mysql.(Ubuntu 16.04)

  • $ sudo apt-get update
  • $ sudo apt-get install mysql-server
  • $ sudo mysql_secure_installation


Once you are logged in clone your code repository from Github.

$ git clone

Now once you have the code install pip (For ubuntu)

sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get install python-pip

Now that you have installed pip use your requirements.txt file to install all the python packages your flask app needs.

$ pip install -r requirements.txt

If you do have a requirements.txt you can create one from your local machine

$ pip freeze > requirements.txt

Install all the packges required by your flask app using

$ pip install -r requirements.txt

(If you get an error

EnvironmentError: mysql_config not found

Then run this command

sudo apt-get install libmysqlclient-dev



Install gunicorn if you were not using it on your local machine

$ pip install gunicorn

We’ll need a web server installed on our instance, because we’re going to forward requests from port 80 to our Flask app running internally. It is best practice to have a web server handle our port 80 requests, because the Flask application server (Gunicorn) we are using is designed to serve Python code, but not ideal for handling port 80 requests from the Internet.

  • sudo apt-get update
  • sudo apt-get install nginx

Nginx Configaration:

$ sudo rm /etc/nginx/sites-enabled/default

$ sudo nano /etc/nginx/sites-available/flask_app

Paste in the below: Here We are passing on to port 8000 as gunicorn by default binds to 8000.

server {
    listen       80;
    server_name  your_public_dnsname_here;

    location / {


Now we can enable the site (by creating a symlink), test our configuration and restart to allow our changes to take place.

$ sudo ln -s /etc/nginx/sites-available/flask_app /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl restart nginx 

And finally, let’s start our Gunicorn process to serve our Flask app:

$ gunicorn app:app 

This should be it. You can create a gunicorn service so that it starts up when the server boots.

Reset Mysql Root password

If you are getting this error:

Error: Access denied for user ‘root’@’localhost’ (using password: YES)

Basic commands to start/stop/restart mysql from Command line

On OS X to start/stop/restart MySQL pre 5.7  from the command line:

 sudo /usr/local/mysql/support-files/mysql.server start
 sudo /usr/local/mysql/support-files/mysql.server stop
 sudo /usr/local/mysql/support-files/mysql.server restart

These are the steps you need to follow:

  1. Stop Mysql server (
    sudo /usr/local/mysql/support-files/mysql.server stop
  2. Start mysql with the following option “/path/to/mysqld –skip-grant-tables ”
     sudo /usr/local/mysql/support-files/mysql.server start--skip-grant-tab
  3. Connect to Mysql ($ mysql)
  4. Update the password

    update user set authentication_string=password(‘NEW PASSWORD’) where user=’root’;

    5. Restart mysql server

Using concurrent.futures to do Multithreading

Using concurrent.futures to download a list of urls and store the result in another list.

import concurrent.futures

import requests

def get_requests(url, data_list):

    resp = requests.get(url)


URLs = [”,”]


data_list = []

with concurrent.futures.ThreadPoolExecutor(max_workers=NUMBER_OF_THREADS) as executor:

    future_to_url = {executor.submit(get_requests, url, data_list):

                     url for url in URLs}

print data_list