一年没写博客了,最近在学 Django,正好趁着项目刚部署完的新鲜劲,写一篇笔记。作为一个菜鸟,本文仅供参考,如有错误,请大大们指出,千万不要吝啬吐嘈。本文主要介绍如何在 CentOS 7 上利用 Postgres, Nginx, Gunicorn 来部署 Django。

本文假设你已经完成了服务器的初始设置,如果没有的话可以参考 Initial Server Setup with CentOS 7 以及 How To Install Python 3 and Set Up a Local Programming Environment on CentOS 7

在此基础上,在 CentOS 7 上利用 Postgres, Nginx, and Gunicorn 来部署 Django 有以下几个步骤:

  1. 安装 EPEL 以及其他
  2. 设置 PostgreSQL
  3. 创建 Python Virtual Environment
  4. 创建或配置 Django
  5. 配置 Gunicorn
  6. 配置 Nginx

1. 安装 EPEL 以及其他

sudo yum install epel-release
sudo yum install python-pip python-devel postgresql-server postgresql-devel postgresql-contrib gcc nginx 

2. PostgreSQL

在服务器端,我选择了常用的 PostgreSQL 代替了 Django 默认的 SQLite3。文章这部分为关于 PostgreSQL 的设置。

2.1 设置 PostgreSQL

首先,初始化数据库:

sudo postgresql-setup initdb

其次,配置 postgresql authentication。打开 sudo vi /var/lib/pgsql/data/pg_hba.conf 把文件最下面几行的 METHOD 修改一下,由

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident

修改成

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

ident 要求数据库用户跟系统用户必须一致,md5 则只需密码。因此之后 Django 的用户可能跟系统用户不一致,所以修改下。

这个时候就完成了 PostgreSQL 的配置。启动一下 PostgreSQL,并且添加到systemctrl,数据库就能跑起来啦。输入以下命令:

sudo systemctl start postgresql
sudo systemctl enable postgresql

其中, sudo systemctl enable postgresql 是让 PostgreSQL 自动开机启动。

2.2 创建表

为 Django 项目创建一个数据库:

CREATE DATABASE $myproject;

为数据库创建用户:

CREATE USER $myprojectuser WITH PASSWORD $'password';

授予用户权限:

GRANT ALL PRIVILEGES ON DATABASE $myproject TO $myprojectuser;

退出:

\q
exit

其中,$表示变量,变量名称自取,注意以上命令后面有;

3. Python Virtual Environment

文章这部分为关于 Python Virtual Environment 的创建。首先,创建:

sudo pip install virtualenv

其次,在项目所在目录,创建虚拟环境并进入:

virtualenv $myvenv
source myvenv/bin/activate

最后,安装 psycopg2:

pip install django gunicorn psycopg2

psycopg2 是 Python 的 PostgreSQL database adapter

4. Django

本文假设你已经有一个 Django 项目在 git 上。如果没有的话,可以先创建,具体参考 Django 教程

4.1 修改 settings

Django 最佳实践推荐将 settings 根据不同的环境分成不同的文件。为简单起见,我就不分了。修改项目的设置,打开

$myproject/settings.py

将 DATABASE 部分修改为

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

在静态文件部分,添加 STATIC_ROOT

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

4.2 项目运行

数据库迁移:

python manage.py makemigrations

如果是第一次 makemigrations ,则需要在加上 application 的名字

python manage.py makemigrations $myapp

然后执行:

python manage.py migrate

随后创建 superuser :

python manage.py createsuperuser

随后,收集静态文件:

manage.py collectstatic

此时,由 STATIC_ROOT 设置的目录下,在这里是项目的根目录,会出现目录 static ,静态文件均包含在此。

最后,测试下项目是否能成功运行:

python manage.py runserver 0.0.0.0:8000

在浏览器打开

http://server_domain_or_IP:8000

查看是否运行成功

5. Gunicorn

Gunicorn 是一个 Python WSGI HTTP Server。在这里 Gunicorn 主要做两件事: 1. 创建并 bind socket 与 Nginx 通信;2. pre-fork workers 来调用 Django 的 WSGI application。

首先, 打开 Gunicorn 的 Systemd service file 并编辑:

sudo vim /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
Environment=DJANGO_SECRET_KEY=$mysecretkey
Environment=DJANGO_DEBUG=''
Environment=DJANGO_SETTINGS_MODULE=django_deltago.settings
WorkingDirectory=/var/www/$myproject
ExecStart=/var/www/$my/bin/gunicorn --workers 3 --bind unix:/var/www/$myproject/$mysock.sock $myproject.wsgi:application

[Install]
WantedBy=multi-user.target

其中, Environment为你想设置的环境变量。WorkingDirectory是你项目的工作目录。

其次,启动 Gunicorn 并设置为开机启动:

sudo systemctl start gunicorn
sudo systemctl enable gunicorn

这个时候可以查看 Gunicorn 的状态为 Active

sudo systemctl status gunicorn

6. Nginx

Nginx 在这里充当了反向代理的角色,把客户端发来的 HTTP 请求写到由 Gunicorn 创建的 socket ,并将处理过的 socket 转发至客户端。

首先,打开 Nginx 的配置文件并编辑:

sudo vim /etc/nginx/nginx.conf

添加 Server 或者覆盖原先的默认设置

server {
    listen 80;
    server_name server_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /var/www/&myproject;
    }

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://unix:/var/www/&myproject/$mysock.sock;
    }
}

测试是否有语法错误:

sudo nginx -t

如果没有会显示:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

其次,启动并设置为开机启动

sudo systemctl start nginx
sudo systemctl enable nginx

最后,打开浏览器

http://server_domain_or_IP

成功!

笔记参考

How To Set Up Django with Postgres, Nginx, and Gunicorn on CentOS 7