Building and deploying a personal site with blog. Part 2
Published 2018-07-21 on Yaroslav's weblog
Welcome back, this post is a continuation of the previous post in which I wrote
about how to initialize and setup a Django project for a personal site with
blog locally. Now we will be focusing on the juicy part, getting your site
deployed so that everyone on the interwebz can get to see your nice new dank
memes in your very own site! the fruits of your sweat and blood.
You might want to read part one
Part II: Deploying your site
I will assume that you already have bought a VPS or dedicated server in any of the many hosting services available online, or maybe if you are cool enough, might even have a machine of your own with a properly setup static IP address. Note that if you are using shared hosting, the deployment process is usually already automatized if they have support for Python and Django, if they don't support Python and Django, you need to get another hosting solution.
If you still don't have any kind of hosting, and you are looking for a nice and comfy VPS for your projects, I would recommend using DigitalOcean, you can get a VPS powerful enough for Django and other Python web projects for as low as $5. You can follow this referral link if you have decided to try DigitalOcean, it will give a $10 credit for your first account, enough for two whole months on their most inexpensive VPS.
Once you have your server set and ready to go, we can continue with the fun part. Deploying your site. I will be assuming that you have a Debian-based distro in your server.
First steps
First let's make sure that our server is up to date
$ sudo apt-get update
$ sudo apt-get upgrade
Next, we need to install all the needed packages
$ sudo apt-get install python3 python3-pip python-virtualenv postgresql nginx supervisor
You can set the virtual environment with your login user, or create another user exclusively to run your Django project and other related stuff.
You can add a user to run the app like so
$ adduser webuser
Let's go ahead and create a directory for virtual environments and create the environment for our project
$ virtualenv mysite -p python3
Now we source the environment
$ source mysite/bin/activate
And use pip to install the necessary modules
$ pip install Django Pillow psycopg2 django-summernote w3blog
After that, we start and enable postgresql
$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
Login to the postgres shell, set the password for user postgres, and create the database for our project
$ sudo su - postgres
$ psql
postgres=# \password
postgres=# create database mysitedb;
In this case, I am using the postgres user directly since I am using this server just for myself, and I only use PSQL for my blog. However, if you host multiple projects, and/or multiple users have a more direct access to postgres, you might want to create separate users and roles for each database or group of databases.
Copying your Django project to the server
One way to copy your project files to the server would be using scp, for example
scp -r /path/to/project user@serveripordomain:/home/webuser/
Or if you are already hosting your project as a git repository in a service like GitHub or BitBucket, you could clone directly into you repository in the home folder, like so
$ git clone https:/github.com/user/repo
After the files have been copied, we need to set some things up for our Django project. Before running this commads, you might need to export the needed environmental variables, if you set up your Django settings using environmental variables as I wrote in the first part. Otherwise, you might want to edit your settings.py file now with the correct settings.
First we collect static files
$ ./manage.py collectstatic
Then, we migrate our models to the database
$ ./manage.py migrate
And after migrating we create a superuser for the Django admin
$ ./manage.py createsuperuser
If you get an authentication error while performing any of the above commands, you will have to edit the following file
$ sudoedit /etc/postgresql/9.1/main/pg_hba.conf
Change this line
local all postgres peer
So that it looks like this
local all postgres md5
Configuring the server
I will be assuming that you are going to use nginx as a proxy server for Django. There are other alternatives such as Apache, but I found nginx to be a really powerful and easy to setup server.
First, while in our virtual environment, we will install gunicorn. We might have been using Django's own development server while building and testing our app locally, but that's what it is, a development server. It is not mean for production, so we will use gunicorn for that
pip install gunicorn
Now we'll cd into our env's bin folder and create a file called
gunicorn_start
, and add the following lines to it:
#!/bin/bash
NAME="mysite"
# Our site's directory
DIR=/home/webuser/mysite
USER=webuser
GROUP=webuser
WORKERS=3
BIND=127.0.0.1:8001
DJANGO_SETTINGS_MODULE=mysite.settings
DJANGO_WSGI_MODULE=mysite.wsgi
LOG_LEVEL=error
cd $DIR
source /home/webuser/venvs/mysite/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DIR:$PYTHONPATH
# This are the environment variables needed for your Django settings
# (see the first part of this guide)
export SITE_SECRETKEY="YOURSECRETKEYGOESHERE"
export SITE_DEBUG="false"
export SITE_DBPASSWORD="YOURPOSTGRESPWDGOESHERE"
export SITE_DBUSER="postgres"
export SITE_HOST="localhost"
export SITE_PORT="5342"
exec /home/webuser/venvs/mysite/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $WORKERS \
--user=$USER \
--group=$GROUP \
--bind=$BIND \
--log-level=$LOG_LEVEL \
--log-file=-
And make it executable
$ chmod a+x gunicorn_start
That's almost it, but before actually running gunicorn, we will install one more program which will take care of the gunicorn server, so that if for any reason we need to reboot our server, it will restart gunicorn for us. It needs to be some kind of supervisor. Well why my dear friend, we are going to use Supervisor.
But first, let's create a folder name logs inside our webuser's home folder, and create a file to be used to log any application errors:
$ mkdir logs
$ touch logs/gunicorn.log
Now we create a new Supervisor config file:
$ sudoedit /etc/supervisor/conf.d/mysite.conf
Add the following:
[program:mysite]
command=/home/webuser/venvs/mysite/bin/gunicorn_start
user=webuser
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/webuser/logs/gunicorn.log
We reread the Supervisor configuration files, and start the program:
$ sudo supervisorctl reread
$ sudo supervisorctl update
And check the status to make sure it is running fine and dandy
$ sudo supervisorctl status mysite
Next we should configure nginx, and for that we are going to make the configuration file for our site. Open it up
$ sudoedit /etc/nginx/sites-available/mysite
And add the following lines
server {
listen 80;
listen [::]:80;
server_name www.example.com;
location /static/ {
alias /home/webuser/mysite/static/;
}
location /media/ {
alias /home/webuser/mysite/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8001;
}
}
I won't be explaining in this guide how to setup an SSL certificate, since it is out of its scope, but, if you want to get a free certificate, I cant point you to letsencrypt.com. It is backed by many of the top internet organizations. If you already have an SSL certificate, and would like to use HTTPS, your file should look like this
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/cert/fullchain.pem;
ssl_certificate_key /path/to/key/privkey.pem;
location /static/ {
alias /home/webuser/mysite/static/;
}
location /media/ {
alias /home/webuser/mysite/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8001;
}
}
After creating the needed config file, we create a symbolic link to it in sites-enabled
$ sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
Remove the default nginx site
$ sudo rm /etc/nginx/sites-enabled/default
Finally, we restart nginx
$ sudo service nginx restart
Et voila!
Final thoughts
This was by no means the most comprehensive guide to Django, but it might help you get started on setting up your own projects, and most importantly, actually deploying them to a live server.
https://www.yaroslavps.com/weblog/building-deploying-personal-site-with-blog-pt2/
© 2018—2024 Yaroslav de la Peña Smirnov.