文章目录
40、部署配置清单
这个部署配置清单是指,我们部署到服务器之后,还要对哪些配置进行修改
1、为什么部署之后要针对配置
-
开发环境:
- 一般是本地电脑
- 为开发服务,一般不会接触到外界
-
生产环境:
- 服务器
- 提供web服务,面临外界复杂未知的环境,可能存在各种危险(XSS攻击、DDos攻击、盗链、渗透、爬虫、暴力破解、安全漏洞等等)
-
1)在互联网的人并非全都是友好的
-
2)要有防范安全意识和相关措施
-
3)Django已经为我们做了不少安全处理
2、Django部署配置清单
- 1)关闭Debug
(1)多个settings.py文件
(2)allow_hosts
(3)使用环境变量设置敏感信息
(4)日志文件
(5)发生错误时,邮件通知管理员
(6)404、500错误页面 - 2)静态文件
(1)收集静态文件
(2)favicon.ico - 3)设置上传文件目录的权限
1)关闭Degug
(1)多个settings.py文件
(2)allow_hosts
settings.py文件中有一个Debug = True
,我们设置为True,指开启了调试,在本地开发的时候可以看到一些调试的信息。当发生错误时候,它还会把错误信息写到页面上,还有错误跟踪,甚至一些变量有一些敏感信息,我们在本地开发的时候在本地去用是没有问题的,但一旦放到服务器,把这些信息显示出来是很危险的。所以我们需要做一些针对性的设置。
但如果我们直接改成False,是有一些问题的,我们本地的时候需要设为True,在服务器的时候需要设为False,这样子来回改动比较麻烦,那么我们可以采取第二种方法,判断当前环境是开发环境还是生产环境,这里一般可以判断ip地址,如果是服务器ip地址的话,就设为False。不过这个办法也不是特别好,这样会把开发环境的settings配置和生产环境的settings配置混到一起,这样不方便我们进行一些多样化处理。
这里最好的方法是有两套settings.py文件:
在项目目录mysite下新建一个文件夹settings,把__init__.py文件复制进去,这个settings文件夹就是一个包了。然后把外面的settings.py剪切进来,复制一份,分别命名为development.py(本地的settings.py)、production.py(服务器的settings.py)。
这样的话,我们就可以通过mysite.settings.development和mysite.settings.production找到配置文件。演示如下:
我们在cmd中启动虚拟环境,输入python manage.py runserver --settings=mysite.settings.development
,回车,没有报错,但刷新页面还是显示有一个问题,模板文件找不到TemplateDoesNotExist
这主要是因为路径有问题,我们需要修改下development.py里面的基础目录BASE_DIR,这个变量意思是找到当前文件的所在位置,然后找到它所在的文件夹名称(上级目录), 再找到该文件夹所在的文件夹名称(即上上级目录,项目所在目录),现在需要我们加多一层上级目录。保存刷新页面,就可以了。(production.py同理)
不过这里每次运行服务python manage.py runserver --settings=mysite.settings.development
都要加一个–settings参数,有点麻烦,我们可以通过一个地方进行修改。可以看到这里是通过关联文件manage.py关联这个脚本去运行的,打开manage.py我们可以发现,这里面会设置一个环境变量,我们可以做如下修改,然后cmd中输入python manage.py runserver
运行,就可以了。
这里我们是修改本地开发环境对应的manage.py里面的配置文件路径,那我们服务器不是用这个文件,而是用的mysite/wsgi.py文件,同样的,我们需要把这里面的环境变量修改一下
这样的话,我们就把settings.py变成两套配置了,我们需要用哪套的时候再用哪套。
我们发现development.py和production.py这两个配置文件有一些共同的内容,写在两个地方的话可能会有些混乱,甚至这些内容是不需要去更改的,那么这里我们可以这样子处理:
在mysite/settings目录下新建一个公共的基础配置文件base.py,将development.py和production.py这两个配置文件的公共部分写到base.py中,而各自只保留各自的配置内容,然后加上一行引用base.py文件的代码from .base import *
。如下所示:
私有的内容:
—— | development.py | production.py |
---|---|---|
SECRET_KEY | – | – |
DEBUG | DEBUG = True | DEBUG = False |
ALLOWED_HOSTS | ALLOWED_HOSTS = [] | ALLOWED_HOSTS = ['*'] |
DATABASES | 本地可以用SQLite | 生产环境可以用MySQL |
EMAIL 设置部分 |
其他的都是基础配置base.py的内容
base.py:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ckeditor',
'ckeditor_uploader',
'blog',
'read_statistics',
'comment',
'likes',
'user',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'mysite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'), # 指向具体路径 mysite_env\mysite\templates
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'user.context_processors.login_modal_form',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'zh-hans' # 设置语言:原本是英文'en-us'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
# media配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 配置ckeditor
CKEDITOR_UPLOAD_PATH = 'upload/'
CKEDITOR_CONFIGS = {
'default': {},
'comment_ckeditor': {
'toolbar': 'custom', # 富文本编辑框的工具栏
'toolbar_custom': [
['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript'],
['TextColor', 'BGColor', 'RemoveFormat'],
['NumberedList', 'BulletedList'],
['Link', 'Unlink'],
['Smiley', 'SpecialChar', 'Blockquote'],
],
'width': 'auto', # 宽度
'height': '180', # 评论框高度
'tabSpaces': 4, # 按tab键会变成4个空格
'removePlugins': 'elementspath', # 去掉底部栏
'resize_enabled': False, # 去掉底部栏
}
}
# 自定义参数
EACH_PAGE_BLOGS_NUMBER = 7
# 缓存设置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 缓存的表名(也可以自己定义)
}
}
这就是前面提到的(1)多个settings.py文件(2)allow_hosts
(3)使用环境变量设置敏感信息
这两个设置完之后我们看(3)使用环境变量设置敏感信息。
敏感信息主要是密钥(SECRET_KEY)、数据库密码(DATABASES-PASSWORD)、授权码(EMAIL_HOST_PASSWORD)这三个。在开发环境中这样写是没有问题,如果是放到服务器环境,我们最好把这些配置文件这些敏感信息写到环境变量里面,然后我们通过读取环境变量的形式把这些信息获取到。环境变量的读取我们刚刚也在manage.py中提到过,同样也是用os.environ
,修改production.py中这一行:
当前前提是环境变量需要写入变量值就行:在windows的话,就是打开高级系统设置——系统变量——新建——变量名:SECRET_KEY,变量值复制进来。这个密钥跟密码没有关系,它是涉及到数据传输的时候,像cookie、session这些传输的时候,它会通过这个东西去加密解密,所以这个比较重要,在生产环境的时候要记得保密。
当然,我们在服务器的时候,跟本地的密钥最好不要用一样的,我们可以手动去生成,在cmd输入python manage.py shell
进入到shell模式,输入:
> from django.core.management import utils
> dir(utils)
> utils.get_random_secret_key()
可以看到,执行这句代码就能得到随机的密钥,我们可以复制这个密钥然后在服务器上设置这个Linux环境变量。
同样的,production.py这里还有数据库密码和授权码也可以这样子设置,修改如下:
然后我们进入到服务器去设置一下,打开git,登录。
Linux环境变量的设置有一种方法是直接用export
赋值,不过这个是临时的,我们关掉控制台就失效了。这里我们要处理一个文件,输入vim /etc/profile
,在这个文件最后位置输入如下代码,这里的密钥就是上面shell里面我们复制过来的,数据库密码这里尽量不要跟本地的一样,因为我们这个代码会放到github上面,很多人都能看得到,我们可以选择付费或者gitlab的形式让它变成私密的:
export SECRET_KEY="67=z0lr9kh+h....b(3=**m@dtxinhk^%4v*ps"
export DATABASE_PASSWORD="abc.....6"
export EMAIL_HOST_PASSWORD="dhvb.....ehccc"
保存退出,然后输入source /etc/profile
让它生效,我们可以输入echo $EMAIL_HOST_PASSWORD
打印出内容,查看有没有生效
同样的,本地的development.py里面的EMAIL_HOST_PASSWORD我们也要把它写入到环境变量里面,写到系统环境变量里的 好处就是,我们直接更改之后是直接生效的,不用重启服务器
(4)日志文件
(5)发生错误时,邮件通知管理员
接着我们来看下一个(4)日志文件
我们关闭Debug的时候,我们这些调试信息一旦犯错误,我们是看不到这些错误信息的,这不太利于我们去找到错误,那么这样的话, 我们最好是写一个日志文件,让它发生错误写到日志里面。
我们可以在production.py里面配置,因为我们本地开发环境是不需要日志文件的,修改production.py如下(django官网也有)
对应的,我们在/home下新建文件vim mysite_debug.log
,通过ls -al
可以查看得到它的权限,显示只有创建者才可写,我们输入chmod 666 mysite_debug.log
修改它的权限让其他人都是可写的(666表示自己可读可写、所属组的人可读可写、其他人可读可写)
production.py:
配置日志文件
# 日志文件
LOGGING = {
'version': 1, # 版本,自己命名
'disable_existing_loggers': False, # 是否禁用已经存在的记录器
'handlers': { # 处理器
'file': { # 把日志写到一个文件里面
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/home/mysite_debug.log', # 指定目录,
},
'mail_admins': { # 发送邮件给管理员
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': { #日志记录器
'django': {
'handlers': ['file'], # 启用‘file’这个处理器
'level': 'DEBUG', # 级别
'propagate': True, # 日志记录完之后,需不需要继续往上传递(DEBUG-->DEFAULT-->WARNING-->ERROR)
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
},
}
配置管理员
# 配置管理员(可以配置多个)
ADMINS = (
('admin', '1248...@qq.com'), # 元组:管理员名称、邮箱
)
另外,发送邮箱设置这里也要改一个地方,腾讯云25号端口比较容易开,而阿里云25号端口是很难开的,它建议使用465这个端口,使用465端口的话,对应的要修改EMAIL_USE_TLS
为EMAIL_USE_SSL
开启安全链接(同理,这个465端口我们也要加到阿里云服务器的安全组里去)
(6)404、500错误页面
这样,我们日志文件和邮箱(4)(5)也配置好了,另外我们还有个(6)404、500错误页面。
在templates下新建404.html(复制error.html)和500.html
404.html
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\404.html -->
{% extends 'base.html' %}
{% block title %}
我的网站 | 页面找不到
{% endblock %}
{% block content %}
404,找不到页面!迷路啦?
{% endblock %}
500.html
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\500.html -->
{% extends 'base.html' %}
{% block title %}
我的网站 | 发生错误
{% endblock %}
{% block content %}
500,发生错误!我已经发送邮件给管理员了
{% endblock %}
修改完毕后,我们打开mysite——git,输入git status
、git add .
,git commit -m "部署配置优化"
,git push
,提交代码到服务器上。
提交完成之后,我们再到服务器上登录,cd /home/mysite
进入到项目目录里,git status
查看状态,输入git pull
,pull成功之后,输入service nginx restart
重启服务器软件(这里我们暂时用nginx,如果是apache的话,输入apache2ctl restart
)。
重启之后,我们浏览器访问47.113.107.189,可以看到是访问成功的。
那现在如果我们随便访问一个不存在的页面,比如47.113.107.189/b,(通过这个方法我们可以看到Debug是否设为False生效了)
这里出现错误,原因是我们修改了django代码,改了django代码的话,是需要重新加载uwsgi的配置文件,uwsgi --reload /home/mysite_uwsgi/master.pid
。加载了之后我们刷新页面,就可以看到显示的是404找不到页面了(这个页面我们可以自己做的更好看一点)
至此,关闭Debug的相关内容已经做好了。
2)静态文件
接下来就是静态文件相关的内容了。
(1)收集静态文件
有一个是收集静态文件,当我们关闭了Debug的时候,它的静态文件就不再通过我们的django去获取了,我们需要通过web服务软件给它提供静态文件服务,这里分两个来讲,第一个是nginx的内容。
首先文件收集,我们需要配置一个东西。修改base.py如下:
这个文件夹我们需要忽略掉,所以我们需要在.gitignore文件里面多加一行static_collected/
然后我们在本地上把代码更新上传上去
接着我们在服务器上把代码pull下来
pull完成之后,先启动虚拟环境source ../mysite_env/bin/activate
,然后我们要在这里执行一条命令python manage.py collectstatic
收集静态文件到一个目录里面
收集完之后,我们有两个地方需要改一下配置。
现在我们用的是nginx,所以我们先改nginx的:
输入vim /etc/nginx/sites-enabled/mysite.conf
找到配置文件,把该文件里面的staticd
的地方改为static_collected
,重启nginx之前,我们可以看一下博客页面是什么样的
因为它的静态文件不在static目录里面,而是在我们收集好的目录static_collected里面
那现在我们重启nginx服务,输入service nginx restart
,(因为我们改动的是nginx里面的配置,所以需要重启nginx服务),然后刷新页面,可以看到评论框的相关静态文件又加载进来了
如果我们使用的是Apache的话,需要这么修改:
输入vim /etc/apache2/sites-enabled/mysite.conf
找到配置文件,把里面的static
修改为static_collected
(2)favicon.ico
另外还有一个东西,有时候页面会显示找不到favicon.ico(网站的图标,可以自己设计或者找一个)
我们把它放到根目录mysite里,然后从本地上传上去,git add .
,git commit -m '添加favicon.ico'
,git push
,然后在服务器上pull下来git pull
。
这个文件我们需要在web服务软件配置下,让它可以使用。
首先我们改一下nginx的配置,vim /etc/nginx/sites-enabled/mysite.conf
,在里面加一行设置
location /favicon.ico {
alias /home/mysite/favicon.ico;
}
然后重启一下nginx,输入service nginx restart
在Apache中,是这样修改的:输入vim /etc/apache2/sites-enabled/mysite.conf
,新加代码:
Alias /favicon.ico/ /home/mysite/favicon.ico/
<Directory /home/mysite>
<Files favicon.ico>
Require all granted
</Files>
</Directory>
然后重启一下Apache就可以
刷新页面,就能出来这个图标
另外3)设置上传文件目录的权限
3)设置上传文件目录的权限
我们输入ll
,可以看到,media只有所有者才可以写入,其他都不可以写,那么这里可以使用设置权限的命令chmod 777 media/
(777是开放全部权限)