Django从零搭建个人博客 | 在linux(Centos)上通过Nginx+Gunicorn部署项目

原文博客地址

部署前准备

在Linux上部署Django项目目前主流的都是采用Nginx代理,本文介绍在服务器环境为 Centos 7 下通过 Nginx + Gunicorn 方式部署 Django 项目,在 Windows Server 下部署查看:在 Windows Server 通过IIS 部署 Django 项目

1、购买服务器

在 linux 上部署时,一般有两种选择。centos系统使用较多,新人可以选择有桌面环境的 ubuntu 系统。学生优惠9.9 元/月购买地址:阿里云服务器学生专区腾讯云服务器学生专区。本文介绍的是 Centos7 的部署。

2、购买域名

阿里云域名注册地址:[ 域名注册系统](https://wanwang.aliyun.com/domain/ " 阿里云域名注册系统"),根据需求购买即可。

3、解析域名到服务器

域名解析前需要先将绑定到服务器:[绑定域名 ](https://help.aliyun.com/knowledge_detail/39881.html " "),随后解析域名:[解析域名](https://help.aliyun.com/knowledge_detail/39903.html?spm=5176.2000002.0.0.43df132dmnCiMy " ")

4、登录到服务器

服务器通常位于云端,需要使用远程登录工具登录后才能对服务器进行操作。如何登录到 Linux :登录 Linux 实例

5、创建新用户

如果是一台全新服务器的话,通常我们是以 root 用户登录的。在 root 下部署代码不安全,最好是建一个新用户(如果你已经以非 root 用户登录的话可以跳过这一步)

# 创建新用户crime
adduser crime
# 配置密码
passwd crime
# 把新创建的用户加入超级权限组
usermod -a -G crime
# 切换到创建的新用户
su - crime

安装Python

1、安装编译相关工具

# 更新系统软件包
yum update -y
# 安装软件管理包和可能使用的依赖
yum -y groupinstall "Development tools"
# 为centos系统增加编译功能
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
# Python3.7需要的依赖包libffi-devel
yum install libffi-devel -y

2、下载安装包解压

# 指定下载目录
cd /home
# 下载
wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
# 解压
tar -xvJf Python-3.7.2.tar.xz

3、编译安装

# 创建编译安装目录
mkdir /usr/local/python3 
# 进入解压目录
cd /home/Python-3.7.2
# 编译安装到指定路径
./configure --prefix=/usr/local/python3
# 安装
make && make install

4、添加软链接

# 建立软链接
ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3  #一般/usr/bin系统应用,/usr/local/bin/用户安装应用
# 建立pip3软链接
ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3
#验证安装
python3 -V
pip3 -V

配置虚拟环境

1、安装Virtualenv

pip3 install virtualenv
# 建立软链接
ln -s /usr/local/python3/bin/virtualenv /usr/local/bin/virtualenv

2、配置项目虚拟环境
首先设计好服务器项目目录结构,一台服务器可能部署多个网站,所有网站代码都放在 sites 目录下。

|-- home
   | |-- crime  #用户名,便于区分
      | |-- sites  #站点,便于管理多个项目
         | |-- demo.eosones.com  #每个项目用域名区分
            | |-- Myblog   #项目目录
            | |-- Myblog_env   #项目虚拟环境

创建项目虚拟环境

#创建项目目录结构
mkdir -p  /home/crime/sites/demo.eosones.com
# 切换到项目地址
cd /home/crime/sites/demo.eosones.com
# 创建项目虚拟环境
virtualenv --python=/usr/local/bin/python3 Myblog_env

常用命令

# 进入启动目录
cd /home/crime/sites/demo.eosones.com/Myblog_env/bin
# 激活
source activate
# 退出
deactivate

在命令行前面出现(Myblog_env)说明是成功进入虚拟环境。

安装Mysql

1、yum下载安装

# 检测系统是否自带安装 MySQL
rpm -qa | grep mysql
# 下载
cd /home/
wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm
# 安装
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 更新 yum 缓存
yum update
# 查看要安装的MySQL版本
yum repolist all | grep mysql
# 安装
yum install mysql-server

2、启动

# 权限设置
chown mysql:mysql -R /var/lib/mysql
# 初始化 MySQL
mysqld --initialize
# 启动 MySQL
systemctl start mysqld
# 查看 MySQL 运行状态
systemctl status mysqld
# 验证 MySQL
mysqladmin --version

3、登录

# 查看初始化密码
grep 'temporary password' /var/log/mysqld.log
# 登录
mysql -u root -p 临时密码
# 更改超级用户帐户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '更改的密码';

4、常用mysql服务命令

# 登录mysql
mysql -u username -p
# 退出mysql 
quit
# 启动mysql
systemctl start mysqld.service
# 结束
systemctl stop mysqld.service
# 重启
systemctl restart mysqld.service
# 开机自启
systemctl enable mysqld.service

本地项目搬迁到服务器

1、部署前的项目配置

在本地环境中配置中DEBUG =True,Django会在STATICFILES_DIRS目录下寻找静态文件,但在生产环境为了安全起见,需要关闭 DEBUG 选项并设置允许访问的域名,此时django.contrib.staticfiles失效,为了能够方便地让 Nginx 处理这些静态文件的请求,需要在项目的配置文件里做一些必要的配置。

#Myblog/settings.py
# 关闭
DEBUG = False
# 添加域名
ALLOWED_HOSTS = ['127.0.0.1', 'localhost ', '.eosones.com']  #允许访问该域名及其下的子域名

# 其他配置(作为前缀映射STATIC_ROOT)
STATIC_URL = '/static/'
# 配置收集静态文件目录
STATIC_ROOT = os.path.join(BASE_DIR, 'collect_static')

#测试环境静态文件目录(失效)
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,'static'),
)

