采用nginx+uwsgi+docker部署django + vue

最近搭一个前后端分离的开发框架,记录下步骤。

1. django部署

  • 安装django依赖包:pip3 install Django
  • 采用命令行创建django项目:django-admin startproject src
  • 执行同步数据库文件:python3 manage.py migrate
    执行时报错sqlite版本过低,因此更新sqlite为3.28.0,参见https://blog.csdn.net/weixin_43336281/article/details/100055435
  • 在settings.py中配置ALLOWED HOSTS,可访问的ip,如果想允许任一ip访问,可设置:ALLOWED_HOSTS = ['*']
  • 启动django:python3 manage.py runserver 0.0.0.0:8000
  • 访问http://localhost:8000,可将localhost替换为允许的ip,正常可以看到一个初始的django页面

2. mysql部署

由于项目对接使用mysql数据库,因此需要配置mysql的环境,并将其配置到django中。

import pymysql
pymysql.version_info = (1, 4, 13, "final", 0)
pymysql.install_as_MySQLdb()
  • 在settings.py中配置mysql连接,并同步数据库文件
    此处报了一个错:django.db.utils.OperationalError: (1044, “Access denied for user… (using password: YES)”)。
    采用mysql -u local_user -p 命令进入mysql数据库,发现密码是正确的,但django的数据库同步始终失败,问题在于mysql用户的权限管理上,处理方法参见:https://www.cnblogs.com/idlo/p/10872324.html
DATABASES = {
    
    
    'default': {
    
    
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'jlpost',
        'USER': 'local_user',
        'HOST': '10.30.239.196',
        'PASSWORD': '123456',
        'PORT': '3306',
    }
}

3. 创建项目

  • 在urls.py中创建相关的接口,并编写相关的api测试脚本
from django.conf.urls import url
from django.contrib import admin
from django.urls import path
from src.view import view_for_edi

urlpatterns = [
    path('admin/', admin.site.urls),
    # 异常发现
    url('^EdiAbnormal$', view_for_edi.get_one_edi_msg),
]

4. VUE部署

  • 安装npm包:npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 安装vue脚手架:cnpm install -g vue-cli
  • 创建前端工程:vue-init webpack web
  • 启动vue工程:npm run dev,正常可以看到一个初始的vue页面
    打开http://localhost:8080时提示无法访问,此处参见https://blog.csdn.net/qq_44224698/article/details/110220941
  • 打包vue项目:npm run build,生成dist目录

5. 整合django与vue

此处需要将Django的TemplateView指向vue生成的前端dist文件。

  • 在urls.py中配置接口
 url(r'^JlPort$', TemplateView.as_view(template_name="index.html")),
 re_path(r'.*', TemplateView.as_view(template_name='index.html')),
  • 在Django工程目录settings.py中配置TemplateView指向的地址,该地址为web目录下dist相关的位置

  • 配置静态文件的地址

TEMPLATES = [
    {
    
    
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ["/opt/web/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',
            ],
        },
    },
]
STATICFILES_DIRS = [
    "/opt/web/dist/static",
]

-配置完成后,启动django工程,正常可以看到一个vue页面
此时,服务的端口已经是Django服务的8000而不是node服务的8080了,说明已经成功通过Django集成了Vue前端工程。

6. 项目部署(本地)

采用uwsgi+nginx部署项目。服务器:CentOS 7.9

6.1 uwsgi启动django

  • 安装uwsgi,报错
pip3 install uwsgi

在这里插入图片描述
查阅资料发现是python3_devel(centos系统下)未安装,补充该安装包,成功

yum install python3-devel
  • 收集静态资源
    配置django目录下的settings.py
# 静态资源访问的起始url
STATIC_URL = '/static/'
# 指定静态资源所在的目录
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
# 设置收集静态资源的路径(部署时使用)
STATIC_ROOT = BASE_DIR

收集静态资源

python3 manage.py collectstatic
  • 新建uwsgi.ini,与manage.py同一目录下,配置uwsgi.ini
[uwsgi]
; 监听的端口
http = :8001

; 指定和nginx进行套接字通信的方式:端口或文件
; socket = :8002

; 项目所在目录,和manage.py同级
chdir = /opt/jlpost/post_process_docker

