From 8c00fdd3158b1f36a81e18fa71eedb6a659b8dc8 Mon Sep 17 00:00:00 2001 From: RobbieHan Date: Tue, 26 Feb 2019 12:43:05 +0800 Subject: [PATCH] add README.md&config --- README.md | 777 +++++++++++++++++++++++++++++++++ config/basic_data_20190225.sql | 219 ++++++++++ config/celery_worker.ini | 19 + config/nginx.conf | 64 +++ config/sandboxmp_uwsgi.ini | 8 + config/smp_uwsgi.ini | 12 + document/images/stepww.png | Bin 0 -> 25761 bytes slogs/sandbox_err.log | 0 slogs/sandbox_info.log | 0 9 files changed, 1099 insertions(+) create mode 100644 README.md create mode 100644 config/basic_data_20190225.sql create mode 100644 config/celery_worker.ini create mode 100644 config/nginx.conf create mode 100644 config/sandboxmp_uwsgi.ini create mode 100644 config/smp_uwsgi.ini create mode 100644 document/images/stepww.png create mode 100644 slogs/sandbox_err.log create mode 100644 slogs/sandbox_info.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..16f5de8 --- /dev/null +++ b/README.md @@ -0,0 +1,777 @@ +> 项目说明:本项目是根据客户需求开发的一套自动化运维项目,在征得客户同意的情况下,将部分功能开源。本项目配套有完整开发文档,详细记录了项目整个实现过程,可作为学习Django的参考文档。文档以项目为主线,逐步介绍了Django基本类视图、通用类视图和自定义类视图,涵盖了Django核心组件和扩展模块的使用,包括:logging 、signals、simple-history等,同时扩展了celery和channel来实现分布式任务队列和websocket功能等,利用ansible进行集中管理和自动化任务执行。 + +# 1 运行环境配置 + +## 1.1 项目运行环境 + +- 系统版本: Centos7(CentOS Linux release 7.6.1810) +- Python版本:Python 3.6.6 (default, Jan 30 2019, 21:53:32) +- Django版本:django 2.1.5 +- 数据库: mysql5.7/mongo3.4/redis3.2 +- 进程管理工具:supervisorctl 3.1.4 +- 扫描工具:Nmap version 6.40 +- 其他依赖:sandboxMP/requirements/pro.txt + +## 1.2 Python虚拟环境配置 + +准备一台centos7的系统作为项目运行的服务器系统,完成基本网络设置、防火墙设置和系统基本优化设置。(以下内容都是在Centos7系统命令行中进行操作) + + +1、基础配置:使用ssh远程工具(我用的是secureCRT)连接准备好的Centos7系统,完成以下设置: + +``` +# 1.修改系统登陆后的提示信息。 +# 将motd内容改为:sandboxMP 172.16.3.200 (地址设置成你登陆的系统地址,上下各空一行); +# 这样在登陆系统是的时候就可以看到上面的提示信息,防止登错系统。 +[root@template ~]$ vim /etc/motd + +sandboxMP 192.168.31.200 + +# 2.修改主机名,exit退出系统,按回车重新连接系统,就可以看到新的提示信息和主机名 +[root@template ~]$ hostnamectl set-hostname sandboxmp +[root@template ~]$ exit +``` + +2、安装python3.6:系统中默认带有python2.7,项目中使用的是python3.6.6 + + +``` +# 1.可以去官网下载python3.6.6(Source release Gzip),也可以在linux下使用wget下载 +[root@sandboxmp ~]$ yum -y install wget +[root@sandboxmp ~]$ wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz + +# 2.安装pip和环境依赖包 +[root@sandboxmp ~]$ yum -y install epel-release +[root@sandboxmp ~]$ yum -y install python-pip +[root@sandboxmp ~]$ pip install --upgrade pip +[root@sandboxmp ~]$ yum install -y zlib zlib-devel --setopt=protected_multilib=false +[root@sandboxmp ~]$ yum install -y bzip2 bzip2-devel openssl openssl-devel ncurses ncurses-devel sqlite sqlite-devel readline readline-devel gcc make python-devel + +# 3.安装python3.6(编译安装完成执行 echo $? 返回0安装成功,否则安装出错) +[root@sandboxmp ~]$ tar -zvxf Python-3.6.6.tgz +[root@sandboxmp ~]$ cd Python-3.6.6 +[root@sandboxmp Python-3.6.6 ~]$ ./configure +[root@sandboxmp Python-3.6.6 ~]$ make && make install +[root@sandboxmp Python-3.6.6 ~]$ echo $? +0 + +# 4.安装成功后,就可以使用python3环境 +[root@sandboxmp Python-3.6.6 ~]$ cd ~ +[root@sandboxmp ~]$ python3 +Python 3.6.6 (default, Nov 26 2018, 16:19:34) +'''''' +>>> exit() # 退出python环境 +``` + +3、安装python虚拟环境:在项目中还是使用虚拟环境,项目环境互不影响 + + +``` +# 1.安装 virtualenv virtualenvwrapper +[root@sandboxmp ~]$ pip install virtualenv virtualenvwrapper + +# 2.设置环境变量,使用vim编辑.bashrc在最后面添加最后两行内容 +[root@sandboxmp ~]$ vim ~/.bashrc +# .bashrc + +# User specific aliases and functions + +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# Source global definitions +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi +# 下面两行是新增加内容 +export WORKON_HOME=$HOME/.virtualenvs +source /usr/bin/virtualenvwrapper.sh + +# 3.保存修改,退出vim,运行命令让变量生效 +[root@sandboxmp ~]$ source ~/.bashrc + +# 4.现在可以在bash窗口使用mkvirtualnev来创建虚拟环境了 +[root@sandboxmp ~]$ mkvirtualenv -p /usr/local/bin/python3.6 sandboxMP +Running virtualenv with interpreter /usr/local/bin/python3.6 +Using base prefix '/usr/local' +New python executable in /root/.virtualenvs/sandboxMP/bin/python3.6 +Also creating executable in /root/.virtualenvs/sandboxMP/bin/python +Installing setuptools, pip, wheel... +done. +...... + +# 5.创建完成系统自动进入了虚拟环境sandboxMP +(sandboxMP) [root@sandboxmp ~]$ + +# 6.离开虚拟环境 +(sandboxMP) [root@sandboxmp ~]$ deactivate +[root@sandboxmp ~]$ + +# 7.查看虚拟环境 +[root@sandboxmp ~]$ workon +sandboxMP +[root@sandboxmp ~]$ + +# 8.激活虚拟环境 +[root@sandboxmp ~]$ workon sandboxMP +(sandboxMP) [root@sandboxmp ~]$ +``` + +通过上面配置,指定使用python3.6来创建一个虚拟环境,虚拟环境名称为sandboxMP,虚拟环境存放的目录在/root/.virtualenvs目录下,这个是由上一步环境变量设置的。 + +## 1.3 安装数据库 + +在准备好的Centos7系统中安装mysql/redis/mongodb,当然数据库也可以和应用分开单独安装。 + +### 1.3.1 安装Mysql + +在Centos7系统中更新yum源文件,安装myslq,创建项目数据库: + +``` +# 1.安装Mysql +[root@sandboxmp ~]$ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm +[root@sandboxmp ~]$ rpm -ivh mysql-community-release-el7-5.noarch.rpm +[root@sandboxmp ~]$ yum -y update +[root@sandboxmp ~]$ yum install -y mysql-server + +# 2.修改配置文/etc/my.cnf,在[mysql]标签下添加后面三行内容,保存退出vim +[root@sandboxmp ~]$ vim /etc/my.cnf +[mysqld] +collation-server = utf8_unicode_ci +character_set_server=utf8 +init_connect='SET NAMES utf8' + +# 3.启动mysql,设置开机启动,为root用户设置密码 +[root@sandboxmp ~]$ systemctl start mysqld +[root@sandboxmp ~]$ systemctl enable mysqld +[root@sandboxmp ~]$ mysql + +mysql> set password for 'root'@'localhost'=password('1234@abcd.com'); +mysql> exit + +# 4.再次连接Mysql会提示要使用密码,连接方式如下,回车,根据提示输入密码 +[root@sandboxmp ~]$ mysql -uroot -p +Enter password: +Welcome to the MySQL monitor. Commands end with ; or \g. +'''''' +mysql> + +# 5.创建数据库,添加用户和访问授权 +mysql> CREATE DATABASE sandboxMP; +mysql> GRANT ALL PRIVILEGES ON sandboxMP.* TO 'ddadmin'@'%' IDENTIFIED BY '1234@abcd.com'; +mysql> GRANT ALL PRIVILEGES ON sandboxMP.* TO 'ddadmin'@'localhost' IDENTIFIED BY '1234@abcd.com'; +``` + +### 1.3.2 安装Redis + +项目中会使用celery来做分布式任务队列,用来处理比较耗时的操作,例如发送邮件,资产扫描等操作。我们使用redis来做中间人,用来存储任务队列和接受返回值。 +在服务器中,执行下面命令安装redis: + +``` +# 1.安装扩展源(前面我们已经安装过扩展源epel-release)和redise +[root@sandboxmp ~]$ yum install epel-release +[root@sandboxmp ~]$ yum install redis + +# 2.修改redis配置文件找到bind去掉前面的注释符号,ip改为0.0.0.0,保存退出 +[root@sandboxmp ~]$ vim /etc/redis.conf +bind 0.0.0.0 + +# 3.启动redise和设置开机启动 +[root@sandboxmp ~]$ systemctl start redis +[root@sandboxmp ~]$ systemctl enable redis +``` + +### 1.3.3 安装Mongodb + +项目中mongodb用来存储日志信息,安装方法如下: + +``` +# 1.配置yum源文件,添加mongo安装源,保存退出 +[root@sandboxmp ~]$ vim /etc/yum.repos.d/mongo.repo +[mongodb-org-3.4] +name=MongoDB 3.4 Repository +baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/ +gpgcheck=0 +enabled=1 + +# 2.安装mongodb, 修改bindIp(把地址改成0.0.0.0后,保存退出) +[root@sandboxmp ~]$ yum install -y mongodb-org +[root@sandboxmp ~]$ vim /etc/mongod.conf +bindIp 0.0.0.0 # 修改bindIp + +# 3.启动mongodb,设置开始启动 +[root@sandboxmp ~]$ systemctl start mongod +[root@sandboxmp ~]$ systemctl enable mongod +``` + +## 1.4 安装项目依赖包 + +项目运行需要安装必要的依赖包,所有依赖包都记录在项目文件中:sandboxMP/requirements/pro.txt 。 + +### 1.4.1 克隆项目到本地 + +登陆服务器系统,使用git命令克隆项目到本地(如果没有git命令需要先安装git:yum -y install git): + +``` +# 1.创建/opt/app目录,用来存放项目文件 +[root@sandboxmp ~]$ mkdir /opt/app +[root@sandboxmp ~]$ cd /opt/app +# 2.克隆项目到本地 +[root@sandboxmp app]$ git clone https://github.com/RobbieHan/sandboxMP.git +Cloning into 'sandboxMP'... +remote: Enumerating objects: 134, done. +remote: Counting objects: 100% (134/134), done. +remote: Compressing objects: 100% (57/57), done. +remote: Total 2041 (delta 96), reused 81 (delta 76), pack-reused 1907 +Receiving objects: 100% (2041/2041), 7.67 MiB | 16.00 KiB/s, done. +Resolving deltas: 100% (663/663), done. + +``` +==**对于无法访问github的朋友可以从码云上克隆项目:**== + +``` +# 进入到/opt/app目录,执行下面命令从码云克隆项目到本地: +[root@sandboxmp app]$ git clone https://gitee.com/RobbieHan/sandboxMP.git +``` + +### 1.4.2 安装项目依赖包 + +项目克隆到本地后,进入python虚拟环境,使用pip安装项目依赖包: + +``` +# 1.进入python虚拟环境 +[root@sandboxmp ~]$ workon sandboxMP +# 2.防止安装mysqlclient报错:EnvironmentError: mysql_config not found,先安装下面两个包 +(sandboxMP) [root@sandboxmp ~]$ yum -y install mysql-devel libmysqlclient-dev +# 3.安装 /opt/app/sandboxMP/requirements/pro.txt文件中所有依赖包 +(sandboxMP) [root@sandboxmp ~]$ pip install -r /opt/app/sandboxMP/requirements/pro.txt +``` + +## 1.5 创建数据表&导入初始数据 + +项目做了自定义的权限管理,更具用户角色权限来动态生成导航数据,所以在运行像目前,需要生成数据表并导入初始数据。 + +``` +# 1. 从模型生成数据表(以下命令在服务器虚拟环境中执行) +(sandboxMP) [root@sandboxmp ~]$cd /opt/app/sandboxMP # 进入项目目录 +(sandboxMP) [root@sandboxmp sandboxMP]$ python manage.py makemigrations +Migrations for 'cmdb': + apps/cmdb/migrations/0001_initial.py + - Create model Cabinet + - Create model Code + - Create model ConnectionInfo + - Create model DeviceFile + - Create model DeviceInfo + - Create model DeviceScanInfo + - Create model HistoricalDeviceInfo + - Add field device to devicefile +(sandboxMP) [root@sandboxmp sandboxMP]$ python manage.py migrate +Operations to perform: + Apply all migrations: admin, auth, cmdb, contenttypes, sessions, system +Running migrations: + Applying contenttypes.0001_initial... OK + '''输出信息省略''' + +# 2.导入基础数据内容,更具提示信息输入密码(默认:1234@abcd.com) +(sandboxMP) [root@sandboxmp sandboxMP]$ mysql -uroot -p sandboxMP < config/basic_data_20190225.sql +Enter password: +(sandboxMP) [root@sandboxmp sandboxMP]$ + +``` +**注意:** sandboxMP/sandboxMP/settings.py中数据库连接设置的是本地地址:127.0.0.1,请根据实际配置进行调整。 + +**环境部署到这里可以在命令行使用manage.py工具临时运行项目。** + +==**测试项目运行:**== + + +``` +# 在虚拟环境下,进入到项目目录,使用manage.py临时运行项目: +(sandboxMP) [root@sandboxmp sandboxMP]$ python manage.py runserver 0.0.0.0:80 +Performing system checks... + +System check identified no issues (0 silenced). +February 25, 2019 - 19:58:19 +Django version 2.1.5, using settings 'sandboxMP.settings' +Starting development server at http://0.0.0.0:80/ +Quit the server with CONTROL-C. +``` + +使用你的服务器地址访问项目(确认系统防火墙有没有限制80端口): + +``` +http://172.16.3.200 # 导入的基础数据包含一个默认管理员:admin 密码:!qaz@wsx +``` +登录系统后可以点击导航菜单,访问对应功能。确认项目环境和项目运行没有问题后在服务器中按 CTRL + C 终止运行。 + + +# 2 功能环境配置 + +项目中使用了一些工具例如:Nmap,异步任务使用的:Celery,进程管理使用的:Supervisor,扫描执行和集中管理使用的密钥认证登录等配置。 + +## 2.1 安装Nmap + +登录服务器使用yum安装nmap工具,nmap的基本使用【Django实战2-自动化运维之配置管理-08:资产扫描工具的使用】 + +``` +[root@sandboxmp ~]$ yum -y install nmap +``` + +## 2.2 密钥认证配置 + +本项目提供的扫描执行和集中管理功能支持密钥认证方式,如果要使用密钥认证来登录管理远程主机,需要设置密钥认证。 + +**1、在项目部署的服务器上创建密钥文件:** + +``` +# 使用 ssh-keygen创建密钥文件,执行命令后,一路回车。生成的密钥文件默认存放在/root/.ssh目录中 +[root@sandboxmp ~]# ssh-keygen +Generating public/private rsa key pair. +Enter file in which to save the key (/root/.ssh/id_rsa): +Enter passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved in /root/.ssh/id_rsa. +Your public key has been saved in /root/.ssh/id_rsa.pub. +The key fingerprint is: +SHA256:dn0G8JVMN6Qby6JhZhFaMzOQ19ko5y518FIGsds5Pbg root@sandboxmp +The key's randomart image is: ++---[RSA 2048]----+ +| .oBoo*o++.| +| .oo*O.=+..| +| ...+.Bo | +| .=++B | +| S=+o+Ooo | +| .+oo..oo .| +| .. E | +| | +| | ++----[SHA256]-----+ + +``` + +**2、在需要管理的远程终端中配置允许密钥登录:** + + +``` +# 1.修改sshd_config配置文件内容,去掉下面内容的注释,保存退出 +[root@server1 ~]$ vim /etc/ssh/sshd_config + +RSAAuthentication yes +PubkeyAuthentication yes +AuthorizedKeysFile .ssh/authorized_keys # 认证授权默认存放位置 + +[root@server1 ~]$ systemctl restart sshd + +# 2.生成公钥私钥文件,执行下面命令然后一路回车 +[root@server1 ~]$ ssh-keygen + Generating public/private rsa key pair. +Enter file in which to save the key (/root/.ssh/id_rsa): +Created directory '/root/.ssh'. +Enter passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved in /root/.ssh/id_rsa. +Your public key has been saved in /root/.ssh/id_rsa.pub. +The key fingerprint is: +be:02:d5:03:c3:bc:64:22:90:a1:12:1f:64:16:76:4e root@server1 +The key's randomart image is: ++--[ RSA 2048]----+ +|+=B.Eo | +|o*.=. B | +|o ...+ = | +|. o o | +| . S. | +| . . | +| . . | +| . . | +| .. | ++-----------------+ +# 3.这时候已经在/root/.ssh目录下生成了密钥文件 +[root@server1 ~]$ ls -l .ssh +total 8 +-rw------- 1 root root 1679 Dec 2 19:59 id_rsa +-rw-r--r-- 1 root root 394 Dec 2 19:59 id_rsa.pub + +# 4. 创建认证文件,设置访问权限,authorized_keys是sshd_config中配置的认证授权默认存放位置 + +[root@server1 .ssh]$ touch authorized_keys +[root@server1 .ssh]$ chmod 600 authorized_keys +[root@server1 .ssh]$ ls -l +total 12 +-rw------- 1 root root 396 Dec 2 20:05 authorized_keys +-rw------- 1 root root 1679 Dec 2 19:59 id_rsa +-rw-r--r-- 1 root root 394 Dec 2 19:59 id_rsa.pub +[root@server1 .ssh]$ +``` + +**3、将项目部署服务器的公钥写入远程终端的认证文件:authorized_keys** + +``` +[root@sandboxmp ~]$ cat ~/.ssh/id_rsa.pub | ssh root@172.16.3.101 'cat >> .ssh/authorized_keys' +The authenticity of host '172.16.3.101 (172.16.3.101)' can't be established. +ECDSA key fingerprint is SHA256:6veR9N0x60mE73zxt+N7sesJrlAEatHK9/UkXHeAd3Y. +ECDSA key fingerprint is MD5:17:89:88:88:25:6e:ca:c9:f8:19:45:3e:c4:2f:d7:bf. +Are you sure you want to continue connecting (yes/no)? yes # 首次登录需要输入yes确认 +Warning: Permanently added '172.16.3.101' (ECDSA) to the list of known hosts. +root@172.16.3.101's password: # 输入远程主机的密码 +[root@sandboxmp ~]$ +``` +代码中172.16.3.101是服务器需要管理的远程终端的IP地址,首次SSH连接远程主机需要输入yes确认连接,根据提示输入密码后成功写入公钥到远程终端。 + +在此通过项目服务器SSH连接到远程终端,已经不需要再输入密码了,可以直接通过密钥完成认证: + +``` +[root@sandboxmp ~]$ ssh root@172.16.3.101 +Last login: Wed Feb 20 17:53:16 2019 from 172.16.3.200 + +server01 172.16.3.101 + + +[root@server01 ~]# # 成功登陆到远程终端,命令行提示符显示的是server01 +[root@server01 ~]# exit # 退出远程终端连接 +logout +Connection to 172.16.3.101 closed. +[root@sandboxmp ~]# +``` + +## 2.3 使用Supervisor管理进程 + +设备扫描功能使用了celery做的任务队列,进行异步扫描,同时又使用到Flower来监控任务队列。为了方便管理,在项目中使用了Supervisor来管理进程数据。 + +项目文件中已经做好了celery的配置和任务队列配置,所以只需要使用Supervisor将进程管理起来即可。 + +### 2.3.1 安装Supervisor + +安装Supervisor可以直接使用pip install supervisor来安装(不支持python3.6),也可以使用yum install 来安装。 + + +``` +# 在项目部署的服务器上安装supervisor +[root@sandboxmp ~]$ yum -y install supervisor +``` + +项目中使用yum方式来安装supervisor,安装后会自带配置文件,可以通过systemctl 来管理supervisor进程。 + +### 2.3.2 创建进程管理文件 + +**1、查看项目部署服务器上的Supervisord配置文件:** +``` +[root@sandboxmp /]$ cat /etc/supervisord.conf +'''以上内容省略''' +[include] +files = supervisord.d/*.ini +``` +可以看到,配置文件中导入了supervisord.d目录下的所有.ini格式文件,所以我们可以把进程管理的配置文件放到这个目录。 + +**2、创建子进程管理配置文件** + +在项目部署的服务器中创建子进程管理文件,来管理celer任务进程和flower进程: + +``` +# 编辑进程管理配置文件 +[root@sandboxmp ~]$ touch /etc/supervisord.d/celery_worker.ini +[root@sandboxmp ~]$ vim /etc/supervisord.d/celery_worker.ini + +# 将以下内容写入配置文件保存并退出 +[program:celery-worker] +command=/root/.virtualenvs/sandboxMP/bin/celery worker -A sandboxMP -l INFO +directory=/opt/app/sandboxMP +environment=PATH="/root/.virtualenvs/sandboxMP/bin/" +stdout_logfile=/opt/app/sandboxMP/slogs/celery_worker.log +stderr_logfile=/opt/app/sandboxMP/slogs/celery_worker.log +autostart=true +autorestart=true +priority=901 + +[program:celery-flower] +command=/root/.virtualenvs/sandboxMP/bin/celery flower --broker=redis://localhost:6379/0 +directory=/opt/app/sandboxMP +environment=PATH="/root/.virtualenvs/sandboxMP/bin/" +stdout_logfile=/opt/app/sandboxMP/slogs/celery_flower.log +stderr_logfile=/opt/app/sandboxMP/slogs/celery_flower.log +autostart=true +autorestart=true +priority=900 +``` + +**3、启动Supervisord** + +``` +[root@sandboxmp ~]$ systemctl start supervisord # 启动supervisord +[root@sandboxmp ~]$ systemctl enable supervisord # 加到开机启动 +``` + +**4、使用supervisorctl管理工具** + +启动supervisord服务后,supervisor会读取配置文件中的子进程配置,并启动celery-worker和celery-flower进程。Supervisor为我们提供了一个子进程管理工具:supervisorctl来管理这些进程数据: + + +``` +[root@sandboxmp /]$ supervisorctl # 启用子进程管理工具,系统会打印当前子进程状态 +celery-flower RUNNING pid 4007, uptime 0:05:13 +celery-worker RUNNING pid 4008, uptime 0:05:13 +supervisor> status # 查看子进程状态 +celery-flower RUNNING pid 4007, uptime 0:05:17 +celery-worker RUNNING pid 4008, uptime 0:05:17 +supervisor> stop celery-flower # 停止子进程,stop all 停止所有 +celery-flower: stopped +supervisor> status +celery-flower STOPPED Jan 18 03:27 PM +celery-worker RUNNING pid 4008, uptime 0:05:32 +supervisor> start celery-flower # 启动子进程 +celery-flower: started +supervisor> help # 查看帮助 + +default commands (type help ): +===================================== +add clear fg open quit remove restart start stop update +avail exit maintail pid reload reread shutdown status tail version +``` + +为了使用Celery任务队列功能,需要确保celery-flower和celery-worker进程状态都是RUNNING。如果有问题请查看对应日志文件(在配置子进程的时候指定了日志存储路径) + +> 完成功能环境配置后,可以在项目服务器中临时运行项目,然后登陆系统,测试设备扫描功能,查看任务队列是否可以正常执行。 + +# 3 将项目部署上线 + +项目部署使用uwsgi来做Web服务,Nginx做代理并提供静态资源访问和简单缓存功能。一般项部署项目上线,我会分步骤进行,这样在遇到问题也清楚是哪一个环节出的问题,可以有针对性的进行排错。 + +![image](https://note.youdao.com/yws/public/resource/a1d5666dbb08d64e54f62356db53a052/xmlnote/528B854C93FC4AE492CAC9815D878822/36874) + +## 3.1 使用uwsgi运行项目 + +经过前面的部署,已经准备好了系统环境、项目以来环,并确认项目可以正常运行,接下来使用uwsgi来运行项目。 + +**1、登陆服务器系统,进入虚拟环境,安装uwsgi** + +``` +[root@sandboxmp ~]# workon sandboxMP +(sandboxMP) [root@sandboxmp ~]$ pip install uwsgi + +``` + +**2、设置Uwsgi配置文件** + + +``` +(sandboxMP) [root@sandboxmp ~]$ vim /etc/smp_uwsgi.ini +[uwsgi] +http = 172.16.3.200:9000 +#socket = 127.0.0.1:9000 +chdir = /opt/app/sandboxMP +module = sandboxMP.wsgi +static-map=/static=/opt/app/sandboxMP/static +#daemonize =/var/log/uwsgi.log +master = Ture +vacuum = True +processes = 4 +threads = 2 +buffer-size=32768 + +``` +配置说明: +- chdir: 指定项目目录,请设置项目所在目录 +- static-map:静态文件映射,测试uwsgi配置时为了能够访问到静态资源,所以加上这个配置。在使用nginx时,需要注销掉这个配置,改用nginx来代理静态资源访问。 + +注意:配置文件中设置http,是为了方便使用Uswgi启动项目后,进行访问和功能测试。 + +**3、使用配置文件启动Uwsgi** + + +``` +# 注意:uwsgi是安装在虚拟环境的,要使用uwsgi命令需要先进入虚拟环境 +(sandboxMP) [root@sandboxmp ~]$ uwsgi /etc/smp_uwsgi.ini +[uWSGI] getting INI configuration from /etc/smp_uwsgi.ini +[uwsgi-static] added mapping for /static => /opt/app/sandboxMP/static +*** Starting uWSGI 2.0.18 (64bit) on [Mon Feb 25 23:21:01 2019] *** +compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-36) on 25 February 2019 14:10:29 +'''中间启动内容省略''' +spawned uWSGI master process (pid: 17054) +spawned uWSGI worker 1 (pid: 17058, cores: 2) +spawned uWSGI worker 2 (pid: 17060, cores: 2) +spawned uWSGI worker 3 (pid: 17061, cores: 2) +spawned uWSGI worker 4 (pid: 17063, cores: 2) +spawned uWSGI http 1 (pid: 17064) +``` +项目运行成功通过服务器地址:http://172.16.3.200:9000就可以访问项目了,使用默认用户名: admin,密码:!qaz@wsx 登陆系统,测试系统功能。 + +至此,确认完Uwsgi配置没有问题,可以正常启动项目,然后终止Uwsgi运行(在命令行使用CTRL + C)。 + +**4、修改Uwsgi配置文件** + +上面的配置是为了方便测试Uwsgi运行项目,线上部署项目,采用socket模式,使用nginx来处理静态文件访问: + + +``` +[uwsgi] +#http = 172.16.3.200:9000 +socket = 127.0.0.1:9000 +chdir = /opt/app/sandboxMP +module = sandboxMP.wsgi +#static-map=/static=/opt/app/sandboxMP/static +#daemonize =/var/log/uwsgi.log +master = Ture +vacuum = True +processes = 4 +threads = 2 +buffer-size=32768 +``` +配置中注销了http和static-map配置,同时启用socket配置。这时你也可以在命令行使用新的配置文件启动下uwsgi看看运行状态,不过这时候外面是无法通过uwsgi来直接访问系统了,还需要配置nginx代理。 + +**5、使用supervisor来管理uwsgi进程** + +在前面已经使用supervisor来管理celery任务进程和flower进程,同样也可以使用supervisor来管理uwsgi进程: + +``` +# 1.新建一个进程文件sandboxmp_uwsgi,写入下面配置内容: +(sandboxMP) [root@sandboxmp ~]$ vim /etc/supervisord.d/sandboxmp_uwsgi.ini +[program:sandboxmp-uwsgi] +command=/root/.virtualenvs/sandboxMP/bin/uwsgi /etc/smp_uwsgi.ini +stdout_logfile=/var/log/uwsgi/smp_uwsgi.log +stderr_logfile=/var/log/uwsgi/smp_uwsgi.log +stdout_logfile_maxbytes = 20MB +autostart=true +autorestart=true +priority=905 + +# 2.创建一个目录用来存放uwsgi日志 +(sandboxMP) [root@sandboxmp ~]$ mkdir /var/log/uwsgi + +# 3.启动sandboxmp_uwsgi进程 +(sandboxMP) [root@sandboxmp ~]# supervisorctl reload +Restarted supervisord + +# 4. 稍微等待一会,然后查看进程状态: +(sandboxMP) [root@sandboxmp ~]# supervisorctl status +celery-flower RUNNING pid 17231, uptime 0:00:05 +celery-worker RUNNING pid 17232, uptime 0:00:05 +sandboxmp-uwsgi RUNNING pid 17233, uptime 0:00:05 + +# 5.查看服务状态 +(sandboxMP) [root@sandboxmp ~]# netstat -tnpl +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name +tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 17233/uwsgi + +``` +通过上面的配置,已经成功使用supervisor管理了sandboxmp-uwsgi进程。 + +## 3.2 使用Nginx做代理访问 + +**1、安装nginx** + + +``` +(sandboxMP) [root@sandboxmp ~]$ yum -y install nginx +``` + +**2、修改nginx配置文件** + + +``` +(sandboxMP) [root@sandboxmp ~]$ echo "" > /etc/nginx/nginx.conf +(sandboxMP) [root@sandboxmp ~]$ vim /etc/nginx/nginx.conf +worker_processes 1; +events { + worker_connections 1024; +} +http { + + include mime.types; + default_type application/octet-stream; + server_tokens off; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + log_format nginxlog '$http_host ' + '$remote_addr [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time ' + '$upstream_response_time'; + access_log /var/log/nginx/access.log nginxlog; + keepalive_timeout 60; + client_header_timeout 10; + client_body_timeout 15; + client_max_body_size 100M; + client_body_buffer_size 1024k; + gzip on; + gzip_min_length 1; + gzip_buffers 4 16k; + gzip_http_version 1.1; + gzip_comp_level 3; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png app lication/vnd.ms-fontobject application/x-font-ttf image/svg+xml; + gzip_vary on; + + + + upstream sandboxmp { + server 127.0.0.1:9000; + } + + server { + + listen 80; + server_name 0.0.0.0; + charset utf-8; + client_max_body_size 75M; + + + + location /static { + + alias /opt/app/sandboxMP/static; + + } + + location /media { + + alias /opt/app/sandboxMP/media; + } + + location / { + uwsgi_pass sandboxmp; + include /etc/nginx/uwsgi_params; + } + } +} +``` +nginx配置说明:
+在nginx中配置了日志格式,应用代理和静态文件的代理访问。 + +**3、启动nginx服务,设置开机启动** + +``` +(sandboxMP) [root@sandboxmp ~]# systemctl start nginx +(sandboxMP) [root@sandboxmp ~]# systemctl enable nginx +Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service. +``` + +## 3.3 项目优化设置 + +项目在开发的时候是启用了Debug模式的,现在部署上线了,可以关闭Debug。 + +``` +# 1.修改项目配置文件,将DEBUG内容改成False +(sandboxMP) [root@sandboxmp ~]$ vim /opt/app/sandboxMP/sandboxMP/settings.py +'''配置文件中内容省略,主要修改下面两个内容''' +DEBUG = False + +ALLOWED_HOSTS = ['*'] + +# 2.保存修改后,重启项目 +(sandboxMP) [root@sandboxmp ~]$ supervisorctl restart sandboxmp-uwsgi +sandboxmp-uwsgi: stopped +sandboxmp-uwsgi: started +(sandboxMP) [root@sandboxmp ~]$ systemctl restart nginx +(sandboxMP) [root@sandboxmp ~]$ +``` + +> 到这里项目已经部署上线了,可以访问系统地址:http://172.16.3.200 用户名:admin 密码:!qaz@wsx 使用项目功能。本文档中配置文件已经包含在项目master版本文件中:sandboxMP/config。 + + +
+
+ +> 更多实战类文档,请关注我的知识星球: https://t.zsxq.com/a6IqBMr (微信中打开链接)
+轻量级办公管理系统项目开源地址:https://github.com/RobbieHan/gistandard
\ No newline at end of file diff --git a/config/basic_data_20190225.sql b/config/basic_data_20190225.sql new file mode 100644 index 0000000..885be3e --- /dev/null +++ b/config/basic_data_20190225.sql @@ -0,0 +1,219 @@ +-- MySQL dump 10.13 Distrib 5.6.43, for Linux (x86_64) +-- +-- Host: localhost Database: sandboxMP +-- ------------------------------------------------------ +-- Server version 5.6.43 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `system_menu` +-- + +DROP TABLE IF EXISTS `system_menu`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `system_menu` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(30) COLLATE utf8_unicode_ci NOT NULL, + `icon` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `url` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL, + `parent_id` int(11) DEFAULT NULL, + `number` double DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + UNIQUE KEY `url` (`url`), + KEY `system_menu_parent_id_c715739f_fk_system_menu_id` (`parent_id`), + CONSTRAINT `system_menu_parent_id_c715739f_fk_system_menu_id` FOREIGN KEY (`parent_id`) REFERENCES `system_menu` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_menu` +-- + +LOCK TABLES `system_menu` WRITE; +/*!40000 ALTER TABLE `system_menu` DISABLE KEYS */; +INSERT INTO `system_menu` VALUES (1,'系统',NULL,'SYSTEM','/system/',NULL,1),(2,'基础设置','fa fa-gg','SYSTEM-BASIC',NULL,1,1.1),(3,'组织架构',NULL,'SYSTEM-BASIC-STRUCTURE','/system/basic/structure/',2,1.11),(4,'组织架构:列表',NULL,'SYSTEM-BASIC-STRUCTURE-LIST','/system/basic/structure/list/',3,1.111),(5,'组织架构:创建',NULL,'SYSTEM-BASIC-STRUCTURE-CREATE','/system/basic/structure/create/',3,1.112),(6,'组织架构:删除',NULL,'SYSTEM-BASIC-STRUCTURE-DELETE','/system/basic/structure/delete/',3,1.113),(7,'组织架构:关联用户',NULL,'SYSTEM-BASIC-STRUCTURE-ADD_USER','/system/basic/structure/add_user/',3,1.114),(8,'用户管理',NULL,'SYSTEM-BASIC-USER','/system/basic/user/',2,1.12),(9,'用户管理:列表',NULL,'SYSTEM-BASIC-USER-LIST','/system/basic/user/list/',8,1.121),(10,'用户管理:详情',NULL,'SYSTEM-BASIC-USER-DETAIL','/system/basic/user/detail/',8,1.122),(11,'用户管理:修改',NULL,'SYSTEM-BASIC-USER-UPDATE','/system/basic/user/update/',8,1.123),(12,'用户管理:创建',NULL,'SYSTEM-BASIC-USER-CREATE','/system/basic/user/create/',8,1.123),(13,'用户管理:删除',NULL,'SYSTEM-BASIC-USER-DELETE','/system/basic/user/delete/',8,1.124),(14,'用户管理:启用',NULL,'SYSTEM-BASIC-USER-ENABLE','/system/basic/user/enable/',8,1.125),(15,'用户管理:禁用',NULL,'SYSTEM-BASIC-USER-DISABLE','/system/basic/user/disable/',8,1.126),(16,'用户管理:修改密码',NULL,'SYSTEM-BASIC-USER-PASSWORD_CHANGE','/system/basic/user/password_change/',8,1.127),(17,'权限管理','fa fa-user-plus','SYSTEM-RBAC',NULL,1,1.2),(18,'菜单管理',NULL,'SYSTEM-RBAC-MENU','/system/rbac/menu/',17,1.21),(19,'菜单管理:创建',NULL,'SYSTEM-RBAC-MENU-CREATE','/system/rbac/menu/create/',18,1.211),(20,'菜单管理:修改',NULL,'SYSTEM-RBAC-MENU-UPDATE','/system/rbac/menu/update/',18,1.213),(21,'角色管理',NULL,'SYSTEM-RBAC-ROLE','/system/rbac/role/',17,1.22),(22,'角色管理:列表',NULL,'SYSTEM-RBAC-ROLE-LIST','/system/rbac/role/list/',21,1.221),(23,'角色管理:创建',NULL,'SYSTEM-RBAC-ROLE-CREATE','/system/rbac/role/create/',21,1.222),(24,'角色管理:修改',NULL,'SYSTEM-RBAC-ROLE-UPDATE','/system/rbac/role/update/',21,1.223),(25,'角色管理:删除',NULL,'SYSTEM-RBAC-ROLE-DELETE','/system/rbac/role/delete/',21,1.224),(26,'角色管理:关联菜单',NULL,'SYSTEM-RBAC-ROLE-ROLE2MENU','/system/rbac/role/role2menu/',21,1.225),(27,'角色管理:菜单列表',NULL,'SYSTEM-RBAC-ROLE-ROLE2MENU_LIST','/system/rbac/role/role2menu_list/',21,1.226),(28,'角色管理:关联用户',NULL,'SYSTEM-RBAC-ROLE-ROLE2USER','/system/rbac/role/role2user/',21,1.227),(29,'配置管理',NULL,'CMDB','/cmdb/',NULL,2),(30,'平台设置','fa fa-yelp','CMDB-PORTAL',NULL,29,2.1),(31,'字典管理',NULL,'CDMB-PORTAL-CODE','/cmdb/portal/code/',30,2.11),(32,'字典管理:创建',NULL,'CMDB-PORTAL-CODE-CREATE','/cmdb/portal/code/create/',31,2.111),(33,'字典管理:列表',NULL,'CMDB-PORTAL-CODE-LIST','/cmdb/portal/code/list/',31,2.112),(34,'字典管理:修改',NULL,'CMDB-PORTAL-CODE-UPDATE','/cmdb/portal/code/update/',31,2.113),(35,'字典管理:删除',NULL,'CMDB-PORTAL-CODE-DELETE','/cmdb/portal/code/delete/',31,2.114),(36,'扫描配置',NULL,'CMDB-PORTAL-SCAN_CONFIG','/cmdb/portal/scan_config/',30,2.12),(37,'设备扫描',NULL,'CDMB-PORTAL-DEVICE_SCAN','/cmdb/portal/device_scan/',30,2.13),(38,'设备扫描:执行',NULL,'CMDB-PORTAL-DEVICE_SCAN-EXEC','/cmdb/portal/device_scan/exec/',37,2.131),(39,'设备扫描:列表',NULL,'CMDB-PORTAL-DEVICE_SCAN-LIST','/cmdb/portal/device_scan/list/',37,2.132),(40,'设备扫描:详情',NULL,'CMDB-PORTAL/DEVICE_SCAN/DETAIL','/cmdb/portal/device_scan/detail/',37,2.133),(41,'设备扫描:删除',NULL,'CMDB-PORTAL-DEVICE-_SCAN-DELETE','/cmdb/portal/device_scan/delete/',37,2.134),(42,'资产管理','fa fa-desktop','CMDB-EAM',NULL,29,2.2),(43,'机柜管理',NULL,'CMDB-EAM-CABINET','/cmdb/eam/cabinet/',42,2.21),(44,'机柜管理:新增',NULL,'CMDB-EAM-CABINET-CREATE','/cmdb/eam/cabinet/create/',43,2.211),(45,'机柜管理:修改',NULL,'CMDB-EAM-CABINET-UPDATE','/cmdb/eam/cabinet/update/',43,2.212),(46,'机柜管理:列表',NULL,'CMDB-EAM-CABINET-LIST','/cmdb/eam/cabinet/list/',43,2.213),(47,'机柜管理:删除',NULL,'CMDB-EAM-CABINET-DELETE','/cmdb/eam/cabinet/delete/',43,2.214),(48,'设备管理',NULL,'CMDB-EAM-DEVICE','/cmdb/eam/device/',42,2.22),(49,'设备管理:列表',NULL,'CMDB-EAM-DEVICE-LIST','/cmdb/eam/device/list/',48,2.221),(50,'设备管理:新增',NULL,'CMDB-EAM-DEVICE-CREATE','/cmdb/eam/device/create/',48,2.222),(51,'设备管理:修改',NULL,'CMDB-EAM-DEVICE-UPDATE','/cmdb/eam/device/update/',48,2.223),(52,'设备扫描:入库',NULL,'CMDB-PORTAL-DEVICE_SCAN-INBOUND','/cmdb/portal/device_scan/inbound/',37,2.135),(53,'设备管理:认证管理',NULL,'CMDB-EAM-DEVICE-DEVICE2CONNECTION','/cmdb/eam/device/device2connection/',48,2.224),(54,'设备管理:删除',NULL,'CMDB-EAM-DEVICE-DELETE','/cmdb/eam/device/delete/',37,2.225),(55,'设备管理:详情',NULL,'CMDB-EAM-DEVICE-DETAIL','/cmdb/eam/device/detail/',48,2.226),(56,'设备管理:上传',NULL,'CMDB-EAM-DEVICE-UPLOAD','/cmdb/eam/device/upload/',48,2.227),(57,'设备管理:删除文件',NULL,'CMDB-EAM-DEVICE-FILE_DELETE','/cmdb/eam/device/file_delete/',48,2.228),(58,'设备管理:自动更新',NULL,'CMDB-EAM-DEVICE-AUTO_UPDATE_DEVICE_INFO','/cmdb/eam/device/auto_update_device_info/',48,2.229); +/*!40000 ALTER TABLE `system_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `system_role` +-- + +DROP TABLE IF EXISTS `system_role`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `system_role` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `desc` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_role` +-- + +LOCK TABLES `system_role` WRITE; +/*!40000 ALTER TABLE `system_role` DISABLE KEYS */; +INSERT INTO `system_role` VALUES (1,'管理员组','系统默认角色组,具有系统管理的全部权限'); +/*!40000 ALTER TABLE `system_role` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `system_userprofile` +-- + +DROP TABLE IF EXISTS `system_userprofile`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `system_userprofile` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `password` varchar(128) COLLATE utf8_unicode_ci NOT NULL, + `last_login` datetime(6) DEFAULT NULL, + `is_superuser` tinyint(1) NOT NULL, + `username` varchar(150) COLLATE utf8_unicode_ci NOT NULL, + `first_name` varchar(30) COLLATE utf8_unicode_ci NOT NULL, + `last_name` varchar(150) COLLATE utf8_unicode_ci NOT NULL, + `is_staff` tinyint(1) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `date_joined` datetime(6) NOT NULL, + `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL, + `birthday` date DEFAULT NULL, + `gender` varchar(10) COLLATE utf8_unicode_ci NOT NULL, + `mobile` varchar(11) COLLATE utf8_unicode_ci NOT NULL, + `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL, + `image` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, + `post` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `department_id` int(11) DEFAULT NULL, + `superior_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `username` (`username`), + KEY `system_userprofile_department_id_a46d57f9_fk_system_structure_id` (`department_id`), + KEY `system_userprofile_superior_id_6b0fd92f_fk_system_userprofile_id` (`superior_id`), + CONSTRAINT `system_userprofile_department_id_a46d57f9_fk_system_structure_id` FOREIGN KEY (`department_id`) REFERENCES `system_structure` (`id`), + CONSTRAINT `system_userprofile_superior_id_6b0fd92f_fk_system_userprofile_id` FOREIGN KEY (`superior_id`) REFERENCES `system_userprofile` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_userprofile` +-- + +LOCK TABLES `system_userprofile` WRITE; +/*!40000 ALTER TABLE `system_userprofile` DISABLE KEYS */; +INSERT INTO `system_userprofile` VALUES (1,'pbkdf2_sha256$120000$qFLcOe8f3gr9$UrT1tFbDnFUaoqV5jZ9F5Xx9duYy33ZVZPauTb20xTU=','2019-02-17 21:18:45.791223',1,'admin','','',1,1,'2019-01-31 00:12:32.113271','管理员',NULL,'male','13951994649','robbie_han@outlook.com','image/default.jpg',NULL,NULL,NULL); +/*!40000 ALTER TABLE `system_userprofile` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `system_userprofile_roles` +-- + +DROP TABLE IF EXISTS `system_userprofile_roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `system_userprofile_roles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `userprofile_id` int(11) NOT NULL, + `role_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `system_userprofile_roles_userprofile_id_role_id_459e3bc3_uniq` (`userprofile_id`,`role_id`), + KEY `system_userprofile_roles_role_id_cc2781b0_fk_system_role_id` (`role_id`), + CONSTRAINT `system_userprofile_r_userprofile_id_0247f4f3_fk_system_us` FOREIGN KEY (`userprofile_id`) REFERENCES `system_userprofile` (`id`), + CONSTRAINT `system_userprofile_roles_role_id_cc2781b0_fk_system_role_id` FOREIGN KEY (`role_id`) REFERENCES `system_role` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_userprofile_roles` +-- + +LOCK TABLES `system_userprofile_roles` WRITE; +/*!40000 ALTER TABLE `system_userprofile_roles` DISABLE KEYS */; +INSERT INTO `system_userprofile_roles` VALUES (1,1,1); +/*!40000 ALTER TABLE `system_userprofile_roles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `system_role_permissions` +-- + +DROP TABLE IF EXISTS `system_role_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `system_role_permissions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL, + `menu_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `system_role_permissions_role_id_menu_id_91fb438a_uniq` (`role_id`,`menu_id`), + KEY `system_role_permissions_menu_id_f48d14c7_fk_system_menu_id` (`menu_id`), + CONSTRAINT `system_role_permissions_menu_id_f48d14c7_fk_system_menu_id` FOREIGN KEY (`menu_id`) REFERENCES `system_menu` (`id`), + CONSTRAINT `system_role_permissions_role_id_a52abc64_fk_system_role_id` FOREIGN KEY (`role_id`) REFERENCES `system_role` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_role_permissions` +-- + +LOCK TABLES `system_role_permissions` WRITE; +/*!40000 ALTER TABLE `system_role_permissions` DISABLE KEYS */; +INSERT INTO `system_role_permissions` VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4),(5,1,5),(6,1,6),(7,1,7),(8,1,8),(9,1,9),(10,1,10),(11,1,11),(12,1,12),(13,1,13),(14,1,14),(15,1,15),(16,1,16),(17,1,17),(18,1,18),(19,1,19),(20,1,20),(21,1,21),(22,1,22),(23,1,23),(24,1,24),(25,1,25),(26,1,26),(27,1,27),(28,1,28),(29,1,29),(30,1,30),(31,1,31),(32,1,32),(33,1,33),(34,1,34),(35,1,35),(36,1,36),(37,1,37),(38,1,38),(39,1,39),(40,1,40),(41,1,41),(44,1,42),(45,1,43),(46,1,44),(47,1,45),(48,1,46),(49,1,47),(50,1,48),(51,1,49),(52,1,50),(53,1,51),(42,1,52),(54,1,53),(43,1,54),(55,1,55),(56,1,56),(57,1,57),(58,1,58); +/*!40000 ALTER TABLE `system_role_permissions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `cmdb_code` +-- + +DROP TABLE IF EXISTS `cmdb_code`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cmdb_code` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `key` varchar(80) COLLATE utf8_unicode_ci NOT NULL, + `value` varchar(80) COLLATE utf8_unicode_ci NOT NULL, + `desc` varchar(100) COLLATE utf8_unicode_ci NOT NULL, + `parent_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `cmdb_code_parent_id_21a5a774_fk_cmdb_code_id` (`parent_id`), + CONSTRAINT `cmdb_code_parent_id_21a5a774_fk_cmdb_code_id` FOREIGN KEY (`parent_id`) REFERENCES `cmdb_code` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cmdb_code` +-- + +LOCK TABLES `cmdb_code` WRITE; +/*!40000 ALTER TABLE `cmdb_code` DISABLE KEYS */; +INSERT INTO `cmdb_code` VALUES (1,'NETWORK_TYPE','网络类型','网络类型',NULL),(2,'SERVICE_TYPE','服务类型','0',NULL),(3,'OPERATION_TYPE','业务类型','0',NULL),(4,'NETWORK_TYPE_PRD','生产网','0',1),(5,'NETWORK_TYPE_PRE','预发布网','0',1),(6,'NETWORK_TYPE_TEST','测试网','0',1),(7,'NETWORK_TYPE_DEV','办公网','0',1),(8,'NETWORK_TYPE_MANAGE','管理网','0',1),(9,'SERVICE_TYPE_PROXY','代理服务','0',2),(10,'SERVICE_TYPE_APPSERVICE','TOMCAT服务','0',2),(11,'SERVICE_TYPE_MYSQL','MYSQL服务','0',2),(12,'SERVICE_TYPE_MONGODB','MONGODB服务','0',2),(13,'SERVICE_TYPE_REDIS','REDIS服务','0',2),(14,'SERVICE_TYPE_FILE','文件服务','0',2),(15,'SERVICE_TYPE_MQ','MQ服务','0',2),(16,'SERVICE_TYPE_MEMCACHED','MEMCACHED服务','0',2),(17,'SYSTEM_TYPE_MAIL','邮件系统','0',3),(18,'SYSTEM_TYPE_IM','即时通信讯','0',3); +/*!40000 ALTER TABLE `cmdb_code` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-02-25 19:37:59 diff --git a/config/celery_worker.ini b/config/celery_worker.ini new file mode 100644 index 0000000..b9ef339 --- /dev/null +++ b/config/celery_worker.ini @@ -0,0 +1,19 @@ +[program:celery-worker] +command=/root/.virtualenvs/sandboxMP/bin/celery worker -A sandboxMP -l INFO +directory=/opt/app/sandboxMP +environment=PATH="/root/.virtualenvs/sandboxMP/bin/" +stdout_logfile=/opt/app/sandboxMP/slogs/celery_worker.log +stderr_logfile=/opt/app/sandboxMP/slogs/celery_worker.log +autostart=true +autorestart=true +priority=901 + +[program:celery-flower] +command=/root/.virtualenvs/sandboxMP/bin/celery flower --broker=redis://localhost:6379/0 +directory=/opt/app/sandboxMP +environment=PATH="/root/.virtualenvs/sandboxMP/bin/" +stdout_logfile=/opt/app/sandboxMP/slogs/celery_flower.log +stderr_logfile=/opt/app/sandboxMP/slogs/celery_flower.log +autostart=true +autorestart=true +priority=900 \ No newline at end of file diff --git a/config/nginx.conf b/config/nginx.conf new file mode 100644 index 0000000..6ef5de4 --- /dev/null +++ b/config/nginx.conf @@ -0,0 +1,64 @@ +worker_processes 1; +events { + worker_connections 1024; +} +http { + + include mime.types; + default_type application/octet-stream; + server_tokens off; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + log_format nginxlog '$http_host ' + '$remote_addr [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time ' + '$upstream_response_time'; + access_log /var/log/nginx/access.log nginxlog; + keepalive_timeout 60; + client_header_timeout 10; + client_body_timeout 15; + client_max_body_size 100M; + client_body_buffer_size 1024k; + gzip on; + gzip_min_length 1; + gzip_buffers 4 16k; + gzip_http_version 1.1; + gzip_comp_level 3; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png app lication/vnd.ms-fontobject application/x-font-ttf image/svg+xml; + gzip_vary on; + + + + upstream sandboxmp { + server 127.0.0.1:9000; + } + + server { + + listen 80; + server_name 0.0.0.0; + charset utf-8; + client_max_body_size 75M; + + + + location /static { + + alias /opt/app/sandboxMP/static; + + } + + location /media { + + alias /opt/app/sandboxMP/media; + } + + location / { + uwsgi_pass sandboxmp; + include /etc/nginx/uwsgi_params; + } + } +} \ No newline at end of file diff --git a/config/sandboxmp_uwsgi.ini b/config/sandboxmp_uwsgi.ini new file mode 100644 index 0000000..07336e6 --- /dev/null +++ b/config/sandboxmp_uwsgi.ini @@ -0,0 +1,8 @@ +[program:sandboxmp-uwsgi] +command=/root/.virtualenvs/sandboxMP/bin/uwsgi /etc/smp_uwsgi.ini +stdout_logfile=/var/log/uwsgi/smp_uwsgi.log +stderr_logfile=/var/log/uwsgi/smp_uwsgi.log +stdout_logfile_maxbytes = 20MB +autostart=true +autorestart=true +priority=905 \ No newline at end of file diff --git a/config/smp_uwsgi.ini b/config/smp_uwsgi.ini new file mode 100644 index 0000000..96af637 --- /dev/null +++ b/config/smp_uwsgi.ini @@ -0,0 +1,12 @@ +[uwsgi] +#http = 172.16.3.200:9000 +socket = 127.0.0.1:9000 +chdir = /opt/app/sandboxMP +module = sandboxMP.wsgi +#static-map=/static=/opt/app/sandboxMP/static +#daemonize =/var/log/uwsgi.log +master = Ture +vacuum = True +processes = 4 +threads = 2 +buffer-size=32768 \ No newline at end of file diff --git a/document/images/stepww.png b/document/images/stepww.png new file mode 100644 index 0000000000000000000000000000000000000000..368ea299a729b66da684edbcea9ebb6c734f8da5 GIT binary patch literal 25761 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 literal 0 HcmV?d00001 diff --git a/slogs/sandbox_err.log b/slogs/sandbox_err.log new file mode 100644 index 0000000..e69de29 diff --git a/slogs/sandbox_info.log b/slogs/sandbox_info.log new file mode 100644 index 0000000..e69de29