文章目录
- 部署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
以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 ./
导出文件到当前路径,后续可继续添加所需要的库
运行项目容器
先跑出项目容器
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解决)
应该pvsite_uwsgi.ini中的IP配置有问题
查看docker容器的IP
docker inspect 99ef4b98f188(该容器ID)
容器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
加完之后继续运行
报错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试试
报错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后台成功了
在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
做完发现的一个比较完善的部署教程