; 主应用中的wsgi文件
wsgi-file = src/wsgi.py

; 代理静态资源:路径映射
static-map = /static=/opt/jlpost/post_process_docker/src/jl_dist/dist

; 启动一个master进程,来管理其余的子进程
master=True
processes = 4
threads = 2

; 保存主进程的pid,用来控制uwsgi服务
pidfile=/opt/jlpost/post_process_docker/logs/uwsgi.pid

; 设置后台运行,保存日志
daemonize=/opt/jlpost/post_process_docker/logs/uwsgi.log

; 设置每个工作进程处理请求的上限,达到上限时,将回收(重启)该进程。可以预防内存泄漏
max-requests=5000

; 服务停止时自动移除unix Socket和pid文件
vacuum=true
  • 启动与关闭
uwsgi uwsgi.ini

# 停止
uwsgi --stop logs/uwsgi.pid
pkill -f uwsgi -9

问题:
采用runserver的命令直接启动django时,无报错信息,网页能够正常使用,但是采用uwsgi启动时,日志报错:sqlite版本过低
检查sqlite版本信息:

find / -name sqlite3*

在这里插入图片描述
检查发现:/usr/bin/sqlite3软链接存在异常,重新设置软链接,失败,仍然无法访问网页

ln -s /usr/local/sqlite/bin/sqlite3 /usr/bin/sqlite3

查阅资料:https://blog.csdn.net/legendary_Dragon/article/details/117295774,可能是sqlite3的库文件没有更新,uwsgi优先调用/usr/lib64/目录下的库文件
替换后成功运行

# 查找库文件
find / -name *sqlite3.so.0
# 替换.so文件
cp /usr/local/sqlite/lib/libsqlite3.so.0 /usr/lib64/libsqlite3.so.0
  • 日志配置
    由于uwsgi的入口是src/wsgi.py,因此需要在该文件下配置日志输出信息,将django请求的日志记录下来。
def _handle_cmd_line(args=None):
    parser = OptionParser()

    parser.add_option("--id", dest="id", action="store",
                      type="string", default="0",
                      help="id use guard and create log file")
    parser.add_option("--logconfig", dest="logconfig", action="store",
                      type="string",
                      default=os.path.join(
                          work_dir, 'etc', 'log.conf'),
                      help="log config file [%default]")

    (options, args) = parser.parse_args(args=args)
    return options, args


options, _args = _handle_cmd_line()
if options.logconfig:
    defaults = {
    
    "id": options.id}
    logging.config.fileConfig(options.logconfig, defaults)

6.2 采用nginx代理

  • 安装nginx,并启动ngix
# 防止报错nginx包不存在
yum install epel-release
yum install nginx
service nginx start
  • 修改6.1节中的uwsgi.ini,添加socket端口
[uwsgi]
; 监听的端口,不配置nginx
; http = :8001

; 指定和nginx进行套接字通信的方式:端口或文件
socket = :8002
#---
# 其它配置不变
#---
  • 配置 uwsgi 和 Nginx 的连接,并重启nginx:service nginx restart
vim  /etc/nginx/nginx.conf
# 修改user为root
user root;

# 在server中添加如下配置
server {
    
    
    client_max_body_size 75M;
    location / {
    
    
        # 通过uwsgi转发请求
        include uwsgi_params;
        proxy_set_header $host:$PORT;
        # 转发的ip和端口
        uwsgi_pass  10.30.180.254:8002;
        # 即django的setting.py目录下的STATIC_ROOT地址
        root /opt/jlpost/post_process/src/jl_dist/dist;
   }
}
  • 启动项目
cd /opt/jlpost/post_process
uwsgi --ini uwsgi.ini
  • 报错,开放访问权限,成功
 /usr/sbin/setsebool httpd_can_network_connect=1

在这里插入图片描述

7. 项目部署(docker)

7.1 linux安装docker

yum install docker -y

设置自启动

systemctl start docker
systemctl enable docker

7.2 docker打包有ssh服务的centos镜像

一般情况下,linux操作系统的管理员通过SSH服务来管理操作系统,但是Docker的很多镜像都是不带SSH服务的,因此需要创建一个带有SSH服务的centos镜像

