Linux02_项目部署


# 项目部署

### 一、MySQL安装

##### 1、安装方式

~~~markdown
# 方式一:使用yum安装 

1. 在CenOS系统中,默认安装了MariaDB,它是MySQL数据库的分支,如果必须要安装MySQL,首先要添加mysql社区repo:
    rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
    
2. 再安装MySQL
    yum install -y mysql-server 
~~~



~~~markdown
# 方式二:下载安装包,使用rpm指令安装
    需要将下载好的rpm文件传输到Linux系统中
    rpm -ivh xx.rpm 
    软件包有先后顺序 (不推荐该方式)
~~~



##### 2、启动MySQL服务

~~~shell
systemctl start mysqld  
~~~



##### 3、修改MySQL密码

~~~markdown
在安装MySQL时,自动生成了一个临时的密码,存放在了MySQL的日志文件中:
1. 在日志文件查找临时密码
        grep 'password' /var/log/mysqld.log 

2. 修改密码 (先进入mysql)
        进入数据库:mysql -uroot -p先回车再输密码
        ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
   此时会报错:
           ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
        解释:密码不符合当前的MySQL策略
  # 解决方案:
           修改MySQL安全策略
   (1) 修改MySQL密码验证的强度等级
           set global validate_password_policy=LOW;    
   (2) 当前要求为8位,需修改密码的长度限制为6位
           set global validate_password_length=6;     
   
再重新执行修改密码的语句:
    ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
~~~



##### 4、操作MySQL

~~~markdown
建库:create database 库名 charset=utf8;
选择库:use 库名;
建表:create table ...
插入:insert into ..
查询:select ... from ..
退出数据库:quit
~~~



##### 5、远程连接MySQL

~~~markdown
使用windows中的navicat连接
# 1. 新建一个连接,选择MySQL
# 2. 主机名:Linux系统的ip地址
# 3. 端口号:3306 数据库用户名:root 数据库密码:123456

# 注意:连接会失败
# 原因一:防火墙  systemctl stop firewalld
# 原因二:不允许其它主机连接
#       进入mysql库中的user表中 
#        update user set host='%' where user='root'; 
#         flush privileges;
~~~



##### 6、MySQL数据库文件

~~~markdown
# mysql是一个磁盘数据库,数据是存储在磁盘中的
/var/lib/mysql
~~~



##### 7、MySQL密码重置

`进入/etc/my.cnf`

~~~markdown
[mysqld]
...
skip-grant-tables   # 修改完配置文件后,需要让配置文件生效:重启mysql服务
~~~

~~~markdown
[root@Mrlee ~]# mysql -uroot 回车(不需要输入密码)
mysql > use mysql;
mysql > update user set authentication_string=password('123456') where user='root';
mysql > flush privileges;

完事后,将配置文件中的 skip-grant-tables删掉
~~~

##### 8、**赋权限**

~~~markdown
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;
# GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

刷新权限
# flush privileges;

# GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.100.113' IDENTIFIED BY '123456' WITH GRANT OPTION;
注:king表示用户名,%表示所有的电脑都可以连接,也可以设置某个ip地址运行连接,第二个123456表示密码、
~~~

##### 9、重启mysql

~~~markdown
# 启动
systemctl start mysqld  
# 重启
service mysql restart
~~~

##### 10、配置端口

~~~markdown
# ufw这个程序是主要功能是管理linux系统的防火墙,致力于提供简单易用的接口给系统用户  
dpkg --get-selections | grep ufw  --> 查看系统有没有安装ufw
yum install ufw    --> 安装ufw
ufw enable  --> 启动ufw 
ufw disable  -->关闭ufw
ufw status    -->查看ufw状态和已设置防火墙的所有规则

ufw allow 80    -->允许外部访问80端口{从本机不能从80端口发出(即本机不能发出http请求) 、 远程主机发送到本地主机80端口的数据会被拒绝(即远程主机不能访问本地主机的http服务)}

ufw allow http    --> 允许外部访问 本机的http服务 (本质上和3.3是一样的效果)

ufw allow 25/tcp   --> 允许通过使用tcp协议来使用25端口
ufw reject out smtp   --> 拒绝并告知:拒绝从本机发出smtp应用数据

ufw allow in on eth0 from 192.168.0.0/16   --> 允许来自192.168.0.0-192.168.255.255的数据通过eth0网卡进入主机

