C panel面板这个比较古老了,国外VPS厂商用的多。多数是英文版,并且操作起来不太符合国人操作习气。
BT面板是国产的,原生支持中文,官网先容“提升运维效率的做事器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项做事器管理功能。”还有他是免费的,收费功能针对技能支持等业务。
以是直接用bt面板来建网站和管理网站了。

bt面板官方网站
[bt面板官网] (https://www.bt.cn/?invite_code=MV9lcWR5emw=)。安装bt面板之后,注册账号,网站后台可以跟微信绑定,方便网站管理等。
详细安装过程可以查看 [阿里云做事器快速建网站_安装BT宝塔面板和wordpress] (https://zhuanlan.zhihu.com/p/137713506)
作为新手来说,免费版bt可知足大部分网站管理需求——网站搭建、运维监控、掩护、备份数据库、备份网站、内存清理等等。
关于面板和原生Linux争议有人说面板的涌现,“切实其实是开历史倒车,把Linux的B格大大降落,一点都没有极客风,面板小白都可以操作”,因此对面板切齿腐心。对此我就呵呵了。 当代社会节奏那么快,不是那么多人有大把韶光能沉下心思来把Linux系统从头到家系统学习一遍的。还怀念以前读书时候,还专门花上几个月来把Linux的系统学习。像《鸟哥的 Linux 私房菜-根本篇·第三版》、《The Linux Command Line》(William E. Shotts Jr)、《深入理解 Linux 内核》( Daniel P.Bovet / Marco Cesati)。 以前年轻时候,也不怎么做条记,都是背命令。但是尴尬的地方在于,等到年纪大了,创造以前的命令记得不太多了,毕竟老话说得好“好记性不如烂笔头”。其余不是专门干Linux运维,如果不怎么用,这些命令很快就会遗漏。对这个没体会的,可以试试会议一下以前你的小学同学、中学同学,还能记起几个人名字?自然就有体会了。
算了,不叨叨那么多了。
当然也可以学习一下bt面板的脚本,学习为自己所用嘛,这便是这篇文章的由来。
以是,面板的涌现,还是降落了不幼年白上手Linux门槛的,以是面板的历史很早就涌现了。而且正由于bt面板符合国人习气,并且是免费的,集成了一大堆网站掩护工具,其余还有专门的收费类做事办理个人和企业难题,bt面板从2014年开始到现在那么盛行。
对了,在利用bt面板之前得要有个云做事器吧。这里推举阿里云的云做事器(Elastic Compute Service,简称ECS)。根据其官网先容是阿里云供应的性能卓越、稳定可靠、弹性扩展的IaaS(Infrastructure as a Service)级别云打算做事。
ECS即类似于国外的VPS。(不要好奇那么多人买国外VPS干嘛用)。架设个人博客网站、企业门户都可以利用ECS。如果其网站如个人博客紧张面向海内用户访问,为加快速率还是建议选用海内的做事器商。
[阿里云域名] (https://wanwang.aliyun.com/domain/com/?userCode=yos4xyvp)连接,
[阿里云做事器ECS] (https://www.aliyun.com/minisite/goods?userCode=yos4xyvp) 链接
为什么选择阿里云以前域名注册一样平常选老牌域名做事商,个中万网已经被阿里收购到旗下了。供应域名备案做事。备案业务还是很知心的。提交完备案信息之后,第二天阿里云小姐姐会帮你免费形式审查一下,还会主动打电话过来帮助校正。如果是自己动手提交备案信息给ICP备案机构,万一由于低级缺点被驳回就摧残浪费蹂躏了十天旁边韶光。域名ICP备案须要做事器,阿里云也供应做事器购买,一条龙做事嘛。做事器在阿里云毕竟做事器才是支出大头,域名什么的都是小意思了。而且购买完做事器之后,还会有客服主动打电话过来讯问利用情形,需不须要技能支持,还是挺不错的。阿里云做事器购买新用户有优惠,最根本的话一年下来不超过100元。如果是本科生的话免费利用的。备案完成之前,做事器不算租赁韶光。比如说3月1日我购买了一年的做事器,域名提交备案。18日域名备案审核通过。做事器租赁韶光重新按18日算起,即可以用到第二年3月18日。相称于免费多用几天。占了一点小便宜。bt面板脚本它的脚本有以下:
开释内存日志分割备份网站一、开释内存#!/bin/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHendDate=`date +"%Y-%m-%d %H:%M:%S"`log="开释内存!"echo "★[$endDate] $log"echo '----------------------------------------------------------------------------'for phpV in 52 53 54 56 70 71 72do if [ -f /etc/init.d/php-fpm-${phpV} ];then /etc/init.d/php-fpm-${phpV} reload fidoneif [ -f "/etc/init.d/mysqld" ];then /etc/init.d/mysqld reloadfiif [ -f "/etc/init.d/nginx" ];then /etc/init.d/nginx reloadfiif [ -f "/etc/init.d/httpd" ];then /etc/init.d/httpd gracefulfi# httpd重新加载if [ -f "/etc/init.d/pure-ftpd" ];then pkill -9 pure-ftpd sleep 0.3 /etc/init.d/pure-ftpd start 2>/dev/nullfi# pkill -9 接进程名,杀去世进程。# 2>/dev/null的意思便是将标准缺点stderr删掉。sync# sync 逼迫把文件系统buff写入磁盘,确保文件系统完全性。sleep 2syncecho 3 > /proc/sys/vm/drop_caches# 开释内存之前须要实行sync命令。sync 逼迫把文件系统buff写入磁盘,确保文件系统完全性。# /proc是一个虚拟文件系统。# 调度/proc/sys/vm/drop_caches来开释内存。# 其默认值为0,值为1时表示可以开释pagecache缓存,值为2时可以开释pagecache和inode缓存,值为3时可以开释pagecache(页面缓存,磁盘块的任何内存映射)), dentries(目录的数据构造)和inodes(文件的数据构造)缓存。# echo 3 > /proc/sys/vm/drop_caches,即调度其数值为3来开释内存(包括页面缓存、目录数据构造、文件数据构造等)。echo '----------------------------------------------------------------------------'#exit 0
CentOS 6.x 以前的版本中,系统的做事 (services) 启动的接口是在/etc/init.d/ 这个目录下,目录下的所有文件都是 scripts。
虽然/etc/init.d/ 这个脚本启动的办法 (systemV) 已经被新一代的 systemd 所取代 (从 CentOS 7 开始), 但是很多的个别做事在管理他们的做事启动方面,还是利用 shell script 的机制。
下面有nginx(nginx发音:恩静埃克斯 = Engine X)、mysqld、php-fpm-72等文件。
日期显示
endDate=`date +"%Y-%m-%d %H:%M:%S"`
把稳bash脚本赋值中,变量后紧跟即是号,即是号之后不能有空格,否则会报错。由于shell会误以为变量是命令,而不是赋值。单引号是全引用,被单引号括起的内容不管是常量还是变量都不会发生更换;双引号会更换表达式内变量。`反引号括起来的字符串被shell阐明为命令行,在实行时,shell首先实行该命令行,并以它的标准输出结果取代全体反引号(包括两个反引号)部分。如date +"%Y-%m-%d %H:%M:%S"便是把这条命令的结果赋给变量endDATE。date +"%Y-%m-%d %H:%M:%S"能显示 2019-12-12 15:32:59
mysqld重新加载
if [ -f "/etc/init.d/mysqld" ];then /etc/init.d/mysqld reloadfi
通过reload命令,将其清理内存。
reload (重新加载),reload会重新加载配置文件,做事不会中断。而且reload时会测试conf语法等,如果出错会rollback用上一次精确配置文件保持正常运行。也叫平滑重启,不会对已经连接的做事造成影响。
httpd重新加载
if [ -f "/etc/init.d/httpd" ];then /etc/init.d/httpd gracefulfi
要在重启 Apache 做事器时不中断当前的连接,则应运行:/usr/local/sbin/apachectl graceful
ftpd重新加载
if [ -f "/etc/init.d/pure-ftpd" ];then pkill -9 pure-ftpd sleep 0.3 /etc/init.d/pure-ftpd start 2>/dev/nullfi
pkill -9 接进程名,杀去世进程。
就寝0.3秒后,重新启动ftpd,并且2>/dev/null的意思便是将标准缺点stderr删掉。
开释内存
syncecho 3 > /proc/sys/vm/drop_caches
开释内存之前须要实行sync命令。sync 逼迫把文件系统buff写入磁盘,确保文件系统完全性。/proc是一个虚拟文件系统,一样平常可以通过调度/proc/sys/vm/drop_caches来开释内存。 drop_caches其默认值为0,值为1时表示可以开释pagecache缓存(页面缓存,磁盘块对应的内存映射),值为2时可以开释pagecache和inode缓存(文件的数据构造),值为3时可以开释pagecache, dentries(目录的数据构造)和inodes缓存。 echo 3 > /proc/sys/vm/drop_caches,即调度其数值为3来开释内存。
#!/usr/bin/python#coding: utf-8import sysimport osimport shutilimport timeimport globprint '=================================================================='print '★['+time.strftime("%Y/%m/%d %H:%M:%S")+'],切割日志'print '=================================================================='print '|--当前保留最新的['+sys.argv[2]+']份'logsPath = '/www/wwwlogs/'oldFileName = logsPath+sys.argv[1]if not os.path.exists(oldFileName): print '|---'+sys.argv[1]+'文件不存在!' exit()logs=sorted(glob.glob(oldFileName+"_"))count=len(logs)num=count - int(sys.argv[2])for i in range(count): if i>num: break; os.remove(logs[i]) print '|---多余日志['+logs[i]+']已删除!'newFileName=oldFileName+'_'+time.strftime("%Y-%m-%d_%H%M%S")+'.log'# time.strftime("%Y/%m/%d %H:%M:%S")天生为 '2019-12-12_200605'shutil.move(oldFileName,newFileName)if os.path.exists('/www/server/nginx/logs/nginx.pid'): os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");# cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。由于nginx启动会在该路径下天生nginx.pid文件。# `反引号括起来的字符串被shell阐明为命令行,在实行时,shell首先实行该命令行,并以它的标准输出结果取代全体反引号(包括两个反引号)部分。# kill -USR1 中,旗子暗记量USR1代表重新打开文件。其在core/ngx_config.h中定义 #if (NGX_LINUXTHREADS) #define NGX_REOPEN_SIGNAL INFO #define NGX_CHANGEBIN_SIGNAL XCPU #else #define NGX_REOPEN_SIGNAL USR1 #define NGX_CHANGEBIN_SIGNAL USR2 #endifelse: os.system('/etc/init.d/httpd reload');print '|---已切割日志到:'+newFileName
这个脚本里面核心部分是
if os.path.exists('/www/server/nginx/logs/nginx.pid'): os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");
cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。由于nginx启动会在该路径下天生nginx.pid文件。 `反引号括起来的字符串被shell阐明为命令行,在实行时,shell首先实行该命令行,并以它的标准输出结果取代全体反引号(包括两个反引号)部分。
kill -USR1 中,旗子暗记量USR1代表重新打开文件。其在core/ngx_config.h中定义
#if (NGX_LINUXTHREADS)#define NGX_REOPEN_SIGNAL INFO#define NGX_CHANGEBIN_SIGNAL XCPU#else#define NGX_REOPEN_SIGNAL USR1#define NGX_CHANGEBIN_SIGNAL USR2#endif
通过Python运行/www/server/panel/script/目录下的backup.py脚本,将网站www.xxx.com保存。保存备份数为3。
#!/bin/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHpython /www/server/panel/script/backup.py site www.xxx.com 3
其调用的backup.py文件如下
#!/usr/bin/python#coding: utf-8#-----------------------------# 宝塔Linux面板网站备份工具#-----------------------------import sys,osreload(sys)sys.setdefaultencoding('utf-8')#Python2.x中由于str和byte之间没有明显差异,常常要依赖于defaultencoding来做转换。 # 在python3中有了明确的str和byte类型差异,从一种类型转换成另一种类型要显式指定encoding。# 但是仍旧可以利用这个方法代替 # import importlib,sys # importlib.reload(sys)os.chdir('/www/server/panel');sys.path.append("class/")# /www/server/panel/class 里有大量的模块文件,public.py, db.py。# 通过改变路径方便下面导入模块。import public,db,time# 是class文件夹的模块文件class backupTools: def backupSite(self,name,count): sql = db.Sql(); path = sql.table('sites').where('name=?',(name,)).getField('path'); #sql.table(self,table)设置表名 #def where(self,where,param): # self.__OPT_WHERE = " WHERE " + where # self.__OPT_PARAM = param # WHERE name=? #getField(self,keyName):#取回指定字段 #result = self.field(keyName).select(); startTime = time.time(); if not path: endDate = time.strftime('%Y/%m/%d %X',time.localtime()) #'2019/12/12 20:41:01' # %Y 年份2019 %m 月份 %d天 %X 标准的韶光串 log = "网站["+name+"]不存在!" print "★["+endDate+"] "+log print "----------------------------------------------------------------------------" return; backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/site'; if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path); filename= backup_path + "/Web_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.tar.gz' public.ExecShell("cd " + os.path.dirname(path) + " && tar zcvf '" + filename + "' '" + os.path.basename(path) + "' > /dev/null") endDate = time.strftime('%Y/%m/%d %X',time.localtime()) if not os.path.exists(filename): log = "网站["+name+"]备份失落败!" print "★["+endDate+"] "+log print "----------------------------------------------------------------------------" return; outTime = time.time() - startTime pid = sql.table('sites').where('name=?',(name,)).getField('id'); sql.table('backup').add('type,name,pid,filename,addtime,size',('0',os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename))) log = "网站["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒"; public.WriteLog('操持任务',log) print "★["+endDate+"] " + log print "|---保留最新的["+count+"]份备份" print "|---文件名:"+filename #清理多余备份 backups = sql.table('backup').where('type=? and pid=?',('0',pid)).field('id,filename').select(); num = len(backups) - int(count) if num > 0: for backup in backups: public.ExecShell("rm -f " + backup['filename']); sql.table('backup').where('id=?',(backup['id'],)).delete(); num -= 1; print "|---已清理过期备份文件:" + backup['filename'] if num < 1: break; def backupDatabase(self,name,count): sql = db.Sql(); path = sql.table('databases').where('name=?',(name,)).getField('path'); startTime = time.time(); if not path: endDate = time.strftime('%Y/%m/%d %X',time.localtime()) log = "数据库["+name+"]不存在!" print "★["+endDate+"] "+log print "----------------------------------------------------------------------------" return; backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/database'; if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path); filename = backup_path + "/Db_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime())+".sql.gz" import re mysql_root = sql.table('config').where("id=?",(1,)).getField('mysql_root') mycnf = public.readFile('/etc/my.cnf'); rep = "\[mysqldump\]\nuser=root" sea = "[mysqldump]\n" subStr = sea + "user=root\npassword=" + mysql_root+"\n"; mycnf = mycnf.replace(sea,subStr) if len(mycnf) > 100: public.writeFile('/etc/my.cnf',mycnf); public.ExecShell("/www/server/mysql/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename) if not os.path.exists(filename): endDate = time.strftime('%Y/%m/%d %X',time.localtime()) log = "数据库["+name+"]备份失落败!" print "★["+endDate+"] "+log print "----------------------------------------------------------------------------" return; mycnf = public.readFile('/etc/my.cnf'); mycnf = mycnf.replace(subStr,sea) if len(mycnf) > 100: public.writeFile('/etc/my.cnf',mycnf); endDate = time.strftime('%Y/%m/%d %X',time.localtime()) outTime = time.time() - startTime pid = sql.table('databases').where('name=?',(name,)).getField('id'); sql.table('backup').add('type,name,pid,filename,addtime,size',(1,os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename))) log = "数据库["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒"; public.WriteLog('操持任务',log) print "★["+endDate+"] " + log print "|---保留最新的["+count+"]份备份" print "|---文件名:"+filename #清理多余备份 backups = sql.table('backup').where('type=? and pid=?',('1',pid)).field('id,filename').select(); num = len(backups) - int(count) if num > 0: for backup in backups: public.ExecShell("rm -f " + backup['filename']); sql.table('backup').where('id=?',(backup['id'],)).delete(); num -= 1; print "|---已清理过期备份文件:" + backup['filename'] if num < 1: break; #连接FTP def connentFtp(self): from ftplib import FTP ftp=FTP() ftp.set_debuglevel(0) ftp.connect('192.168.1.245','21') ftp.login('uptest','admin') ftp.cwd('test') bufsize = 1024 return ftp; #上传文件 def updateFtp(self,filename): ftp = self.connentFtp(); file_handler = open(filename,'rb') ftp.storbinary('STOR %s' % os.path.basename(filename),file_handler,bufsize) ftp.set_debuglevel(0) file_handler.close() ftp.quit() #从FTP删除文件 def deleteFtp(self,filename): ftp = self.connentFtp(); ftp.delete(filename); return True; #获取列表 def getList(self): ftp = self.connentFtp(); return ftp.nlst();if __name__ == "__main__": backup = backupTools()# python /www/server/panel/script/backup.py site www.pythondaquan.com 3 type = sys.argv[1]; if type == 'site': backup.backupSite(sys.argv[2], sys.argv[3]) else: backup.backupDatabase(sys.argv[2], sys.argv[3])
作者的其他回答:
[自己拥有一台做事器可以做哪些很酷的事情]、
[阿里云做事器快速建网站 (安装BT宝塔面板和wordpress)]、
阿里云域名注册与备案、做事器ECS购买与登录 、
[七牛图床添加阿里云域名]、
[markdown多平台发布及七牛图床利用]