Python3 + Django + uWSGI + Nginx On FreeBSD

1. uWSGI Installation.

$ sudo pip-3.6 install uwsgi
Collecting uwsgi
  Downloading uwsgi-2.0.17.tar.gz (798kB)
    100% |################################| 798kB 709kB/s
Installing collected packages: uwsgi
  Running setup.py install for uwsgi ... done
Successfully installed uwsgi-2.0.17

1.1 Basic test
Let’s start with a simple “Hello World” example:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]
As you can see, it is composed of a single Python function. It is called “application” as this is the default function that the uWSGI Python loader will search for (but you can obviously customize it).
1.2 Now start uWSGI to run an HTTP server/router passing requests to your WSGI application:

uwsgi --http :9090 --wsgi-file foobar.py

2.Installing Django.
Install Django into your virtualenv, create a new project

$ mkproject django
$ pip install Django
Collecting Django
  Downloading Django-2.0.2-py3-none-any.whl (7.1MB)
    100% |################################| 7.1MB 87kB/s
Collecting pytz (from Django)
  Downloading pytz-2018.3-py2.py3-none-any.whl (509kB)
    100% |################################| 512kB 1.2MB/s
Installing collected packages: pytz, Django
Successfully installed Django-2.0.2 pytz-2018.3
$ django-admin.py startproject mysite

2.1 Test your Django project
Update mysite/settings.py file set ALLOWED_HOSTS = ['*']


$ cd mysite
$ python manage.py runserver 0.0.0.0:8080

If the following exception was raised.We will install sqlite3 first.

ModuleNotFoundError: No module named '_sqlite3'


$ sudo pkg install sqlite3
$ sudo pkg install py36-sqlite3

3.Installing nginx


$ sudo pkg install nginx
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        nginx: 1.12.2_3,2

Number of packages to be installed: 1

The process will require 1 MiB more space.
389 KiB to be downloaded.

Proceed with this action? [y/N]: y
[1/1] Fetching nginx-1.12.2_3,2.txz: 100%  389 KiB 398.1kB/s    00:01
Checking integrity... done (0 conflicting)
[1/1] Installing nginx-1.12.2_3,2...
===> Creating groups.
Using existing group 'www'.
===> Creating users
Using existing user 'www'.
Extracting nginx-1.12.2_3,2: 100%
Message from nginx-1.12.2_3,2:

===================================================================
Recent version of the NGINX introduces dynamic modules support.  In
FreeBSD ports tree this feature was enabled by default with the DSO
knob.  Several vendor's and third-party modules have been converted
to dynamic modules.  Unset the DSO knob builds an NGINX without
dynamic modules support.

To load a module at runtime, include the new `load_module'
directive in the main context, specifying the path to the shared
object file for the module, enclosed in quotation marks.  When you
reload the configuration or restart NGINX, the module is loaded in.
It is possible to specify a path relative to the source directory,
or a full path, please see
https://www.nginx.com/blog/dynamic-modules-nginx-1-9-11/ and
http://nginx.org/en/docs/ngx_core_module.html#load_module for
details.

Default path for the NGINX dynamic modules is

/usr/local/libexec/nginx.
===================================================================

Add 'nginx_enable=YES' to rc.conf


$ sudo sysrc nginx_enable=YES
nginx_enable:  -> YES
If something else is already serving on port 80 and you want to use nginx there, you’ll have to reconfigure nginx to serve on a different port.

$ sudo vi /usr/local/etc/nginx/nginx.conf
<         listen       8080;
---
>         listen       80;
$ sudo service nginx start
And now check that nginx is serving by visiting it in a web browser on port 8080 - you should get a message from nginx: “Welcome to nginx!”.

4. Configure nginx and uWSGI and Django

4.1 uwsgi_params
You will need the uwsgi_params file, which is available in the nginx directory of the uWSGI distribution, or from
https://github.com/nginx/nginx/blob/master/conf/uwsgi_params

Copy it into your project directory. In a moment we will tell nginx to refer to it.



uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

4.2 mysite_nginx.conf
Now create a file called mysite_nginx.conf in your project directory, and put this in it:


# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    # server 127.0.0.1:8001;                          # for a web port socket
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;

    # the domain name it will serve for
    # .example.com = (example.com,example.com,*.example.com)
    # example.com = example.com
    # www.example.com = www.example.com
    #server_name .example.com; # substitute your machine's IP address or FQDN
    #server_name example.com; # substitute your machine's IP address or FQDN
    #server_name www.example.com; # substitute your machine's IP address or FQDN
    #server_name 127.0.0.1; # substitute your machine's IP address or FQDN
    #server_name localhost; # substitute your machine's IP address or FQDN

    server_name example.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    location /media  {
        alias /home.../djangodev/mysite/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /home/.../djangodev/mysite/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /home/.../djangodev/uwsgi_params; # the uwsgi_params file you installed
    }
}

This conf file tells nginx to serve up media and static files from the filesystem, as well as handle requests that require Django's intervention. For a large deployment it is considered good practice to let one server handle static/media files, and another handle Django applications, but for now, this will do just fine.

Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:


sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /usr/local/etc/nginx/sites-enabled/

4.3 mysite_uwsgi.ini
Now create a file called ysite_uwsgi.ini in your project directory, and put this in it:


# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = [/paph/to]/djangodev/mysite
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path)
home            = [/paph/to]/.virtualenvs/djangodev

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = [/paph/to]/djangodev/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 664
# clear environment on exit
vacuum          = true

Now create a vassals directory. Symlink to this file from the vassals directory:


$ sudo mkdir -p /usr/local/etc/uwsgi/vassals
$ sudo ln -s ~[/path/to/your/project]/mysite_uwsgi.ini /usr/local/etc/uwsgi/vassals/

Now these files in your project directory.

[djangodev]$ ls
mysite                  mysite_nginx.conf       mysite_uwsgi.ini       uwsgi_params

4.4 Emperor mode
You may need to run uWSGI with sudo:


$ sudo uwsgi --emperor /usr/local/etc/uwsgi/vassals --uid www --gid www
The options mean:

emperor: where to look for vassals (config files)
uid: the user id of the process once it's started
gid: the group id of the process once it's started
Check the site; it should be running.

5.Make uWSGI startup when the system boots
The last step is to make it all happen automatically at system startup time.
Edit /etc/rc and add:

/usr/local/bin/uwsgi --emperor /usr/local/etc/uwsgi/vassals --uid www --gid www --daemonize /var/log/uwsgi-emperor.log
before the line "exit 0".

And that should be it!

Comments

Popular posts from this blog

arduino最小構成 (atmega328/8MHz/3.3V/内部クロック)FT232RLにてブートローダーの書き込み

FreeBSD: Configuring Apache to permit CGI