• Django项目部署


    一、打包文件传到服务器

    参考博客:https://www.cnblogs.com/wupeiqi/articles/8591782.html

    http://www.cnblogs.com/alex3714/p/6538374.html

    示例代码下载

    将本地代码打包,拷贝到服务器上。(打包: tar czvf deploy.tar deploy  解包: tar zxvf deploy.tar)
                
    mac/linux:  
      scp 本地文件路径  root@192.168.10.33:/data/
           scp deploy.tar root@10.0.0.200:/data/
          
     
      点点点上传
                

    二、服务器环境准备好

    安装Python3:

      (http://www.cnblogs.com/wupeiqi/articles/4906230.html)

      http://www.cnblogs.com/alice-bj/articles/9277961.html


      1、安装gcc,用于编译Python源码
        yum install gcc
      2、下载源码包,https://www.python.org/ftp/python/
      3、解压并进入源码文件
      4、编译安装
        ./configure
        make all
        make install
      模式:/usr/local/bin/python3

    安装django:
      pip3 install django==1.11.7

    报错:no module _sqlite3
      所以应该先装:yum install sqlite-devel

      重新编译安装py3
      ./configure
      make
      make install

    三、运行

    - 1.解压
    - 2.配置:ALLOWED_HOSTS = ['*',]   # 允许访问
    - 3.配置:DEBUG = False
      # 用户看不到错误信息,以及暴露出来的url;注意改完之后,样式没有了!!
      # 为什么?因为django对静态文件上线时,需要特殊处理。
    - 4.找到django程序中每一个app和全局的静态文件,统一放置到某处。
      # python3 manage.py
      # python3 manage.py collectstatic
      # 报错:You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
      # 静态文件收集到哪里?STATIC_ROOT
      # 需要在 settings中配置 STATIC_ROOT = "allstatic"
      # 之后在 python3 manage.py collectstatic 这样所有的静态文件就都收集到了项目下的allstatic下面
      # 因为django对静态文件处理特别次,所以选择用nginx专门处理静态文件。
      

    - 5.python manage.py runserver 0.0.0.0:8001

    四、Nginx做反向代理(处理静态文件)

    安装:
      yum install nginx
      # cat /etc/nginx/nginx.conf
    配置文件:

    user root;
    worker_processes 4;  #核数
    
    error_log /var/log/nginx/error.log;
    pid /var/run/nginx.pid;
    
    events {
        worker_connections  1024; # IO多路复用,监听socket发生变化的,监听最多的连接数
    }
    
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        upstream django {
            server 127.0.0.1:8001; 
        }
        server {
            listen      80;
    
            charset     utf-8;
    
            # max upload size
            client_max_body_size 75M;
    
            location /static {
                alias  /data/s9deploy/allstatic; 
            }
    
            location / {
                uwsgi_pass  django;
                include     uwsgi_params;
            }
        }
    }

    运行起来:systemctl start nginx   # 默认是80端口
         service nginx start         # Centos6.9用这个实现了

    五、uwsgi替换原来的wsgiref

    安装:
      pip3 install uwsgi
    使用:
      uwsgi启动django : uwsgi --socket 127.0.0.1:8001 --chdir /data/s9deploy/ --wsgi-file s9deploy/wsgi.py
                  uwsgi --socket :8002 --chdir /data/deploy/ --wsgi-file deploy/wsgi.py

    六、操作

    1. 程序
      DEBUG = False
      ALLOWED_HOSTS = ['*',]
      STATIC_ROOT = "allstatic"

    2. 程序:s9deploy.zip 上传到服务器
      yum install lrzsz

    3. 解压:
      yum install unzip

    4. 安装uwsgi
      pip3 install uwsgi

      代替wsgi运行django:
        不处理静态文件:
          uwsgi --http 0.0.0.0:8001 --chdir /data/s9deploy/ --wsgi-file s9deploy/wsgi.py
        处理静态文件:
          python manage.py collectstatic # /data/s9deploy/allstatic

        uwsgi --http 0.0.0.0:8001 --chdir /data/s9deploy/ --wsgi-file s9deploy/wsgi.py --static-map /static=/data/s9deploy/allstatic

      简单运行方式:
        vim uwsgi_s9deploy.ini

        [uwsgi]
        http = 0.0.0.0:8001 # scoket = 0.0.0.0:8001
        chdir = /data/s9deploy/
        wsgi-file = s9deploy/wsgi.py
        processes = 4
        static-map = /static=/data/s9deploy/allstatic

        uwsgi --ini /data/s9deploy/uwsgi_s9deploy.ini

    5. 安装nginx
      yum install nginx

      配置:

    user root;
    worker_processes 4;
    
    error_log /var/log/nginx/error.log;
    pid /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        upstream django {
            server 127.0.0.1:8001; 
            server 127.0.0.1:8002; 
        }
        server {
            listen      80;
    
            charset     utf-8;
    
            # max upload size
            client_max_body_size 75M;
    
            location /static {
                alias  /data/s9deploy/allstatic; 
            }
    
            location / {
                uwsgi_pass  django;
                include     uwsgi_params;
            }
        }
    }

    6. 安装supervisor,检测进程不要被关闭。

    第二阶段:管理工具,ansible/fabric/puppet/saltstack       

      将本地代码打包,通过管理工具,将代码上传到每一台服务器上。
        

     第三阶段:基于git + 管理工具

      运维人员:
             git clone -b v1.0  http://www.github.com/xxx/xxx/xx
      编译:(c java csharp 上线需要编译成加密之后的文件; python php 不需要编译)
           再通过管理工具,将代码上传到每一台服务器上。      
     

    第四阶段:jekins web程序

      基于git +  编译 + 管理工具

    七、总结

    nginx 做了负载均衡, web集群,多个机器处理请求
      uwsgi_deploy_8002.ini uwsgi_deploy_8003.ini
      uwsgi --ini /data/s9deploy/uwsgi_s9deploy_8001.ini & # 后台运行
      uwsgi --ini /data/s9deploy/uwsgi_s9deploy_8002.ini &

    nginx 反向代理;请求制作转发 静态文件自己处理 动态文件 交给uwsgi
      192.168.12.22:8001
      192.168.12.23:8001

      192.168.12.22: uwsgi:配置文件 + 代码
      192.168.12.23: uwsgi: 配置文件 + 代码
      运行: uwsgi --ini /data/s9deploy/uwsgi_s9deploy_8002.ini &


      uwsgi 也可以 开进程; processes = 4
      nginx接4个,后台接 4个 ,实现并发 (加一个& 后台运行 不卡住;)
      uwsgi --ini uwsgi_deploy_8002.ini &
      

    ----------------------------
    第二阶段: 批量上传 批量

    ---------------------------- 
    项目部署方案:

    supervisor 监测这三个进程 看谁的进程死掉了,会自动启动; 安装supervisor,检测进程不要被关闭。
      如果关闭,立即重启;
      ps -ef|grep uwsgi
      kill -9 3101

    假设:程序要做负载均衡;
      两个uwsgi 一个nginx 有三个程序运行;

    ----------------------

    八、code 配置

    user root;
    worker_processes 4;
    
    error_log /var/log/nginx/error.log;
    pid /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        upstream django {
            server 127.0.0.1:8003;
            server 127.0.0.1:8004;
            # server 192.1.123.1; 
        }
        server {
            listen      80;
    
            charset     utf-8;
    
            # max upload size
            client_max_body_size 75M;
    
            location /static {
                alias  /data/deploy/allstatic;
            }
    
            location / {
                uwsgi_pass  django;
                include     uwsgi_params;
            }
        }
    }

     

    """
    Django settings for deploy project.
    
    Generated by 'django-admin startproject' using Django 1.11.11.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '&4r0zssdr8%(cph&+^nx#k)r+rpwpw)^_q)2f7()*a3ki8p^ju'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = False
    
    ALLOWED_HOSTS = ['*',]
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
    ]
    
    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 = 'deploy.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, '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',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'deploy.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
    
    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',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.11/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static')
    ]
    STATIC_ROOT = os.path.join(BASE_DIR, "allstatic")

    九、图片

     

     

    十、补充

    项目开发完毕后,需要将代码放到服务器上,这样用户才能访问。接下来我们一步一步来进行一波部署操作。

    1. 简单粗暴

    项目开发完毕,在部署之前需要再配置文件中将 ALLOWED_HOSTS配置设置为:当前服务器IP或*,如:

    1
    ALLOWED_HOSTS = ["*",]

    然后将源码上传至服务器指定目录,如:/data/ ,然后执行命令来运行:

    注: 上传命令: scp /Users/wupeiqi/PycharmProjects/oldboy-1.zip root@192.168.10.33:/data/

    解压,进入目录并执行以下命令:

    1
    python3 mange.py runserver 0.0.0.0:8000  

    类似这样的上线网站:

    2. uwsgi

    Django框架运行依赖wsgi(本质提供socket服务端),众多模块实现了wsgi规范,而django框架中默认使用wsigiref模块来实现,他由于性能比较低,所以用于本地开发和测试,而线上部署时需要使用uwsgi来代替。

    a. 在服务器上安装uwsgi

    1
    pip3 install uwsgi

    需要先安装:yum install python-devel

    b. 单文件使用uwsgi

    在服务器上编写一个Python文件:

    1
    2
    3
    def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return [b"Hello World"]

    在服务器上执行命令启动Web服务器:

    1
    2
    3
    uwsgi --http :9001 --wsgi-file app.py
    # 或
    uwsgi --http :9002 --wsgi-file foobar.py --master --processes 4

    PS: flask需要再加 --callable app

    访问查看即可:

    c. django程序使用uwsgi

    将开发好的django程序拷贝到服务器目录【同示例一】,即:/data/oldboy ,执行命令启动:

    1
    uwsgi --http :9005 --chdir /data/oldboy/ --wsgi-file oldboy/wsgi.py --master --processes 4
    1. 创建配置文件 oldboy.ini
    
    [uwsgi]
    http = 0.0.0.0:9005
    chdir = /data/oldboy/
    wsgi-file = oldboy/wsgi.py
    processes = 4
    static-map = /static=/data/oldboy/allstatic
    
    2. 根据配置文件启动uwsgi
    
    uwsigi --ini  oldboy.ini

    PS: 如果有虚拟环境可以添加上虚拟环境路径配置: virtualenv = /env/oldboy_venv

    此时访问时,会出现找不到静态文件的错误。

    想要uwsgi处理静态文件,需要先将django的静态文件收集到制定目录,然后再设置对应关系。

    • 收集django静态文件
      • 在django的配置文件中添加:STATIC_ROOT = os.path.join(BASE_DIR,"allstatic")
      • 执行 python3 manage.py collectstatic 命令,至此django项目所有相关静态文件都会收集到制定目录。
    • 设置uwsgi静态文件对应关系
      • uwsgi --http :9005 --chdir /data/oldboy/ --wsgi-file oldboy/wsgi.py --master --processes 4 --static-map /static=/data/oldboy/allstatic

    访问地址,即可看到网站了....

    3. nginx

    利用Nginx做反向代理、负载均衡以及处理静态文件。

    a. 安装Nginx

    1
    yum install nginx

    b. 配置nginx

    user root;
    worker_processes 4;
    
    error_log /var/log/nginx/error.log;
    pid /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
    
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        upstream django {
            server 127.0.0.1:8001; 
            # server 192.1.123.1; 
        }
        server {
            listen      80;
    
            charset     utf-8;
    
            # max upload size
            client_max_body_size 75M;
    
            location /static {
                alias  /data/oldboy/allstatic; 
            }
    
            location / {
                uwsgi_pass  django;
                include     uwsgi_params;
            }
        }
    }

    确保nginx配置文件目录下有uwsgi_params文件(默认)

    c. 配置uwsgi

    为了确保让所有请求均通过80端口来访问网站,将uwsgi的配置文件修改为:

    1
    2
    3
    4
    5
    6
    [uwsgi]
    socket = 127.0.0.1:9005
    chdir = /data/oldboy/
    wsgi-file = oldboy/wsgi.py
    processes = 4
    logto = /tmp/oldboy.log

    d. 启动uwsgi和nginx

    1
    2
    3
    uwsgi --ini /data/oldboy/oldboy.ini &
     
    /etc/init.d/nginx start

    4. supervisor

    supervisor是一个对进程管理的软件,可以帮助我们启动uwsgi并维护(uwsgi进程关闭时,自动将其启动起来)。

    a. 安装

    1
    yum install supervisor

    b. 配置 vim /etc/supervisor.conf

    [supervisord]
    http_port=/var/tmp/supervisor.sock ; (default is to run a UNIX domain socket server)
    ;http_port=127.0.0.1:9001  ; (alternately, ip_address:port specifies AF_INET)
    ;sockchmod=0700              ; AF_UNIX socketmode (AF_INET ignore, default 0700)
    ;sockchown=nobody.nogroup     ; AF_UNIX socket uid.gid owner (AF_INET ignores)
    ;umask=022                   ; (process file creation umask;default 022)
    logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
    logfile_maxbytes=50MB       ; (max main logfile bytes b4 rotation;default 50MB)
    logfile_backups=10          ; (num of main logfile rotation backups;default 10)
    loglevel=info               ; (logging level;default info; others: debug,warn)
    pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
    nodaemon=false              ; (start in foreground if true;default false)
    minfds=1024                 ; (min. avail startup file descriptors;default 1024)
    minprocs=200                ; (min. avail process descriptors;default 200)
    
    ;nocleanup=true              ; (don't clean up tempfiles at start;default false)
    ;http_username=user          ; (default is no username (open system))
    ;http_password=123           ; (default is no password (open system))
    ;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)
    ;user=chrism                 ; (default is current user, required if root)
    ;directory=/tmp              ; (default is not to cd during start)
    ;environment=KEY=value       ; (key value pairs to add to environment)
    
    [supervisorctl]
    serverurl=unix:///var/tmp/supervisor.sock ; use a unix:// URL  for a unix socket
    ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
    ;username=chris              ; should be same as http_username if set
    ;password=123                ; should be same as http_password if set
    ;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
    
    ; The below sample program section shows all possible program subsection values,
    ; create one or more 'real' program: sections to be able to control them under
    ; supervisor.
    
    ;[program:theprogramname]
    ;command=/bin/cat            ; the program (relative uses PATH, can take args)
    ;priority=999                ; the relative start priority (default 999)
    ;autostart=true              ; start at supervisord start (default: true)
    ;autorestart=true            ; retstart at unexpected quit (default: true)
    ;startsecs=10                ; number of secs prog must stay running (def. 10)
    ;startretries=3              ; max # of serial start failures (default 3)
    ;exitcodes=0,2               ; 'expected' exit codes for process (default 0,2)
    ;stopsignal=QUIT             ; signal used to kill process (default TERM)
    ;stopwaitsecs=10             ; max num secs to wait before SIGKILL (default 10)
    ;user=chrism                 ; setuid to this UNIX account to run the program
    ;log_stdout=true             ; if true, log program stdout (default true)
    ;log_stderr=true             ; if true, log program stderr (def false)
    ;logfile=/var/log/cat.log    ; child log path, use NONE for none; default AUTO
    ;logfile_maxbytes=1MB        ; max # logfile bytes b4 rotation (default 50MB)
    ;logfile_backups=10          ; # of logfile backups (default 10)
    
    
    
    [program:oldboy]
    command=/usr/local/bin/uwsgi /data/oldboy/oldboy.ini ;命令
    priority=999                ; 优先级(越小越优先)
    autostart=true              ; supervisord启动时,该程序也启动
    autorestart=true            ; 异常退出时,自动启动
    startsecs=10                ; 启动后持续10s后未发生异常,才表示启动成功
    startretries=3              ; 异常后,自动重启次数
    exitcodes=0,2               ; exit异常抛出的是0、2时才认为是异常
    stopsignal=QUIT             ; 杀进程的信号
    stopwaitsecs=10             ; 向进程发出stopsignal后等待OS向supervisord返回SIGCHILD 的时间。若超时则supervisord将使用SIGKILL杀进程 
    user=chrism                 ; 设置启动该程序的用户
    log_stdout=true             ; 如果为True,则记录程序日志
    log_stderr=false            ; 如果为True,则记录程序错误日志
    logfile=/var/log/cat.log    ; 程序日志路径
    logfile_maxbytes=1MB        ; 日志文件最大大小
    logfile_backups=10          ; 日志文件最大数量

    c. 启动

    1
    2
    3
    supervisord /etc/supervisor.conf
    /etc/init.d/supervisor start

    https://blog.csdn.net/lileihappy/article/details/79580291

  • 相关阅读:
    codechef: ADAROKS2 ,Ada Rooks 2
    codechef: BINARY, Binary Movements
    codechef : TREDEG , Trees and Degrees
    ●洛谷P1291 [SHOI2002]百事世界杯之旅
    ●BZOJ 1416 [NOI2006]神奇的口袋
    ●CodeForce 293E Close Vertices
    ●POJ 1741 Tree
    ●CodeForces 480E Parking Lot
    ●计蒜客 百度地图的实时路况
    ●CodeForces 549F Yura and Developers
  • 原文地址:https://www.cnblogs.com/alice-bj/p/9295326.html
Copyright © 2020-2023  润新知