ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)

文章目录

    • 部署Django后端接口
      • 下载Python环境及一些尝试
      • pip包管理
      • 运行项目容器
        • 报错1(查询容器IP解决)
        • 报错2(pvsite_uwsgi.ini文件配置socket还是http)
        • 报错3(用http先)
        • 用python manage.py runserver运行项目先
          • 报错4(下载cryptography库)
        • 回到用uwsgi+django运行成功先
        • 在uwsgi+django中加入nginx配置
    • 最终使用docker-compose双容器配置
      • 项目目录树
      • docker-compose.yml配置
      • 最终Django文件配置
        • requirements.txt文件配置
        • pvsite_uwsgi.ini文件配置
        • Django下的Dockerfile文件配置
      • 最终Vue文件配置
        • Vue下的Dockerfile文件配置
        • Vue下的nginx.conf文件配置
    • 其他笔记
    • 写在最后

部署Django后端接口

下载Python环境及一些尝试

由于项目用到是3.8.8版本,避免之后出现问题。就不下最新的了

docker pull python:3.8.8

ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第1张图片
以python镜像启动一个容器,参数以命令模式进入该容器:

docker run -it python /bin/bash

/bin/bash进入容器中的命令行,暂时我理解为进入之后用法和ubuntu中的终端一样。(毕竟一个容器相当于一个虚拟机[滑稽])
但是上面的命令的命令会默认运行最新的python版本,本地的旧版本都不行
运行指定版本镜像

docker run -it python:3.8.8 /bin/bash

请添加图片描述
后台运行
在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式,--name给容器起名

docker run -itd  --name pythonTest python:3.8.8 /bin/bash  

在这里插入图片描述
进入容器
exec 命令适用于进入后台运行的容器

docker exec -it 容器ID /bin/bash

可以直接进入容器中下载Django,执行如下命令,第一次不行,第二次就好了

pip install django

pip包管理

在本地下载pip管理工具(可以下载其他工具试试,这里用pipreqs)

pip install pipreqs

下载完执行命令

pipreqs  --encoding=utf8  ./

导出文件到当前路径,后续可继续添加所需要的库
ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第2张图片
ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第3张图片

运行项目容器

先跑出项目容器

docker run -it -d --name Djangotest -p 9001:9001 -v /home/andy/Web/Django:/home/andy/Web/Django python:3.8.8
#-v /home/test:/home/test是将/home/test是将主机上的该目录挂载到容器内的home目录下(当然也可以使用docker cp命令)

其他解释见第一节

-v         用于挂载容器目录路径,内外共享目录,用法:-v 宿主机路径:容器路径

进入容器

docker exec -it Djangotest bash

然后安装requirements.txt中的库,执行完再安装uwsgi

pip install -r /home/andy/Web/Django/requirements.txt
pip install uwsgi

uwsgi运行项目

uwsgi  --ini  /home/andy/Web/Django/pvsite_uwsgi.ini 
报错1(查询容器IP解决)

ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第4张图片
应该pvsite_uwsgi.ini中的IP配置有问题
查看docker容器的IP

docker inspect 99ef4b98f188(该容器ID)

ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第5张图片
容器IP就是172.17.0.5
修改pvsite_uwsgi.ini配置如下

[uwsgi]

#chdir=/home/andy/Documents/photovoltaic/photovoltaicsite   # 指定运行目录:项目根目录的绝对路径

# 指定sock的文件路径,可以用端口或sock文件(Nginx监听的端口)
socket = 172.17.0.5:9001
# stats子系统允许您将uWSGI的内部统计数据导出为JSON, 在指定的地址上,开启状态服务
#stats = 127.0.0.1:9999
#载入wsgi-file
wsgi-file = photovoltaicsite/wsgi.py

#允许主进程存在(enable master process)
master=true
#设置最大工作进程数:将会生成4个进程, 每个进程有2个线程
processes=4
threads = 2
#某个权限
chmod-socket = 666  
#退出时清除环境  
vacuum=true  

再次运行

报错2(pvsite_uwsgi.ini文件配置socket还是http)

invalid request block size:21573 (max 4896) …skip

看样子能访问,但是uwsgi内部解析的数据包只能最大4k。
看样子给pvsite_uwsgi.ini文件增加一条这个就行。(后续结合nginx应该不会出现这种问题)

#设置用于uwsgi包解析的内部缓存区大小到64k。默认是4k。
buffer-size = 65536

ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第6张图片
加完之后继续运行

报错3(用http先)
uwsgi_proto_uwsgi_parser(): Resource temporarily unavailable [proto/uwsgi.c line 40]

这个报错目前不清楚是为什么,在docker中测试了很久。我是按照这个地址192.168.80.128:9001去访问的。而这个地址和端口是Django+uwsgi容器运行直接映射的端口。
知道为什么了,人都傻了。自己在pvsite_uwsgi.ini配置的socket = 172.17.0.5:9001。我部署的是socket不是http怎么能用浏览器去访问到了。要在nginx中去监听这个socket才能访问啊。socket改成http就可以了。

用python manage.py runserver运行项目先

