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.htmlhttps://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/82961680https://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://[email protected]:2379/1 --inspect=True --persistent=True --db=./flower
  • https://flower-docs-cn.readthedocs.io/zh/latest/docker.html https://flower-docs-cn.readthedocs.io/zh/latest/config.html

docker-compose


其他
  • 更改容器映射端口https://www.cnblogs.com/shijf/p/10386193.html
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
  • python 语法检查https://note.qidong.name/2019/09/pylint-django/https://github.com/robot527/python_primer/blob/master/pylint.conf
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