基于Django构建Blog(14)-部署续

我们的Django工程至少有两个运行环境,即:"开发/调试环境"和"生产环境"。两种环境下的工程配置"settings.py"是不同的,同时,工程所需的依赖通常也是有区别的,即:"requirements.txt"文件也会不同。

这就导致了一个结果:每当我们把处于某一环境中的代码部署到另一个环境中时,就需要修改一次"settings.py"和"requirements.txt"文件,尤其是"settings.py",是必须要修改的。这样做不仅麻烦,而且更容易出错。

问题的根源就在于,"settings.py"和"requirements.txt"文件都只有一份,而我们的环境却不止一个。我们应该为不同的环境分别提供一份"settings.py"和"requirements.txt"文件。处于哪个环境,就使用哪套配置,不同环境下的配置不会互相污染。

针对这个问题,我们可以这么做:在"settings.py"和"requirements.txt"文件的基础上,分别拆分出三个部分:base,dev和pro。base文件中存放的是两个环境公有的基础配置,这些配置是稳定的,不会轻易修改,dev文件中存放的是开发环境所特有的配置,pro中存放的是生产环境特有的配置。dev和pro均继承了base的内容。

settings

新增三个settings文件:settings_base.py、settings_dev.py、settings_pro.py和一个production_secret.json文件,秘钥,数据库账号等敏感信息都保存在这个json文件中。

- production_secret.json -

1
2
3
4
5
6
7
{
    "SECRET_KEY":"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
    "DB":{
        "USER":"root",
        "PASSWORD":"123456"
    }
}

- settings.py -

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from settings_pro import PRODUCTION_SECRET_FILE
import os.path

if True == os.path.exists(PRODUCTION_SECRET_FILE):
    from settings_pro import *
else:
    from settings_dev import *

- settings_base.py -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
SECRET_KEY = 'abcdefghijklmnopqrstuvwxyz1234567890'
DEBUG =TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django_markdown',
        'apps.blog',
        'haystack',
)
MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'), )
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'), )
ROOT_URLCONF = 'xblog.urls'
WSGI_APPLICATION = 'xblog.wsgi.application'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xblog',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = '/data/static/'

- settings_dev.py -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from settings_base import *

DEBUG = TEMPLATE_DEBUG = True
INSTALLED_APPS += ()
MIDDLEWARE_CLASSES += ()
DATABASES['default']['ENGINE'] = 'django.db.backends.mysql'
DATABASES['default']['NAME'] = 'xblog'
DATABASES['default']['USER'] = 'root'
DATABASES['default']['PASSWORD'] = '123456'
DATABASES['default']['HOST'] = '127.0.0.1'
DATABASES['default']['PORT'] = '3306'

- settings_pro.py -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from settings_base import *
import json
import sys

DEBUG = TEMPLATE_DEBUG = False
PRODUCTION_SECRET_FILE = '/data/production_secret.json'
if True == os.path.exists(PRODUCTION_SECRET_FILE):
        with open(PRODUCTION_SECRET_FILE) as json_file:
                data = json.load(json_file)
                SECRET_KEY = data['SECRET_KEY']
                DATABASES['default']['USER'] = data['DB']['USER']
                DATABASES['default']['PASSWORD'] = data['DB']['PASSWORD']

DATABASES['default']['ENGINE'] = 'django.db.backends.mysql'
DATABASES['default']['NAME'] = 'xblog'
DATABASES['default']['HOST'] = '127.0.0.1'
DATABASES['default']['PORT'] = '3306'
ALLOWED_HOSTS = ['.xus.io']
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'DENY'
INSTALLED_APPS += ()
MIDDLEWARE_CLASSES += ()
STATIC_ROOT = '/data/static/'
MEDIA_ROOT = '/data/media/'

requirements

删除原"requirements.txt"文件,新建"install_requirements.py"文件和"requirements"目录,在该目录下新增三个文件:base.txt,pro.txt,dev.txt。安装依赖时,直接运行"install_requirements.py"文件即可。

- install_requirements.py -

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from xblog.settings_pro import PRODUCTION_SECRET_FILE
import os

if True == os.path.exists(PRODUCTION_SECRET_FILE):
    os.system("pip install -r ./requirements/pro.txt")
else:
    os.system("pip install -r ./requirements/dev.txt")

- base.txt -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
django==1.7.1
pygments==2.0.2
django-pygments==0.1
markdown==2.6.2
django-markdown==0.8.4
django-haystack==2.4.0
Whoosh==2.7.0
jieba==0.37
django-adminfiles==1.0.1
sorl-thumbnail==12.2
pillow==2.8.1

- dev.txt -

-r base.txt

- pro.txt -

-r base.txt

这是文中工程的源码:xblog.tar.gz,代码详见io工程:


Prev-基于Django构建Blog(13)-部署