某些情况下,docker拉取镜像会报超时错误,处理方法:https://www.cnblogs.com/ws0316/p/12066454.html

  docker pull centos
  • 检查centos中是否存在ssh服务
# 启动centos镜像
docker run -it -d centos:latest /bin/bash
# 查看已启动的容器
docker ps
# 查找某个容器id,进入已启动的容器中
docker exec -it 86 /bin/bash

该容器并没有安装此服务

sshd

在这里插入图片描述

  • 创建镜像打包目录,创建Dockerfile,run.sh两个文件,并赋予run.sh执行权限
cd ssh_centos
touch Dockerfile run.sh
chmod +x run.sh
  • run.sh写入配置
#! /bin/bash
/usr/sbin/sshd -D
  • dockerfile写入配置文件
# 设置继承镜像
FROM centos:latest

# 开始运行命令
RUN yum install -y openssh-server
RUN yum install -y passwd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key
RUN echo "123456" | passwd --stdin root  # 系统密码,可自行更改
ADD run.sh /run.sh

EXPOSE 22

CMD ["/run.sh"]
  • 创建镜像
 docker build -t sshd:centos .

7.3 docker打包有python3服务的centos镜像

由于机器学习必备python3的一些环境,因此,制作一个python3的基础镜像

  • 创建镜像打包目录,创建Dockerfile
cd python3_centos
touch Dockerfile
  • dockerfile写入配置文件
# 指定操作的镜像
FROM sshd:centos

# 创建文件夹
RUN mkdir -p /opt/install

# 安装软件
# 安装centos的yum源
RUN yum install epel-release -y
RUN yum -y install wget
# 安装python 3.6
RUN yum install -y libffi-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make
# 存放安装包的路径
WORKDIR /opt/install
RUN wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz
# 解压
RUN tar -zxvf Python-3.6.8.tgz
WORKDIR Python-3.6.8
RUN ./configure
RUN make&&make install
  • 打包镜像
 docker build -t python3:centos .

7.4 基于python3:centos打包django镜像

  • 创建镜像打包目录,创建Dockerfile、web_run.sh,赋予web_run.sh执行权限
cd django_centos
touch Dockerfile
  • dockerfile写入配置文件
# 指定操作的镜像
FROM python3:centos
# 指定语言,防止中文日志乱码
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8
# 创建文件夹
# 项目存放路径
RUN mkdir -p /opt/JlPost/post_process	

# 拷贝文件
# django项目地址
COPY post_process /opt/JlPost/post_process

#这句指令相当与:cd django项目
WORKDIR /opt/JlPost/post_process

# 安装依赖包
RUN pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple

EXPOSE 8002
  • 使用当前目录的 Dockerfile 创建镜像,标签为 web:django
 docker build -t web:django .

7.5 docker打包nginx镜像

创建镜像打包目录,创建Dockerfile

 docker pull nginx
 cd django_nginx
 touch Dockerfile
  • dockerfile写入配置文件
# 指定操作的镜像
FROM docker.io/nginx

# 系统部署
RUN mkdir -p /opt/JlPost/static
  • 使用当前目录的 Dockerfile 创建镜像,标签为 web:nginx
docker build -t web:nginx .

在这里插入图片描述

  • 启动并访问nginx
# 80是nginx访问端口
docker run -d -p 80:80 --name nginx nginx

访问页面:ip,能够看到欢迎页面,表示nginx启动成功。
在这里插入图片描述

  • 配置nginx

首先在宿主机建立存放nginx日志、配置文件和相关静态资源的目录,并将其挂载到容器内对应路径

将nginx.conf文件cp到本地,可以看到该文件下引入了其它文件,同样也需要cp到宿主机,进入nginx查看文件名,并cp到本地

 docker cp nginx:/etc/nginx/nginx.conf /opt/jlpost/nginx/conf/nginx.conf
 docker cp nginx:/etc/nginx/conf.d/default.conf /opt/jlpost/nginx/conf.d/default.conf

在这里插入图片描述
在这里插入图片描述
nginx初始访问页面同样cp到本地

docker cp nginx:/usr/share/nginx/html/index.html /opt/jlpost/nginx/static/index.html
  • 删除初始的nginx容器