ufw allow out on eth1 to 10.0.0.0/8   --> 允许指向10.0.0.0-10.255.255.255的数据通过eth1网卡从本机发出

ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 25   --> 拒绝来自10.0.0.0/8域tcp协议指向192.168.0.1端口25的数据进入本机

ufw route allow in on eth1 out on eth2   --> 允许经eth1进入,eth2发出的数据经本机路由

ufw delete 3  --> 删除第三条规则

ufw logging on|off  LEVEL   --> 系统日志保存于/var/log/ufw.log。LEVEL指定不同的级别 ,默认级别是‘低’
~~~



~~~markdown
sudo ufw allow 3306
~~~



### 二、Python安装

##### 1、安装依赖

~~~markdown
1. 依赖
yum -y install  python-devel  openssl-devel  bzip2-devel  zlib-devel  expat-devel ncurses-devel sqlite-devel gdbm-devel xz-devel tk-devel readline-devel  gcc 

2. 开发工具包 
yum -y groupinstall "Development tools"
~~~



~~~cdmarkdown
# 注意:
如果只安装上述的依赖,再去安装并编译Python时,执行到【198/406】步时,会出现【_SSL.c:777】出错

# 解决方案:
使用libressl来代替openssl-devel

(1)下载libressl包,并传送给Linux系统
(2)解压libressl包,并进入解压目录
(3)执行以下指令:
        ./config –prefix=/usr/local/libressl
        make
        make install
 
        mv /usr/bin/openssl /usr/bin/openssl.bak
        mv /usr/include/openssl /usr/include/openssl.bak
        ln -s /usr/local/libressl/bin/openssl /usr/bin/openssl
        ln -s /usr/local/libressl/include/openssl /usr/include/openssl
(4)加载lib
        cd /etc/ld.so.conf.d
        vi libressl-2.8.0.conf 加入以下内容:/usr/local/libressl/lib
        ldconfig -v #重新加载库文件
5)配置环境变量
        5.1  vi /etc/profile 
            进入环境变量配置文件,在最后面加入以下内容:
            export LDFLAGS="-L/usr/local/libressl/lib"
            export CPPFLAGS="-I/usr/local/libressl/include"
            export PKG_CONFIG_PATH="/usr/local/libressl/lib/pkgconfig"
        5.2 让环境变量生效
            source /etc/profile
~~~





##### 2、安装Python

~~~markdown
(1) 下载安装包,并发送到Linux系统中 
    建议放在 /usr/local 下

(2) 解压tar包
    tar -zxvf Python-3.6.4rc1.tgz
    
(3) 进入解压目录,执行
    ./configure --prefix=/usr/local/Python3 --enable-shared CFLAGS=-fPIC
    目的:a. 检测依赖是否完整  b. 指定Python安装位置   
    
(4) 编译
    make
    
(5) 安装
    make install 
~~~

~~~markdown
# 安装完Python后,出现以下内容
Collecting setuptools
Collecting pip
Installing collected packages: setuptools, pip
Successfully installed pip-9.0.1 setuptools-28.8.0
~~~



##### 3、配置Python3的环境变量

###### 3.1 修改原来的Python2.7.5

~~~markdown
# 将环境变量中的已有Python进行重命名
mv /usr/bin/python /usr/bin/python2.7.5
~~~

###### 3.2 软链接

~~~markdown
# 将Python3解释器软链接到/usr/bin/python
ln -s /usr/local/Python3/bin/python3 /usr/bin/python
~~~

以上操作,仅仅是发了python3解释器的快捷方式到环境变量中已存在的一个目录/usr/bin下。



###### 3.3 解决错误

~~~markdown
此时,正常来说,现在在命令中直接输入python回车,即可进入python3的交互式界面。
但是报错了:
    python: error while loading shared libraries: libpython3.6m.so.1.0: cannot open shared object file: No such file or directory
    
# 解决方案:
    执行以下指令即可:
    cp /usr/local/Python3/lib/libpython3.6m.so.1.0 /usr/lib64/
~~~



###### 3.4 测试Python

~~~markdown
在Linux的命令行中,输入python即可进入交互式界面
~~~



###### 3.5 配置环境变量

~~~markdown
将Python安装目录下的bin目录添加到环境变量中
(1)进入配置文件
        vi /etc/profile 
(2)加入配置,保存并退出
        export PATH=$PATH:/usr/local/Python3/bin
