From a9e50293dceb237d665ba56903d414f5302ca4ff Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Tue, 17 Mar 2020 15:19:15 +0300 Subject: started migration of weblog articles --- .../index.md | 365 +++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md (limited to 'content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md') diff --git a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md new file mode 100644 index 0000000..5bfd1f1 --- /dev/null +++ b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md @@ -0,0 +1,365 @@ ++++ +title = "Building and deploying a personal site with blog. Part 2" +date = 2018-07-21T22:26:00Z ++++ + +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](/weblog/building-deploying-personal-site-with-blog-pt1/)_ + +## 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 + +```sh +$ sudo apt-get update +$ sudo apt-get upgrade +``` + +Next, we need to install all the needed packages + +```sh +$ 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 + +```sh +$ adduser webuser +``` + +Let's go ahead and create a directory for virtual environments and create the environment for our project + +```sh +$ virtualenv mysite -p python3 +``` + +Now we source the environment + +```sh +$ source mysite/bin/activate +``` + +And use pip to install the necessary modules + +```sh +$ pip install Django Pillow psycopg2 django-summernote w3blog +``` + +After that, we start and enable postgresql + +```sh +$ 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 + +```sh +$ 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 + +```sh +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 + +```sh +$ 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 + +```sh +$ ./manage.py collectstatic +``` + +Then, we migrate our models to the database + +```sh +$ ./manage.py migrate +``` + +And after migrating we create a superuser for the Django admin + +```sh +$ ./manage.py createsuperuser +``` + +If you get an authentication error while performing any of the above commands, +you will have to edit the following file + +```sh +$ 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 + +```sh +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: + +```sh +#!/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 + +```sh +$ 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: + +```sh +$ mkdir logs +$ touch logs/gunicorn.log +``` + +Now we create a new Supervisor config file: + +```sh +$ sudoedit /etc/supervisor/conf.d/mysite.conf +``` + +Add the following: + +```cfg +[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: + +```sh +$ sudo supervisorctl reread +$ sudo supervisorctl update +``` + +And check the status to make sure it is running fine and dandy + +```sh +$ 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 + +```sh +$ sudoedit /etc/nginx/sites-available/mysite +``` + +And add the following lines + +```nginx +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 + +```nginx +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 + +```sh +$ sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite +``` + +Remove the default nginx site + +```sh +$ sudo rm /etc/nginx/sites-enabled/default +``` + +Finally, we restart nginx + +```sh +$ sudo service nginx restart +``` + +Et voila! + +![It's alive!](result.png) + +## 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. + -- cgit v1.2.3