aboutsummaryrefslogtreecommitdiff
path: root/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2
diff options
context:
space:
mode:
authorYaroslav <contact@yaroslavps.com>2020-03-17 15:19:15 +0300
committerYaroslav <contact@yaroslavps.com>2020-03-17 15:19:15 +0300
commita9e50293dceb237d665ba56903d414f5302ca4ff (patch)
tree185d310ba37366b37a11e1d695571759b11784a2 /content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2
parent2dace68a24ca0fc4355b2ebceea8eaa1be36fd10 (diff)
downloadyaroslavps.com-a9e50293dceb237d665ba56903d414f5302ca4ff.tar.gz
yaroslavps.com-a9e50293dceb237d665ba56903d414f5302ca4ff.zip
started migration of weblog articles
Diffstat (limited to 'content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2')
-rw-r--r--content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/index.md365
-rw-r--r--content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.pngbin0 -> 117627 bytes
2 files changed, 365 insertions, 0 deletions
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.
+
+<!-- more -->
+
+_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.
+
diff --git a/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png
new file mode 100644
index 0000000..586f708
--- /dev/null
+++ b/content/weblog/2018-07-21_building-deploying-personal-site-with-blog-pt2/result.png
Binary files differ