当前位置: 代码迷 >> 综合 >> Django uwsgi nginx https 部署云端
  详细解决方案

Django uwsgi nginx https 部署云端

热度:23   发布时间:2023-11-22 11:12:44.0

文章目录

  • 正文
    • 1.创建虚拟机
    • 2.安装python:
    • 3.创建虚拟环境:
      • I.创建目录用来存放虚拟环境
      • II.在~/.bashrc中添加行:
      • III.运行:
      • IV.终于可以创建虚拟环境了,这里又有一个坑,要指定python版本:
    • 4.安装必要包并测试环境
      • I.安装 Django, pymysql
      • II. 安装Mysql
      • III.配置远程访问
      • IV.新建数据库和用户
        • 补充命令
      • V.创建样本项目并将目录更改为项目文件夹
      • VI. 迁移或引导您的数据库。
      • VII. 创建超级用户以访问管理面板。
      • VIII.在setting中添加IP
      • IX.测试项目与环境
      • X.上传项目并测试
      • XI.配置静态文件
    • 5.uWSGI安装与设置
      • I.安装uwsgi
      • II.配置uwsgi
    • 6.安装配置nginx
      • I.安装nginx
      • II.配置nginx
    • 7.创建域名
    • 8.添加ssl证书
    • 9.维护注意事项
      • 数据库更改
        • 暴力更改
        • 2
      • 数据库备份
      • Mysql 数据库迁移
        • 删除 5.x 安装 8.0
        • 从 8.x 版本向 5.x 版本迁移
    • 维护修复
      • 1038, 'Out of sort memory, consider increasing server sort buffer size'
      • 1022, "Can't write; duplicate key in table
  • References:

正文

1.创建虚拟机

注意选择新版的ubuntu,若为旧版会发现apt-get 或者其他命令各种安装或升级失败。原因为下载链接库过时。

2.安装python:

一般来说ubuntu都自带了python2 和3,默认为2,可以设置默认python为python3:

sudo rm -rf /usr/bin/python
sudo ln -s /usr/bin/python3  /usr/bin/python

3.创建虚拟环境:

这里又有一个坑,如果使用的账户是非root账户,请酌情使用 pip install xxx --user 确保module安装位置。

sudo apt-get update
sudo apt install python3-pip
sudo pip3 install virtualenv
sudo pip3 install virtualenvwrapper

上述工具装好后找不到mkvirtualenv命令,需要执行以下环境变量设置。

I.创建目录用来存放虚拟环境

mkdir $HOME/.virtualenvs

II.在~/.bashrc中添加行:

sudo apt-get  install vim
vim ~/.bashrc
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

III.运行:

source ~/.bashrc

如果出现错误,可能会有各种路径文件不存在,因此,用

sudo find / -name xxxx.xx

xxxx.xx表示文件名
查找缺失文件的具体路径,然后回到bashrc中修改,但是我这里出现一个奇葩错误,说

-bash: /usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh: No such file or directory

所以我自己跑到/usr/share/ 下新建了一个文件夹,然后又查找到virtualenvwrapper_lazy.sh的具体路径,然后用一个link连起来。

sudo ln -s /usr/local/bin/virtualenvwrapper_lazy.sh /usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh

然后执行source命令,成功了。

IV.终于可以创建虚拟环境了,这里又有一个坑,要指定python版本:

mkvirtualenv --python=python3.6 venvname # venvname 虚拟环境名称
#启用虚拟环境
workon [虚拟环境名称]

退出虚拟环境 离开

deactivate

删除(慎用)

rmvirtualenv [虚拟环境名称]

4.安装必要包并测试环境

I.安装 Django, pymysql

pip3 install Django
pip3 install pymysql
sudo apt install python-django-common

II. 安装Mysql

sudo apt-get install mysql-server

配置mysql,一些基本设置。

sudo mysql_secure_installation

如果出现其他各种奇葩错误,比如最后运行mysql的时候找不到sock文件,我这里怀疑是我之前装过一个另外的sql然后删除后又装mysql,产生的问题,于是经过一天的实践摸索,直接tmd rebuild机器重新来一遍,完美解决问题。

如下:

New password: Re-enter new password: 
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.Remove anonymous users? (Press y|Y for Yes, any other key for No) : no... skipping.Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.Disallow root login remotely? (Press y|Y for Yes, any other key for No) : no... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.Remove test database and access to it? (Press y|Y for Yes, any other key for No) : no... skipping.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.All done! 