(3)让环境变量生效
        在linux的命令行中执行:
        source /etc/profile
(4)测试
        pip3 -V 
~~~



##### 4、更新pip

~~~markdown
pip3 install --upgrade pip

# 执行上述命令后,报错SSL 因为pypi的URL是https的

# 解决方案:更改pip源
(1)创建.pip目录
    mkdir ~/.pip     # 该命令在任意地方都可执行
(2)创建pip.conf文件    
    vi ~/.pip/pip.conf     #  创建文件
(3) 加入以下内容
[global]
timeout = 6000
index-url = http://pypi.douban.com/simple
trusted-host = pypi.douban.com

# 再重新更新pip     pip3 install --upgrade pip

# 更新完后,以后使用pip时,直接pip install xx即可
~~~



##### 5、补充

安装mysql的开发库

~~~markdown
yum install mysql-devel

# 报错,原因:yum本身是基于python2的,而此时环境变量中的python是python3
        [root@Mrlee bin]# yum install mysql-devel
          File "/usr/bin/yum", line 30
            except KeyboardInterrupt, e:
                                    ^
        SyntaxError: invalid syntax
# 解决方案:
(1)进入yum文件
    vi /usr/bin/yum
(2)修改文件头为:
    #!/usr/bin/python2.7.5
(3)再重新安装mysql-devel
    yum install mysql-devel
    
# 又报错,解决思路上述一样
        Downloading packages:
          File "/usr/libexec/urlgrabber-ext-down", line 28
            except OSError, e:
                          ^
        SyntaxError: invalid syntax
# 解决方案:        
(1)进入urlgrabber-ext-down文件
    vi /usr/libexec/urlgrabber-ext-down
(2)修改文件头为:
    #!/usr/bin/python2.7.5
(3)再重新安装mysql-devel
    yum install mysql-devel       
~~~



### 三、Django安装

##### 1、模块的安装

~~~markdown
1. 安装Django
        pip install django==2.0.6
        
2. 安装mysqlclient
        pip install mysqlclient
        
3. 其它的第三方库
        pip install pillow 等  如果项目使用了pillow但未安装 PIL错误
~~~

##### 2、测试django项目

~~~markdown
1. 创建项目
        [root@Mrlee ~]# django-admin startpoject helloworld
        
2. 修改seetings.py
        ALLOWED_HOST = ['*']  # 允许远程访问
        
3. 启动服务
        python manage.py runserver 0.0.0.0:8000
        
4. 打开浏览器(windows),输入:linux-ip:8000 访问        
~~~



### 四、uWSGI服务器

##### 1、简介

~~~markdown
当使用python manager.py runserver时,启动的是一个开发服务器来运行着项目,当项目上线时,就不能使用该方式来启动服务。

此时,需要一个专业的服务器来运行项目:uWSGI、gunicorn等服务器
~~~



##### 2、wsgi协议

~~~markdown
1. 当我们使用django或flask框架编写的web项目,在启动服务后,都是使用了框架内置的服务器(开发服务器Server)来运行着项目(application)。此时服务器Server要和应用程序Application通信,就需要使用到通信的协议--`wsgi`协议

2. 之前django项目就是基于了wsgi协议而编写的  (在项目根目录的,同名子目录下有一个wsgi.py文件)
内置服务器也遵循了wsgi协议,因此内置服务器才可以运行django的项目
~~~

![ebServer和WebApplication关](D:\资料\第二阶段 Web全栈\04 Linux\Linux上课资料\WebServer和WebApplication关系.png)



~~~markdown
WSGI:全称Web Server Gateway Inteface ,WSGI不是一个服务器,也不是Python模块,框架,API或任何的软件,只是一个规范,描述的是Web Server如何与Web Application通信的规范。

# 各方的职责:
1. WSGI的Server:
        负责接收客户端浏览器的请求,将request转发给application,将application返回的response返回给浏览器。
    
1. WSGI的Application:
        接收由Server转发的请求,处理请求,并将处理结果返回给Server
~~~



~~~markdown
如果要实现WSGI协议,Web Server和Web Application都需要实现。而当运行在WSGI协议之上的Web框架有:Django,Flask 等

# 总结: WSGI是Web Server和Web Application之间通信的一种协议规范(一种低级别的接口)
~~~



##### 3、uWSGI服务器

###### 3.1 简介

