最近,自己写了一些Django 的小应用,因一直在本机做测试及使用,未将其部署至服务器。然而当部署至公司服务器的时候,各种环境问题频出,如Python3没有安装加密模块及Sqlite版本太低等,因为是公司服务器无法找到比较干净的环境,故考虑使用Docker来部署。
查阅网上资料,各个概念就不在这一一做介绍,开始实战:
准备:请在Django的setting文件中将DEBUG设置为False(部署在正式环境,该项肯定要设为False。同事,如果在调试环境中设置为false,则会出现找不到static路径下资源的情况,如:加载不了css和js文件("Failed to load resource: the server responded with a status of 404 (Not Found)")。另外,设置 ALLOWED_HOSTS = ['*']
- 制作Docker Images
Dockerfile 如下:
FROM python:latest # 使用最新的python 镜像制作
LABEL author="Jerry"
RUN mkdir /code # 创建一个工作目录
ADD requirements.txt /code # Django项目中需要使用的模块,根据自己需要下载
WORKDIR /code
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt \
&& rm -f requirements.txt # 使用清华镜像源来下载所需的模块
EXPOSE 8000 # 暴露 8000 端口
requirment.txt 如下:
django
psycopg2
pymysql
uwsgi
docker
- 准备好配置文件及 Django 程序
uwsgi.ini 配置文件如下:
[uwsgi]
# Django程序所在目录,放在Dockerfile中创建的code目录中
chdir = /code/ziguan
# 使用socket 方式与Nginx 连接
socket = /code/uwsgi.sock
# 使用root 用户和组,注意:Nginx也需要设置启动用户为root,否则会权限错误
uid = root
gid = root
# Django's wsgi文件,一般是"项目名.wsgi:application"
module = ziguan.wsgi:application
# 启动主进程来管理其他进程,其他进程都是该进程的子进程
master = True
# 使用多少个进程
processes = 2
# 每个工作进程的最大请求数。当一个工作进程达到该值,将被重启
max-requests = 5000
# 指定pid所在路径
pidfile = /tmp/ziguan.pid
# 当服务器退出的时候自动删除socket和pid文件
vacuum = true
# 允许用内嵌的语言启动线程。允许app程序中产生一个子线程
enable-threads = true
# 一个请求花费的时间超过该值将被丢弃,并当重启处理这个请求的工作的进程
harakiri = 30
# 后台运行,并且记录日志的路径;注意:如果需要在前台运行 uwsgi 请注释该项
daemonize = /tmp/uwsgi.log
# 用户uwsgi包解析的内部缓存区大小为64k,默认为4k;大于64k的包会被拒绝
buffer-size = 65536
PS: uwsgi 也可先使用命令启动来检测程序是否正常: uwsgi --http :8000 --module ziguan.wsgi (使用http方式启动,后面是ziguan.wsgi 而不是usgi, 请注意!!!)
Nginx配置文件
# 注意:如果这边用户使用普通用户而uwsgi配置文件使用了root用户,将造成nginx无法访问uwsgi的socket
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_connect_timeout 30;
# 指定uwsgi socket的位置
uwsgi_pass unix:/usr/share/nginx/html/uwsgi.sock;
}
# 指定Django静态资源所在路径
location /static {
alias /usr/share/nginx/html/ziguan/static;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
- 使用Docker-Compose 部署 Nginx + Uwsgi
Docker-Compos 配置文件如下:
version: '3'
services:
uwsgi:
# 制作的镜像名称
image: uwsgi:v1
restart: always
networks:
django:
ipv4_address: 10.0.0.10
volumes:
# 将项目挂载的容器中(uwsgi.ini配置文件一起放在了项目中)
- /tmp/docker/django/ziguan:/code
# 使用命令启动uwsgi
command: uwsgi --ini uwsgi.ini
web:
image: nginx
restart: always
depends_on:
- uwsgi
ports:
# 将服务器端口与nginx端口做映射
- "3333:80"
networks:
django:
ipv4_address: 10.0.0.11
volumes:
# 挂载配置文件,并将项目也挂载到nginx相关目录下
- /tmp/docker/django/nginx.conf:/etc/nginx/nginx.conf
- /tmp/docker/django/ziguan:/usr/share/nginx/html
# 创建一个网络,让两个docker互通
networks:
django:
ipam:
config:
- subnet: 10.0.0.0/24
额外的补充:
当我在K8s部署该环境是,发现两个Nginx的Pod不能同时共享uwsgi创建的socket文件(部署环境为一个独立的uwgi的Pod 和一个独立的nginx的Pod),否则会出错(一个可以正常访问,另一个访问404的问题);可以将uwsgi 和 nginx部署至同一个Pod中,再使用Ingress + svc 进行负载均衡。
参考:
https://blog.csdn.net/midion9/article/details/51354774
https://blog.csdn.net/Miss_Audrey/article/details/81874038
网友评论