检查mysql服务状态

systemctl status mysql.service

显示如下结果说明mysql服务是正常的:

● mysql.service - MySQL Community ServerLoaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)Active: active (running) since Mon 2020-02-17 08:40:58 UTC; 1min 6s agoMain PID: 8106 (mysqld)Tasks: 28 (limit: 4915)CGroup: /system.slice/mysql.service└─8106 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pidFeb 17 08:40:57 dds systemd[1]: Starting MySQL Community Server...
Feb 17 08:40:58 dds systemd[1]: Started MySQL Community Server.

III.配置远程访问

在Ubuntu下MySQL缺省是只允许本地访问的,使用workbench连接工具是连不上的;
如果你要其他机器也能够访问的话,需要进行配置;

首先安装 net-tools 用于检测端口
sudo apt install net-tools

检测3306 MySql监听端口情况:
netstat -an | grep 3306

显示:
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN

从上面可以看出,MySql的3306端口只是监听本地连接127.0.0.1。我们做下修改,使其对外其他地址开放。

打开/etc/mysql/mysql.conf.d/mysqld.cnf文件
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

把bind-address = 127.0.0.1注释掉
在这里插入图片描述
重启MySql服务
sudo /etc/init.d/mysql restart

用根用户进入MySql 设置账户

sudo mysql -uroot -p

登入root进行其他设置:

GRANT ALL PRIVILEGES ON *.* TO root@localhost IDENTIFIED BY "123456";

上面是简写命令,有些俺不能不支持请按照以下方法写:

CREATE USER 'ohdear_ci'@'localhost' IDENTIFIED BY 'ohdear_secret';
GRANT ALL ON ohdear_ci.* TO 'ohdear_ci'@'localhost';

其中root@localhos,localhost就是本地访问,配置成%就是所有主机都可连接;

第二个’123456’为你给新增权限用户设置的密码,%代表所有主机,也可以是具体的ip;

这里还是不要用root作为远程操作用户了,为了安全性,所以新建数据库和用户;

最后别忘了设置Django 中的 settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'table name, 'USER': 'xxxxx', 'PASSWORD': 'xxx', 'HOST': 'xx.xx.xx.xx', 'PORT': '3306', } }

IV.新建数据库和用户

用root用户新建数据和用作远程访问的用户
显示数据库

show databases;

创建数据库dds

CREATE DATABASE DDS;

创建用户admin(密码654321) 并允许admin用户可以从任意机器上登入mysql的dds数据库

GRANT ALL PRIVILEGES ON dds.* TO admin@"%" IDENTIFIED BY "654321"; 

上面的dds.*如果改成*.*则表示所有的数据库都可以访问

补充命令

删除数据库

drop database name;

进入数据库mysql

use mysql;

查看user:

select * from user;

删除user

drop user name@'%'
drop user name@localhost

刷新权限

flush privileges;

记住别忘了Django settings.py 中的更改:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'xxx', 'USER': 'xxxxx', 'PASSWORD': 'xxxxxxx', 'HOST': 'xxx.xxx.xxx.xxx', 'PORT': '3306', } }

V.创建样本项目并将目录更改为项目文件夹

django-admin startproject TestWeb
cd TestWeb

VI. 迁移或引导您的数据库。

python manage.py makemigrations
python manage.py migrate

VII. 创建超级用户以访问管理面板。

python manage.py createsuperuser

VIII.在setting中添加IP

在您的项目settings.py文件中,设置ALLOWED_HOSTS如下:

ALLOWED_HOSTS = ['your ip', 'localhost', '127.0.0.1', ]

或者也可以直接改成:

ALLOWED_HOSTS = ['*', ]

IX.测试项目与环境

python manage.py runserver 0.0.0.0:8000

如果端口被占用 则:

sudo fuser -k 8000/tcp

如果不成功,请务必检查云端机器的防火墙规则是否将端口屏蔽
可以在另一台机器上使用Telnet命令检测端口是否打开

telnet ip_address port

最后浏览器访问ip后出现Succefully页面表示完成:
在这里插入图片描述

X.上传项目并测试

因为我是放在github上所以先安装git命令:

sudo apt-get install git

然后将项目git clone:

git clone xxx.xxx.xx

