使用uwsgi、nginx和postgresql进行Django的构建(AmazonLinux2)

系统要求

操作系统:AmazonLinux2
Python版本:3.9.2
SQLite版本:3.35.0
Django版本:4.0.5
uWSGI版本:2.0.20
Nginx版本:1.20.0
psycopg2-binary版本:2.9.3
PHP版本:8.0.18
PostgreSQL版本:14.1

目录结构

完成后的目录结构如下所示。
由于执行层级非常重要,请一边确认一边进行。
这次我们将配置放置在ec2-user的主目录中。
(部分内容已省略。)

~/
└ uwsgi-tutorial/
    └ mysite
        ├ manage.py
        ├ media/
        ├ mysite/
        │    ├ asgi.py
        │    ├ __init__.py
        │    ├ __pycache__/
        │    ├ settings.py
        │    ├ urls.py
        │    └ wsgi.py
        ├ mysite_uwsgi.ini
        ├ static
        │    └ admin/
        └ test.py

只使用Django的方法来运行

Django已经内置了一些简单的功能,因此可以在浏览器上单独运行Django。如果要单独运行,请参考下面的文章,只需从上面复制并粘贴命令即可实现。
尝试创建Django环境并使用venv(需要Python3.3或更高版本)。

建设任务

我們將按照基於官方文件的方式進行操作。
uWSGI官方文檔
Django官方文檔

安装 Python 3.9.2

请参考本文,将文章整理在这里。使用pyenv的方法进行操作。
关于Python版本更改的方法(别名和pyenv)。

升级SQLite

在AmazonLinux2上,默认安装了sqlite3.7.17。
由于Django需要使用sqlite3.9.0或更高版本才能正常运行,因此我们需要进行升级。
由于本文最终将采用posgresql,所以可以跳过这个步骤。
本次我们将按照官方文档的指引进行操作。

$ wget https://www.sqlite.org/2021/sqlite-autoconf-3350000.tar.gz
$ tar fxvz sqlite-autoconf-3350000.tar.gz

$ cd sqlite-autoconf-3350000/
$ ./configure
$ make
$ sudo make install

$ sqlite3 --version
3.35.0 2021-03-12 15:10:09 acd63062eb06748bfe9e4886639e4f2b54ea6a496a83f10716abbaba4115500b

我会将路径添加到共享库中。

vi ~/.bashrc
#一番下に追記する
export LD_LIBRARY_PATH="/usr/local/lib"
$ source ~/.bashrc

当更改Python和SQLite的版本后,我们开始构建Django。

在uWSGI上运行Django

使用venv在虚拟环境中安装Django和uWSGI。

$ cd
$ python3 -m venv uwsgi-tutorial
$ cd uwsgi-tutorial
$ source bin/activate

安装 Django 并创建项目。
安装与 Python 版本相匹配的 Django 版本(本次为 4.0.5)。
可以使用 pip list 命令确认通过 pip 安装的版本。

$ pip install Django
$ django-admin startproject mysite
$ cd mysite

安装uWSGI并创建一个测试页面。

$ pip install uwsgi
$ vi test.py
# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

我将启动uWSGI并显示测试页面。
本次我将按照官方指南,使用8000端口。

$ uwsgi --http :8000 --wsgi-file test.py

我们来访问公共IP地址加端口8000,然后尝试显示测试页面。一旦确认uWSGI正在运行,我们将使用uWSGI来显示Django。

vi mysite/settings.py
#変更前
ALLOWED_HOSTS = []

#変更後
ALLOWED_HOSTS = ['パブリックIPアドレス']
# manage.pyがある階層で実行
$ uwsgi --http :8000 --module mysite.wsgi

如果再次访问http://公共IP地址:8000,能够看到Django页面的话,就表示成功了。

使用nginx来显示Django。

通过前面的操作,Web客户端<->uWSGI<->Django之间的协同已经完成。
接下来将推进Web客户端<->Web服务器<->套接字<->uWSGI<->Python之间的协同。

首先安装并启动nginx。

$ sudo amazon-linux-extras install nginx1
$ sudo systemctl start nginx.service
$ sudo systemctl enable nginx.service

我会创建一个nginx的配置文件。

$ sudo mkdir /etc/nginx/sites-available/
$ sudo vi /etc/nginx/sites-available/mysite_nginx.conf
# 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 (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name パブリックIPアドレス; # 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/ec2-user/uwsgi-tutorial/mysite/media;  # your Django project's media files - amend as required #projectのパス配下にmediaを配置します。
    }

    location /static {
        alias /home/ec2-user/uwsgi-tutorial/mysite/static; # your Django project's static files - amend as required #projectのパス配下にstaticを配置します。
    }

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

在/etc/nginx/sites-enabled上创建一个符号链接。

$ sudo mkdir /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/mysite_nginx.conf /etc/nginx/sites-enabled/

在nginx.conf文件的末尾添加上述创建的配置文件,以便可以加载它。