~~~markdown
uWSGI服务器是一个遵循了wsgi协议的Web Server,因此它可以与django框架编写的application进行通信。

当前遵循了wsgi协议的服务器有:django内置的开发服务器、uWSGI、gunicorn等
~~~



###### 3.2 安装uWSGI

~~~markdown
(1)下载uWSGI的tar包,并发送到linux中

(2)解压tar包  
        tar -zxvf uwsgi-2.0.17.tar.gz
        
(3)进入解压目录,并编译
        make

(4)为了方便在任意目录下启动uwsgi
        ln -s /usr/local/uwsgi-2.0.17/uwsgi  /usr/bin/uwsgi
    此时就可以在任意目录下,直接使用uwsgi来启动uwsgi的服务器    
~~~



###### 3.3 测试uwsgi服务器

~~~markdown
需要写一个基于wsgi协议的程序即可

在任意目录下,定义一个hello.py文件:

def application(env,start_response):
    start_response('200 OK',[('Content-Type','text/html;charset=utf-8')])
    return [bytes('你好啊','utf-8'),b'Mr_lee']
    
# 上述的代码,是一个遵循了wsgi协议而编写的程序,没有使用任何的框架    
~~~

~~~markdown
使用uwsgi来运行hello.py

`uwsgi --http 192.168.79.129:8000 --wsgi-file hello.py`

打开浏览器访问即可
~~~



##### 4、uWSGI运行Django项目

###### 4.1 准备工作

~~~markdown
1. 将django项目发送到Linux系统中

2. 修改settings.py文件
    DEBUG = False        # 项目上线 非调试模式
    ALLOWED_HOST = ['*']
    
3. 检测数据库配置,并建库
    localhost 现在指向了Linux中的数据库
    需要在Linux的数据库中新建项目需要的数据库-加字符集
    
4. 迁移生成表
    python manage.py migrate 
    
    或者是将本地(windows)库中的数据迁移到Linux的数据库中
    (1)使用navicat 找到windows的本地库,选中库名->右键->转储SQL文件->结构和数据->选择电脑的一个存储位置
    (2)在navicat中,打开Linux数据库中新建的库(项目相关),右键 -> 运行SQL文件,选择上述转储的SQL文件即可    
~~~



###### 4.2 编写uWSGI的配置文件

~~~markdown
#随意找一个目录,创建一个文件:config.ini -- 建议放在项目的根目录下
[uwsgi]
# Linux的ip和项目的端口号
http = 192.168.79.129:9000 
# 将来会用到 用于和其它的服务器通信的端口
socket = 192.168.79.129:9001
# 项目根目录的路径 - Linux
chdir = /usr/local/django_projects/ems_project
# 项目中的wsgi文件的相对路径
wsgi-file = ems_project/wsgi.py
processes = 4
threads = 2
stats = 192.168.79.129:9002
vacuum = true
# 保存uwsgi服务器的进程号
pidfile = /usr/local/django_projects/ems_project/uwsgi.pid  
# 表示以守护进程模式启动-后台模式
daemonize = /usr/local/django_projects/ems_project/uwsgi.log 
# 配置静态资源
static-map =/static=/usr/local/xxx/static 资源 
~~~

~~~markdown
# 启动uwsgi服务(启动之前一定要先关闭 ps -ef | grep uwsgi)
uwsgi --ini config.ini

# 关闭服务
uwsgi --stop uwsgi.pid
~~~



###### 4.3 静态资源

~~~
现在使用uwsgi访问项目后,无法加载静态资源
原因:
    在开发服务器中(DEBUG=True),django查找静态资源是在每个app的static目录下或STATICFILES_DIRS所指定的目录下。
    而在uwsgi服务器中,django就不会在上述路径中查找静态资源了。uwsgi有自己的静态资源的处理方式。
~~~



~~~markdown
在config.ini配置中:
static-map =/static=静态资源的存放路径  (有几个写几个)

# 但是如果app过多,添加static-map过于麻烦
# 因此需要将所有app下的静态资源收集到一块

# 具体操作:
# (1)在settings.py文件添加
    STATIC_ROOT = os.path.join(BASE_DIR,'static')
    # 告诉django,收集静态资源时的存储路径
    
# (2) 执行收集指令
    python manage.py collectstatic
    
# (3) 在config.ini中,添加项目根目录的static为static-map
    static-map=/static=/usr/.../项目根目录/static
~~~


~~~