背景
因为公司业务主要与工业相关,工业使用的多数为Windows电脑,此时就需要将公司的系统部署在Windows平台上,这里使用Django来作为后端。
在后端部署mysql,我们只需要准备好表结构sql文件,到时候直接执行sql文件即可。
python 虚拟环境的管理有很多种,之前使用的 virtualenvwrapper-win
这个工具,这个工具有一个好处就是可以实现全局的虚拟环境管理,但是会有一个问题,它无法做到项目中的实际依赖,什么叫实际依赖呢?就是说一个安装包它依赖一些第三方包,当我们不想使用该包的时候,会进行uninstall操作,此时python只会卸载当前这个包,并会删除它的依赖包。我们的想法是删除这个包的同时,它的依赖包也要删除。
我这边使用poetry来作为python的包管理工具,poetry使用教程
导出项目依赖包
# 导出项目依赖包信息
pip freeze > r.txt
# 将虚拟环境中的包导出为离线包, 会在当前目录下创建文件夹(packages)
pip download -r r.txt -d packages
整体文件打包
python解释器安装过程这里就不展示了
有网络环境
如果当前环境有网络,可以使用 poetry
来安装依赖
# 进入到后端项目根目录
poetry install
- poetry 默认创建的文件夹目录是在c盘中,C:\Users{UserName}\AppData\Local\pypoetry\Cache\virtualenvs\
- poetry config virtualenvs.in-project true 可以将虚拟环境文件夹创建在当前目录下
无网络环境
若客户环境没有网络,我们可以使用离线安装的方式
pip install --no-index --find-links=/packages/ -r GOMusicApi\r.txt
启动Django项目
在启动项目前,需要我们配置好数据库信息,包含用户名、密码和端口等。
# 监听本地8000端口,若接收其他地址使用 python manage.py runserver 0.0.0.0:8000
python manage.py runserver
红色文字时提示我们的数据库表没有迁移,不用管他。我这边是仅测试,实际项目是不用django的migrate来迁移数据库表的。而且在数据库层面一般是不做外键关系,外键关系在控制层(视图层)进行约束。
在上述部署后端的过程中存在一个很严重的问题,若客户电脑断电了,是不是我们的程序就会自动停止,或者说我们的cmd窗口不小心被客户给关闭了,此时后端服务也停止了。
pyinstaller安装
建议在虚拟环境下打包程序,这样可以有效避免被其他包所影响。
poetry add pyinstaller
生成pyinstaller 打包配置文件
pyinstaller -F manage.py
# 执行上面命令,将看到详细的生成过程。当生成完成后,将会在此 app 目录下看到多了一个 dist 目录,并在该目录下看到有一个 app.exe 文件,这就是使用 PyInstaller 工具生成的 EXE 程序。
参考地址: http://c.biancheng.net/view/2690.html
在执行命令之后,会在当前目录下生成一个manage.spec
文件,这个文件告诉我们这个项目的打包配置信息。下面我介绍一个django打包exe需要注意的点及配置
# manage.spec
block_cipher = None
a = Analysis(
['manage.py'],
pathex=[],
binaries=[],
# datas 表示所依赖的资源文件,如static目录下的文件, 以及templates文件夹(有需要)
datas=[(r'D:\PycharmProjects\o12307\templates', r'.\templates')],
# 因为在打包过程中,程序依赖django本身的一些模块,所以我们需要在打包时主要将这些模块加入,主要为配置文件中,INSTALL_APP 及 MIDDLE 这两个对象中的配置
hiddenimports=[
'api.apps',
'api.middleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
......
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='manage',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
# 设置打包程序的ico信息
icon='../logo.ico',
)
启动程序
manage.exe runserver --noreload
在打包过程中会出现一些问题,主要包含以下几点:
- 资源文件丢失
- exe执行后报错: NoModule ,即上述中hiddenimports 配置没有写全,缺啥补啥
- 执行报错,使用 --noreload 模式
- 注意:在使用pyinstaller 一定要知道使用的虚拟环境中的还是本机中的pyinstaller
如何把打包的程序进行配置抽离
配置抽离,就是django在进行打包过程中,数据库的配置信息,以及一些settings中需要做出调整的配置项,如果我们写死在了settings中,在部署到生成环境中就无法对配置进行修改
我们可以创建一个用于打包setting配置文件,例如叫win_exe_prod.py
,具体如下:
# default_settings 是默认的django配置文件,即不需要需改的配置项
from .default_settings import *
import sys
import os
import json
if getattr(sys, 'frozen', False):
APPLICATION_PATH = os.path.dirname(sys.executable)
elif __file__:
APPLICATION_PATH = os.path.dirname(__file__)
# 加载当前目录下的config.json 文件
jsonConfig = json.load(open(os.path.join(APPLICATION_PATH, 'config.json')))
DATABASES = jsonConfig['DATABASES']
REDIS_CONFIG = jsonConfig['REDIS_CONFIG']
Pyinstaller
可以将资源文件一起打包到exe
中,当exe
在运行时,会生成一个临时文件夹,程序可通过sys._MEIPASS
访问临时文件夹中的资源。
if getattr(sys, 'frozen', False)
作用:
Pyinstaller
程序打包成exe的时,会将一个变量frozen注入到sys中,这里使用判断,检测sys是否有frozen这个变量,如果有,就使用sys._MEIPASS访问临时文件夹路径,如果没有,就使用当前路径,当程序不管是以PyInstaller打包后形式运行,还是本地测试,都能找到正确的资源路径。
config.json 配置
{
# 本质就是把django settings中的DATABASES 抽离出来了
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': "dev",
'USER': "postgres",
'PORT': 5432,
'PASSWORD': "Dieteng109",
'HOST': "192.168.1.109",
}
},
REDIS_CONFIG = {
"HOST": '192.168.1.103',
"PORT": 6379,
"PASSWORD": None,
"DBID": 9
}
}
此时,我们修改django运行时加载的配置文件
# Windows 平台, 设置了django 启动时读取的配置文件
set DJANGO_SETTINGS_MODULE=website.settings.win_exe_prod.py
# 执行打包程序,注意config.json、manage.spec、manage.py 处于同级目录下
poetry run pyinstaller manage.spec
winsw.exe
程序winsw
配置文件winsw
如何下载程序大家可以实行百度,我简单述说一下如何使用。
winsw install 安装服务
winsw uninstall 卸载服务
winsw start 开启服务
winsw stop 停止服务
winsw restart 重新启动服务
winsw status 检查服务的当前状态
详细使用步骤后续有时间再补充
下面我给出两个配置文件,添加说明以供大家参考
nginx.xml
这是一个nginx配置windows服务的配置信息,在第三章使用winsw将nginx作为Windows后台服务
# nginx.xml 文件
# 服务id
Nginx
# 服务执行命令
D:\nginx\nginx.exe
# 描述
Nginx by WinSW
# 参数
-c conf/nginx.conf
# 工作目录
D:\nginx
Normal
# 15秒超时
15 sec
# 停止winsw服务时,追加的后续命令,即停止nginx服务
D:\nginx\nginx.exe
-s stop
# 表示会自动重启服务
Automatic
使用该配置文件
> winsw.exe install -c nginx.xml
再补充一个python文件添加为后台服务
# python01.xml
ServerID
ServerName
Server Desc
# 使用python环境
# 自动重启
Automatic
# 执行python
python
# 指定python 执行的py文件,不写工作目录(workingdirectory)表示当前目录下
test.py
60
8
2.3 小节和 2.4 小节写的比较糙,很多详细细节没有写。但是基本思路是这样的。
修改前端请求地址
首先,我们需要配置请求的后端接口地址,如果后端和前端在一台电脑上,则不需要指定请求的url域名地址,直接写后端的api后缀即可,若是不在一台电脑上,则需指定后端的api的全路径,我这是请求的本地后端接口8000。
前端项目打包
yum run build
命令执行后会在本地生产一个dist文件,将dist文件夹拷贝到生产环境中
此时前端的运行我们可以使用nginx
来作为转发前端访问(当然也可以使用IIS,即window自带的web服务程序),将nginx包拷贝到生产环境中。
nginx部署
配置conf 文件
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /api {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 追加请求
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 请求转发
proxy_pass http://localhost:8000/api/;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
检测配置文件是否有误
先启动nginx.exe 程序,然后检测配置文件是否有误
C:\GOMusic\nginx-1.15.2>nginx.exe -t
nginx: the configuration file C:\GOMusic\nginx-1.15.2/conf/nginx.conf syntax is ok
nginx: configuration file C:\GOMusic\nginx-1.15.2/conf/nginx.conf test is successful
如果后续修改了配置文件,使用 nginx.exe -s reload
重载配置文件
加载nginx web目录内容访
我们将拷贝的dist文件夹内容,移动到nginx目录下的html中
在配置和启动成功后,在浏览器中访问本地的80端口(http://127.0.0.1),即可查看访问系统。
上述便是在windows平台下部署项目的一些方式。大家要是有其他方式欢迎在评论区留言,写的时间比较赶,有任何疑问或意见欢迎大家指出。