运行到现在其实还没配置好数据库(直觉告诉我先python manage.py runserver运行成功,这些问题迎刃而解),先用python manage.py runserver启动项目。配置好数据库吧。

Django项目在settings.py中先改成连接另外一个ubuntu里的mysql试试
ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第7张图片

报错4(下载cryptography库)

出现了之前一样的问题。确实个package。

bash RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods

按照下面下载之后就可以运行成功了。

 pip install cryptography
回到用uwsgi+django运行成功先

先收集Django后台的资源,运行如下命令,在当前路径下会生成static文件夹保存网页需要的静态资源。

python manage.py collectstatic

由于之前在Django中的settings配置过资源路径只需要pvsite_uwsgi.ini文件新增如下:

#加上读取静态资源路径(Django后台的css文件等,不然没样式)
static-map =/static=/home/andy/Web/Django/photovoltaicsite/static

访问Django后台成功了
ubuntu+Docker双容器docker-compose部署Django+Vue项目(2-Django)_第8张图片

在uwsgi+django中加入nginx配置

先将pvsite_uwsgi.ini配置的http= 172.17.0.5:9001。改成socket=容器IP:端口
加上-d后台运行uwsgi -d --ini /home/andy/Web/Django/pvsite_uwsgi.ini

然后运行nginx容器
这里我用的是-v挂载宿主机的目录和文件,所以有点长。(后面完善直接打包镜像用更好的方法) 。别忘了最后的nginx镜像

docker run -it -d --name Vuetest -p 8080:8080 -v /home/andy/Web/Vue/dist/:/usr/share/nginx/html/ -v /home/andy/Web/Vue/nginx.conf:/etc/nginx/nginx.conf  nginx

文件目录挂载

#-v /home/andy/Web/Vue/dist/:/usr/share/nginx/html/
#-v /home/andy/Web/Vue/nginx.conf:/etc/nginx/nginx.conf

这里已经要开启另外的nginx容器了。双容器运行的话要进行通信(像两个独立的虚拟机)。下面用到docker-compose

最终使用docker-compose双容器配置

项目目录树

/home/andy/web目录下的大致目录结构

Web:.
│  docker-compose.yml
├─Django
│  │  Dockerfile
│  │  uwsgi_params 
│  └─photovoltaicsite
│      │  manage.py
│      │  pvsite_uwsgi.ini
│      │  requirements.txt
│      ├─photovoltaiccalculation
│      │  │  admin.py
│      │  │  api.py
│      │  │  api_url.py
│      │  │  apps.py
│      │  │  models.py
│      │  │  modelToJson.py
│      │  │  tests.py
│      │  │  views.py
│      │  │  __init__.py
│      │  ├─migrations
│      │          
│      ├─photovoltaicsite
│      │  │  asgi.py
│      │  │  settings.py
│      │  │  urls.py
│      │  │  wsgi.py
│      │  │  __init__.py
│      │  └─__pycache__         
│      ├─static
│      │  ├─admin
│      │  │  ├─css            
│      │  │  ├─fonts    
│      │  │  ├─img          
│      │  │  └─js                 
│      │  └─rest_framework
│      │      ├─css      
│      │      ├─docs
│      │      │  ├─css    
│      │      │  ├─img  
│      │      │  └─js        
│      │      ├─fonts     
│      │      ├─img     
│      │      └─js
│      │              
│      └─upload
│          └─headImg
│                  20221027135148-4.png
│                  20221206021825-1.png
│                  
├─Mysql(这个项目我直接连接了另外一台虚拟机上的mysql)
└─Vue
    │  Dockerfile
    │  nginx.conf
    └─dist
        │  favicon.ico
        │  index.html  
        ├─css     
        ├─fonts     
        ├─img      
        └─js            

在windows下可以终端下用tree /f >tree.md生成目录树

docker-compose.yml配置

version: "3"

networks: # 自定义网络(默认桥接), 不使用links通信 
  #proxy:
    #ipam:
      #config:
      #- subnet: 172.16.0.0/24 #由于默认bridge桥接网络,重启容器后ip地址会改变.固定IP
  django_network:
    driver: bridge
  vue_nginx_network:
    driver: bridge

services:
  django:
    build: /home/andy/Web/Django # '.'代表当前目录
    #command: uwsgi  --ini  /home/andy/Web/Django/photovoltaicsite/pvsite_uwsgi.ini   # 容器启动后启动web服务器,执行多条指令用下面的
    command: bash -c 'python manage.py makemigrations&&python manage.py migrate&&uwsgi  --ini  /home/andy/Web/Django/photovoltaicsite/pvsite_uwsgi.ini'
    networks:
     - django_network
     #proxy:
      #ipv4_address: 172.17.0.5 #固定IP
    ports:       #暴露容器端口,与-p相同,但是端口不能低于60
      - "9090:9090"
    volumes:      #虚拟机挂载文件和目录到容器
      - /home/andy/Web/Django:/home/andy/Web/Django
    restart: always # always表容器运行发生错误时一直重启

  vue_nginx:
    build: /home/andy/Web/Vue
    ports:
      - "8080:8080"
      - "9001:9001"
    restart: always # always表容器运行发生错误时一直重启
    volumes:     #虚拟机挂载文件和目录到容器
      - /home/andy/Web/Vue/nginx.conf:/etc/nginx/nginx.conf
      - /home/andy/Web/Vue/dist/:/usr/share/nginx/html/
      - /home/andy/Web/Django:/home/andy/Web/Django
    networks:
      - vue_nginx_network
      - django_network #将vue_nginx_network加入到django的网络中
    depends_on: #此标签用于解决容器的依赖,启动先后问题。如启动应用容器,需要先启动数据库容器php:depends_on:- apache- mysql
      - django

