之前的文章中将uwsgi, nginx mysql 等全部安装完毕.
本篇内容最终达到的效果是提交代码到某分支, 远程服务器自动更新.
在将django项目正式部署到测试服务器上之前需要做一点点修改.
不同的环境应用不同的配置.
由于脚本的特点, 从上往下执行, 以下几行简单代码可以根据不同的环境导入不同的配置文件.
import sys
SERVER_ENVIRONMENT = None
if os.path.exists(os.path.join(BASE_DIR, "setting-environment-local")):
SERVER_ENVIRONMENT = 'local'
from .settings_local import *
if os.path.exists(os.path.join(BASE_DIR, "setting-environment-develop")):
SERVER_ENVIRONMENT = 'develop'
from .settings_dev import *
if SERVER_ENVIRONMENT == None:
# SERVER_ENVIRONMENT = 'develop'
# from .settings_dev import *
raise RuntimeError("没有找到 环境标记文件")
# sys.exit()
上面的代码 根据项目路径来判断当前环境.
有两个环境标记文件.
setting-environment-local 本机环境
setting-environment-develop 测试服务器
环境标记文件使用vim 创建即可, 对os.path.exists(os.path.join(BASE_DIR, "setting-environment-local")
这行代码来说, 文件和路径是一样的效果.
记得环境标记文件需要使用.gitignore忽略版本管理. !!!!!!!!!!!!!
上面的代码中有.setting_local
和.setting_dev
两个文件, 这个我们手动创建的配置文件, 两个文件内容分别为本地环境的配置和测试环境的配置, 主要不同点在于数据库配置.
settingdev 与settinglocal两个文件的内容除了 "user" "password"不同, 其余基本相同.
创建依赖列表.
cd 到项目的manage.py 同一目录下
# 切换工作环境
workon python35
pip freeze >requirements.txt
此时项目中多出requirements.txt文件.
内容为各个依赖库与版本. 例如
certifi==2017.7.27.1
chardet==3.0.4
coreapi==2.3.3
coreschema==0.0.4
Django==1.11.6
django-rest-swagger==2.1.2
django-simple-serializer==2.0.7
djangorestframework==3.7.1
future==0.16.0
idna==2.6
itypes==1.1.0
Jinja2==2.9.6
MarkupSafe==1.0
olefile==0.44
openapi-codec==1.3.2
Pillow==4.3.0
PyMySQL==0.7.11
pytz==2017.2
requests==2.18.4
simplejson==3.11.1
uritemplate==3.0.0
urllib3==1.22
将静态文件单独放入一个目录下方便nginx管理
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'common_static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "common_static"),
)
urls.py 文件
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework_swagger.views import get_swagger_view
from rest_framework.routers import DefaultRouter
from rest_framework.documentation import include_docs_urls
from rest_framework.schemas import get_schema_view
from django.contrib.auth.models import User
from ifacerecognition.views import home, uploadImage
from ifacerecognition import views as ifacerecognitionViews
from django.conf.urls.static import static
from django.conf import settings
from ifacerecognition.developer import urls as DeveloperUrls
from django.views.static import serve
# from facerecognition.settings import STATIC_ROOT as SettingStaticRoot
urlpatterns = [
# 为pad android 开发板等提供的接口
url(r'^api/', include('ifacerecognition.urls')),
# 接口文档
url(r'^docs/', ifacerecognitionViews.SwaggerSchemaView.as_view(), name='apiDocs'),
# django
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', admin.site.urls),
# html 页面
url(r'^pages/uploadImage$', uploadImage),
# url(r'^developer/', include(DeveloperUrls)),
url(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
url(r'^$', home),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
执行以下命令
workon python35
python manage.py collectstatic
此时发现common_static目录下有很多文件. 这个目录下的文件使用nginx管理.
远程服务器拉取代码
cd 到一个合适的目录 例如创建一个目录叫做webapps
cd webapps
git clone "项目地址"
cd 到manage.py 文件所在目录下
# 创建环境标记文件, :wq 不写内容或者写入任意内容
vim setting-environment-develop
切换分支. 例如切换到develop分支, 以后只要向develop分支提交代码就会更新测试服务器. 向master分支提交代码可以配置为更新正式服务器.
编写uwsgi 配置文件
vim mysite.ini
mysite.ini文件是此项目的uwsgi 配置. 举个配置的例子.
[uwsgi]
project = xxx
chdir = /data/apps/xxx_server/xxx
module = xxx.wsgi
home = /root/.virtualenvs/xxx
socket = /uwsgi_sock/xxx.sock
chmod-socket = 664
master = true
processes = 7
vacuum = true
daemonize = /data/logs/uwsgi_xxx.log
py-autoreload = 1
log-maxsize = 50000000
pidfile = /uwsgi_sock/xxx.pid
touch-reload = /uwsgi_sock/xxx-reload
disable-logging = true
[uwsgi]
# 项目名称
project = xxx
# 项目路径
chdir = /data/apps/xxx_server/xxx
# wsgi文件名
module = xxx.wsgi
# python环境目录
home = /root/.virtualenvs/xxx
# 监听端口(文件)
socket = /uwsgi_sock/xxx.sock
# 分配权限.
chmod-socket = 664
#
master = true
# 开多少工作进程, (视服务器配置和项目需求而定.)
processes = 7
#
vacuum = true
# 日志文件路径
daemonize = /data/logs/uwsgi_xxx.log
# 是否自动重启服务器, 例如项目某文件有变换直接重启服务器
py-autoreload = 1
# 日志文件大小
log-maxsize = 50000000
# 配置端口, 向.pid文件发命令控制服务器停止, 重启等等.
pidfile = /uwsgi_sock/xxx.pid
# touch reload文件, 意思就是 touch xxx-reload 文件, 项目立即重启
touch-reload = /uwsgi_sock/xxx-reload
#
disable-logging = true
各种路径应该提前创建. 例如上面的uwsgi_sock路径等等.
应用此配置.
uwsgi --ini /data/apps/xxx_server/xxx/mysite.ini
此命令执行一次即可.
上面的配置例子. 使用了virtualenv创建的python环境./root/.virtualenvs/xxx
监听/uwsgi_sock/xxx.sock
文件(和监听端口一个意思, 还可以监听8000之类的端口).
nginx配置
cd /etc/nginx/conf.d
# 再次目录下创建项目配置文件
vim xxx.conf
文件内容
server{
listen 80 ;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
include uwsgi_params;
uwsgi_pass unix:/uwsgi_sock/xxx.sock;
}
location /static {
alias /data/apps/xxx_server/xxx/common_static;
}
location /media {
alias /data/apps/xxx_server/xxx/media;
}
}
上面的配置表示nginx监听80端口, 将80端口收到的一切信息发送到/uwsgi_sock/xxx.sock/ 而 uwsgi也监听 /uwsgi_sock/xxx.sock 这样就达到了 nginx向uwsgi 发送消息的目的. 而静态文件使用了nginx管理.
重启nginx 以应用配置.
/etc/init.d/nginx restart
其他命令
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start
持续集成
持续集成其实就是提交代码之后想办法立即让远程服务器执行一个脚本.
按照这个思路. 需要测试服务器运行一个web项目用来监听 脚本运行请求, 需要对应项目的更新脚本, 需要web项目接口的调用机制.
1.用来运行脚本的项目. 此项目可以直接使用jenkins 也可以自己写一个, 我新建的一个叫做runshell的django项目(增加的代码一共也不到10行的样子)用来跑 更新脚本.
2.如何提交代码的同时触发更新机制. 我这里使用gitlab 创建一个hock即可
当然浏览器直接执行以下也一样, 提交代码之后访问指定url 即执行脚本.
用来运行脚本的简单项目
接口内容如下
def build_face(request):
status = os.system('sh /data/apps/runShell/buildApp')
return HttpResponse("success", content_type="application/json", )
简单脚本.
运行buildApp脚本
buildApp内容
workon xxx
cd /data/apps/xxx_server/
git pull
cd /data/apps/xxx_server/xxx
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
touch /uwsgi_sock/xxx-reload
切换python环境
cd到项目目录下
拉取代码
安装依赖库
创建数据库表.
重启服务器