文中涉及的示例代码,已同步更新到HelloGitHub-Team仓库
在上一篇教程中,我们通过手工方式将代码部署到了服务器。整个过程涉及到十几条命令,输了N个字符。一旦我们本地的代码有更新,整个过程又得重复来一遍,这将变得非常繁琐。
使用织物可以在服务器中自动执行命令。因为整个代码部署过程都是相同的,只要我们用织物写好部署脚本,以后就可以通过运行脚本自动完成部署了。
首先在本地安装面料:
美元pipenv安装织物- dev
因为织物只需在本地使用,因此使用- dev选项,让Pipenv将织物依赖写到dev-packages配置下,线上环境就不会安装面料。
在写布脚本之前,先来回顾一下当我们在本地开发环境下更新了代码后,在服务器上的整个部署过程。
-
<李>远程连接服务器。李>
<李>进入项目根目录,从远程仓库拉取最新的代码。李>
<李>如果项目引入了新的依赖,需要执行pipenv安装部署——ignore-pipfile安装最新依赖。李>
<李>如果修改或新增了项目静态文件,需要执行pipenv python运行管理。py collectstatic收集静态文件。李>
<李>如果数据库发生了变化,需要执行pipenv python运行管理。py迁移迁移数据库。李>
<李>重启Nginx和Gunicorn使改动生效。李>
整个过程就是这样,把每一步操作翻译成织物对应的脚本代码,这样一个自动化部署脚本就完成了。
<强>
强>
<>强分离设置文件强>
为了安全,线上环境我们将调试改为了假,但开发环境要改为真实的,改来改去将很麻烦。此外,django的SECRET_KEY是很私密的配置,django的很多安全机制都依赖它,如果不慎泄露,网站将面临巨大安全风险,像我们现在这样直接写在配置文件中,万一不小心公开了源代码,SECRET_KEY就会直接泄露,好的实践是将这个值写入环境变量,通过从环境变量取这个值。
解决以上问题的一个方案就是拆分设置。py文件,不同环境对应不同的设置文件,django在启动时会从环境变量中读取DJANGO_SETTINGS_MODULE的值,以这个值指定的文件作为应用的最终配置。
我们来把设置。py拆分,首先在blogproject目录下新建一个Python包,名为设置,然后创建一个common.py,用于存放通用配置,当地。py存放开发环境的配置,生产。py存放线上环境的配置:
blogproject \ 设置\ __init__ . py local.py production.py settings.py
将设置。py文件中的内容全部复制到常见。py里,并将SECRET_KEY、调试ALLOWED_HOSTS这些配置移到本地。py和生产。py中(常见。py中这些项可以删除)。
开发环境的配置当地。py内容如下:
从.common进口* SECRET_KEY=' development-secret-key ' DEBUG=True ALLOWED_HOSTS=(“*”) >之前线上环境的配置:
从.common进口* SECRET_KEY=os.environ (“DJANGO_SECRET_KEY”) DEBUG=False ALLOWED_HOSTS=(“hellodjango-blog-tutorial.zmrenwu.com”) >之前注意这里我们在顶部使用从.common进口*将全部配置从常见。py导入,然后根据环境的不同,在下面进行配置覆盖。
线上环境和开发环境不同的是,为了安全,调试模式被关闭,SECRET_KEY从环境变量获取,ALLOWED_HOSTS设置了允许的HTTP主机(具体作用见后面的讲解)。
以上操作完成后,<代码>一定记得删除settings.py> 代码。
现在我们有了两套配置,一套是当地的。py,一套是生产。py,那么启动项目时,django怎么知道我们使用了哪套配置呢?答案是在运行管理。py脚本时,django默认帮我们指定了。在使用python管理。py执行命令时,django可以接收一个——settings-module的参数,用于指定执行命令时,项目使用的配置文件,如果参数未显示指定,django会从环境变量DJANGO_SETTINGS_MODULE里获取。看到管理。py的源码:
def main (): os.environ。setdefault (“DJANGO_SETTINGS_MODULE”、“blogproject.settings”) 试一试: 从django.core。管理导入execute_from_command_line 除了ImportError exc: 提高ImportError ( “不能导入Django。你确定这是安装和” “可用> BASE_DIR=os.path.dirname (os.path.dirname (os.path.abspath (__file__)))使用织物自动化部署Django项目的实现