2、迁移依赖包

激活并进入本地测试虚拟环境,执行:

pip freeze > requirements.txt

此时包依赖信息将保存本地虚拟环境下的 requirements.txt 文件中,注意在有些包安装前需要依赖其他包的需要手动调整一下顺序。
然后上传文件到服务器:

# 本地Centos上传到Centos服务器
scp /path/requirements.txt root@服务器IP:/home  #指定上传位置
[email protected]'s password: 输入root密码

# 本地 windowss上传到Centos服务器(使用PuTTy的pscp功能)
cd D:\PuTTy  #切换到PuTTy根目录
pscp E:\myblog.sql root@服务器IP:/home   #指定文件与上传位置

上传到服务器后,在激活虚拟环境下执行:

pip3 install -r /home/requirements.txt

pip就会自动从网上下载并安装所有包,此时虚拟环境已经完全迁移到服务器。

3、迁移数据库

使用Sqlite数据库的话,直接打包数据库文件上传到服务器即可。使用Mysql数据库,服务器上需要先安装Mysql数据库软件,并要先在本地Mysql里备份导出数据。

# 选择导出目录
cd /home
# 导出本地Mysql数据(Win进入Mysql所在bin目录下)
mysqldump -uroot -ppassword myblog>myblog.sql  # myblog为你的项目数据库名字

通过上面的命令将 myblog.sql 上传到服务器home文件夹下,进行迁移。

# 登录服务器Mysql
mysql -uroot -ppassword  
# 选择目标数据库
use myblog; 
source /home/myblog.sql

4、迁移项目

为了方便将代码拉取到拉取到服务器与后期完善代码,可以代码上传到 GitHub 等代码托管平台 ,需要在本地与服务器安装GIT:如何安装GIT与配置教程如何添加远程库Github

# 切换项目目录
cd /home/crime/sites/demo.eosones.com
# 克隆项目
git clone https://github.com/CRIME-Z/Myblog.git Myblog  #项目克隆到本地并命名为Myblog
# 查看
[[email protected]] # ls
Myblog Myblog_env

5、收集静态文件

虚拟环境下继续运行 python manage.py collectstatic 命令收集静态文件到之前配置的 collect_static 目录下:

python manage.py collectstatic

完成全部迁移后,激活虚拟环境,测试项目是否成功运行。

python3 manage.py runserver 0.0.0.0:80

此时可以通过外网IP访问,因为我们关闭了Django静态文件功能,所以目前还无法加载静态文件,之后我们会用 Nginx 进行代理。

安装和配置 Gunicorn

Gunicorn 一般用来管理多个进程,有进程挂了Gunicorn 可以把它拉起来,防止服务器长时间停止服务,还可以动态调整 worker 的数量。

1、安装测试

在虚拟环境下,安装 Gunicorn:

pip3 install gunicorn

测试 Gunicorn 是否能启动你的项目服务

# 切换项目目录
cd /home/crime/sites/demo.eosones.com/Myblog
# 启动
gunicorn --bind 0.0.0.0:8000 Myblog.wsgi:application

浏览器输入域名,可以看到访问成功了。

2、添加自启动

为了使用方便,创建一个 Gunicorn Systemd Service 文件,直接运行以下命令(退出虚拟环境)

vim /etc/systemd/system/gunicorn.service