$ sudo vi /etc/nginx/nginx.conf
   ~~~前略~~~
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

    include /etc/nginx/sites-enabled/*;

}
$ sudo systemctl restart nginx.service

为了在nginx上显示Django的静态文件,需要将这些文件复制到项目内部。
首先,根据之前mysite_nginx.conf中指定的路径,在项目中创建”media”和”static”目录。

$ mkdir media
$ mkdir static

接下来,我们将在项目的settings.py文件中进行追加。

$ vi mysite/settings.py
"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 4.0.5.

For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""

import os           #追記
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

 
   ~~~中略~~~


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

STATIC_ROOT = os.path.join(BASE_DIR, "static/")   #追記

在manage.py所在的文件夹中执行。

$ python manage.py collectstatic

在完成到這一步之後,我們來確認一下uWSGI和nginx的搭配,試著顯示測試頁面。
在test.py所在的目錄中執行以下命令。

$ uwsgi --socket :8001 --wsgi-file test.py

如果通过访问公共IP地址:8000能够显示测试页面,那么我们也可以检查Django的显示。我们将在manage.py所在的目录层次中执行以下命令。

$ uwsgi --socket :8001 --module mysite.wsgi

使用UNIX套接字进行连接

我将使其能够使用UNIX套接字进行连接。
我将修改mysite_nginx.conf的内容。

$ sudo vi /etc/nginx/sites-available/mysite_nginx.conf
# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
     server unix:/run/uwsgi/mysite.sock; # for a file socket #コメントアウトを外し、パスを入力する
    #server 128.0.0.1:8001; # for a web port socket (we'll use this first) #コメントアウトする
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for

$ sudo systemctl restart nginx.service

创建一个目录来存放套接字文件,并更改其权限。
该目录的权限应设置为所有者为执行uWSGI的用户(本例中为ec2-user),所有组为执行Web服务器的用户组。

$ sudo mkdir /run/uwsgi
$ sudo chown ec2-user:nginx /run/uwsgi/

让我们尝试使用UNIX套接字来确认是否可以显示Django。
在具有manage.py的目录中执行以下命令。
使用–chmod-socket=666来将套接字文件的权限设置为666,并执行命令。

$ uwsgi --socket /run/uwsgi/mysite.sock --module mysite.wsgi --chmod-socket=666

使用 .ini 文件启动 uWSGI

将以前通过命令执行的操作改为创建.ini文件,并使其能够通过启动进行操作。

$ vi mysite_uwsgi.ini
# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /home/ec2-user/uwsgi-tutorial/mysite
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path)
home            = /home/ec2-user/uwsgi-tutorial

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

让我们启动并从浏览器中进行确认。

$ uwsgi --ini mysite_uwsgi.ini

如果你能到这一步,就能轻松地使用Django启动,即使退出了虚拟环境。
我们来尝试以下的操作。

$ deactivate
$ pip3 install uwsgi
$ uwsgi --ini mysite_uwsgi.ini

将PostgreSQL与Django进行整合。

进行安装和设置

为了将Python和PostgreSQL进行连接,我们将使用psycopg2来实现。
请在虚拟环境中安装psycopg2。

$ cd ..   #uwsgi-tutorialがある階層へ移動
$ source bin/activate
$ pip3 install psycopg2-binary

安装完后,请用pip list进行确认。

我们将安装PHP和PostgreSQL。

$ sudo amazon-linux-extras install php8.0 postgresql14

如果使用pyenv,可能会出现以下错误。

/home/ec2-user/.pyenv/versions/3.9.2/bin/python: No module named amazon_linux_extras

通过创建符号链接,应该能够使用。

ln -s /lib/python2.7/site-packages/amazon_linux_extras ~/.pyenv/versions/3.9.2/lib/python3.9/site-packages/

我们将安装所需的工具。

$ sudo yum install postgresql-server postgresql-devel postgresql-contrib

在初始化数据库后,我们将更改配置以允许临时无需密码登录。打开配置文件,并将ident处更改为trust。

$ sudo postgresql-setup initdb
$ sudo vi /var/lib/pgsql/data/pg_hba.conf
    ~~~前略~~~
# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust #ここを変更
# IPv6 local connections:
host    all             all             ::1/128                 trust #ここを変更
# Allow replication connections from localhost, by a user with the
   ~~~以下略~~~

我們將啟動系統。

$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
$ psql -h localhost -p 5432 -U postgres

如果成功启动,我们将设置数据库为django,用户名为django,密码为django。
请根据需要适当修改每个名称。
我们还会更改为Django的推荐设置。

postgres=# CREATE DATABASE django;
CREATE DATABASE
postgres=# CREATE USER django WITH PASSWORD 'django';
CREATE ROLE
postgres=# ALTER ROLE django SET client_encoding TO 'utf8';
ALTER ROLE
postgres=# ALTER ROLE django SET default_transaction_isolation TO 'read committed';
ALTER ROLE
postgres=# ALTER ROLE django SET timezone TO 'Asia/Tokyo';
ALTER ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE django TO django;
GRANT

回到命令行,并将密码认证的设置更改为新值。
打开配置文件,并将peer更改为md5。

$ sudo vi /var/lib/pgsql/data/pg_hba.conf
     ~~~前略~~~
# "local" is for Unix domain socket connections only
local   all             all                                     md5 #ここを変更
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
$ sudo systemctl restart postgresql

到目前为止,PostgreSQL的设置已经完成了。

Django的配置

接下来,我们将进行Django的配置。
请根据需要适当更改用户名和数据库名称。

$ vi mysite/mysite/settings.py

变更之前

# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

更改后

# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'localhost',
        'PORT': '',
    }
}

一旦设置完成后,我们进行迁移操作。

$ cd mysite    #manage.pyがある階層へ
$ python manage.py migrate

如果能做到这一点,协作就完成了。

我们来启动一下吧。

$ uwsgi --ini mysite_uwsgi.ini
スクリーンショット 2022-06-28 153539.png

请参考以下网站

使用venv创建Django环境(Python3.3及以上版本)
uWSGI官方文档
Django官方文档
使用pyenv构建Python执行环境
在Amazon Linux2(ec2)和CentOS7上安装最新版本的SQLite3
解决在Django 2.2启动开发服务器时出现SQLite3错误的方法
Django部署:Nginx、uWSGI
安装psycopg2并通过Python操作PostgreSQL
解决”amazon-linux-extras” → “No module named amazon_linux_extras”的方法
将PostgreSQL应用于Django

广告
将在 10 秒后关闭
bannerAds