Requirements
Command:
sudo yum install epel-release
sudo yum install python-pip python-devel postgresql-server postgresql-devel postgresql-contrib gcc nginx wget git python36
sudo postgresql-setup initdb
This installs the extra packages for linux repo on centos that allows downloads of the other requirements. Then it installs the python tools we will be needing to setup a virtual env for our project along with postgres and nginx. Finally the last command initializes the Postgres db.
Setup Postgres 1
Command:
sudo systemctl start postgresql
sudo systemctl enable postgresql
This start and enables the start of the postgres database on restart.
Setup Postgres 2
Command:
sudo vi /var/lib/pgsql/data/pg_hba.conf
Edit the postgres connector file with the following info
/var/lib/pgsql/data/pg_hba.conf
#Skip this and copy below
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
#host all all 127.0.0.1/32 ident
host all all 127.0.0.1/32 md5
# IPv6 local connections:
#host all all ::1/128 ident
host all all ::1/128 md5
Enable Postgres After the Changes
Command:
sudo systemctl restart postgresql
sudo systemctl enable postgresql
Start postgres and enable on reboot
Create Postgres Database
Command:
sudo su - postgres
psql
Test the databae
Command:
exit
psql -U djangodatabaseuser -h localhost -d yourdatabasename
Exit the postgres user and then use postgres to attempt to connect to the database
Get python 3.6 with
Command:
yum -y install python36
wget https://bootstrap.pypa.io/get-pip.py
sudo python3.6 get-pip.py
sudo python3.6 -m pip install virtualenv
This installed python36. I will do a guide for higher versions of python in a future blog. Back to the commands, they install python3 which is needed for django2, get pip for python 3 then installs pip then install virtualenv for our pip which we will need for building our django virtual environment in the future.
Create user for Django Project
Command:
sudo adduser djangoprojectuser
I run each Django project with a custom user for that project for security reasons.
Create Django Env Dir
Command:
sudo mkdir /home/djangoprojectuser/projectname-env
sudo chown -R djangoprojectuser:djangoprojectuser /home/djangoprojectuser/projectname-env
sudo cd /home/djangoprojectuser/
python3.6 -m virtualenv projectname-env
sudo chown -R djangoprojectuser:djangoprojectuser /home/djangoprojectuser/projectname-env
I put this in the django project user's home dir but you can put it wherever you like.
Activate Virtual Env for Project
Command:
source yourproject-env/bin/activate
This activates the python3.6 virtual env for your project
Install Django into the Virtual Env
Command:
pip install django gunicorn psycopg2
or
pip install -r requirements.txt
The top is the base you need to get django going. If you have a dev project which you probably do you can freeze the virtual env using pip freeze -l > requirements.txt and send it to the directory you want to install it from.
New Project. Skip if gitting in project
Command:
cd ..
python djangoadmin startproject projectname
This takes you back to home directory for the djangoprojectuser and then creates a project folder named whatever you put in projectname. You can then start building your app or editing your setting.py file
Install Project with Git
Command:
yum install git
git clone https://respository
cd project name
python makemigrations
python migrate
python manage.py makesuperuser
python manage.py runserver
These commands add the git folder from git. You will or should change the settings file or have it using env variables. You will want to add the djangodbuser and make sure it is setup with the postgres connector the way we are setitngs this up and I would change the secret key. You are then having python build the changes and migrate the changes to the database. Then creating an admin user and testing the dev server to make sure the project starts up correctly and is not throwing any errors.
Test Gunicorn
Command:
gunicorn --bind 0.0.0.0:8000 bottomofbarrel.wsgi:application
Make sure you are in the project dir. Then issue this command to make sure gunicorn is going to work. At this point you should be able to go your project by the http://yourip:8000. If that works you are ready to startup your service.
Deavtivate virtualenv
Command:
deactivate
This takes you out of your virtual enviroment
Create Gunicorn service
Command:
sudo vi /etc/systemd/system/projectname.service
Then click i to go into insert mode
This starts to configure the systemd service. Paste the below into it.
/etc/systemd/system/gunicorn.service
[Unit]
Description=Projectname daemon
After=network.target
[Service]
User=djangoprojectuser
Group=nginx
WorkingDirectory=/home/djangoprojectuser/project/
ExecStart=/home/djangoprojectuser/djangoproject-env/bin/gunicorn --workers 3 --bind unix:/home/djangoprojectuser/djangoproject/bottomofthebarrel.sock bottomofbarrel.wsgi:application
[Install]
WantedBy=multi-user.target
Save the serice
Command:
click esc
type :wq!
This exits insert mode and saves the file
Enable the Django Service
Command:
sudo systemctl start projectname
sudo systemctl enable projectname
Start the service that you just created. Whatever you can name the service whatever you want but I find it easiest to name it based on the project.
Nginx Config
Command:
sudo vi /etc/nginx/nginx.conf
This takes you to default nginx config. There will be another blog on how to do seperate site configs. Find the server block and make the changes below
Nginx Server Block
###Match the server block with something similar to below###
server {
access_log /var/log/nginx/projectname-access.log;
error_log /var/log/nginx/projectname-error.log;
server_name yourdomain.com;
gzip on;
gzip_proxied any;
gzip_buffers 16 8k;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_vary on;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
autoindex on;
alias /home/djangprojectuser/project/static/;
}
location /media/ {
autoindex on;
alias /home/djangprojectuser/project//media/;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix /home/djangprojectuser/project/gallowaylabs.sock;
}
Nginx config explained
Command:
Esc
:wq!
The top command saves the config. In the actual name, put your domain name or ip for server, it is going to listen on 80 if you do not change this. Point the static and media to where you have saved them in your file, I keep them in the main project folder. fianlly you want to make sure the proxy_pass is pointing to where you had the .sock file go in the service. This is the unix socket that is created by gunicorn that nginx is using for requests. Not that in your settings file you will need add allowed host name to whatever you nginx server is listening for.
Nginx permissions for Project
Command:
sudo usermod -a -G djangoprojectuser nginx
chmod -r 710 /home/djangoprojectuser
The first command puts you into the nginx group so nginx can access your folders. The second sets permissions on the project folder and env.
Testing nginx
Command:
sudo nginx -t
Test the nginx config. You will find errors in /var/log/nginx/error.log by default. A common error you will find with little details is SE Linux enabled on centos. You can disable if you want to get it running fast. Otherwise set to permissive and write custom rules for your Django app.
Enable Nginx
Command:
sudo systemctl start nginx
sudo systemctl enable nginx
Start nginx which should work fine if the tests have passed. Then the second command enables nginx on restart.
Firewall rules
Command:
yum install firewalld
sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
This makes sure firewalld is installed. The second command per mentally opens 443 and the next command does the same for 80.
SSL Cert
Command:
sudo yum install certbot-nginx
certbot --nginx
These commands should find your domain from nginx and then you can click option 2 for a permanent redirect from 80 to 443. Note that if you do not have public dns that is the same as the certbot this part will fail but you will still be able to access your site in clear text from http. I would not log into the admin portal if you are doing this as it will be in clear text with no encryption.
Conclusion
Command:
You should be up and running
At this point as long as you have dns records or are accessing through ip, you should have a fully functioning django website. Do some testing and make sure you set DEBUG=false in the settings file.