配置如下:

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

[Service]
User=cimre
Group=www-data
WorkingDirectory=/home/crime/sites/demo.eosones.com/Myblog
ExecStart=/home/crime/sites/demo.eosones.com/Myblog_env/bin/gunicorn --workers 3 --bind unix:/home/crime/sites/demo.eosones.com/Myblog.sock Myblog.wsgi:application

[Install]
WantedBy=multi-user.target

User填写自己当前用户名称、WorkingDirectory填写项目的地址、ExecStart中第一个地址是虚拟环境中 gunicorn 的目录,--bind中使用IP:端口或者套接字,防止端口冲突。
文件配置完成之后,使用下面的命令启动服务:

# 重新加载systemctl
systemctl daemon-reload

之后就可以使用systemctl命令控制Gunicorn服务

# 查看Gunicorn服务状态
systemctl status gunicorn
# 开启Gunicorn服务
systemctl start gunicorn
# 关闭Gunicorn服务
systemctl stop gunicorn
# 开机自启
systemctl enable gunicorn
# 重启Gunicorn服务
systemctl restart gunicorn
# 查看日志
journalctl -u gunicorn

配置Nginx

Nginx 是一个高性能的负载均衡HTTP和反向代理服务器,可以高效地处理静态文件请求,由于其底层使用 epoll 异步IO模型进行处理,使其深受欢迎。在 CentOS7 中可以通过yum命令yum install nginx安装Nginx应用,会自动配置好相关 Nginx 服务,本文介绍手动编译安装配置。

1、下载编译安装

# 指定下载目录
cd /home
# 下载
wget http://nginx.org/download/nginx-1.16.0.tar.gz
# 解压
tar -zxvf nginx-1.16.0.tar.gz
# 进入解压目录
cd /home/nginx-1.16.0
# 编译安装到指定路径
./configure --prefix=/usr/local/nginx
# 安装
make && make install
# 查找安装路径
whereis nginx

2、Nginx常用命令:

# 启动
/usr/local/nginx/sbin/nginx
# 指定配置文件启动
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 
# 快速停止
/usr/local/nginx/sbin/nginx -s stop
# 完整有序的停止
/usr/local/nginx/sbin/nginx -s quit
#重启
/usr/local/nginx/sbin/nginx -s reload
#测试nginx配置文件是否正确 
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf 
# 检查nginx是否已经启动
ps -aux | grep nginx
# 强制停止
pkill -9 nginx

启动成功后,通过外网IP访问即可看到下面页面:

3、添加自启动

为了使用方便,现将 Nginx 服务添加至 systemctl ,CentOS7 的服务 systemctl 脚本存放在/usr/lib/systemd/下,有系统(system)和用户(user)之分,需要开机不登陆就能运行的程序,存在系统服务里,即/usr/lib/systemd/system目录下。
Nginx 服务关闭情况下,通过vi命令打开服务配置:

vi /usr/lib/systemd/system/nginx.service

编辑如下代码:

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
#  
ExecStartPre=/usr/bin/rm -f /usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf  #启动准备
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf   #启动命令
ExecReload=/usr/local/nginx/sbin/nginx -s reload   #重启命令
ExecStop=/usr/local/nginx/sbin/nginx -s stop   #停止命令
ExecQuit=/usr/local/nginx/sbin/nginx -s quit   #快速停止

KillSignal=SIGQUITTimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

路径修改为对应的路径即可,在编译安装的情况下,PIDFile 默认位置一般为/usr/local/nginx/logs/nginx.pid,在二进制包安装方式下,PIDFile 默认位置一般为/run/nginx.pid,这个位置在 /usr/lib/systemd/system/nginx.service 中配置需与nginx.conf 文件中的保持一致。

#配置754的权限
chmod 754 /usr/lib/systemd/system/nginx.service
# 重新加载systemctl
systemctl daemon-reload 

之后就可以进行systemctl操作:

# 查看状态
systemctl status nginx
# 启动
systemctl start nginx
# 重启
systemctl reload nginx 
# 停止
systemctl stop nginx
# 开机自启动
systemctl enable nginx

4、部署配置

首先到安装位置下 /usr/local/nginx/conf/ 中先备份一下nginx.conf配置文件,以防意外。

cp nginx.conf nginx.conf.bak

然后打开 nginx.conf 并修改以下内容:

