美文网首页
ubuntu django+uwsgi+nginx部署与持续集成

ubuntu django+uwsgi+nginx部署与持续集成

作者: 行如风 | 来源:发表于2017-10-23 18:57 被阅读235次

    之前的文章中将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 两个文件, 这个我们手动创建的配置文件, 两个文件内容分别为本地环境的配置和测试环境的配置, 主要不同点在于数据库配置.

    setting0.png

    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即可

    webhock.png

    当然浏览器直接执行以下也一样, 提交代码之后访问指定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到项目目录下
    拉取代码
    安装依赖库
    创建数据库表.
    重启服务器

    相关文章

      网友评论

          本文标题:ubuntu django+uwsgi+nginx部署与持续集成

          本文链接:https://www.haomeiwen.com/subject/bmoauxtx.html