-
Notifications
You must be signed in to change notification settings - Fork 0
How To Deploy
We assume that the server user is set up based on the previous wiki page.
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install python-virtualenv
$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"
$ sudo dpkg-reconfigure locales
$ virtualenv ~/bidiloenv -p python3
$ sudo apt-get install rabbitmq-server
$ sudo apt-get install libpq-dev python3-dev
$ sudo apt-get install postgresql postgresql-contrib
$ sudo -u postgres psql
postgres=# CREATE DATABASE bidilo;
postgres=# CREATE USER bidilouser WITH PASSWORD 'PASSWD';
postgres=# ALTER ROLE bidilouser SET client_encoding TO 'utf8';
postgres=# ALTER ROLE bidilouser SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE bidilouser SET timezone TO 'Asia/Tehran';
postgres=# GRANT ALL PRIVILEGES ON DATABASE bidilo TO bidilouser;
postgres=# \q
The requirements should now be composed of these files:
requirements/
base.py
development.py
production.py
The we add gunicorn and psycopg2-binary to the production requirements.
We then add the following at the end of settings.py:
try:
from .local_settings import *
except ImportError:
passAnd in last, we create a local_settings.py for the project:
SECRET_KEY = 'i#%ew3j&g9fg*p++n$5=f*=ko)2=2=m-e)(7fl@pjg$c=wb=w%'
DEBUG = False
ALLOWED_HOSTS = ['IP', 'localhost']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'bidilo',
'USER': 'bidilouser',
'PASSWORD': 'PASSWD',
'HOST': 'localhost',
'PORT': '',
}
}Now we are ready to clone the project:
$ git clone https://github.com/kgolezardi/SAD-Project.git
$ source ~/bidiloenv/bin/activate
$ cd SAD-Project/bidilo
$ pip install -r requirements/production.txt
$ # Change local settings
$ ./manage.py collectstatic
$ ./manage.py migrate
$ ./manage.py createsuperuser
$ sudo ufw allow 8123
$ # We can now test the server with django runserver or gunicorn$ sudo vim /etc/systemd/system/gunicorn.socket:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
sudo vim /etc/systemd/system/gunicorn.service:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=bidilo
Group=www-data
WorkingDirectory=/home/bidilo/SAD-Project/bidilo
ExecStart=/home/bidilo/bidiloenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
bidilo.wsgi:application
[Install]
WantedBy=multi-user.target
Now we have created the systemd socket and service file for gunicorn. We can now start and enable the Gunicorn socket. This will create the socket file at /run/gunicorn.sock now and at boot. When a connection is made to that socket, systemd will automatically start the gunicorn.service to handle it:
$ sudo systemctl start gunicorn.socket
$ sudo systemctl enable gunicorn.socket
Installation is typically done by sudo apt-get install nginx.
$ sudo vim /etc/nginx/sites-available/bidilo:
server {
listen 80;
server_name IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/bidilo/SAD-Project/bidilo;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Now, we can enable the file by linking it to the sites-enabled directory:
$ sudo ln -s /etc/nginx/sites-available/bidilo /etc/nginx/sites-enabled
Test your Nginx configuration for syntax errors by typing:
$ sudo nginx -t
Restart Nginx by typing sudo systemctl restart nginx.
We can now remove out previous firewall rule: sudo ufw delete allow 8000 and a new one just for NGINX:
$ sudo ufw allow 'Nginx Full'
The server is now ready to serve!
$ sudo vim /etc/systemd/system/celery.service:
[Unit]
Description=Celery Service
After=network.target
[Service]
Type=forking
User=bidilo
Group=www-data
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/home/bidilo/SAD-Project/bidilo
ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} \
-A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
--logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} \
--pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh -c '${CELERY_BIN} multi restart ${CELERYD_NODES} \
-A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
--logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
[Install]
WantedBy=multi-user.target
$ sudo vim /etc/conf.d/celery:
# Name of nodes to start
# here we have a single node
CELERYD_NODES="w1"
# or we could have three nodes:
#CELERYD_NODES="w1 w2 w3"
# Absolute or relative path to the 'celery' command:
CELERY_BIN="/home/bidilo/bidiloenv/bin/celery"
# App instance to use
# comment out this line if you don't use an app
CELERY_APP="bidilo"
# or fully qualified:
#CELERY_APP="proj.tasks:app"
# How to call manage.py
CELERYD_MULTI="multi"
# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=8"
# - %n will be replaced with the first part of the nodename.
# - %I will be replaced with the current child process index
# and is important when using the prefork pool to avoid race conditions.
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"
Now we should create the directories for our logs:
$ sudo mkdir /var/log/celery
$ sudo chown bidilo /var/log/celery
$ sudo chgrp www-data /var/log/celery
$ sudo mkdir /var/run/celery
$ sudo chown bidilo /var/run/celery
$ sudo chgrp www-data /var/run/celery
Then we run these commands to start celery daemon:
$ sudo systemctl daemon-reload
$ sudo systemctl restart celery
If some changes were made to the Django code, you should restart Gunicorn socket by:
$ sudo systemctl restart gunicorn.socket
If you make changes to the /etc/systemd/system/gunicorn.service file, reload the daemon to reread the service definition and restart the Gunicorn process by typing:
$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn
This also gets the job done after changing Django code.
Most of this wiki has came to life with the help of this DigitalOcean page.
Also this is a similar document.