vim /usr/local/nginx/conf/nginx.conf
# 修改位置
server {
    # 端口和域名
    listen 80;
    server_name www.eosones.com 0.0.0.0;
    # static 和 media 的地址
    location /static {
      alias /home/crime/sites/demo.eosones.com/Myblog/collect_static;
    }
    location /media {
      alias /home/crime/sites/demo.eosones.com/Myblog/media;
    }
    
    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:/home/crime/sites/demo.eosones.com/Myblog.sock;  #端口或者套接字要和gunicorn里配置的一样      
    }

Nginx通过根据server_name域名得知访问哪个项目,监听请求80端口,首先 location 会匹配到静态文件的URL ,其请求均由 Nginx 处理,alias 指明了静态文件的存放目录。其它请求转发给 Django 处理,proxy_pass 后面配置需与gunicorn配置相同。

# 把 nginx 加入超级权限组
usermod -a -G root nginx
# 配置项目文件夹权限
chmod 710 -R /home/

以后如果更新了代码,只要运行下面的命令重启一下 Nginx 和 Gunicorn 就可以使新的代码生效了:

# 更改配置执行
systemctl daemon-reload
# 更改代码执行
systemctl restart gunicorn
systemctl restart nginx

其他优化

1、多站点部署配置

在上面的部署中我们直接在默认主配置文件 /usr/local/nginx/conf/ngnix.conf 中进行的配置,为了方便一台服务器需要部署多个项目,进入 Nginx 的配置文件目录/usr/local/nginx/conf/,然后新建一个目录:

mkdir vhost

首先使用 /usr/local/nginx/conf/ 目录下的原来默认的 nginx.conf 文件,修改相应的代码:

http {
    include mime.types;   # nginx支持的媒体类型库文件
    default_type application/octet-stream; #默认的媒体类型
    sendfile on; #开启高效传输模式
    keepalive_timeout 65; #连接超时时间 65秒

    include /usr/local/nginx/conf/vhost/*.conf; #主要是这个地方,把原来的配置文件包含进来

    server {
      listen 80 default_server;
      server_name _;
      return 404;
    }
}

最后为每个站点配置如下,并且移动到 /usr/local/nginx/conf/vhost 下即可

#Myblog.conf

server {
    # 端口和域名
    listen 80;
    server_name www.eosones.com;
    # static 和 media 的地址
    location /static {
      alias /home/crime/sites/demo.eosones.com/Myblog/collect_static;
    }
    location /media {
      alias /home/crime/sites/demo.eosones.com/Myblog/media;
    }
    
    location / {
      proxy_pass http//:unix:/home/crime/sites/demo.eosones.com/Myblog.sock; #端口或者套接字要和gunicorn里配置的一样      
    }

    error_page 500 502 503 504 /50x.html;
      location = /50x.html {
      root html;
    }
}

2、使用 CDN 加载速度

我们的项目使用了 Bootstrap 和 jQuery,这两个文件我们是从本地加载的。如果服务器性能比较差的话,加载需要耗费很长的时间。我们使用 CDN 来加快加载速度。具体来说,替换 base.html 的几个静态文件的加载标签:

base.html

- <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
- <script src="{% static 'blog/js/jquery-2.1.3.min.js' %}"></script>
- <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
+ <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+ <script src="https://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script>
+ <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

3、问题汇总

如果本地开发环境为windows,部署到Linux服务器需注意:
linux目录名、文件名、文件后缀、Mysql 表名等都要区分大小写

外网无法访问:
有些服务器外网默认是无法访问的,因为防火墙不允许,所以要开启防火墙,让其可以访问需要访问的端口号。

firewall-cmd --get-active-zones
# 打开80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
# 重启防火墙
firewall-cmd --reload
# 查看端口号是否开启
firewall-cmd --query-port=80/tcp

有些服务器在防火墙里开启端口之后还不能访问,那就需要到对应的服务器提供商的管理后台安全组里开启对应的端口才能正常访问。

配置完成后无法加载静态媒体文件:

首先确保配置目录正确并python manage.py collectstatic收集过静态文件

# Myblog/settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'collect_static')

# /usr/local/nginx/conf/ngnix.conf
    location /static {
      alias /home/crime/sites/demo.eosones.com/Myblog/collect_static;
    }
    location /media {
      alias /home/crime/sites/demo.eosones.com/Myblog/media;
    }

确保Nginx具有项目目录的访问权限

# 查看nginx日志
less /usr/local/nginx/logs/error.log
# 如果是Permission denied 问题
chmod -R 777 /home  # -R 是指级联应用到目录里的所有子目录和文件,777 是所有用户都拥有最高权限

猜你喜欢

转载自www.cnblogs.com/crime/p/11068694.html
今日推荐