Django + Gunicorn + Nginx Setup

Prior to gunicorn and nginx, i’ve tried to user apache + mod_wsgi and failed. Still don’t know why it fail. After 3 days trying, I give up. I have to look for another method, I try using gunicorn dan nginx, and It took me only 2 days for gunicord + nginx setup to works. ūüôā

Here is condition on my Django + Gunicorn + Nginx setup:

  • I use CentOS 7 on my server
  • I create new user for running django (in my case /home/myuser)
  • I install python 3.7.3, django, pandas, django_extensions, virtual environment, gunicorn dan nginx
  • My django project folder is /home/myuser/myproject
  • I put all my django app (created using ‘python manage.py startapp myapp apps/myapp’) in /home/myuser/myproject/apps

Here is some of reference I use:

Here is my setup:

/home/myuser/myproject/wsgi.py

import os
import sys

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
sys.path.append('/home/myuser/myproject/apps')

application = get_wsgi_application()

/etc/nginx/nginx.conf

user  nginx; 
worker_processes  1; 

error_log  /var/log/nginx/error.log warn; 
pid        /var/run/nginx.pid; 


events { 
   worker_connections  1024; 
} 


http { 
   include       /etc/nginx/mime.types; 
   default_type  application/octet-stream; 

   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' 
                     '$status $body_bytes_sent "$http_referer" ' 
                     '"$http_user_agent" "$http_x_forwarded_for"'; 

   access_log  /var/log/nginx/access.log  main; 

   sendfile        on; 
   #tcp_nopush     on; 

   keepalive_timeout  65; 

   #gzip  on; 

   include /etc/nginx/conf.d/*.conf; 
}

/etc/systemd/system/gunicorn.service

setup for gunicorn to be run as service.

[Unit] 
Description=gunicorn service 
After=network.target 

[Service] 
User=myuser 
Group=myuser 
WorkingDirectory=/home/myuser/myproject/ 
ExecStart=/home/myuser/app1/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/myuser/myproject/myproject.sock myproject.wsgi:application --log-level debug 

[Install] 
WantedBy=multi-user.target

don’t forget to enable service using:

systemctl enable gunicorn

/home/myuser/myproject/myproject/setting.py

import os 

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 

SECRET_KEY = '6sp(_!o*NOT_MY_REAL_KEY_OF_COURSE*uu5o(9q1+ir=:-)r' # change: my key

DEBUG = True # to be changed on production

ALLOWED_HOSTS = ['192.168.0.2','myuser.mydomain.com'] #change: my domain


# Application definition 

INSTALLED_APPS = [ 
   'django.contrib.admin', 
   'django.contrib.auth', 
   'django.contrib.contenttypes', 
   'django.contrib.sessions', 
   'django.contrib.messages', 
   'django.contrib.staticfiles', 
   'django.contrib.humanize', 
   'django_extensions', 
   'myproject', 
   'myproject.templatetags', # delete:my custom tags
   'login', # delete:my app
   'weeklyreport', # delete:my app
]
MIDDLEWARE = [ 
   'django.middleware.security.SecurityMiddleware', 
   'django.contrib.sessions.middleware.SessionMiddleware', 
   'django.middleware.common.CommonMiddleware', 
   'django.middleware.csrf.CsrfViewMiddleware', 
   'django.contrib.auth.middleware.AuthenticationMiddleware', 
   'django.contrib.messages.middleware.MessageMiddleware', 
   'django.middleware.clickjacking.XFrameOptionsMiddleware', 
] 

ROOT_URLCONF = 'myproject.urls' 

TEMPLATES = [ 
   { 
       'BACKEND': 'django.template.backends.django.DjangoTemplates', 
       'DIRS': ['templates'], 
       'APP_DIRS': True, 
       'OPTIONS': { 
           'context_processors': [ 
               'django.template.context_processors.debug', 
               'django.template.context_processors.request', 
               'django.contrib.auth.context_processors.auth', 
               'django.contrib.messages.context_processors.messages', 
           ], 
       }, 
   }, 
] 

WSGI_APPLICATION = 'myproject.wsgi.application' 


DATABASES = { 
   'default': { #change: my database setup
       'ENGINE': 'django.db.backends.mysql', 
       'NAME': 'mydb1', 
       'USER': 'myuseruser', 
       'PASSWORD': 'my_db_password', 
       'HOST': '192.168.0.2', 
       'OPTIONS': { 
           'read_default_file': '/etc/my.cnf.d/client.cnf', 
           'init_command': "SET sql_mode='STRICT_TRANS_TABLES'; SET SESSION binlog_format = 'ROW';", 
       },
        'jgmotordb': { #delete: my database setup
       'ENGINE': 'django.db.backends.mysql', 
       'NAME': 'mydb2', 
       'USER': 'myuseruser', 
       'PASSWORD': 'my_db_password', 
       'HOST': '192.168.0.2', 
       'OPTIONS': { 
           'read_default_file': '/etc/my.cnf.d/client.cnf', 
           'init_command': "SET sql_mode='STRICT_TRANS_TABLES'; SET SESSION binlog_format = 'ROW';", 
           } 
       }
   } 
}

AUTH_PASSWORD_VALIDATORS = [ 
   { 
       'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 
   }, 
   { 
       'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 
   }, 
   { 
       'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 
   }, 
   { 
       'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 
   }, 
] 

LANGUAGE_CODE = 'en-us' 
TIME_ZONE = 'UTC' 
USE_I18N = True 
USE_L10N = True 
USE_TZ = True 

STATIC_URL = '/static/' # my static folder
STATICFILES_DIRS = [ 
   os.path.join(BASE_DIR, '0static'),  # my static folder (before for 'collectstatic' command)
] 
STATIC_ROOT = os.path.join(BASE_DIR, 'static') 
AUTHENTICATION_BACKENDS = ( 'myproject.backend.custombackend', ) #delete: my custom backends

It’s my django project. Therefor, you might find my setup is not ideal, but it works! ūüôā (and it took me a week to make it works).

I learn that, most of tutorials use apt /¬†apt-get for installation. Since I use CenOS (which use yum as default) I find it annoying. ūüė¶

Please leave a comment for any suggestion or if you find this post helpful.

Mission Impossible: Fallout

Mission Impossible: Fallout

penggunaan practical effect daripada CGI racikan Christopher McQuarrie emang bikin setiap aksi laga bikin Fallout terasa lebih … genuine. Intrik politik didalamnya jadi ‘teka-teki’ yang menghibur buat ‘penonton pinter’ yang mau mendalami ceritanya, tapi untuk penonton yang cuma mau liat aksi dar der dor juga, film ini akan sangat memuaskan.

It is a beautifully crafted action movie, makes you feel that waching it once is not enough.

Kitab Wahyu X Avengers: Infinity War

Kitab Wahyu X Avengers: Infinity War

Catatan Sekolah Minggu

Kalau ada orang bertanya: ‚ÄúFilm Avengers: Infinity War, rame ga?‚ÄĚ
Saya akan balik bertanya: ‚Äúkamu nonton 18 film sebelumnya ga?‚ÄĚ

Ya, Avengers: Infinity War (AIW) adalah film action yang cukup fenomenal dan spektakuler, tapi ia cuma salah satu bagian dalam satu narasi besar Infinity War yang dimulai sejak 10 tahun lalu. Ada 18 film mendahului cerita AIW ini, sehingga orang yang menonton AIW tanpa mengikuti keseluruhan ceritanya dari awal, akan menemukan AIW sebagai film dar-der-dor yang wah tapi dengan alur cerita yang ga jelas dan ending yang ngegantung.

AIW sebagai bagian dari Marvel Cinematic Universe (MCU)

Membuat character development pada suatu film, memiliki tantangan tersendiri. Oleh sebab itu, pada umumnya film akan menampilkan tidak lebih dari 5-6 tokoh utama. Lebih dari itu, pada umumnya penonton akan cukup kesulitan mendalami masing-masing karakter. Disinilah keistimewaan AIW, AIW memiliki lebih dari 70 tokoh dan hampir semuanya memiliki character development di 18 film sebelumnya…

Lihat pos aslinya 725 kata lagi

Dilema Cinta Thanos

Dilema Cinta Thanos

Cinta boleh dikatakan tak mungkin nyata tanpa adanya pengorbanan. Kadang kala ada hal yang perlu dikorbankan demi kepentingan yang dicintai. Tapi bagaimana jika cinta kepada kemanusiaan yang damai dan sejahtera dicapai dengan mengorbankan sebagian umat manusia? Apalagi jika didasari dengan perhitungan matematis yang logis dan valid.

Namun herannya, mengapa kita tidak dapat menerima tindakan itu? Sedangkan pengorbanan para pembela ‚Äúkebenaran‚ÄĚ atas dasar cinta pada manusia dapat diterima bahkan sangat dikagumi? Ataukah sebenarnya cinta dan pengorbanan adalah kondisi hati dan wujud tindakan yang membutuhkan standar dan pedoman?

Jika demikian, maka kita perlu mengevaluasi kembali hal-hal yang kita cintai dan korbankan. Sebab cinta dan pengorbanan adalah keadaan hati dan tindakan yang mulia. Dan tentu saja, pada akhirnya kita dapat tertipu karena kemuliaan itu telah kita jadikan alat untuk kebodohan dan kejahatan. Jangan-jangan inilah yang disebut sebagai peperangan tanpa batas: perang kemanusiaan atas nama cinta

@wilsonmariop