最终Django文件配置

Django下的setttings.py配置就不展示了。网上其他教程容易搜到

requirements.txt文件配置
Django==4.1
djangorestframework==3.14.0
PyMySQL==1.0.2
django-cors-headers==3.13.0
uwsgi==2.0.21
cryptography==38.0.4
pvsite_uwsgi.ini文件配置
[uwsgi]

#chdir=/home/andy/Documents/photovoltaic/photovoltaicsite   # 指定运行目录:项目根目录的绝对路径

# 指定sock的文件路径,可以用端口或sock文件(Nginx监听的端口)
socket = 0.0.0.0:9090

# stats子系统允许您将uWSGI的内部统计数据导出为JSON, 在指定的地址上,开启状态服务
#stats = 127.0.0.1:9999
#载入wsgi-file
wsgi-file = photovoltaicsite/wsgi.py

#允许主进程存在(enable master process)
master=true
#设置最大工作进程数:将会生成4个进程, 每个进程有2个线程
processes=4
threads = 2
#某个权限
chmod-socket = 666  
#退出时清除环境  
vacuum=true  
#设置用于uwsgi包解析的内部缓存区大小到64k。默认是4k。
buffer-size = 65536
Django下的Dockerfile文件配置
# 建立  python:3.8.8 环境
FROM python:3.8.8
# 镜像作者andy
MAINTAINER andy
# 将项目文件拷贝到工作目录下(拷贝的主机内容,最好是相对路径)
COPY Django/ /home/andy/Web/Django
# 设置容器内工作目录
WORKDIR /home/andy/Web/Django/photovoltaicsite
# 在容器内安装django项目需要的库
RUN pip install -r /home/andy/Web/Django/photovoltaicsite/requirements.txt

最终Vue文件配置

dist文件是vue-cli中build项目得到的

Vue下的Dockerfile文件配置
# 设置基础镜像
FROM nginx
# 定义作者
MAINTAINER andy
# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY dist/  /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
#-v dist/  /usr/share/nginx/html/
#-v /home/andy/Web/Vue/nginx.conf:/etc/nginx/nginx.conf
Vue下的nginx.conf文件配置
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
}

http {
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	#	Vue configuration
	server {
	listen   8080;     #配置访问时的端口号
	server_name  192.168.80.129;
	charset     utf-8;
	client_max_body_size  75M;  #影响post文件的最大大小

	location / {          #配置web静态资源
		root /usr/share/nginx/html/;
		index index.html;
		add_header 'Access-Control-Allow-Origin' '*';
		}
	}

#	uWSGi configuration
	upstream django {
	    server 192.168.80.129:9090; # for a web port socket (we'll use this first)
	}
	server {
	listen   9001;     #配置访问时的端口号
	server_name  192.168.80.129;
	charset     utf-8;
	client_max_body_size  75M;  #影响post文件的最大大小
	
	location /upload {        #配置媒体资源文件
		expires 30d;
		autoindex  on;
		add_header Cache-Control private;
		alias /home/andy/Web/Django/photovoltaicsite/upload;
		}
	location /static {      #配置静态资源文件
		expires 30d;
		autoindex on;
		add_header Cache-Control private;
		#alias /home/andy/Documents/photovoltaic/photovoltaiccalculation;
		alias /home/andy/Web/Django/photovoltaicsite/static;
	}
	location / {          #配置uWSGI服务器
		include /etc/nginx/uwsgi_params;
		uwsgi_pass django;
		uwsgi_read_timeout 2;

	}
	}
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

请添加图片描述
最后能成功运行。

其他笔记

Linux中echo命令的功能是写内容到标准输出。

#echo hello world
hello world

给static文件夹及其子文件和子目录的所有权限(读写)给所有用户:(当前路径有static文件夹)

chmod -R 777 static

写在最后

由于初次使用Docker。这篇博客更像是个人的一个笔记(边做边记),可能写的不是很清晰。但是对ubuntu+Docker环境的部署还是会有一些参考价值。

在部署完后之后。对个人也有一些开发上的思考。比如在访问前端项目时,如果出现一些网络错误或是莫名其妙的短暂性的跨域(Django中已经设置过cors解决跨域了,不知道为什么会间歇性出现这个报错。但却不影响功能)导致访问不到资源,此时网站应该给出一个响应,类似返回一个自定义404页面或是500页面。

主要参考链接1
主要参考链接2
做完发现的一个比较完善的部署教程

你可能感兴趣的:(Django,Docker,django,ubuntu,docker)