Masonite is an incredible developer friendly framework to develop modern web applications with python. With a lot of out of the box functionality with an extremely extendable architecture. On my own experience, it helps you a lot to build your applications with a beautiful code.
It brings you a useful utility called craft
command that make much easy and faster to create your models/controllers/authentication/middlewares classes and so on.
Craft command brings built in a web server designed to run on development environment your web application. While this makes development comfortable, this web server is not designed to deploy on production.
On this guide i will try to explain how to configure and deploy your Masonite app on a virtual private server such as AWS or DigitalOcean.
Requirements used for this guide
- Debian Buster
- Masonite 2.2
- Python 3.7
- Nginx
- Gunicorn
Installing your web app
To start, i will make a new Masonite project. I'm gonna skip the install step because is no the goal of this guide, but you can use this very well explained tutorial for installation process.
craft new demoapp
cd demoapp
# Create the virtual env with python3
python3 -m venv venv
source venv/bin/activate
craft install
This will make a new demoapp folder with the crafted application, then it will create the virtual env and activate it and to finish it will install the requirements described in the requirements.txt
file.
In this last step (on my machine using Debian Sid) it prints some errors with Debian version of python wheels installed:
Failed building wheel for masonite
Failed building wheel for masonite-validation
Failed building wheel for masonite-dot
Failed building wheel for pyyaml
but craft command creates the application key and all is working without problems, but if it makes you noise, my suggested workaround is to install in the virtual env the wheels with pip:
# activate virtualenv if is deactivated
source venv/bin/activate
pip install wheel
craft install
Install nginx & gunicorn
In debian you can use apt, apt-get or aptitude to install packages. We will need to install nginx web server and configure it to make a proxy reverse to gunicorn.
# We need nginx and gunicorn3 for python3
sudo aptitude install nginx gunicorn3
Gunicorn is a Python WSGI HTTP Server for UNIX. Is recommended to use Gunicorn behind an HTTP proxy server (as Nginx in this case).
Masonite brings out of the box a wsgi.py
file that you can use to execute our application:
gunicorn3 wsgi:application
Gunicorn defaults settings will allow to access to local machine only. If you want to access from other device you can use -b
option.
Nginx and Gunicorn Configuration
After install nginx we will configure Gunicorn to run as a service on systemd, so this will allow us to control with systemctl
command and run after system reboot.
This will be the /etc/nginx/sites-avalaible/default
file, the path to the project is /home/admin/webapps/demoapp
server {
server_name demoapp.io;
location = /favicon.ico { access_log off; log_not_found off; }
location /public/ {
root /home/admin/webapps/demoapp/storage;
}
location /static/ {
root /home/admin/webapps/demoapp/storage;
}
location /uploads/ {
root /home/admin/webapps/demoapp/storage;
}
location /compiled/ {
root /home/admin/webapps/demoapp/storage;
}
access_log /var/log/nginx/access.log;
location / {
include proxy_params;
proxy_set_header Host $host;
proxy_pass http://unix:/run/gunicorn.socket;
}
}
Now the Nginx config file is edited we need to check the syntax is ok:
sudo nginx -t
# Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Create the Gunicorn service:
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
PIDFile=/run/gunicorn/pid
User=admin
Group=www-data
RuntimeDirectory=gunicorn
WorkingDirectory=/home/admin/webapps/demoapp
ExecStart=/usr/bin/gunicorn3 --pid /run/gunicorn/pid\
--workers 3\
--bind unix:/run/gunicorn.socket wsgi\
--error-logfile /home/admin/logs/error.log\
--access-logfile /home/admin/logs/access.log\
--log-level debug\
--timeout 320
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
This service file execute gunicorn3
command using the pid-file (on /run/gunicorn/pid
) and make a connection thought a socket file located on /run/gunicorn.socket
, it saves logs on /home/admin/logs/
directory so it will need permissions:
mkdir ~/logs/
sudo chown admin.www-data ~/logs/
Create /etc/systemd/system/gunicorn.socket
file:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.socket
[Install]
WantedBy=sockets.target
Now almost everything is in place, we need to reload our services:
sudo systemctl daemon-reload
# start gunicorn
sudo systemctl start gunicorn
To check if gunicorn service is working:
sudo systemctl status gunicorn
# Output
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled)
Active: active (running) since Wed 2019-07-29 21:05:07 UTC; 49s ago
Main PID: 10154 (gunicorn)
CGroup: /system.slice/gunicorn.service
├─10154 /home/admin/webapps/demoapp/venv/bin/python3 /home/admin/webapps/demoapp/venv/bin/gunicorn --workers 3 --bind unix:/run/gunicorn.socket wsgi:application
├─10157 /home/admin/webapps/demoapp/venv/bin/python3 /home/admin/webapps/demoapp/venv/bin/gunicorn --workers 3 --bind unix:/run/gunicorn.socket wsgi:application
├─10158 /home/admin/webapps/demoapp/venv/bin/python3 /home/admin/webapps/demoapp/venv/bin/gunicorn --workers 3 --bind unix:/run/gunicorn.socket wsgi:application
└─10159 /home/admin/webapps/demoapp/venv/bin/python3 /home/admin/webapps/demoapp/venv/bin/gunicorn --workers 3 --bind unix:/run/gunicorn.socket wsgi:application
Dec 21 21:05:07 debian-512mb-nyc3-01 systemd[1]: Started gunicorn daemon.
Finally restart nginx to work with our deployed application
sudo systemctl restart nginx
Conclusions
If you like beautiful code, try Masonite.
Top comments (3)
Awesome explanation!
Thanks for this awesome guide!.
hey, I want to build a web app using python, can you please help me on how to get started?