Django uwsgi nginx https 部署云端

正文

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 Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-02-17 08:40:58 UTC; 1min 6s ago
 Main PID: 8106 (mysqld)
    Tasks: 28 (limit: 4915)
   CGroup: /system.slice/mysql.service
           └─8106 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid

Feb 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.txt

use 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部署生产环境

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值