7.6 基于docker镜像启动django容器

docker run -it -d -p 8002:8002 --name web --rm web:django python3 manage.py runserver 0.0.0.0:8002

8002端口的服务启动后:在外部打开网页时,访问被拒绝,但是本地可以curl通过,尝试关闭防火墙,成功

curl -H "Content-Type: application/json" -X POST -d '{"DataType": "EDI" }' "http://0.0.0.0:8002/GetDailyRiskStatistic"
systemctl stop firewalld.service
# 永久关闭,否则重启后会再次启动
systemctl disable firewalld.service

7.7 基于docker镜像启动django容器–uwsgi

创建镜像打包目录,创建Dockerfile

 cd uwsgi_django
 touch Dockerfile
  • dockerfile写入配置文件
 # 指定操作的镜像
FROM web:django
# 指定语言,防止中文日志乱码
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8

ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1
# 创建文件夹
# 项目存放路径
RUN mkdir -p /opt/jlpost/post_process	

# 拷贝文件
# django项目地址
COPY post_process /opt/jlpost/post_process

#这句指令相当与:cd django项目
WORKDIR /opt/jlpost/post_process

EXPOSE 8001

CMD ["uwsgi","/opt/jlpost/post_process/uwsgi.ini"]

创建镜像

docker build -t uwsgi:django .

启动容器

docker run -it -d -p 8001:8001 --name web_uwsgi --rm uwsgi:django /bin/bash
# 进入容器,id根据实际情况修改
docker exec -it 9f /bin/bash
uwsgi uwsgi.ini

7.8 使用nginx代理django容器

将6.1节收集的静态资源挂载到nginx,采用如下命令启动nginx容器,报错,关闭setenforce,成功

docker run -d -p 443:443 -p 80:80 --name nginx -v /opt/jlpost/nginx/dist2:/usr/share/nginx/html -v /opt/jlpost/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/jlpost/nginx/log:/var/log/nginx -v /opt/jlpost/nginx/conf.d:/etc/nginx/conf.d -v /opt/jlpost/nginx/ssl:/ssl nginx

在这里插入图片描述

setenforce 0

配置nginx.conf文件,在http段中添加如下配置

server {
    
    
        listen       80;
        #server_name  localhost;
        location / {
    
    
    		proxy_pass  http://10.30.180.254:8002/;
    		#root /usr/share/nginx/html;
    		#index  index.html index.htm;
    		#try_files $uri /index.html;
    	}

        location /static/ {
    
    
            alias   /usr/share/nginx/html/static/;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
    
    
            root   html;
        }
    }

8 docker打包mysql

  • 下载mysql镜像
docker pull mysql:latest
  • 启动mysql容器
docker run -itd --name mysql-jlpost -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
  • 进入mysql
# 进入容器
docker exec -it 04 /bin/bash
# 进入mysql
mysql -h localhost -u root -p
# 开放远程连接权限
use mysql;
# 开放权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
#刷新权限
FLUSH PRIVILEGES;
  • 数据迁移:本机——>服务器——>挂载docker
# 从本机中迁出
mysqldump -u root -p jinling_post abnormal_result_2>/opt/jlpost/abnormal_result_2.sql
# 复制sql文件
scp /opt/jlpost/abnormal_result_new.sql 10.30.180.254:/opt/jlpost/mysql_data/
# 导入新服务器
use jinling_post;
source /opt/jlpost/mysql_data/abnormal_result_new.sql;

9 附录

9.1 删除docker镜像

删除创建失败的docker镜像:先停止容器,再删除容器,再删除镜像

# 查看docker内的所有容器
docker ps -a
# 停止并删除容器
docker stop <CONTAINER ID>
docker rm <CONTAINER ID>
# 删除镜像
docker rmi <IMAGE ID>
# 删除镜像的另一种命令
docker rmi <REPOSITORY>:<TAG>

9.2 docker镜像的导入导出

# 导出
docker save -o python3_centos.tar python3:centos
# 复制文件至新服务器,导入
docker load --input python3_centos.tar

猜你喜欢

转载自blog.csdn.net/shlhhy/article/details/115674057