[PYTHON] Deploy a Django application on EC2 with Nginx + Gunicorn + Supervisor

I launched a Django application with a combination of Nginx + Gunicorn + Supervisor, so a memo of the procedure This time we will start with nothing in the OS

environment

OS: Amazon Linux AMI Python: 3.6.1 Django: 1.11.4 Nginx: 1.10.3 Gunicorn: 19.7.1 Supervisor: 3.3.3

Nginx installation

nginx installation

$ sudo yum install nginx

start nginx

$ sudo nginx

nginx auto start setting

$ sudo chkconfig --add nginx
$ sudo chkconfig nginx on

Confirm automatic start setting If it looks like the following, it's ok

$ chkconfig | grep nginx
nginx          	0:off	1:off	2:on	3:on	4:on	5:on	6:off

Access http: // ip address and check if it is running properly OK if it is as follows スクリーンショット 2017-08-03 13.40.56.png

Building a Python environment

This time it was built with Anaconda Download the Python 3.6 version from here Upload the downloaded package to / home / ec2-user with an FTP tool such as Cyberduck

After uploading, install Anaconda with the following command

$ bash Anaconda3-4.4.0-Linux-x86_64.sh

After the installation is complete, put it in your PATH so that you can use Anaconda commands.

$ export PATH="$PATH:/home/ec2-user/anaconda3/bin"

Confirm by typing the command of conda

$ conda info -e
# conda environments:
#
root                  *  /home/ec2-user/anaconda3

It's good

In addition, if you added environment variable settings to bashrc when installing annaconda

Do you wish the installer to prepend the Anaconda3 install location
to PATH in your /root/.bashrc ? [yes|no]
[no] >>> yes

The root environment python is also 3.6

$ python --version
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)

Create a Django project

This time I will create a project directly on EC2 You should git clone a locally developed Django application DB also uses the default SQlite, but use Postgresql or MariaDB to publish the actual service.

First, install Django Whether or not to run in the root environment is a bit controversial, and I think that it is better to create a separate environment and run Django, but for the time being, I will install it in the root environment.

$ pip install django

Create a project if there is no problem

$ django-admin startproject test_project

Confirm that the project has been created

$ ls -ltr
total 511032
-rw-rw-r--  1 ec2-user ec2-user 523283080 Aug  3 04:50 Anaconda3-4.4.0-Linux-x86_64.sh
drwxrwxr-x 20 ec2-user ec2-user      4096 Aug  3 04:53 anaconda3
drwxrwxr-x  3 ec2-user ec2-user      4096 Aug  3 05:05 test_project

Edit ALLOW HOST of /test_project/test_project/settings.py as follows

settings.py


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ["IP address of the server"]

Start Django with the following command By default 127.0.0.1:8000 is used as the bind address, so you need to add 0.0.0.0:8000 as an option In addition, it is necessary to open port 8000 in the AWS security group in advance.

$ cd test_project
$ python manage.py runserver 0.0.0.0:8000

And if you access http: // IP address: 8000, you can access the Django application as follows スクリーンショット 2017-08-03 15.23.25.png

Install Gunicorn

Gunicorn is a WSGI server made by Python A WSGI server is a server that connects a web server and a web application. So, I hope you can imagine a configuration like Nginx <-> Gunicorn <-> Django.

First, install Gunicorn

$ pip install gunicorn

Launch Django with Gunicorn once installed

$ gunicorn test_project.wsgi --bind=0.0.0.0:8000

As before, you can connect to your Django application by visiting http: // IP address: 8000 If settings.py is divided into production and development, it looks like the following.

$ gunicorn test_project.wsgi.wsgi --env DJANGO_SETTINGS_MODULE=test_project.settings_dev --bind=0.0.0.0:8000

Change Nginx settings

Edit /etc/nginx.conf as follows

/etc/nginx.conf



~ Omitted ~

http {
~ Omitted ~

    upstream app_server {
        server 127.0.0.1:8000 fail_timeout=0;
    }

    server {
        #Comment out the following 4 lines
        #listen       80 default_server;
        #listen       [::]:80 default_server;
        #server_name  localhost;
        #root         /usr/share/nginx/html;

        #Add the following 3 lines
        listen    80;
        server_name IP address or domain;
        client_max_body_size    4G;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            #Add the following 4 lines
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass   http://app_server;
        }

~ The following is omitted ~

After editing, restart nginx with the following command

$ sudo service nginx restart
Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]

This completes the reverse proxy settings in Nginx This time I edited nginx.conf directly, but it is also OK to write the configuration file somewhere else and load it.

Then launch Django with Gunicorn

$ gunicorn test_project.wsgi --bind=0.0.0.0:8000

Next, when you access http: // IP address, you should see the Django screen.

Daemonize a process with Supervisor

In the current state, if you stop the Gunicorn command or log out from the server, the application will stop. To solve this, daemonize the Gunicorn process with Supervisor.

I'd like to install Supervisor immediately, but Supervisor only works with Python 2 series. Therefore, build a Python2 virtual environment with Anaconda and install Supervisor in that environment.

First, create a Python2 virtual environment for Supervisor with the following command

$ conda create -n supervisor python=2.7

Switch to python2 environment and install supervisor with pip

$ source activate supervisor
$ pip install supervisor

