• 10.单个容器部署django (docker + django + uwsgi)


    一.环境准备

    • 1.拉取centos基本镜像
    docker pull centos:7
    # centos               7                   b5b4d78bc90c        6 weeks ago         203MB
    
    • 2.创建一个容器
    # docker run --name dbmsrbac  -p 9000:8000 -v /home/jenvid/PycharmProjects/django/dbmsrbac:/usr/local/dbmsrbac -d -i -t b5b4d78bc90c /bin/bash 
    # 上面这个执行 systemctl start 时会报错
    docker run --name dbmsrbac  -p 9000:8000 -v /home/jenvid/PycharmProjects/django/dbmsrbac:/usr/local/dbmsrbac -d -i -t  --privileged=true centos:7 /usr/sbin/init 
    # 多端口
    docker run --name dbmsrbac  -p8000:8000 -p9000:9000 -p8001:8001 -p8002:8002 -p8888:8888 -p8080:8080 -v /home/jenvid/PycharmProjects/django/dbmsrbac:/usr/local/dbmsrbac -d -i -t  --privileged=true dbmsrbac:1 /usr/sbin/init 
    
    • 3.登入容器
    docker exec -it <CONTAINER ID> /bin/bash
    
    • 4.容器内安装必要包
    yum install -y net-tools libaio numactl wget
    
    • 5.安装 python3
    yum install  -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel gcc make
    //替换自己需要的版本
    export DOWNLOAD_PYTHON_VERSION=3.7.4 
    wget https://www.python.org/ftp/python/$DOWNLOAD_PYTHON_VERSION/Python-$DOWNLOAD_PYTHON_VERSION.tgz
    //定义安装目录 根据自己情况修改
    export PYTHON_DIR=/usr/local/python 
    
    //开始安装并创建软链、下面命令一起复制
    tar -zxvf Python-$DOWNLOAD_PYTHON_VERSION.tgz 
    && cd Python-$DOWNLOAD_PYTHON_VERSION 
    && ./configure --prefix=$PYTHON_DIR 
    && sudo make 
    && sudo make install 
    && sudo ln -s $PYTHON_DIR/bin/python3 /usr/bin/python3
    
    • 6.安装redis
    yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
    yum --enablerepo=remi install redis
    systemctl enable redis
    systemctl start redis
    
    • 7.安装mysql
    tar -zxvf mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz -C /usr/local
    cd /usr/local
    ln -s mysql-5.7.28-linux-glibc2.12-x86_64 mysql
    cd mysql/support-files/
    cp -rp mysql.server /etc/init.d/mysql
    systemctl enable mysql
    mkdir /data
    useradd mysql
    chown -R mysql:mysql /usr/local/mysql* /data
    echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile && source /etc/profile
    

    二.部署django

    不映射卷可以拷贝文件进入docker内 docker cp /home/jenvid/PycharmProjects/django/dbmsrbac cbd20cc53f56:/usr/local/dbmsrbac

    • 1.生成开发环境所有包
    pip3 freeze > requirements.txt
    
    • 2.配置下载加速源

    https://www.ctolib.com/xufqing-rest_xops.html
    https://www.pianshen.com/article/69731187958/

    mkdir ~/.pip
    touch ~/.pip/pip.conf
    echo "[global]">>~/.pip/pip.conf
    echo "index-url=https://mirrors.aliyun.com/pypi/simple/">>~/.pip/pip.conf
    echo "trusted-host=mirrors.aliyun.com">>~/.pip/pip.conf
    
    /usr/local/python/bin/pip3 install -r requirements.txt
    

    或者命令行指定 /usr/local/python/bin/pip3 install -r requirements.txt -i https://pypi.douban.com/simple --trusted-host=pypi.douban.com

    • 3.收集静态文件
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, "static")
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )
    
    python manage.py collectstatic
    
    • 4.安装依赖和 uwsgi
    /usr/local/python/bin/pip3 install -r requirements.txt -i https://pypi.douban.com/simple --trusted-host=pypi.douban.com^C
    /usr/local/python/bin/pip3 install uwsgi
    
    • 5.测试
    /usr/local/python/bin/uwsgi --http :8080 --chdir /usr/local/dbmsrbac --file dbmsrbac/wsgi.py --static-map=/static=static
    

    三..开发的时候vue用的是本地 127.0.0.1:8000 的api,构建的时候需要显示指定未来运行的 api 服务器,也就是 uswgi 连接信息(前端的 nginx http 连接 ip:port)

    • 1.创建1个生产构建配置文件 .env.production
    # 生产环境
    
    # 页面 title 前缀
    VUE_APP_TITLE=数据库管理系统
    
    VUE_APP_BASE_URL="http://172.17.0.2"             //服务器地址
    
    # 后端API地址
    VUE_APP_BASE_API=http://127.0.0.1:8888
    
    # 指定构建模式
    NODE_ENV=production
    
    # 标记当前是 No Mock 构建
    VUE_APP_BUILD_MODE=PRODUCTION
    
    # 部署路径
    VUE_APP_PUBLIC_PATH=/static/
    # 这个路径很关键,告诉前端我的静态文件是在哪个目录,可以在 nginx 中用 alias 重新指向实际的存储目录
    
    • 2.原来每个页面下的 api 都是已经使用了拦截的 axios,但是url还是指向 127.0.0.1
    import request from '@/plugin/axios'
    import SERVER from '@/server'
    let apiPrefix = SERVER.server
    
    export function GetList (query) {
      return request({
        url: apiPrefix + '/assets/hostaccount/v1/',
        method: 'get',
        params: query
      })
    }
    
    • 3.用配置文件替换
    // const server = 'http://127.0.0.1:8000'
    const server = process.env.VUE_APP_BASE_API
    export default {
      server
    }
    
    • 4.打包前端 d2admin -- 以下忽略

    https://blog.csdn.net/qq_41000891/article/details/82961680
    https://github.com/CJFJack/django_vue_cmdb

    # 修改d2-admin/vue.config.js文件
    let publicPath = process.env.VUE_APP_PUBLIC_PATH || '/static/'
    # 运行前端打包命令
    cd d2-admin
    npm run build
    # 收集项目所有静态文件
    python manage.py collectstatic
    # 还原d2-admin/vue.config.js文件
    let publicPath = process.env.VUE_APP_PUBLIC_PATH || '/'
    

    在d2-admin项目的 dist 生成文件

    ├── dist
    │   ├── css
    │   ├── fonts
    │   ├── icon.ico
    │   ├── image
    │   ├── img
    │   ├── index.html
    │   ├── js
    │   └── static
    
    

    四.定义主页

    • 1.django 更改静态文件地址
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'd2-admin/dist')],
    
            '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',
                ],
            },
        },
    ]
    
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, "static")
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'd2-admin/dist'),
    ]
    
    • 2.定义一个静态主页 - 该步骤忽略,测试使用
    # view 加载静态界面index首页
    def index(request):
        request.META["CSRF_COOKIE_USED"] = True
        return render(request,'index.html')
    # url 指向 html 页面
    from apps.users.views import index
        path('index/',index,name="index"),
    
    • 3.uwgi 启动指定路径,进行 uwsg 测试
    cd /usr/local/dbmsrbac 
    /usr/local/python/bin/uwsgi --http :8000 --chdir /usr/local/dbmsrbac --file dbmsrbac/wsgi.py --static-map=/static=d2-admin/dist
    

    image

    • 4.此时 admin 的样式丢失了,因为django收集的静态文件放在了 django 项目根下的 static,而 uwsgi 映射的静态目录是 d2-admin/dist
    [pid: 1781|app: 0|req: 20/20] 172.17.0.1 () {44 vars in 1169 bytes} [Thu Jun 25 12:19:20 2020] GET /static/admin/css/login.css => generated 26295 bytes in 18 msecs (HTTP/1.1 404) 6 headers in 188 bytes (1 switches on core 0)
    Not Found: /static/admin/css/responsive.css
    
    • 5.将 static 下的静态文件拷贝到 d2-admin/dist, 可以正常显示
    [pid: 1781|app: 0|req: 22/22] 172.17.0.1 () {48 vars in 1297 bytes} [Thu Jun 25 12:20:59 2020] GET /admin/login/?next=/admin/ => generated 1915 bytes in 18 msecs (HTTP/1.1 200) 9 headers in 483 bytes (1 switches on core 0)
    [pid: 1781|app: -1|req: -1/23] 172.17.0.1 () {44 vars in 1167 bytes} [Thu Jun 25 12:20:59 2020] GET /static/admin/css/base.css => generated 16378 bytes in 0 msecs via sendfile() (HTTP/1.1 200) 2 headers in 88 bytes (0 switches on core 0)
    [pid: 1781|app: -1|req: -1/24] 172.17.0.1 () {44 vars in 1169 bytes} [Thu Jun 25 12:20:59 2020] GET /static/admin/css/login.css => generated 1233 bytes in 0 msecs via sendfile() (HTTP/1.1 200) 2 headers in 87 bytes (0 switches on core 0)
    

    nginx 动静分离

    所有启动配置文件放在项目根目录的 script

    1.配置 uwsgi.ini

    [uwsgi]
    env LANG="en_US.UTF-8"
    env LANGUAGE="en_US.UTF-8"
    # 项目 目录
    chdir=/usr/local/dbmsrbac/
    # 启动uwsgi的用户名和用户组
    uid=nginx
    gid=nginx
    # 指定项 目的application
    module=dbmsrbac.wsgi:application
    # 指定sock的文件路径,需要提供给nginx进行连接
    #socket=/usr/local/dbmsrbac/script/uwsgi.pid
    socket=127.0.0.1:8000
    # nginxd upstream 要与这个一致,否则upstream prematurely closed connection while reading response header from upstream,
    # 启用主进程
    master=true
    # 进程个数
    workers=2
    pidfile=/usr/local/dbmsrbac/script/uwsgi.pid
    # 自动移除unix Socket和pid文件当服务停止的时 候
    vacuum=true
    # 序列化接 受的内容,如果可能的话
    thunder-lock=true
    # 启用线程
    enable-thre ads=true
    # 设置自中断时间
    harakiri=30
    # 设置缓冲
    post-buffer ing=4096
    # 设置日志目录,配合 supervisor 使用时,需要注释这里,否则冲突
    # daemonize=/usr/local/dbmsrbac/script/uwsgi.log
    

    2.安装 nginx

    yum install nginx -y
    # 配置文件
    # 后端连接 uwsgi,对外提供的端口就是 vue 构建时指定的后端API地址 VUE_APP_BASE_API=http://127.0.0.1:8888
    server {
        listen       8888;
        server_name  127.0.0.1;
       location / {
                  include uwsgi_params;
                  uwsgi_pass 127.0.0.1:8000;
                  uwsgi_ignore_client_abort on;
            }
        location /static/ {
            alias /usr/local/dbmsrbac/script/dist/;
            index index.html index.htm;
            autoindex on;
        }
    }
    
    # 前端对外提供服务的端口
    server {
        listen 8080;
        server_name 172.17.0.2 ;
        access_log /var/log/nginx/access.log main;
        charset utf-8;
        gzip on;
        gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;
        error_page 500 502 503 504 /50x.html;
        # 指定项目路径uwsgi
        location / {
            root /usr/local/dbmsrbac/script/dist;
            index index.html;
            try_files $uri $uri/ /static/;
            }
        # 指定静态文件路径
        location /static/ {
            alias /usr/local/dbmsrbac/script/dist/;
            index index.html index.htm;
            autoindex on;
        }
        # 反向代理 django 的 admin web服务
        location /admin/ {
                  include uwsgi_params;
                  uwsgi_pass 127.0.0.1:8000;
                  uwsgi_ignore_client_abort on;
        }
    }
    
    # link 到 nginx配置目录
    ln -s /usr/local/dbmsrbac/script/dbmsrbac.conf dbmsrbac.conf
    

    3.启动

    • uwsgi
    /usr/local/python/bin/uwsgi --ini uwsgi.ini
    
    [root@14cd2ca60598 script]# /usr/local/python/bin/uwsgi --ini uwsgi.ini
    [uWSGI] getting INI configuration from uwsgi.ini
    [root@14cd2ca60598 script]# ps -ef|grep uwsgi
    root      2131     1 31 07:04 ?        00:00:01 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2134  2131  0 07:04 ?        00:00:00 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2135  2131  0 07:04 ?        00:00:00 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2136  2131  0 07:04 ?        00:00:00 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2137  2131  0 07:04 ?        00:00:00 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2138  2131  0 07:04 ?        00:00:00 /usr/local/python/bin/uwsgi --ini uwsgi.ini
    root      2140  1698  0 07:04 pts/1    00:00:00 grep --color=auto uwsgi
    
    • nginx
    systemctl enable nginx
    
    [root@14cd2ca60598 script]# ps -ef|grep nginx
    root      2170     1  0 07:09 ?        00:00:00 nginx: master process /usr/sbin/nginx
    nginx     2171  2170  0 07:09 ?        00:00:00 nginx: worker process
    nginx     2172  2170  0 07:09 ?        00:00:00 nginx: worker process
    nginx     2173  2170  0 07:09 ?        00:00:00 nginx: worker process
    nginx     2174  2170  0 07:09 ?        00:00:00 nginx: worker process
    root      2176  1698  0 07:09 pts/1    00:00:00 grep --color=auto nginx
    

    image

    • 重启 uwsgi
    #### 启动:
    uwsgi --ini xxx.ini
    #### 重启:
    uwsgi --reload xxx.pid
    #### 停止:
    uwsgi --stop xxx.pid
    

    配置 supervisor 管理django和celery

    • 1.安装supervisor
    cd ~ && yum -y install epel-release && yum -y install supervisor
    systemctl enable supervisord
    systemctl start supervisord
    
    • 2.配置
    vi /usr/local/dbmsrbac/script/supervisor.ini
    
    # django
    [program:dbmsrbac]
    command=/usr/local/python/bin/uwsgi --ini /usr/local/dbmsrbac/script/uwsgi.ini
    directory=/usr/local/dbmsrbac
    stdout_logfile=/var/log/supervisor/django.log
    stderr_logfile=/var/log/supervisor/django.log
    stdout_logfile_maxbytes = 20MB
    autostart=true
    autorestart=false
    
    # worker
    [program:celery_worker]
    environment=PYTHONOPTIMIZE=1
    command=/usr/local/python/bin/celery -A dbmsrbac worker -l info -O OPTIMIZATION
    directory=/usr/local/dbmsrbac
    user=root
    numprocs=1
    # 设置log的路径
    stdout_logfile=/var/log/supervisor/celery_worker.log
    stderr_logfile=/var/log/supervisor/celery_worker.log
    autostart=true
    autorestart=true
    startsecs=10
    stopwaitsecs = 60
    priority=901
    
    # beat
    [program:celery_beat]
    directory=/usr/local/dbmsrbac
    command=/usr/local/python/bin/celery -A dbmsrbac beat --loglevel=INFO 
    numprocs=1
    # 设置log的路径
    stdout_logfile=/var/log/supervisor/celery_beat.log
    stderr_logfile=/var/log/supervisor/celery_beat.log
    autostart=true
    autorestart=true
    startsecs=10
    stopwaitsecs = 60
    priority=902
    
    #flower是celery的监控,请注意修改redis连接
    [program:celery_flower]
    # command=/usr/local/python/bin/celery flower --broker=redis://localhost:6379/1
    command=/usr/local/python/bin/celery flower --address=0.0.0.0 --basic-auth=admin:admin --port=5555 --broker=redis://127.0.0.1:6379/1 --inspect=True --persistent=True --db=/var/log/supervisor/flower 
    directory=/usr/local/dbmsrbac
    stdout_logfile=/var/log/supervisor/flower_celery.log
    stdout_logfile=/var/log/supervisor/flower_celery.log
    autostart=true
    autorestart=true
    priority=903
    
    • 3.link 到 conf 下
    ln -s /usr/local/dbmsrbac/script/supervisor.ini /etc/supervisord.d/supervisor.ini
    
    • 4.执行
    supervisorctl start all
    
    supervisor> status
    celery_beat                      RUNNING   pid 4496, uptime 0:34:49
    celery_flower                    RUNNING   pid 4497, uptime 0:34:49
    celery_worker                    RUNNING   pid 4495, uptime 0:34:49
    dbmsrbac                         RUNNING   pid 4498, uptime 0:34:49
    
    
    • flower
    celery flower --address=0.0.0.0 --basic-auth=admin:admin --port=5555 --broker=redis://123456@127.0.0.1:2379/1 --inspect=True --persistent=True --db=./flower  
    

    docker-compose


    其他

    1、停止docker容器
    
    docker stop container01
    
    2、commit该docker容器
    
    docker commit container01 new_image:tag
    
    3、用前一步新生成的镜像重新起一个容器
    
    docker run --name container02 -p 80:80 new_image:tag
    
    pip install pylint-django
    
    pylint django_example/
    pylint --load-plugins pylint_django django_example/
    [MASTER]
    load-plugins=pylint_django
    
    项目根目录 .pylintrc
    [MASTER]
    load-plugins=pylint_django
    
    • vue-cli 打包环境说明

    https://blog.csdn.net/liyunkun888/article/details/103322625

  • 相关阅读:
    spring给容器中注入组件的几种方式
    Linux多进程
    Linux多进程的应用
    Linux进程通信
    Linux信号
    Linux共享内存
    Linux信号量
    Linux多线程
    Linux线程同步
    Linux调用可执行程序
  • 原文地址:https://www.cnblogs.com/jenvid/p/13229066.html
Copyright © 2020-2023  润新知