在运行前,首先调配好数据库,该迁移的迁移,想远程调试的调试,导入的导入。然后项目所必须的安装依赖库。所有的准备工作做完后尝试运行:

python manage.py runserver 0.0.0.0:8000

成功:
在这里插入图片描述

XI.配置静态文件

由于nginx无法识别Django中的静态文件,所以我们需要做一个步骤把静态文件都集结起来,放在一个文件夹,让nginx知道去哪里找。这里我的建议是最好不要和原来的static重复吧,弄一个static_all 啥的 清晰一点。

python manage.py collectstatic

注意要求你已经在settings.py中设置了static_root。

遇到问题:permission deny 无法收集:
暂时还没解决但是针对小项目我直接在本地把static打包好 upload上服务器代替。

unzip -d dir zip_file

5.uWSGI安装与设置

I.安装uwsgi

pip3 install uwsgi

II.配置uwsgi

首先进入项目目录然后测试

uwsgi --http 0.0.0.0:8080 --file ./DDS/wsgi.py

file表示关联,相当于一个接口,直接就可以接入Django项目。
尝试从浏览器访问,访问成功。

在生产环境中一般都是通过配置文件启动,所以接下来我们配置init文件。
现在项目文件外创建一个新文件夹Script来存放我们的配置文件:

mkdir Script

然后新建编辑uwsgi.ini:

vim uwsgi.ini

输入如下内容:

[uwsgi]
#项目目录
#Project Directory
chdir=/home/xxx/DDS-Agile1/DDS#启动uwsgi的用户名和用户组
#username and usergroup used to launch uwsgi
uid=root
gid=root#指定项目的application
#application for project
module=DDS.wsgi:application#指定sock文件路径
#path for sock file
socket=/home/xxx/DDS-Agile1/Script/uwsgi.sock#启用主程序
#Enable main process
master=true#进程个数
#Number of process
workers=5
pidfile=/home/xxx/DDS-Agile1/Script/uwsgi.pid#服务停止时自动移除unix Socket和pid文件
#Automatically remove unix socket and pid files when service stop
vacuum=true#如果可以,序列化接受的内容
#If possible, serialize the received content
thunder-lock=true#启用线程
#Enable Thread
enable-threads=true#设置自中断时间
#Slef-interrupt time
harakiri=30#设置缓冲
#Buffer size
post-buffering=4096#日志目录
#Log Directory
daemonize=/home/xxx/DDS-Agile1/Script/uwsgi.log

测试:

uwsgi --ini uwsgi.ini

返回如下:

[uWSGI] getting INI configuration from uwsgi.ini

查看Scripe下是否有pid 和sock文件:
在这里插入图片描述
如果缺少了什么文件或发生了什么错误,直接去看uwsig.log里面的内容,看看发生了什么错误,是不是配置文件写错了。

这里的坑就是出错了是不会报错的,所以最好还是启动后去看log是否启动成功。

查看进程:

ps -ef | grep -i uwsgi

停止uwsgi:

uwsgi --stop uwsgi.pid

6.安装配置nginx

I.安装nginx

sudo apt install nginx

II.配置nginx

进入设置目录

cd /etc/nginx/conf.d

创建配置文件,文件名随意

sudo vim DDS.conf

输入:
这里注意一个大坑啊,一定要配置media和static文件的路径,否则你把debug=False 后服务器就无法访问这些文件了。坑死我了。

server {listen 8080;server_name 0.0.0.0;access_log /var/log/nginx/access.log;charset utf-8;gzip on;gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json image/jpeg image/gif image/png application/octet-stream;error_page 404 /404.html;error_page 500 502 503 504 /50x.html;#指定uwsgi目录location / {include uwsgi_params;uwsgi_connect_timeout 30;uwsgi_pass unix:/home/xxx/DDS-Agile1/Script/uwsgi.sock;}#指定静态文件路径location /static/ {alias /home/xxx/DDS-Agile1/DDS/static_all/;}#指定media文件路径location /media/ {alias /home/xxx/DDS-Agile1/DDS/media/;}
}

启动,如果非root用户不加sudo则要求输入密码验证:

sudo /etc/init.d/nginx start

万能debug命令,感谢救了我一命
sudo nginx -t

尝试访问,我成功了!眼泪都要出来了。。。。

确认浏览从nginx走的:

tail -f /var/log/nginx/access.log

重启Nginx服务

systemctl restart nginx.service

重新载入配置文件当有系统配置文件有修改,用此命令,建议不要停止再重启,以防报错!

nginx -s reload

停止nginx:

nginx -s quit

立即停止服务这种方法比较强硬,无论进程是否在工作,都直接停止进程。

nginx -s stop

systemctl 停止systemctl属于Linux命令

sudo systemctl stop nginx.service

killall 方法杀死进程直接杀死进程,在上面无效的情况下使用,态度强硬,简单粗暴!

killall nginx

这里的坑也会有,最好的解决方法就是去看nginx log日志或者是err日志。

7.创建域名

Freenom创建域名教程
重点是有了域名之后,先在官网设置DNS指向我们的服务器ip,可能需要等一段时间。
可以用这个 网站 查看DNS分配进度
然后更改nginx 之前的配置文件,将server_name 改为我们的域名地址。

8.添加ssl证书

本来以为会很麻烦,结果妈呀好简单照着步骤输几个命令搞定:
letsencrypt官网
步骤

9.维护注意事项

数据库更改

暴力更改

如果更改数据库结构等,这里采用非常暴力的方法。
更改完model文件后,先删除数据库。
然后删除每个app下的cache 和 migrations文件。

接着用代码重建每个app的migrations文件夹:

python manage.py makemigrations --empty app_name

然后开始重建:

python manage.py makemigrations
python manage.py migrate

接着还要重新创建超级用户,mysql里面的用户等等。还挺麻烦的。

2

最近我直接对migration folder 里的 文件进行删除,这个还是要根据数据库来删除,而且删除了之后还要确保创建时不会和现有数据库冲突,要把数据库相应的table也删掉。这个比第一种稍微简单点。不过还是超级麻烦。
好在随着我慢慢熟练,只有极少数极端情况需要这样操作,其他修改都能通过Django 自动修改。

数据库备份

ubuntu server如何查看crontab定时任务日志
crontab 定时任务

Mysql 数据库迁移

删除 5.x 安装 8.0

不太懂,反正我全来了一遍。

sudo apt-get autoremove --purge mysql-server
sudo apt-get remove mysql-common?
sudo apt-get remove --purge mysql*
sudo apt-get autoremove
sudo apt-get autoclean

安装
先去 官网 查看一下 8.0 config 最新版,然后下载下来,现在最新版是0.8.18

wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.18-1_all.deb

运行一下, 就选你想要的8.0,你会发现一直按回车会循环,这个时候选那个ok就行了:

sudo dpkg -i mysql-apt-config_0.8.18-1_all.deb

继续安装,第二个命令检查下有没有8.0的链接:

sudo apt-get update
sudo apt-cache policy mysql-server

继续:

sudo apt-get install mysql-server
sudo mysql_secure_installation

从 8.x 版本向 5.x 版本迁移

首先导出数据库:

mysqldump -uroot -p --databases db1 > mysqldump.sql

然后替换如下字符串:

utf8mb4_0900_ai_ci 替换为 utf8_general_ci
utf8_croatian_ci替换为utf8_general_ci
utf8mb4_general_ci替换为utf8_general_ci
utf8mb4 替换为 utf8

我这里替换后有一个坑,有两个东西被连在一起了,把他们分开:

然后导入:

use db;
source xxx.sql;

如果数据库数据量大就需要取消输出:

mysql --user=myusername --password=mypassword --silent --force -b 2> error.txtuse db;
source xxx.sql;

维护修复

1038, ‘Out of sort memory, consider increasing server sort buffer size’

mysql -u root -p
show variables like '%sort_buffer_size%'; 
SET GLOBAL sort_buffer_size = 1024*1024*1024;

https://www.cnblogs.com/Coder-Photographer/p/12949062.html

1022, "Can’t write; duplicate key in table

出现背景:在一个表中新增外键字段,指向File表。
这个问题,在我这里是一个bug,因为在最新版Django 和 mysql下没有出现问题,推测是由于mysql版本过低的bug导致。造成的原因是File 下有一个数据 的 ID 就叫beep_audio, 然后我新增的字段也叫beep_audio, 他就以为我的主键重复了,应该是bug,我改了字段名字就好了。

References:

Nginx+uWSGI+Django部署生产环境

  相关解决方案