If you can install it without any problem, create a supervisor configuration file and place it under / etc.

$ echo_supervisord_conf > supervisord.conf
$ sudo mv supervisord.conf /etc

Next, edit supervisord.conf as follows to set the supervisor.

supervisord.conf


~ Omitted ~
[supervisord]
logfile=/var/log/supervisord.log ;Change log location
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log #Comment out
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/var/run/supervisord.pid ;Postscript
;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid #Comment out

~ Omitted ~
#include is commented out so uncomment it
[include]
files = supervisord.d/*.conf ;Location of the conf file of the process to be started
;files = relative/directory/*.ini

Create a log file and set permissions

$ sudo touch /var/log/supervisord.log
$ sudo chown ec2-user /var/log/supervisord.log
$ sudo chgrp ec2-user /var/log/supervisord.log
$ sudo chmod 774 /var/log/supervisord.log

Also, set log rotation

$ sudo sh -c "echo '/var/log/supervisord.log {
       missingok
       weekly
       notifempty
       nocompress
}' > /etc/logrotate.d/supervisor"

Next, create a file that describes the commands of the process to be daemonized. First, create a directory to place those files

$ sudo mkdir /etc/supervisord.d

Create django_app.conf under /etc/supervisord.d Here, write the settings for daemonizing the Gunicorn process as follows.

django_app.conf


[program:django_app]
directory=/home/ec2-user/test_project
command=gunicorn test_project.wsgi --bind=0.0.0.0:8000
numprocs=1
autostart=true
autorestart=true
user=ec2-user
redirect_stderr=true

Specify the directory to be executed in directory, and specify the command to start the process in command

If you can do so far, start the supervisor with the following command

$ supervisord

Next, let the conf file be read This is always executed when modifying conf etc.

$ supervisorctl reread

In addition, restart the daemon with the following command, and conf is read even at that timing

$ supervisorctl reload

Daemon the Gunicorn process with the following command

$ supervisorctl start django_app

If you get the message django_app: ERROR (already started), use the following command to restart or stop the process before starting it.

$ supervisorctl stop django_app #Stop
$ supervisorctl restart django_app #Reboot

Now, try logging out of the server in this state And when you access http: // IP address, you'll see the Django screen. The Gunicorn process is now daemonized by Supervisor

It was good

Recommended Posts

Deploy a Django application on EC2 with Nginx + Gunicorn + Supervisor
Deploy a Django application with Docker
How to deploy a Django application on Alibaba Cloud
Deploy a Django application on Google App Engine (Python3)
Launch a Python web application with Nginx + Gunicorn with Docker
Try running a Django application on an nginx unit
Deploy a Django app made with PTVS on Azure
Deploy your Django application on Heroku
Launched a web application on AWS with django and changed jobs
A note on enabling PostgreSQL with Django
I made a WEB application with Django
Until you publish (deploy) a web application made with bottle on Heroku
# 1 Until you deploy Django's web application (instance construction with EC2 on AWS)
Hello World with nginx + uwsgi + python on EC2
Run Flask on CentOS with python3.4, Gunicorn + Nginx.
Create a one-file hello world application with django
Deploy a Python 3.6 / Django / Postgres web app on Azure
Looking back on creating a web service with Django 1
Looking back on creating a web service with Django 2
A memo about building a Django (Python) application with Docker
Create a django environment with docker-compose (MariaDB + Nginx + uWSGI)
Deploy Django serverless with Lambda
Create a homepage with django
Web application creation with Django
(Failure) Deploy a web app made with Flask on heroku
Create a Python3.4 + Nginx + uWSGI + Flask Web application execution environment with haste using pyenv on Ubuntu 12.04
If you know Python, you can make a web application with Django
Build a Flask / Bottle-like web application on AWS Lambda with Chalice
# 3 Build a Python (Django) environment on AWS EC2 instance (ubuntu18.04) part2
Measure Django application coverage with Coverage.py
Django Tips-Create a ranking site with Django-
Twitter posting application made with Django
Implement a Django app on Hy
Run python3 Django1.9 with mod_wsgi (deploy)
Make a filter with a django template
Create a file uploader with Django
Deploy a Python app on Google App Engine and integrate it with GitHub
Run a batch of Python 2.7 with nohup on Amazon Linux AMI on EC2
Until you publish your Django application (+ MySQL) on AWS EC2 (+ RDS (+ S3))
I made a webAPI! Build environment from Django Rest Framework 1 on EC2
Publish a web application for viewing data created with Streamlit on heroku
Build a proxy server with nginx on multiple remote servers using Ansible
Django + Apache with mod_wsgi on Windows Server 2016
A memo with Python2.7 and Python3 on CentOS
Map rent information on a map with python
Deploy the Django app on Heroku [Part 2]
Deploy the Django app on Heroku [Part 1]
Throw a request with a certificate on httpie
Creating a login screen with Django allauth
[Python] A quick web application with Bottle!
Run a Python web application with Docker
Launch Flask application with Docker on Heroku
Flask + Gunicorn + Nginx + Supervisor Until it works
The story of making a web application that records extensive reading with Django
How to run a Django application on a Docker container (development and production environment)
Try creating a web application with Vue.js and Django (Mac)-(1) Environment construction, application creation
Build a TensorFlow development environment on Amazon EC2 with command copy and paste