Deploying A Masonite Project To AWS
Tags: aws, ec2, masonite, python
Published: 2020-04-06 18:53:14

## Deploying Masonite To AWS

In this article we are going to walk through the steps of deploying your Masonite python project to an EC2 instance on AWS. We are going to be using Ubuntu 18.04 LTS, Nginx as a front-end reverse proxy and uWSGI as the application server. 



### Prerequisites

Before moving on there are a few prerequisites.

- An AWS account
- A Masonite project ready to be deployed
- All your dependencies should be inside your requirements.txt so we can easily install them.
- Some knowledge of AWS and EC2



### Step 1 - Spin Up An EC2 Instance

Our first step is to get an EC2 instance up and running with Ubuntu 18.04 LTS. Let's go ahead and open up the AWS console and head over to the EC2 dashboard. Launch an instance and make sure to select the Ubuntu 18.04 image. You can choose any instance type but I chose a T2 Nano for this purpose. Be sure to edit the security group to allow HTTP traffic through port 80. You can leave everything else as is for now. Just go ahead and click Review & Launch. Don't forget to download the Key Pair so we can SSH into the instance. 



### Step 2 - Install Nginx

Once the EC2 instance is up and running, SSH into it so we can install Nginx. 

```bash
sudo apt update
sudo apt install nginx
```

This will install Nginx and all the required dependencies. To confirm lets check the status of Nginx. 

```bash
sudo systemctl status nginx
```

You should see something like this below

```
Output
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-04-06 18:32:37 UTC; 10s ago
     Docs: man:nginx(8)
 Main PID: 2417 (nginx)
    Tasks: 2 (limit: 547)
   CGroup: /system.slice/nginx.service
           ├─2417 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─2419 nginx: worker process
```

As you can see it looks as though Nginx is up and running. The best way to actually test this is to see if we can get Nginx to serve anything. 

Open up a browser and visit:

```
http://your_ec2_ip_address
```

If all is working  you should see the default Nginx screen

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9pnv2ei954w4vdwjkmo5.png)

Now that we have Nginx installed and running we can move onto installing some necessary dependencies.



### Step 3 - Installing System Dependencies

We need to install all the dependencies we need to get our Masonite project and uWSGI server working. We are going to install `pip` and everything needed for uWSGI.

Run the following command

```bash
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools python3-venv git
```

Once this is done we can start setting up our python virtual environment. 


### Step 4 - Deploying Masonite Project

Now we need to get our Masonite project into the project folder we just created. There are a few ways to do this. We are going to use git to clone our repo. 

```bash
mkdir ~/masoniteproject
cd ~/masoniteproject
```

```bash
git clone https://github.com/repoOwner/yourRepo .
```

This will install your project into our current directory. Once your project is on the EC2 instance we can move onto installing your project dependencies.



### Step 4 - Virtual Environment

In order to isolate our Masonite application we need to create a Virtual Environment. 

```bash
python3.6 -m venv venv
source venv/bin/activate
```

Those commands have created and activated our virtual environment allowing us to now install our python dependencies and our application server uWSGI


### Step 6 - Installing Project Dependencies

Before we install any project dependencies we are going to install a few things we need. Make sure your virtual environment is still activated.

> HINT: Please install using pip and not pip3.

Now lets install our application server uWSGI and wheels.

```bash
pip install wheel uwsgi
```

Finally, we can install all our project dependencies. 

```bash
pip install -r requirements.txt
```

This will install our masonite dependencies along with any other dependencies you have placed in `requirements.txt`

 We can now deactivate our virtual environment

```bash
deactivate
```



### Step 7 - Creating a uWSGI configuration file

The next step is to configure uWSGI to serve our application. First we need to create a uWSGI configuration file.

```bash
nano ~/masoniteproject/project.ini
```

Add the following information into your `project.ini`

```ini
[uwsgi]
module = wsgi
callable = application

master = true
processes = 5

socket = project.sock
chmod-socket = 660
vacuum = true

die-on-term = true
```

Save your ini and let's move onto creating a service.



### Step 8 - Creating Systemd service file

Creating a systemd unit file will allow Ubuntu to automatically start your uWSGI application server whenever it boots. 

```bash
sudo nano /etc/systemd/system/project.service
```

Put the following information into your service file.

```ini
[Unit]
Description=uWSGI instance to serve your masonite project
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/masoniteproject
Environment="PATH=/home/ubuntu/masoniteproject/venv/bin"
ExecStart=/home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini

[Install]
WantedBy=multi-user.target
```

Save that file and now we have a service. We can now start our uWSGI server and enable it so it boots on startup.

```bash
sudo systemctl start project
sudo systemctl enable project
```

You can check the status of your project using this:

```bash
sudo systemctl status project
```
You should see something like this:
```
Output
● project.service - uWSGI instance to serve your masonite project
   Loaded: loaded (/etc/systemd/system/project.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-04-06 18:45:27 UTC; 8s ago
 Main PID: 8946 (uwsgi)
    Tasks: 6 (limit: 547)
   CGroup: /system.slice/project.service
           ├─8946 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
           ├─8975 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
           ├─8976 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
           ├─8977 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
           ├─8978 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
           └─8979 /home/ubuntu/masoniteproject/venv/bin/uwsgi --ini project.ini
```


If you see any errors, be sure to resolve them before continuing on to configure Nginx



### Step 9 - Configuring Nginx

Let's start by creating an Nginx configuration file for our project

```bash
sudo nano /etc/nginx/sites-available/masoniteproject.conf
```

Put the following information into your conf file.

```nginx
server {
    listen 80;
    server_name aws_ec2_ip_address;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/ubuntu/masoniteproject/project.sock;
    }
}
```

To enable the Nginx server block configuration you’ve just created, link the file to the `sites-enabled` directory:

```bash
sudo ln -s /etc/nginx/sites-available/masoniteproject.conf /etc/nginx/sites-enabled
```

Now lets restart Nginx to make our changes take effect.

```bash
sudo systemctl restart nginx
```

You should now be able to navigate to your EC2's IP address in your web browser:

```
http://aws_ec2_ip_address
```
You should see your masonite project in your browser.



### Conclusion

Ta da! Your masonite project is now hosted on an AWS EC2 instance. Make sure you set up your `.env` file. We are missing an important piece to all this though. And that is that database. I'm going to be writing another article soon about connecting your Masonite EC2 instance to an AWS RDS database. Please leave any comments or questions below and I will try to answer them the best I can.