- 1. VPS及域名的购买和基本配置
- 2. Linux常用命令
- 2.1 Linux基本命令使用
- 2.2 Linux常用操作
- 2.2.1 常用命令安装
- 2.2.2 使用Shell脚本
- 2.2.3 放行指定端口
- 2.2.4 扩充SWAP空间
- 2.2.5 Crontab定时任务
- 2.2.6 设置开机自启
- 2.2.7 修改系统时间
- 2.2.8 将Python升级为3.x
- 2.2.9 安装pip
- 2.2.10 安装conda
- 2.2.11 安装jdk及Maven
- 2.2.12 jar包部署
- 2.2.13 kill指定端口号的进程
- 2.2.14 监控进程状态
- 2.2.15 安装Node.js和npm
- 2.2.16 统计文件及文件夹个数
- 2.2.17 拷贝同步大量文件
- 2.2.18 查看系统发行版
- 2.2.19 递归删除某目录下指定扩展名的文件
- 2.2.20 安装go及bee工具
- 2.2.21 磁盘空间占用分析
- 2.2.22 查看GPU基础信息及驱动版本
- 2.2.23 查找文件及目录
- 2.2.24 查看指定行的nohup.out日志
- 2.2.25 进程被kill的问题排查
- 2.2.26 ufw防火墙常用命令
- 2.2.27 远程文件拷贝命令
- 2.2.28 查看目录结构
- 2.2.29 安装ffmpeg
- 2.2.30 解决IP无法ping通的问题
- 2.2.31 查询CPU详细参数
- 2.3 vim常用操作
- 2.4 Linux运维脚本
- 2.5 使用curl发送接口请求
- 3. 科学上网环境的搭建
- 4. 版本控制环境搭建
- 5. 部署容器环境搭建
- 6. 项目运行环境搭建
- 7. 网站环境搭建
- 8. 开发辅助环境搭建
- 9. 参考资料
1. VPS及域名的购买和基本配置
1.1 VPS的购买及基本配置
1.1.1 购买Banwagon VPS
如果是自己玩的话,推荐购买国外VPS,搭网站不用备案,带宽足,价格低廉。国内阿里云、腾讯云、百度云等大厂真是一言难尽,上述国外VPS的优点取反就是国内VPS的缺点,国内VPS看似便宜,磁盘空间也足,但同价位VPS的带宽是MB级的,用起来慢的一批,要想快就要买高配的,算下来价格比国外的还贵。当然如果是商业用途还是老老实实使用国内VPS厂商的吧,延迟会低一些,该备案备案。
推荐老牌大厂Banwagon,支持支付宝付款,且新用户购买后1个月内可以退款。购买时建议使用循环优惠码(后续每次续订都会享受折扣),一般每年黑色星期五(相当于国外的双11)会放出来最大力度的优惠码。这里放一个平时的循环优惠码,如果失效了请自行搜索。
1 | 循环优惠码:BWH3HYATVBJW(6.58%) |
购买后会往你的邮箱里发送:“发票”,“IP、端口号、root密码”,KiWiVM管理面板地址等必要信息。
1.1.2 使用KiWiVM面板管理VPS
我们打开管理面板 KiWiVM,重置一个KiWiVM密码(邮箱验证),然后输入IP和刚刚重置的KiWiVM密码即可登录。
在此点击Install new OS,选择一个合适的系统镜像进行安装,我选择的是Debian 10 x86_64,下文所有的操作命令也都是基于该系统的,如有不同请自行查阅。
VPS因搭建并使用科学上网导致被墙
- 搬瓦工官方查询IP是否被墙:https://www.bwgyhw.cn/go/?url=https://kiwivm.64clouds.com/main-exec.php?mode=blacklistcheck
- 付费更换IP解决被墙问题:https://www.bwgyhw.cn/go/?url=https://bwh88.net/ipchange.php (8.79美刀每次)
注:如果是自用,就没必要付费换IP了,可以添加代理访问服务器,被墙之后一般过几个月就会自行放出来(如果不想被墙,就不要使用自己服务器搭建的科学上网服务,尤其是在两会、国庆等敏感时期)
1.2 SSH远程连接VPS
1.2.1 使用FinallShell远程连接
然后就可以使用FinallShell、Xshell等工具ssh远程连接到该服务器了,我这里建议使用FinallShell(它包含了Xshell和Xftp的功能,还不用破解),界面如下所示:
名称随便填(有多个服务器的话建议标注上IP以区分),主机填写服务器IP,端口填写服务器端口,用户名填root,密码填root密码。
解决FinallShell退格乱码问题:选项——终端——Backspace退格键选择ASCIl-Backspace,Delete删除键选择ASCll-Delete
1.2.2 设置代理访问被墙服务器
如果服务器被墙了(连接时报错:Session.connect xxx Need Username/Password authentication
),还可通过添加代理服务器访问(前提是电脑上装有可用的代理工具,如Clash、SSR等)
名称随便填,类型选HTTP,主机填127.0.0.1
,端口号一般是1080(端口根据你代理软件的配置来填)
1.3 购买NameSilo域名
NameSilo是一家国外的知名域名服务注册商,价格便宜而且非常可靠,管理也很方便,支持支付宝付款。这家有很多首年1美刀廉价域名,当然一般都是些不知名的域名(我们所熟知的.com
、.cn
域名一般价格很贵),如果是自己玩的话买个廉价域名就好了。下面放一个优惠1美刀的优惠码(优惠后的实际购买价格不低于1美刀,例如你买了个1.5美刀的域名,使用该优惠码只能优惠至1美刀),如果失效了自行搜索。
1 | idcspy2020(优惠1美刀) |
1.4 NameSilo域名解析
购买完域名之后,首先要做的事儿就是域名解析(说白了就是把域名与你的服务器IP进行绑定)
[1] 打开NameSilo官网,依次完成下图所示的三步操作

[2] Type选A,Address/Value处填服务器IP,TTL填3600即可(是指全国各地的DNS服务器中缓存解析结果的时间周期)

注:一个二级域名可以绑若干个三级域名;一般十分钟左右 DNS 解析记录会生效(可以直接在cmd里ping域名验证是否解析成功)
1.5 宝塔面板的搭建及使用
1.5.1 宝塔面板简介
宝塔面板是一个广东堡塔安全技术有限公司开发的一款LInux管理面板,分为商业版和免费版,有较好的图形化交互界面,可以傻瓜式的管理Linux服务器,适合小白用户自己折腾着玩。生产环境勿用宝塔面板进行部署,有一些意想不到的bug,同时也存在安全隐患,老老实实用命令手动部署。
1.5.2 安装宝塔面板
以下以我所使用过的Debian10和Centos7为例,其余发行版的安装方式参见:宝塔Linux面板安装教程
Debian 10:
1 | wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh |
Centos 7:
1 | yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh |
最后得到了宝塔面板的登陆信息,将其保存下来
1 | Bt-Panel: http://IP/******** |
注:如果忘记了可以使用bt default
命令进行查看(只能看到面板地址和初始的账号及密码,如果改过了就只能重置了)
1.5.3 修改面板基本设置
进入宝塔面板的第一件事就是修改面板端口、面板用户、面板密码等关键信息,否则存在安全隐患,其他面板配置根据自己需要来就好。
Step1:安全——防火墙——放行指定端口,顺便把默认的8888端口关掉。
Step2:面板设置——修改面板端口、面板用户、面板密码等关键信息。
1.5.4 安装LNMP/LAMP开发环境
刚进来宝塔面板的时候会提示安装LNMP或者LAMP环境,根据需求勾选部分即可(忘记勾的可以去软件商店那里搜索下载),建议使用较慢的编译安装。

1.5.5 卸载宝塔面板
1 | $ wget http://download.bt.cn/install/bt-uninstall.sh |
1.6 服务器之间的数据迁移
1.6.1 通过KiWiVM管理面板进行迁移
俩服务器之间可以直接通过镜像同步,无需把镜像下载到本地再上传,以下方法仅适用于两台VPS都是Banwagon的。
- 旧服务器:Snapshots——Export——复制VEID和TOKEN
- 新服务器:Snapshots——Import Snapshots——粘贴VEID和TOKEN
1.6.2 通过宝塔面板进行迁移
使用宝塔面板进行数据迁移之前,最好给新的服务器安装上和旧服务器一样的宝塔环境,包括php、mysql版本。 网站数据一定要提前备份,防止出现意外问题。
Step1:去旧服务器安装“宝塔一键迁移”插件
- 宝塔面板——软件商店——应用搜索——宝塔一键迁移——安装
Step2:去新服务器获取API密钥,并添加旧服务器IP至白名单
- 宝塔面板——面板设置——打开API接口——接口密钥重置——添加旧服务器IP至白名单
Step3:去旧服务器迁出
- 宝塔一键迁移 ——设置——填写迁出地址与API密钥 ——选择迁出数据——一键迁移
2. Linux常用命令
2.1 Linux基本命令使用
2.1.1 文件目录
1 | ls命令:显示指定文件或指定目录中的所有文件信息 |
注:/bin存放二进制可执行文件,常用命令一般都在这里。/usr 用于存放系统应用程序。
2.1.2 拷贝移动
1 | cp命令:复制文件 |
2.1.3 文件内容
1 | cat命令:显示文件内容 (注:cat /etc/issue 查看Linux系统版本) |
2.1.4 远程管理
1 | ifconfig命令:显示或配置网络设备 |
2.1.5 权限管理
1 | chmod命令:修改文件或目录的存取权限 |
2.1.6 下载安装
1 | wget命令:从网络上下载文件,wget+网址即可。 |
2.1.7 压缩解压
1 | 对于.tar.xz |
注:使用tar解压文件到指定目录时出现Not found in archive问题,在 filename.tar.gz 后面加个 -C参数即可。
2.1.8 系统管理
1 | xrandr命令:调整屏幕分辨率 |
2.1.9 其他常用
1 | who命令:显示已登录的用户 |
2.2 Linux常用操作
2.2.1 常用命令安装
查看Linux系统版本
1 | $ cat /etc/issue |
常用命令的安装
1 | $ apt-get install -y sudo # 安装sudo |
说明:如果使用 apt-get 出现 404 Not Found 错误,说明用的系统太老了,那个源已经弃用了,可以升级系统或者换源解决。
2.2.2 使用Shell脚本
Shell脚本是一个可执行文件,其中包含了多行用于命令行输入的文本,也包含了一些用于控制脚本中各行命令执行顺序的专用命令。
运行shell脚本时,必须启动其他程序来解释该脚本,这个程序在Shell脚本的首行指定。在shell提示符下输入脚本名运行脚本时,shell首先检查脚本文件的首行内容,然后启动该行中指定的解释器。
- Shell脚本的首行格式:以
#
作为前缀,后面紧跟一个!
,之后是解释器的完整路径。(如:#! /bin/bash
) - 文本文件必须设定执行权限,不然无法运行。(如:
chmod ugo+x test.sh
) - 运行该脚本:在命令行输入
./
(告诉文件在当前目录下),后面紧跟脚本名。(如./test.sh
)
附:Shell脚本接受命令数组传参的示例(./test.sh 1 2 3)
1 | #!/bin/bash |
另附:Shell脚本遍历数组
1 | #!/bin/bash |
2.2.3 放行指定端口
Step1:安装iptables(通常系统都会自带,如果没有就需要安装)
1 | $ apt-get update |
Step2:放行指定端口(以8888为例)并保存放行规则。
1 | $ iptables -I INPUT -p tcp --dport 8888 -j ACCEPT |
完成上述设置便将端口的放行规则添加到了防火墙中,防火墙的一些其他命令如下:
1 | $ iptables -L # 查看防火墙规则 |
Step3:保持规则持续生效
设置完就已经放行了指定的端口,但重启后会失效,下面设置持续生效规则。
1 | $ apt-get install iptables-persistent |
设置完成后指定端口就会持续放行了。
2.2.4 扩充SWAP空间
SWAP:交换分区,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。
Step1:查看SWAP分区大小:
free -h
Step2:创建swap分区的文件:
dd if=/dev/zero of=/root/swapfile bs=1M count=1024
注:其中 bs是每块的大小,count是块的数量,
bs*count
就是swap文件的大小了,这里就是1M*1024=1G。根据实际需要自行调整count的数量。此外,/root/swapfile
是swap文件的路径,可以根据需求修改,后续操作的路径要与此对应。Step3:格式化交换分区文件:
mkswap /root/swapfile
Step4:启用swap分区文件:
swapon /root/swapfile
Step5:添加开机启动:修改
/etc/fstab
文件,末尾加/root/swapfile swap swap defaults 0 0
Step6:再次查看SWAP分区大小:
free -h
,扩充完毕
2.2.5 Crontab定时任务
Debian系统自带crontab,Ubuntu的话需要自己安装,命令如下:
1 | 安装:apt-get install cron |
crontab 相关命令
1 | crontab [-u username] // 省略用户表表示操作当前用户的crontab |
另注CentOS的crontab安装及管理命令:
1 | $ yum install crontabs // 安装 |
crontab 定时任务语法:
1 | # For details see man 4 crontabs |
crontab定时任务实例:
1 | 实例1:每1分钟执行一次myCommand |
2.2.6 设置开机自启
crontab 是 Linux 下的计划任务,当时间达到我们设定的时间时,可以自动触发某些脚本的运行。其中有个特殊的任务,叫作 @reboot
,这个任务就是在系统重启之后自动运行某个脚本。
要设置开机自启,首先在任意目录创建一个shell脚本然后赋予执行权限,然后输入crontab -e
在里面配置上对应的@reboot
任务即可。
1 | $ crontab -e |
2.2.7 修改系统时间
通过修改时区文件来修改系统时间
1 | $ rm -rf /etc/localtime |
2.2.8 将Python升级为3.x
Debian10 预装的 pyhton 是 2.7.16 版本,而现在很多新软件都是用 python3 编写的,有一些甚至已经不支持 Python2 了,这时候就会报一大堆错,因此建议升级到 Python3.x 版本。
Step1:下载Python3.x
1 | $ wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz |
Step2:安装配置
1 | $ cd Python-3.7.6/ |
Step3:编译安装
1 | $ make |
Step4:验证是否安装成功
1 | $ python -V |
一个是旧版本 2.x,另外一个是新版本 3.x
Step5:设置 3.x 为默认版本
查看 Python 的路径,在 /usr/bin 下面。可以看到 python 链接的是 python 2.7,所以,执行 python 就相当于执行 python 2.7。
将原来 python 的软链接重命名:
1 | $ mv /usr/bin/python /usr/bin/python.bak |
将 python 链接至 python3:
1 | $ ln -s /usr/local/bin/python3 /usr/bin/python |
查看 python 版本:
1 | $ python -V |
2.2.9 安装pip
pip是一个软件包管理系统,可让您安装Python软件包。使用pip,您可以从[Python软件包索引(PyPI)和其他存储库中安装软件包。
Step1:更新软件包列表
1 | $ sudo apt update |
Step2:安装pip
1 | $ sudo apt install python3-pip |
注:如果你的python版本是2.x的话,这里的命令换成sudo apt install python-pip
。
Step3:查看pip3版本
1 | $ pip3 --version |
Step4:将 pip 链接至 pip3:
1 | $ ln -s /usr/local/bin/pip3 /usr/bin/pip |
Step5:查看pip版本
1 | $ pip --version |
2.2.10 安装conda
Conda 是一个开源的软件包管理系统和环境管理系统,用于安装多个版本的软件包及其依赖关系,并在它们之间轻松切换。 Conda 是为 Python 程序创建的,适用于 Linux,OS X 和Windows,也可以打包和分发其他软件。
1 | $ curl -O https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh // 从官网下载安装脚本 |
2.2.11 安装jdk及Maven
jdk11(Open JDK 11):
1 | $ sudo apt-get update |
jdk8(Open JDK 8):
目前 Java OpenJDK 8 在官方 Debian Buster 存储库中不可用,我们需要使用第三方源 AdoptOpenJDK 进行安装。
1 | $ sudo apt-get update |
安装完成后使用如下命令验证:
1 | $ java -version |
如果需要卸载,可使用如下命令:
1 | $ sudo apt remove default-jdk // 卸载jdk11 |
注:jdk8的安装路径为/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64
另附:CentOS7系统安装jdk8
1 | $ yum search java | grep jdk // 查看java版本库 |
Maven(3.8.4):
Step1:下载Maven
1 | $ cd /opt |
附:可以去 https://maven.apache.org/download.cgi 找所需要的版本。
Step2:配置环境变量
1 | $ vi /etc/profile.d/maven.sh |
配置信息如下:
1 | export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64 |
使用source命令重新加载环境变量
1 | $ source /etc/profile.d/maven.sh |
检查maven的版本:
1 | $ mvn --version |
Step3:配置maven的settings文件
1 | $ mkdir /opt/apache-maven-3.8.4/repository |
配置好localRepository的路径
1 | <localRepository>/opt/apache-maven-3.8.4/repository</localRepository> |
配置好镜像源地址
1 | <mirror> |
2.2.12 jar包部署
Springboot项目的部署流程(用IDEA的Maven插件将其打成jar包——将jar上传到服务器——写个运行脚本并开机自启——域名解析、反向代理、HTTPS)
1 | $ java -jar xxx.jar // 运行jar包 |
注:正式部署建议加上时区参数,如东8区-Duser.timezone=GMT+8
,不设置的话会导致日志记录时间异常(即便修改了系统之间也没用–date命令显示的时间是对的),可能会影响问题排查及项目使用。服务器部署jar包的完整示例命令如下:
1 | $ nohup java -jar -Duser.timezone=GMT+8 xxl-job-admin.jar > xxl-job-admin.log 2>&1 & |
注意事项:
- nohup加在一个命令的最前面,表示不挂断的运行命令。
- 2>&1的意思是将标准错误(2)也定向到标准输出(1)的输出文件。
- &加在一个命令的最后面,表示这个命令放在后台执行。
2.2.13 kill指定端口号的进程
1 | $ lsof -i:端口号 |
2.2.14 监控进程状态
1 | ps -aux | grep 进程号 |
2.2.15 安装Node.js和npm
Node.js是跨平台JavaScript的运行环境,旨在在服务器端执行JavaScript代码。npm是Node.js的默认软件包管理器,可帮助开发人员共享和重用其代码。可通过以下命令进行安装:
1 | $ sudo apt update |
安装后,可用以下命令进行验证:
1 | $ nodejs --version |
2.2.16 统计文件及文件夹个数
1 | $ ls -l | grep "^-" | wc -l // 统计当前目录下文件的个数(不包括子目录) |
2.2.17 拷贝同步大量文件
rsync 是一个常用的 Linux 应用程序,用于文件同步。它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cp和mv命令。
1 | $ sudo apt-get install rsync |
2.2.18 查看系统发行版
1 | $ cat /etc/issue // 适用于ubuntu、debian等系统 |
2.2.19 递归删除某目录下指定扩展名的文件
在删除文件之前,建议先预览文件列表(如果文件列表很长,至少部分预览):
1 | $ find path/to/files -type f -regextype posix-extended -iregex '.*\.(avi|mkv|wmv|mp4)$' |
上面的命令将显示要删除的文件列表。若要实际删除文件,只需在末尾添加-delete
1 | $ find path/to/files -type f -regextype posix-extended -iregex '.*\.(avi|mkv|wmv|mp4)$' -delete |
如果您想要查看剩余的内容,可以加个!
逆匹配输出
1 | $ find path/to/files -type f -regextype posix-extended ! -iregex '.*\.(avi|mkv|wmv|mp4)$' |
解释说明:
-type f
将匹配限制为仅文件(目录不会被匹配),把它放在开头而不是结尾,因为谓词的顺序对速度很重要。-iregex
表示不区分大小写,如果要区分的话选择-regex
。- 尽量使用 find xxx -delete来删除文件,它比 rm 命令执行速度更快且更安全。
2.2.20 安装go及bee工具
说明:bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建、热编译、开发、测试、和部署。
Step1:安装并配置go开发环境
1 | $ sudo apt update |
在配置文件末尾追加go的环境配置
1 | export GOROOT=/usr/local/go |
刷新.profile配置文件并验证安装是否成功
1 | $ source ~/.profile |
Step2:bee 工具的安装
1 | $ apt-get install git |
说明:这里有个坑,网上给的方案大多是如下命令:
1 | go get github.com/astaxie/beego |
会耗费很长时间且遇到一些错误,无法成功安装,这是由于hcl包同样更新到了v2,所以此路径不再可用。
1 | cannot find package "github.com/hashicorp/hcl/hcl/printer" in any of: |
2.2.21 磁盘空间占用分析
1 | $ du -s /* | sort -nr // 查看哪个目录占用空间大 |
2.2.22 查看GPU基础信息及驱动版本
使用 nvidia-smi
命令可以显示出当前GPU的所有基础信息。
1 | $ nvidia-smi -q // 查询GPU型号 |

解释相关参数含义:
1 | GPU:本机中的GPU编号 |
查看CUDA驱动版本(安装PyTorch之类的深度学习库需要与CUDA驱动版本对应):
1 | $ nvcc --version |
2.2.23 查找文件及目录
1 | $ find . -type d -name "tra*" // 根据名称查找目录 |
2.2.24 查看指定行的nohup.out日志
1 | $ tail -fn 100 nohup.out |
2.2.25 进程被kill的问题排查
OOM killer:Linux内核Out-Of-Memory killer机制是一种防止内存耗尽影响系统运行而采用的一种自我保护机制。根据内核源码oom_kill.c中的定义,系统会依据“进程占用的内存”,“进程运行的时间”,“进程的优先级”,“是否为 root 用户进程“,”子进程个数和占用内存“,”用户控制参数oom_adj ”等计算一个oom_score值,分数越高就越会被内核优先杀掉。
查看kill日志
1 | $ egrep -i 'killed process' /var/log/syslog |
含义说明:
- total-vm:进程总共使用的虚拟内存;
- anon-rss:虚拟内存实际占用的物理内存;
- file-rss:虚拟内存实际占用的磁盘空间;
其他的一些分析命令:
1 | $ dmesg | grep -i -B100 'killed process' // 查看被kill的所有进程 |
2.2.26 ufw防火墙常用命令
1 | $ sudo ufw enable // 启动ufw防火墙 |
2.2.27 远程文件拷贝命令
1 | $ scp -P port /root/file.txt [email protected]:/root/file.txt // 远程拷贝文件 |
注:port是目标服务器的端口号(如果两台服务器的端口号相同,可省略该参数),[email protected]是目标服务器的用户和ip。以上命令在发送方输入,之后会提示输入接收方的服务器连接密码。
2.2.28 查看目录结构
1 | $ apt-get install tree // 安装tree命令(Debian、Ubuntu系统) |
2.2.29 安装ffmpeg
1 | $ vi /etc/apt/sources.list // 编辑文件,添加如下配置 |
2.2.30 解决IP无法ping通的问题
检查内核参数 icmp_echo_ignore_all
1 | $ cat /proc/sys/net/ipv4/icmp_echo_ignore_all |
若返回结果为0,表示系统允许所有的 ICMP Echo 请求,请检查防火墙设置。
若返回结果为1,表示系统禁止所有的 ICMP Echo 请求,执行如下命令即可解决:
1 | $ echo "0" >/proc/sys/net/ipv4/icmp_echo_ignore_all |
2.2.31 查询CPU详细参数
总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
1 | $ cat /proc/cpuinfo // 查询CPU型号(完整) |
2.3 vim常用操作
2.3.1 vim工作模式
vim主要包含普通模式、插入模式、末行模式等三种工作模式。
- 普通模式:启动vim编辑器后默认进入普通模式,该模式中主要完成如光标移动、字符串查找,以及删除、复制、粘贴文件内容等相关操作。
- 插入模式:该模式中主要的操作就是录入文件内容,可以对文本文件正文进行修改、或者添加新的内容。处于输入模式时,vim编辑器的最后一行会出现“– INSERT –”的状态提示信息。按i可进入插入模式。
- 末行模式:该模式中可以设置vim编辑环境、保存文件、退出编辑器,以及对文件内容进行查找、替换等操作。处于末行模式时,vim编辑器的最后一行会出现冒号“:”提示符。按ESC可进入末行模式。
2.3.2 vim常用命令
[1] 移动光标操作
1 | j:向下 |
[2] 复制操作
1 | yy:复制一行 |
[3] 剪切操作
1 | x:向后剪切一个一个字符,如果是在行尾,则为向前剪切 |
[4] 删除操作
删除的内容会放到剪贴板,按p即可粘贴到其他地方。
1 | dd:删除一行 |
[5] 粘贴操作
1 | p:粘贴复制或剪切的内容 |
[6] 查找和替换操作
在normal模式下按下 / 即可进入查找模式,输入要查找的字符串并按下回车。 Vim会跳转到第一个匹配。 按下 n 查找下一个,按下 N 查找上一个。
1 | r+<待替换字母>:将游标所在字母替换为指定字母 |
[7] 全选操作
1 | ggvG:全选(高亮显示) |
[8] 撤销操作
1 | u:撤销一次操作 |
[9] 保存操作
1 | wq:保存当前文件并退出 |
2.4 Linux运维脚本
2.4.1 自动重启挂掉的jar包
部署到服务器上的jar包有时会自己挂掉,比如当系统内存占用过高,触发了oom-killer机制,导致进程被kill。我们可以在服务器部署一个监控脚本monitor.sh,定时监测系统情况,当服务挂掉时自动重启,一定程度的保证系统的高可用性。
1 | !/bin/bash |
注:webUrl应该给出公开访问的地址(比如有登录页面的,应该出登录页的地址而不是首页的地址),不然curl测出来的状态码是302,导致项目没有挂掉也不断地重启。
可以使用如下命令获取目标网址的重定向目标:
1 | $curl -Ls -w %{url_effective} -o /dev/null https://google.com // 把url换成你的目标网址,输出的即可作为webUrl |
然后给脚本设置可执行权限,再执行crontab -e
命令,设置定时任务。
1 | */1 * * * * bash /myshell/monitor.sh >> /myproject/monitor.log |
说明:每一分钟执行一次并将日志打印在固定文件中,若文件不存在会自动创建。
2.4.2 jar包运维脚本
可以把springboot项目打包出的jar包通过运维脚本来管理,新建一个restart.sh的脚本,内容如下:
1 | !/bin/bash |
使用方法:给脚本赋予可执行权限,放到jar同一目录下,执行下列命令管理即可。
1 | $ ./restart.sh status |
2.5 使用curl发送接口请求
使用curl模拟get/post/put/delete请求
其中curl -h查看请求参数的含义 -v 显示请求的信息 -X 选项指定其它协议
1 | get: |
-H ‘xxx’ 带请求头
1 | curl -v -H 'ApiKey:xxx' -H 'Sign:xxx' -H 'RequestTime:xxx' -H 'Content-Type:application/json' -H 'User-Agent:PostmanRuntime/7.26.10' -H 'Accept:*/*' -H 'Accept-Encoding:gzip, deflate, br' -H 'Connection:keep-alive' -X POST 192.xxx.xx.xx:xxxx/test/xxxx -d '{"orgCode":"xxx","districtId":"1"}' |
3. 科学上网环境的搭建
以下采用一键脚本搭建科学上网环境,虽然足够方便,一般也没有什么问题,但存在一定的隐患,建议运行前先看一下脚本的内容,了解清楚它都对你的服务器做了什么,再去执行。
3.1 SSR服务器端搭建
3.1.1 ShadowsocksR简介
ShadowsocksR是一个高性能安全的socks5代理,基于和兼容Shadowsocks,帮助用户更加安全访问全球网络。ShadowsocksR简称为SSR,支持复杂协议和混淆,有更强的抗干扰能力。
3.1.2 一键脚本搭建SSR服务
1 | $ wget -N --no-check-certificate https://makeai.cn/bash/ssrmu.sh && chmod +x ssrmu.sh && bash ssrmu.sh |
3.2 Trojan-Go服务器端搭建
3.2.1 Trojan-Go简介
Trojan是一款新型的代理工具,其特点是代理流量和伪装网站共用服务器的443端口,使代理流量被识别为正常的网站浏览,从而降低被封锁的机率。Trojan-Go则是在Trojan的基础上,经过二次开发,优化了原版的一些功能,额外添加了新的功能,比如Trojan-Go支持多路复用,支持CDN流量中转。
3.2.2 一键脚本搭建Trojan-Go服务
1 | $ bash <(curl -sL https://raw.githubusercontent.com/phlinhng/v2ray-tcp-tls-web/master/install.sh) && v2script |
4. 版本控制环境搭建
4.1 Git环境搭建
4.1.1 安装配置Git
Step1:下载安装Git服务器
1 | $ apt-get install git |
Step2:验证是否安装成功
1 | $ git --version |
若显示版本信息则说明安装成功。
4.1.2 创建用户并赋予权限
Step1:创建git用户
1 | $ adduser git |
用户名以git为例,根据提示设置密码。
Step2:赋予git用户权限
1 | $ chmod 740 /etc/sudoers |
在root ALL=(ALL:ALL) ALL
这一行下面添加git ALL=(ALL:ALL) ALL
1 | # User privilege specification |
保存退出后,修改回文件权限
1 | $ chmod 440 /etc/sudoers |
Step3:关闭git用户的shell权限
考虑到安全因素,需要禁止git用户ssh登录服务器,设置后git用户可以通过ssh正常使用git服务,但无法登录shell。
1 | $ nano /etc/passwd |
将最后一行的bash
处改为git-shell
1 | git:x:1001:1001:,,,:/home/git:/bin/bash 改成 git:x:1001:1001:,,,:/home/git:/bin/git-shell |
4.1.3 初始化git仓库并配置SSH
Step1:初始化git仓库
1 | $ cd /home/git //切换到git用户目录 |
Step2:查看公钥
打开本地的 git bash,输入以下命令查看公钥(前提是本地已经配好了git环境并完成初始化),复制公钥
1 | $ cat ~/.ssh/id_rsa.pub |
Step3:配置SSH
1 | $ cd /home/git //切换到git用户目录 |
Step4:用户组管理
修改/home/git/repo.git
目录的用户组权限为git:git
1 | $ sudo chown git:git -R /home/git/repo.git |
修改后执行下列命令后再查看
1 | $ ls -l /home/git |
4.1.4 本地连接远程仓库
打开本地的git bash,检出仓库并设置记住用户名和密码,然后我们就可以使用git进行版本控制了,git无需手动设置开机自启。
Step1:本地检出仓库
1 | $ git clone ssh://[email protected]:port/home/git/repo.git |
Step2:设置记住用户名和密码
1 | $ git config --global credential.helper store |
4.2 SVN环境搭建
4.2.1 安装配置SVN
Step1:下载安装SVN服务器
1 | $ apt-get install subversion |
Step2:创建仓库,首先创建SVN的根目录 svn,然后再创建一个项目目录(以test为例)
1 | $ mkdir /svn |
Step3:创建新的 svn 仓库
1 | $ svnadmin create /svn/test |
Step4:启动 svn 服务,并指定 svn 数据存储的根目录
1 | $ svnserve -d -r /svn |
Step5:放行 svn 所使用的3690端口
宝塔面板——安全——放行3690端口(不放行会报错“由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败”)
然后就可以用 TortoiseSVN 客户端,在Windows上 Checkout 这个项目了,SVN地址为svn://IP/test
4.2.2 SVN权限控制
默认的SVN配置是允许匿名访问的,我们可以配置权限使其只能通过用户名密码登录后才能访问。
Step1:编辑配置文件
1 | $ nano /svn/test/conf/svnserve.conf |
添加以下四行代码(或者把原有配置里对应这四项的#及空格去掉,改成如下配置)
1 | anon-access = none |
这四行的含义分别是:匿名用户无权限、授权用户可写、使用哪个文件作为账号文件、使用哪个文件作为权限文件。
Step2:添加用户名密码
1 | $ nano /svn/test/conf/passwd |
在后面添加用户名(以testuser为例)和密码(以testpasswd为例)
1 | [users] |
Step3:给用户分配权限
1 | $ nano /svn/test/conf/authz |
在后面添加如下权限
1 | [/] |
注:r代表读权限,w代表写权限(如果多个用户就一行一个)
Step4:重启 svn 服务
1 | $ killall svnserve |
重启 svn 服务之后就可以用设置的用户名密码登录了。
4.2.3 SVN开机自启
我们可以使用crontab的@reboot
任务实现SVN的开机自启。
Step1:创建 启动svn 服务的shell脚本并赋予执行权限
1 | $ mkdir /myshell |
Step2:将shell脚本添加到 crontab 计划任务里
1 | $ crontab -e |
然后把如下内容写入,重启即可
1 | @reboot /myshell/startsvn.sh |
5. 部署容器环境搭建
5.1 Docker简介
5.1.1 Docker是什么
是什么:Docker是一个用于开发,交付和运行应用程序的开放平台。可以将应用程序与基础架构分开,从而可以快速交付软件。
作用:将一整套环境打包封装成镜像,无需重复配置环境,解决环境带来的种种问题。Docker容器间是进程隔离的,谁也不会影响谁。
官方文档:Docker官方文档
5.1.2 Docker的架构
Docker 其实指代的是用于开发,部署,运行应用的一个平台。平常中说的 Docker 准确来说是 Docker Engine。Docker Engine 是一个 C/S 架构的应用。其中主要的组件有:
- Docker Server:长时间运行在后台的程序,就是熟悉的 daemon 进程.
- Docker Client:命令行接口的客户端。
- REST API:用于和 daemon 进程的交互。
我们通过给 Docker Client 下发各种指令,然后 Client 通过 Docker daemon 提供的 REST API 接口进行交互,来让 daemon 处理编译,运行,部署容器的繁重工作。 大多数情况下, Docker Client 和 Docker Daemon 运行在同一个系统下,但有时也可以使用 Docker Client 来连接远程的 Docker Daemon 进程,也就是远程的 Server 端。
5.1.3 Docker Compose是什么
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Compose 使用的三个步骤:
- 使用
Dockerfile
定义应用程序的环境。 - 使用
docker-compose.yml
定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。 - 最后,执行
docker-compose up
命令来启动并运行整个应用程序。
5.1.4 Docker与Docker Compose的区别
Docker是一个供开发和运维人员开发,测试,部署和运行应用的容器平台。这种用linux container部署应用的方式叫容器化。
Docker Compose是一个用于运行和管理多个容器化应用的工具。
我们可以列出下列几项来进行二者对比:
docker是自动化构建镜像,并启动镜像。 docker compose是自动化编排容器。
docker是基于Dockerfile得到images,启动的时候是一个单独的container。
docker-compose是基于docker-compose.yml,通常启动的时候是一个服务,这个服务通常由多个container共同组成,并且端口,配置等由docker-compose定义好。
两者都需要安装,但是要使用docker-compose,必须已经安装docker。
5.1.5 直接安装和Docker安装的区别
下面以MySQL数据库为例,看看直接安装MySQL和使用Docker安装MySQL有什么区别:
- docker安装快速,效率高;
- docker隔离性好,可以安装无数个mysql实例,互相不干扰,只要映射主机端口不同即可;
- 占用资源少,MB级别,而服务器安装GB级别;
- 启动速度秒级,而服务器安装启动分钟级别;
- 性能接近原生,而服务器安装较低;
- 数据备份、迁移,docker更方便强大;
- 卸载管理更方便和干净,直接删除容器和镜像即可;
- 稳定性,只要保证docker环境没问题,mysql就没问题。
5.2 Docker环境搭建
5.2.1 卸载原先安装的Docker
Debian11系统:
1 | $ dpkg -l | grep docker # 查询相关软件包 |
CentOS7系统:
1 | $ sudo yum remove docker \ |
5.2.2 安装Docker环境
Debian11系统:
方式一:通过脚本安装(推荐)
1 | $ apt-get update -y && apt-get install curl -y # 安装curl |
方式二:手动安装
1 | $ sudo apt-get update |
CentOS7系统:
1 | $ curl -fsSL get.docker.com -o get-docker.sh |
5.2.3 Docker的GPU环境配置
在Docker中使用GPU,必须在创建容器时打开--gpus
参数,并保证docker的版本在19.03以上。
关于配置Docker使用GPU,其实只用装官方提供的toolkit即可。未配置的话会有Error response from daemon: could not select device driver ““ with capabilities: [[gpu]]
的报错,解决办法如下:
1 | $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - |
5.2.4 Docker更换镜像源地址
缘由:在Dockerfile创建镜像拉取基础镜像时遇到了Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
报错,原因是连不上官方的源,可修改配置换源解决。
Docker安装后默认没有daemon.json
这个配置文件,需要进行手动创建,配置文件的默认路径:/etc/docker/daemon.json
,权限为644,内容如下:
1 | { |
修改后需要重新加载配置,然后重启docker服务。
1 | $ sudo systemctl daemon-reload |
5.2.5 Docker常用命令
[1] 搜索及拉取docker镜像
1 | $ docker search [NAME] # 搜索docker镜像(搜索结果里OFFICIAL为OK的是官方镜像) |
[2] 查看docker容器实例和镜像
1 | $ docker ps -a # 查看所有docker容器实例 |
[3] 开启停止docker容器实例和镜像
1 | $ docker start [CONTAINER ID/NAMES] # 开启指定docker容器实例 |
[4] 强制删除docker容器实例和镜像
1 | $ docker rm -f [CONTAINER ID/NAMES] # 强制删除指定docker容器实例(删除前需先停止实例) |
[5] 进入/退出docker容器内部
1 | $ docker exec -it [CONTAINER ID/NAMES] /bin/bash # 进入指定docker容器内部 |
注:如果遇到OCI runtime exec failed: exec failed
问题,则使用如下命令进入
1 | $ docker exec -it [CONTAINER ID/NAMES] /bin/sh |
[6] 查看docker运行日志
1 | $ docker logs -f [CONTAINER ID/NAMES] --tail 100 # 查看指定条数的docker运行日志 |
[7] docker容器内部的文件上传和下载
1 | $ docker cp /root/test.txt [CONTAINER ID/NAMES]:/root # 上传文件 |
[8] 让容器使用GPU环境
docker run 的时候加上 –gpus all 即可
1 | --gpus all |
[9] 在docker容器外执行容器内的命令
有时候我们想执行某个容器的某条命令,但又不想进入容器内,可通过如下命令示例实现:
1 | $ docker exec -it [CONTAINER ID/NAMES] /bin/bash -c 'cd /code && python test.py' |
注:如果遇到the input device is not a TTY
问题,去掉t即可,即:
1 | $ docker exec -i [CONTAINER ID/NAMES] /bin/bash -c 'cd /code && python test.py' |
[10] docker的跨容器调用
需求情景:爬虫项目和定时任务项目分别在两个容器中部署的,想要在定时任务项目里编写脚本调用爬虫项目中的具体执行文件。
我们可以通过挂载docker.sock
和docker
命令行客户端实现用docker exec
来间接调用。只需要在docker run的时候挂载如下路径即可:
1 | -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker |
[11] 给docker镜像打Tag
1 | $ docker tag [IMAGEID] [REPOSITORY]:[TAG] |
[12] 给docker容器设置开机自启
1 | $ docker update [CONTAINER ID/NAMES] --restart=always |
[13] 显示docker容器占用的系统资源
1 | $ docker stats // stats命令默认会每隔1秒钟刷新一次输出的内容直到你按下ctrl + c |
[14] 容器进程查看
1 | $ ps -ef // 查看容器内进程(需要先进入容器内部) |
另注:在外部查看指定docker容器的进程号
1 | $ docker container top [CONTAINER ID/NAMES] |
[15] 查看容器内系统版本
1 | $ cat /etc/*release // 查看容器内系统版本(需要先进入容器内部) |
[16] 无ENTRYPOINT方式启动
如果是直接执行的代码,写Dockerfile时就不需要加ENTRYPOINT了,然后用以下命令进入容器:
1 | $ docker run -it --name [CONTAINER ID/NAMES] [IMAGE ID/NAMES] /bin/bash |
如果要覆盖原先Dockerfile里的ENTRYPOINT配置,加个--entrypoint /bin/bash
即可。
1 | $ docker run -it --entrypoint /bin/bash --name [CONTAINER ID/NAMES] [IMAGE ID/NAMES] |
[17] 查看指定容器的元数据
1 | $ docker inspect [CONTAINER ID/NAMES] // 查看指定容器的元数据 |
5.2.6 清理Docker占用的存储空间
[1] docker空间清理
1 | $ docker system df # 类似于Linux上的df命令,用于查看Docker的磁盘使用情况 |
[2] 查看并清空容器日志
在Linux上,Docker容器日志一般存放在/var/lib/docker/containers/container_id/下面, 以json.log结尾。
手动处理容器日志:
1 | $ docker inspect --format='{{.LogPath}}' [CONTAINER ID/NAMES] # 查看指定容器的日志 |
批量查找容器日志find_docker_log.sh:
1 | !/bin/sh |
批量清空容器日志 clear_docker_log.sh:
1 | !/bin/sh |
注:以上清理日志的方法治标不治本,可通过以下方式设置Docker容器日志大小治本。
方案一:设置一个容器服务的日志大小上限
设置一个容器服务的日志大小上限
1 | --log-driver json-file #日志驱动 |
方案二:全局设置
编辑文件/etc/docker/daemon.json
, 增加以下日志的配置:
1 | "log-driver":"json-file", |
解释说明:
- max-size=500m,意味着一个容器日志大小上限是500M,
- max-file=3,意味着一个容器有三个日志,分别是id+.json、id+1.json、id+2.json。
然后重启docker守护进程
1 | $ systemctl daemon-reload |
注:设置的日志大小限制,只对新建的容器有效。
5.3 Docker Compose环境搭建
1 | // 下载安装docker-compose,最新版见:https://github.com/docker/compose/releases |
5.4 通过Dockerfile自动构建镜像
Step1:在项目里面再新建一个Dockerfile文件(有的开源项目会提供现成的 Dockerfile,如果没有就要自己去写)

Step2:切换到项目目录里,执行如下命令即可成功构建镜像。
1 | $ docker build -t 'test-image' . |
Step3:我们可以打包导出镜像,示例如下。
1 | $ docker save test-image > test-image.v1.dockerimage |
5.4.1 使用Docker部署Springboot项目
Step1:使用Maven将项目打包成jar包,并编写Dockerfile,示例如下:
1 | # 基于java8镜像创建新镜像 |
Step2:将jar包和Dockerfile上传到服务器并制作镜像运行容器
1 | $ cd /root/deploy // 切换到存放jar包和Dockerfile的目录 |
5.4.2 使用Docker部署Flask项目
Step1:导出项目依赖,并编写Dockerfile,示例如下:
1 | $ pip freeze > requirements.txt |
注:建议对项目单独建一个conda虚拟环境,再导出依赖,这样导出的依赖就这一个项目的,就不用手动删除无用的了。
1 | # 基于python3.7镜像创建新镜像 |
Step2:将项目和Dockerfile上传到服务器并制作镜像运行容器
1 | $ cd /root/deploy // 切换到存放项目和Dockerfile的目录 |
5.4.3 使用Docker部署前端项目
Step1:将前端项目打包,生成dist文件(或者其他的),编写Dockerfile,示例如下:
1 | # 设置基础镜像 |
Step2:将项目和Dockerfile上传到服务器并制作镜像运行容器
1 | $ cd /root/deploy // 切换到存放项目和Dockerfile的目录 |
访问地址:http://ip:9500
注:容器内nginx的默认端口是80,如要使用其他端口,请修改nginx配置。以下是容器内的几个重要目录,如有需要可挂载出来。
1 | /etc/nginx/conf.d // Nginx配置目录 |
另注:如果访问页面时出现403问题,进入容器内修改权限即可。
1 | $ docker exec -it test-web /bin/bash |
5.5 正式环境的前后端分离项目部署
正式环境使用docker network对Docker容器进行统一管理,像数据库这种提供服务的,就不对外提供端口了,各容器之间通过hostname进行内部通信。
下面以一个Springboot + Vue的前后端分离项目(项目依赖于MySQL、Redis、 Elasticsearch、Emqx)为例。
Step1:创建docker network
1 | $ docker network create yoyo |
注:可使用 docker network ls
查看已创建的网络
Step2:创建项目依赖环境,并添加到网络里去
1 | $ docker run -itd --name yoyo_mysql -h yoyo_mysql --network yoyo \ |
注:创建容器时要用 -h 指定 hostname,–network 指定网络,除Emqx外不需要 -p 对外映射端口号。
Step3:项目打包并修改配置文件
将Springboot项目打成jar包,Vue项目打成dist包。除此之外,需要修改Springboot项目的配置文件(把项目依赖的MySQL、Redis、 Elasticsearch、Emqx环境地址由原来的ip:port改成 docker 的 hostname),这里采用包外配置。
这部分内容有不熟悉的可以参考我的 Springboot和一些主流框架的整合样例 、 前端开发环境配置及Vue开发样例 两篇博客。
Step4:准备项目部署所需要的文件
项目部署所需要文件的目录结构如下:
1 | ├── config |
[1] 准备 java8 环境(jdk-8u202-linux-x64.tar.gz)
去官网下载一个linux版的jdk,jdk-8u202-linux-x64.tar.gz 的官网下载地址
[2] 准备 nginx 配置文件 (yoyo_web.conf、proxy.conf)
yoyo_web.conf(需要修改后端的接口地址和前端文件的存放路径)
1 | upstream dev_yoyo_web { |
proxy.conf(无需修改)
1 | proxy_connect_timeout 900s; |
[3] 准备Dockerfile
1 | # 设置基础镜像 |
注:前端包建议打成tar.gz
格式,ADD命令会自动对其进行解压。而zip、rar等格式不会自动解压,还需要进入容器自行解压。
Step5:打包镜像并创建容器启动项目
1 | $ docker build -t 'yoyo_web' . |
启动成功后,项目就部署好了,Chrome访问 IP:9500
地址即可查看。
5.6 将已有容器部署到其他服务器
步骤简述:将容器保存成镜像——将镜像打成tar包,压缩成tar.gz——使用scp命令将文件传输到目标服务器——将tar.gz解压成tar包,载入镜像——docker run 运行镜像创建容器
Step1:将容器保存成镜像
1 | $ docker ps -a |
说明:-a后面的是提交用户的用户名,-m后面的是提交信息,1c786853ea40是容器id,最后是镜像名及tag,打包出来的镜像如下:
1 | REPOSITORY TAG IMAGE ID CREATED SIZE |
Step2:将镜像打包并压缩
1 | $ docker save -o eula-uptime-kuma-v1.0.tar eula/uptime-kuma:v1.0 |
Step3:将文件传输到目标服务器
1 | $ scp -P port /root/eula-uptime-kuma-v1.0.tar.gz [email protected]:/root/eula-uptime-kuma-v1.0.tar.gz |
Step4:解压并载入镜像
1 | $ tar -zxvf eula-uptime-kuma-v1.0.tar.gz |
载入出来的镜像如下:
1 | REPOSITORY TAG IMAGE ID CREATED SIZE |
Step5:运行镜像创建容器
1 | $ docker run -d --restart=always -p 3001:3001 --name uptime-kuma eula/uptime-kuma:v1.0 |
注意事项:
[1] 通过容器打Docker镜像要比Dockerfile生成的包要大(里面有很多没用的东西),尽量使用后者,但一些需要离线部署并且需要自动下载算法模型的除外。
[2] 直接对设置挂载的容器打包,会导致通过挂载加进去的文件并没有加进去(打出来的镜像不包含挂载进去的文件),可以再创建个不挂载的容器,把文件替换进去,再对这个不挂载的容器打包。
6. 项目运行环境搭建
6.1 Docker-MySQL环境搭建
6.1.1 搜索MySQL镜像
1 | $ docker search mysql |
通常选择OFFICIAL里Star数最多的那个镜像,即mysql。
6.1.2 拉取镜像创建实例容器并运行
1 | $ docker pull mysql:5.7 |
命令解释说明:
1 | -p 3306:3306:将主机的3306端口映射到docker容器的3306端口。 |
说明:如果是挂载已有的其他服务器数据,可能会出现用户权限问题,如果网络是通的,建议使用Navicat的数据传输功能(工具——数据传输——配置源与目标链接——选择需要传输的数据表即可),数据传输速度很快。
6.1.3 创建数据库及用户
在本地使用Navicat工具使用root用户连接上该数据库(国外服务器建议配置代理),使用如下四条命令创建数据库及用户。
1 | --创建新的数据库,并设置数据库编码 |
注:如果连接数据库时出现Access denied for user '用户名'@'某IP' (using password: YES)
问题,则是第三句授权出了问题,你的本地外网IP被拦截了,那个’%’代表的是访问IP不受限制。
6.1.4 数据库的备份与恢复
[1] 数据备份
可以使用mysqldump实现,docker-mysql的数据库备份语句如下:
1 | // 备份单个数据库的结构与数据 |
说明:1)如果安的是原生mysql,直接执行mysqldump语句备份即可。2)如果需要同时导出多个数据库,“数据库名”处用空格分割多个数据库即可。3)不要数据只保留数据库结构的话加个-d
参数即可。
[2] 数据恢复
docker-mysql的数据库恢复语句如下:
1 | docker exec -i mysql sh -c "exec mysql -uroot -p'root密码'" < /mydocker/mysql/backup/db.sql |
注:建议使用命令去恢复数据,直接用Navicat工具运行导出的sql来恢复数据有时会出问题(比如我就遇到过导出的库在Navicat执行报错,但用命令可以导入成功的情况)
6.1.5 数据库的定时备份
实际在生产环境上,我们不会每天都去手动备份。可以写一个脚本出来,完成这项操作,然后用 crontab 定时执行。
Step1:新建一个mysqlbackup.sh
脚本,并使用chmod u+x
命令赋予可执行权限,脚本内容如下:
1 | !/bin/bash |
说明:
1)上面的信息部分换成自己的,备份输出目录的末尾不要加‘/’,多个数据库用空格分隔不要加逗号。
2)正式备份数据库的语句也换成自己的,注意"exec mysqldump --databases ${table} -u ${dbuser} -p'${dbpasswd}'"
处外面是双引号,里面套单引号,反过来会因为${}
导致转义问题。
3)为了节约硬盘空间,我这里对sql进行了压缩(如果不想压缩就不用安了,注释掉相关代码即可),请先安装xz命令。
1 | $ apt-get install xz-utils |
4)为了节约硬盘空间,我这里删除了30天前的备份(根据文件的最后改动时间来判定),具体保留几天自己定就行。
Step2:配置定时任务执行脚本
1 | $ crontab -e |
然后添加如下代码保存即可:
1 | 59 23 * * * 脚本路径/mysqlbackup.sh |
说明:含义是每天23:59分自动执行脚本,详细使用见上文”2.2.5 Crontab定时任务”.
6.2 Docker-Nginx环境搭建
6.2.1 获取Nginx镜像
1 | $ docker search nginx |
6.2.2 创建Nginx容器
Step1:查看我们拉取到本地的nginx镜像IMAGE ID
1 | $ docker images nginx |
Step2:创建并启动容器
1 | $ docker run -d --name nginx -p 9999:80 [image-id] |
命令解释说明:
1 | - -d 指定容器以守护进程方式在后台运行 |
6.2.3 修改Nginx配置文件
[1] 每次都进入到nginx容器内部修改–适用于临时修改情况
Step1:进入到nginx容器内部
1 | docker exec -it [CONTAINER ID/NAMES] /bin/bash |
命令解释说明:
1 | - exec 命令代表附着到运行着的容器内部 |
进入到nginx容器内部后,我们可以cd /etc/nginx
,可以看到相关的nginx配置文件都在/etc/nginx
目录下。而nginx容器内的默认首页html文件目录为/usr/share/nginx/html
,日志文件位于/var/log/nginx
。执行exit
命令可以从容器内部退出。
[2] 将nginx容器内部配置文件挂载到主机–适用于频繁修改情况
Step1:创建挂载目录
这里我为了跟mysql的挂载目录保持一致,也使用了自己创建的/mydocker
目录(一般放在/mnt
目录,这个是Linux专门的挂载目录)
1 | $ cd /mydocker |
Step2:将容器内的nginx.conf
与default.conf
文件分别拷贝到主机/mydocker/nginx
与/mydocker/nginx/conf
目录下
1 | $ cd /mydocker/nginx |
命令解释说明:
1 | - [CONTAINER ID/NAMES] 是我们要进入的容器ID(可以省略后面的部分,能唯一区分即可)或名字 |
Step3:重新创建容器实例
先停止、删除原有的容器实例
1 | $ docker stop [CONTAINER ID/NAMES] # 停止指定docker容器实例 |
再重新创建新的容器实例
1 | $ docker run -d --name nginx -p 9999:80 -v /mydocker/nginx/nginx.conf:/etc/nginx/nginx.conf -v /mydocker/nginx/logs:/var/log/nginx -v /mydocker/nginx/html:/usr/share/nginx/html -v /mydocker/nginx/conf:/etc/nginx/conf.d --privileged=true [image-id] |
命令解释说明:
1 | -v 挂载目录,表示将主机目录与容器目录之间进行共享 |
Step4:设置开机自启
1 | $ docker update nginx --restart=always |
6.2.4 测试Nginx环境
Step1:新建测试用的index.html
文件(不配置会出现403报错)
1 | $ cd /mydocker/nginx/html |
Step2:打开Chrome浏览器,地址输入IP:port
,出现hello world
即配置成功。
6.2.5 搭建过程踩的坑
情景描述:搭建完的nginx在本地用curl IP:port
可以访问(当然在nginx容器里使用curl 127.0.0.1
也是可以访问的),但在Chrome浏览器内找不到该地址(提示“该网页可能已永久移到新的网址”)
错误原因:创建nginx容器时误用了Chrome浏览器的默认非安全端口,访问会直接被拦截,因而出现了该情况。Chrome 默认非安全端口列表如下:
1 | 1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, 513, 514, 515, 526, 530, 531, 532, 540, 556, 563, 587, 601, 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667, 6668, 6669 |
解决办法:删掉nginx容器重新搭建,创建nginx容器时避开Chrome浏览器的默认非安全端口即可。
6.2.6 Nginx的一些其他管理命令
1 | $ nginx -s reload # 重新加载配置文件,而nginx服务不会中断 |
6.3 Docker-Redis环境搭建
6.3.1 获取Redis镜像
1 | $ docker pull redis:3.2.8 |
6.3.2 创建Redis容器
1 | $ docker run --name redis -p 6379:6379 -d redis:3.2.8 --requirepass "mypassword" |
6.3.3 Redis数据库的可视化连接
建议使用 AnotherRedisDesktopManager 开源工具。
6.4 Docker-Oracle环境搭建
6.4.1 拉取镜像并运行容器
1 | $ docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g |
6.4.2 进入容器进行配置
Step1:进入容器,切换到root用户
1 | $ docker exec -it oracle11g /bin/bash # 进入oracle11g容器 |
Step2:配置环境变量
1 | $ vi /etc/profile |
在末尾加上:
1 | export ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/dbhome_2 |
Step3:创建软连接,并用oracle用户登录
1 | $ ln -s $ORACLE_HOME/bin/sqlplus /usr/bin # 创建软链接 |
6.4.3 修改密码创建用户
1 | $ sqlplus /nolog # |
6.4.4 用连接工具登录
在PLSQL里使用 system/system 账号连接,注意服务名不是orcl,而是helowin。
具体可查看tnsnames.ora文件的配置:
1 | $ vi /home/oracle/app/oracle/product/11.2.0/dbhome_2/network/admin/tnsnames.ora |
6.5 Docker-ElasticSearch环境搭建
6.5.1 拉取镜像并运行容器
1 | $ docker pull elasticsearch:7.16.2 |
注意事项:
1)Elasticsearch请选择7.16.0之后的版本,之前的所有版本都使用了易受攻击的 Log4j2版本,存在严重安全漏洞。
2)ES_JAVA_OPTS="-Xms1g -Xmx1g"
只是一个示例,内存设置的少了会导致数据查询速度变慢,具体设置多少要根据业务需求来定,一般而言公司的实际项目要设置8g内存以上。
数据挂载遇到的问题:
[1] 数据锁定问题
报错信息:java.lang.IllegalStateException: failed to obtain node locks, tried [[/usr/share/elasticsearch/data]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing
产生原因:ES在运行时会在/data/nodes/具体分片
目录里生成一个node.lock
文件,由于我是在运行期scp过来的挂载数据,这个也被拷贝过来了,导致数据被锁定。
解决办法:删掉/data/nodes/具体分片/node.lock
文件即可
[2] data目录权限问题
解决办法:进入容器内部,把data目录的权限设置为777即可
[3] 集群与单节点问题
解决办法:修改config/elasticsearch.yml
里的集群配置即可,如果原来是集群,现在要单节点,就把集群配置去掉。
[4] 堆内存配置问题
报错信息:initial heap size [8589934592] not equal to maximum heap size [17179869184]; this can cause resize pauses
解决办法:-Xms 与 -Xmx 设置成相同大小的内存。
6.5.2 进入容器进行配置
这时使用docker ps
命令查看虽然运行起来了,但还无法访问,需要进入容器内部修改配置解决跨域问题。
1 | $ docker ps |
其中,在 elasticsearch.yml 文件的末尾添加以下三行代码(前两行解决跨域问题,第三行开启xpack安全认证)
1 | http.cors.enabled: true |
然后把权限修改回来,重启容器,设置账号密码,浏览器访问http://IP:9200
地址即可(用 elastic账号 和自己设置的密码登录即可)
1 | $ chmod o-w elasticsearch.yml |
注:可借助 Elasticvue Chrome插件实现ES数据库的可视化管理。
6.5.3 安装ik分词器插件
项目简介:IK 分析插件将 Lucene IK 分析器集成到 elasticsearch 中,支持自定义字典。
项目地址:https://github.com/medcl/elasticsearch-analysis-ik
安装方式:去Releases下载对应ES版本的ik分词器插件,然后上传到Plugins目录将其挂载到容器内。
测试方式:k分词器有2种算法:ik_smart和ik_max_word,下面我们通过postman工具来测试ik分词器的分词算法。
[1] 测试ik_smart分词
请求url:http://ip:9200/_analyze
请求方式:get
请求参数:
1 | { |
[2] 测试ik_max_word分词
请求url:http://ip:9200/_analyze
请求方式:get
请求参数:
1 | { |
上面测试例子可以看到,不管是ik_smart还是ik_max_word算法,都不认为”特靠谱”是一个关键词(ik分词器的自带词库中没有有”特靠谱”这个词),所以将这个词拆成了三个词:特、靠、谱。
自定义词库:ik分词器会把分词库中没有的中文按每个字进行拆分。如果不想被拆分,那么就需要维护一套自己的分词库。
Step1:进入ik分词器路径/config
目录,新建一个my.dic
文件,添加一些关键词,如”特靠谱”、”靠谱”等,每一行就是一个关键词。
Step2:修改配置文件IKAnalyzer.cfg.xml
,配置<entry key="ext_dict"></entry>
。
1 |
|
Step3:重启ES,并再次使用Postman测试上述请求,发现”特靠谱”、”靠谱”等将其视为一个词了。
6.5.4 安装kibana可视化插件
下载与ES版本相同的Kibana
1 | $ mkdir -p /root/kibana |
修改配置文件内容如下(用不到的我这里给删掉了,原配置文件有着很详尽的英文说明):
1 | server.port: 5601 |
启动kibana:
1 | $ cd /root/kibana/kibana-7.16.2-linux-x86_64/bin # 进入可执行目录 |
说明:如果是root用户,会报Kibana should not be run as root. Use --allow-root to continue.
的错误,建议切换别的用户去执行,如果就是想用root用户启动,则使用nohup /mydocker/kibana/kibana-7.16.2-linux-x86_64/bin/kibana --allow-root &
。
启动成功后,浏览器打开http://ip:5601/
地址,用es的用户名和密码进行登录,就可以使用了。
关闭kibana:
1 | $ ps -ef | grep kibana |
6.5.5 ES的导入与导出
方案一:使用elasticdump插件进行导入导出
elasticdump:Elasticsearch的导入导出工具
Step1:安装npm
1 | $ sudo apt update |
Step2:安装elasticdump插件
1 | $ npm install elasticdump -g |
ES的导入导出(以导出为例):
1 | $ elasticdump \ |
说明:开启了xpack安全认证的话就要像上面那样加上username:[email protected]
,没有的话就不需要加。导入跟导出命令基本一致,互换一下input和output的内容即可。
方案二:使用esm工具进行导入导出
esm:一个 Elasticsearch 迁移工具
1 | $ mkdir -p /root/esm |
注:可使用./migrator-linux-amd64 --help
查看使用帮助
1 | -s, --source=源elasticsearch实例,即:http://localhost:9200 |
方案三:使用python脚本进行导入导出
代码已在Github上开源,项目地址为:https://github.com/Logistic98/es-data-transfer
详见我的另一篇博客:使用Flask封装集成深度学习算法
6.5.6 ES的定期自动备份
实际在生产环境上,我们不会每天都去手动备份。可以写一个脚本出来,完成这项操作,然后用 crontab 定时执行。
Step1:新建一个esbackup.sh
脚本,并使用chmod u+x
命令赋予可执行权限,该脚本是基于elasticdump的,脚本内容如下:
1 | !/bin/bash |
说明:
1)上面的信息部分换成自己的,备份输出目录的末尾不要加‘/’,多个数据库用空格分隔不要加逗号。
2)为了节约硬盘空间,我这里对sql进行了压缩(如果不想压缩就不用安了,注释掉相关代码即可),请先安装xz命令。
1 | $ apt-get install xz-utils |
3)为了节约硬盘空间,我这里删除了30天前的备份(根据文件的最后改动时间来判定),具体保留几天自己定就行。
Step2:配置定时任务执行脚本
1 | $ crontab -e |
然后添加如下代码保存即可:
1 | 59 23 * * * 脚本路径/esbackup.sh |
说明:含义是每天23:59分自动执行脚本,详细使用见上文”2.2.5 Crontab定时任务”.
6.5.7 使用Logstash将MySQL数据同步到ES
[1] 安装Logstash
项目地址:https://github.com/elastic/logstash
下载地址:https://www.elastic.co/guide/en/logstash/7.14/installing-logstash.html#_apt
处理流程:

注意要有 java8 的环境(没有的话先参照 2.2.11 安装 jdk8),然后要安装跟ES一样的版本,以下是 Logstash 的安装命令:
1 | $ mkdir -p /root/mysql_sync_es && cd /root/mysql_sync_es |
[2] 配置Logstash
Step1: 下载一个 mysql-connector-java-5.1.34.jar
1 | $ wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.34/mysql-connector-java-5.1.34.jar |
Step2:创建同步配置文件
1 | $ mkdir -p /root/mysql_sync_es/last_update_data |
单表同步的配置示例如下:
1 | input { |
注:多表配置和单表配置的区别在于input模块的jdbc模块有几个type,output模块就需对应有几个type。document_id => "%{id}"
是根据id去更新(如果不会更新旧数据,这个去掉即可),如果有重命名,%{}
里应该是重命名之后的。
[3] 启动Logstash开始数据同步
1 | 方式一:指定具体的配置文件 |
注意事项:
1)需要指定 path.data,否则会报如下错误
1 | Logstash could not be started because there is already another instance using the configured data directory. If you wish to run multiple instances, you must change the "path.data" setting |
2)可以提前写好用于启动的 shell 脚本,这样就更方便启动了。
3)关闭 Logstash 可通过 kill 进程来实现
1 | $ ps -ef | grep logstash |
6.5.8 使用curl命令操作ES
1 | // 查询所有索引 |
6.6 Docker-Neo4j环境搭建
6.6.1 拉取镜像并运行容器
1 | $ docker pull neo4j |
6.6.2 neo4j的可视化查看
浏览器打开:http://IP:7474/browser/
查看即可。
6.7 Docker-Minio环境搭建
6.7.1 拉取镜像并运行容器
1 | $ docker pull minio/minio |
注:密码不可以设置的太简单了(会导致创建失败),出现此问题请查看容器日志。
6.7.2 minio的管理面板
浏览器打开:http://IP:9001
查看即可。MINIO_ACCESS_KEY为账号,MINIO_SECRET_KEY为密码。进去之后创建存储桶,即可进行使用。
6.7.3 使用rclone同步minio数据
Rclone 是一个开源的命令行程序,用来同步文件和目录进或者出云存储系统,它旨在成为”云存储的rsync”。除了minio之外,也支持其他云存储的同步。
项目地址:https://github.com/rclone/rclone 官方文档:http://docs.minio.org.cn/docs/master/rclone-with-minio-server
Step1:安装rclone
1 | $ curl https://rclone.org/install.sh | sudo bash |
Step2:新建配置文件
在/root/.config/rclone/rclone.conf
路径新建配置文件,内容如下:
1 | [oldminio] |
注:只需修改 access_key_id、secret_access_key、endpoint的值即可,可添加多个数据源。
Step3:进行数据同步
1 | $ rclone sync -P oldminio:mybucket newminio:mybucket |
解释说明:
- 使用
sync
参数,同步有差异的数据 -P
显示详细过程mybucket
桶名称,新minio
没有则自动创建
注意事项:
- 注意存储桶的访问策略,如果为Public可以直接访问,如果为Private不可访问,如果为Custom请在有权限访问的服务器上进行操作。
- rclone是一个数据同步工具,支持增量更新,可用于minio数据的跨网传输。
6.8 Docker-MongoDB环境搭建
6.8.1 拉取镜像并运行容器
1 | $ docker pull mongo:latest |
参数说明:–auth:需要密码才能访问容器服务,启动容器后进入容器为用户设置密码
6.8.2 Mongodb创建用户并可视化查看
1 | $ docker exec -it mongodb mongo admin |
Mongodb使用Navicat工具连接即可(验证数据库那栏空着就行)
7. 网站环境搭建
7.1 申请泛域名SSL证书并开启HTTPS
SSL证书是一种数字证书,用于加密从用户的浏览器发送到Web服务器的数据。 通过这种方式,发送的数据对于使用Wireshark等数据包嗅探器来拦截和窃听您的通信的黑客来说是安全的。
Chrome一直在推动https,所有的http协议网站被标记为不安全,如果再不对网站进行https改造的话,那么可能会对信任度造成一定的影响,所以说对一个面向用户的网站来说,开启https是非常有必要的。
下面将使用acme.sh开源项目申请免费的Let’s Encrypt 泛域名SSL证书。
7.1.1 安装 acme.sh
1 | $ curl https://get.acme.sh | sh |
普通用户和 root 用户都可以安装使用,安装过程进行了以下几步:
[1] 把 acme.sh 安装到你的 root 目录下,并创建 一个 bash 的 alias, 方便你的使用。
[2] 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书。
注:安装过程不会污染已有的系统任何功能和文件,所有的修改都限制在安装目录中。那个socat未安装的问题不用管,那是http验证无Web Server时才需要的。
7.1.2 生成SSL泛域名证书
acme.sh 实现了 acme 协议支持的所有验证协议,一般有两种方式验证:http 和 dns 验证。
- http 验证:http 方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权。
- dns 验证:dns 方式,在域名上添加一条 txt 解析记录,验证域名所有权。
dns 方式的可以使用域名解析商提供的 API 自动添加 txt 记录完成验证,下面我们将采用这种方法申请Namesilo的泛域名证书。
Step1:打开 https://www.namesilo.com/account/api-manager 去申请 NameSilo API,勾选第2个复选框,点击Generate,即可生成。
注:务必不要勾选上Generate key for read-only access的哪个复选框,否则会导致Unable to add the DNS record. Error add txt for domain
的问题。另外,生成的API只出现一次,如果没记下来只能重置。
Step2:在服务器输入以下命令,实现自动dns验证生成泛域名证书。
1 | $ cd /root/.acme.sh |
等待1800s即可看到申请下来的SSL证书(NameSilo的验证比较慢,官方文档上写的900s有时不足以验证完)
生成文件都放在/root/.acme.sh/example.com/
目录下,其中:example.com.key
是密钥文件,fullchain.cer
是证书文件。
注:如果你的域名不是NameSilo的,上述操作有所不同,具体请参考: https://github.com/acmesh-official/acme.sh/wiki/dnsapi
7.1.3 acme.sh的一些其他管理命令
[1] 更新 acme.sh
目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步。
1 | $ ./acme.sh --upgrade # 升级 acme.sh 到最新版 |
[2] 管理证书
1 | $ ./acme.sh --list # 查看证书列表 |
注:证书/密钥文件未从磁盘中删除,需要自己去删除相应的目录/root/.acme.sh/example.com/
[3] 证书自动续订
安装了 acme.sh 后,它会添加一个自动任务到你服务器的Cron里,每天都会检查你的证书是否快要过期,acme.sh 会自动帮你续签。
1 | $ ./acme.sh --renew -d example.com --force # 强制续签证书 |
[4] 错误排查
如果使用命令出现了错误,可在原有命令的基础上加上--debug
排查问题。
7.1.4 给网站开启HTTPS
打开宝塔面板——网站——设置——SSL——其他证书,把example.com.key
密钥文件、fullchain.cer
证书文件复制上去,强制https。
7.2 网站开启CDN服务
7.2.1 CDN与Cloudflare是什么
CDN的全称是Content Delivery Network,即内容分发网络。 CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。 CDN的关键技术主要有内容存储和分发技术。
Cloudflare 是一家全球最著名的 CDN 加速服务商,提供了免费和付费的网站加速和保护服务。即使是免费版,也提供了比较全面和强大的功能,非常不错。对于国外访问(或者使用代理)的加速效果十分明显,但对国内访问加速效果十分有限,如果是国内商用的话还是要买国内的CDN服务。
通过使用 Cloudflare CDN 服务提供的全球节点,一方面可以提高网站响应速度和性能,节省源站资源;另一方面也可以保护站点抵御攻击,保证网站长期稳定在线。
7.2.2 开启 Cloudflare CDN 服务
Step1:打开 Cloudflare CDN官网 注册账号,登录后点击添加站点(填根域名即可),选择选择 Free 套餐,确认计划。
Step2:这时 Cloudflare 会自动扫描域名已有的 DNS 解析记录,如果扫描到的话,会显示在下面,没有或者显示不正确,则需要我们自己设置。

Step3:添加成功后会显示在下面,点击 Continue 继续,按说明修改自己的域名服务器为 Cloudflare 给出的地址。
NameSilo的修改方式是:勾选域名——点击Change Nameservers——删掉原有的名称服务器,添加新的域名服务器。
注:修改域名服务器后需要一定时间生效,不会立即检测到,需要稍微等待一会儿(可打开cmd输入nslookup 域名
进行验证,如有多个IP出现,则证明已生效)。配置了CDN之后再ping域名指向的就不是我们服务器本身的IP地址了,这样对保护我们的服务器也有好处。
Step4:CDN生效后主页的域名处会标注绿色的“有效“二字,这时我们就可以开启CDN的各种服务了,根据自己需求进行配置就好。
7.2.3 CDN缓存问题
开启了CDN之后,网站的一些静态资源在更新后不会即时刷新,需要等待一段时间。如果你是在调试过程,想要即时看到结果,可以开启开发模式(登录Cloudflare CDN——缓存——配置——打开“开发模式”的按钮)
7.2.4 关闭IPv6支持
进入 CloudFlare 后台,在网站配置的“Network”下面,可以看到“IPv6 兼容性”的选项,但是比较坑的一点就是图形界面不让你操作,只能使用API去操作。
我们可以借助 CloudFlare 的 API 来实现关闭 IPv6,首先打开我们的 账户 获取 API Key。
点击Global API Key后面的查看即可。
接下来使用curl命令发送请求即可,我们只需要修改邮箱和密钥处即可。
1 | $ curl -X PATCH "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/settings/ipv6" -H "X-Auth-Email: 邮箱" -H "X-Auth-Key: 密钥" -H "Content-Type: application/json" --data '{"value":"off"}' |
请求成功后,再回到IPv6的界面,发现它已经被成功关闭啦。
7.3 Git Hooks自动部署
7.3.1 Git Hooks简介
Git 除了用作版本控制,还有许多高级功能,Git Hooks 就是其中之一。简单来说,Hook 就是在执行某个事件之前或之后进行一些其他额外的操作。Git 支持的非常多的钩子供我们使用,下面以post-receive钩子为例讲解自动部署项目。
在本地修改项目并生成编译后用于部署的文件,使用Git推送到VPS的Git仓库。Git Hooks实际上就是当Git仓库收到最新的push时,将Git仓库接受到的内容复制到VPS上的网站目录内。相当于完成了手动将用于部署的文件复制到VPS网站根目录里的操作。
7.3.2 新建网站
Step1:宝塔面板安装Nginx环境(软件商店——搜索安装Nginx)
Step2:网站——添加站点——填写域名(不创建FTP、数据库、PHP)后提交即可
Step3:修改网站根目录的用户组权限为git:git
1 | $ sudo chown git:git -R 网站根目录 |
修改后执行下列命令后再查看
1 | $ ls -l 网站根目录 |
7.3.3 修改Nginx配置
网站——指定站点——设置——配置文件
在宝塔默认的配置文件里注释掉以下代码
1 | location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ |
再添加如下代码(按照自己的网站根目录来,宝塔生成的根目录默认为新建网站时加的域名)
1 | location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ { |
7.3.4 配置Git Hooks
创建post-receive文件
1 | $ cd /home/git/blog.git/hooks //切换到hooks目录下 |
编写post-receive文件(以下仅作为参考,根据实际情况来写)
1 | #!/bin/bash |
保存退出后,赋予其执行权限
1 | $ chmod +x post-receive |
7.4 给网站设置反向代理
宝塔面板——网站——设置——反向代理——添加反向代理——填写代理名称和目标URL(http://127.0.0.1:port
)
8. 开发辅助环境搭建
8.1 搭建ReverseProxy破解JRebel热部署插件
JRebel是一款非常好用的Springboot热部署插件,但它是付费的,我们可以通过ReverseProxy服务进行破解。
这个反向代理需要一直开启着,关了就会出现连不上license server的问题,因此不建议在本机搭建,在自己VPS上搭建更为方便使用。
8.1.1 在VPS搭建ReverseProxy服务
Step1:去lanyus大佬的Github下载自己VPS对应的工具:http://github.com/ilanyu/ReverseProxy/releases/tag/v1.4,上传到服务器的/root
目录,并将文件权限改为777。
1 | $ wget https://github.com/ilanyu/ReverseProxy/releases/download/v1.4/ReverseProxy_linux_amd64 |
Step2:输入以下命令运行该代理工具:
1 | $ ./ReverseProxy_linux_amd64 |
参数说明:
1 | Usage of ./ReverseProxy_linux_amd64: |
在Jrebel的激活URL处填写:http://{VPS的IP地址}:8888/{GUID}
即可成功激活。下面是一些优化部署,建议加上但不强制。
8.1.2 配置开机自启、HTTPS及反向代理
Step1:使用 crontab 计划任务配置开机自启,见本文2.2.5节
Step2:申请SSL泛域名证书并开启HTTPS,见本文7.1节
Step3:宝塔面板新建网站并设置反向代理,见本文7.4节(注:目标URL填写为http://127.0.0.1:8888
)
Step4:在Jrebel的激活URL处填写:https://domain.com/{GUID}
即可成功激活。
8.2 搭建ProxyPool爬虫代理IP池
使用Python爬虫抓取数据的时候,我们经常会触发目标网站的反爬虫措施(通常是封IP,需要输入验证才能继续访问),导致抓取中断。我们可以利用网上的代理IP网站(有免费的也有付费的)去构建代理池,封了就自动换一个IP继续抓取。
ProxyPool是一个爬虫代理IP池的项目,可以自动从代理IP网站抓取可用的代理,目前支持十余个免费代理源,也可以自己添加代理源。
1 | ______ ______ _ |
官方提供的测试地址:http://demo.spiderpy.cn (懒得自己搭建的话也可以用这个,下面就不用看了)
8.2.1 搭建Redis数据库
ProxyPool的部署需要用到Redis数据库,用以存储代理IP信息,因此我们首先要搭建Redis数据库。
需要注意的一点是Redis数据库的版本不要太高,我一开始用的最新版报错,降级到3.2.8版本就好了。
Docker-Redis环境的搭建见本文6.3节
8.2.2 使用Docker部署ProxyPool项目
依次执行以下命令,拉取镜像并创建容器。
1 | $ docker pull jhao104/proxy_pool |
注:第二条命令db处填写的应该是0-15的一个数字,否则会报:redis.exceptions.ResponseError: invalid DB index
错误。
可以使用以下命令进入容器内部,配置文件是setting.py,我们可以根据自己的需求进行更改配置。
1 | $ docker exec -it proxy_pool /bin/sh |
注:建议将检测代理IP可用性的网址换成你要爬取的目标网址。
扩展代理也在这个文件里配置,详见项目的README吧,我这里就不赘述了。
8.2.3 配置HTTPS及反向代理
Step1:申请SSL泛域名证书并开启HTTPS,见本文7.1节
Step2:宝塔面板新建网站并设置反向代理,见本文7.4节(注:目标URL填写为http://127.0.0.1:5010
)
8.2.4 ProxyPool的API服务
用Chrome浏览器打开:https://域名
,即可访问API接口服务。
8.2.5 在爬虫中使用ProxyPool
如果要在爬虫代码中使用的话, 可以将此API封装成函数直接使用,以下是官方提供的示例,仅供参考。
1 | import requests |
注:由于代理池的节点并不全部有效,我们使用的时候仍然会有出错的情况。我这里提供一个思路——直接获取全部代理,依次尝试,把requests请求放在try-except代码块里,请求的时候检测response的状态码,如果不是200的话就再获取下一个代理节点。如果捕捉到异常或者获取的代理IP数为0,就尝试不使用代理抓取,再失败的话就报错。
建议配合上其他反反爬手段一起使用,比如随机headers、随机sleep等等。总之我用上这些手段之后,基本不被再被反爬了。
8.3 搭建EMQX物联网MQTT消息服务器
EMQX 是一款大规模可弹性伸缩的云原生分布式物联网 MQTT 消息服务器,高效可靠连接海量物联网设备,实时双向移动物联网数据,助力构建关键业务的物联网平台与应用。
8.3.1 使用Docker搭建EMQX消息服务器
1 | $ docker pull emqx/emqx |
搭建完后用浏览器访问 http://IP:18083/
地址,默认账号及密码为:admin / public
。

8.3.2 与之配套的客户端MQTTX
MQTTX是一个跨平台的 MQTT 5.0 桌面客户端工具,与EMQX搭配使用。
下载地址:https://mqttx.app/zh

说明:MQTTX崩溃的问题——删掉 C:\Users\xxx\AppData\Roaming\MQTTX\db.json
即可恢复(但原来的配置信息也都没了)
8.4 搭建LibreTranslate机器翻译API
8.4.1 LibreTranslate简介
一个开源的、可以自行搭建的翻译服务,支持多种语言的互相翻译,包括中文。翻译的准确度不如商业API,但它是永久免费的。服务器上部署LibreTranslate共计需要大约13GB的存储空间。
8.4.2 LibreTranslate部署
1 | $ docker run -itd -p 5000:5000 --name libretranslate libretranslate/libretranslate |
注:创建容器后会自动下载语言包,这个过程会比较慢,等待它安装完毕后,浏览器访问http://ip:5000
即可查看以下Web页面。
8.5 Docker可视化工具Portainer的部署
8.5.1 Portainer简介
项目简介:Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
项目地址:https://github.com/portainer/portainer
8.5.2 Portainer部署
1 | $ docker pull portainer/portainer |
用Chrome浏览器打开http://IP:9000
即可访问Portainer。
8.6 使用 verdaccio 搭建私有npm仓库
8.6.1 verdaccio简介
项目简介:verdaccio是一个简单的、零配置要求的本地私有 npm 注册表。无需整个数据库即可开始!Verdaccio 开箱即用, 拥有自己的小型数据库,并且能够代理其他注册表,并在此过程中缓存下载的模块。
项目地址:https://github.com/verdaccio/verdaccio
8.6.2 verdaccio部署
Step1:拉取镜像并创建容器挂载目录
1 | $ docker pull verdaccio/verdaccio |
Chrome 浏览器打开 http://ip:4873
,会看到如下管理界面。
Step2:发布npm包到私有库的流程
有了私有库以后,就可以在其上发布 npm 包。但初始化时需要先添加用户,设置用户名和密码等,然后就可以直接发包了。
添加用户:输入如下命令,然后输入用户名、密码和邮箱。
1 | $ npm adduser --registry http://ip:4873/ |
发布npm包:当需要把某个项目发布到私有库时,直接publish。发布成功后,刷新页面,就能看到最新发布的包。
1 | $ npm publish --registry http://ip:4873 |
Step3:安装私有库npm包的流程
在项目目录下增加 .npmrc 文件,指定仓库地址。使用 npm install 包名
,即可安装私有包了。
1 | registry=http://ip:4873/ |
8.7 搭建项目管理工具禅道
8.7.1 禅道简介
禅道 是一款国产的开源项目管理软件,它的核心管理思想基于敏捷方法scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。
8.7.2 禅道部署
1 | $ docker pull idoop/zentao |
启动完成后,打开Chrome访问http://ip:8183
地址(默认用户名:admin,密码:123456;数据库用户:root,默认密码:123456)
8.8 搭建 Nginx Proxy Manager 管理面板
8.8.1 Nginx Proxy Manager 简介
Nginx Proxy Manager门槛极低,操作简单,不需要你掌握很复杂的Nginx配置知识,只需要几步就能很轻松完成反向代理的设置和SSL证书的部署。便捷直观的web页面管理和操作无疑大大简化了一般Nginx反代服务的步骤。
项目地址:https://github.com/jc21/nginx-proxy-manager
8.8.2 Nginx Proxy Manager 部署
Step1:安装 Docker 和 Docker-Compose
Step2:编写配置文件
docker-compose.yml
1 | version: '3' |
Step3:创建并运行容器
1 | $ docker-compose up -d |
Step4:浏览器访问面板
使用 Chrome 浏览器访问 http://IP:81
地址,默认账号如下,登录后建议立刻进行修改,之后便可以看到如下面板。
1 | Email: [email protected] |
9. 参考资料
[1] 50个最常用的Unix/Linux命令 from gywbd
[2] Linux 下十大命令行下载工具 from Linux中国
[3] linux查看历史命令history from CSDN
[7] 从0搭建ShadowsocksR与BBR加速 from bbaaz
[8] Trojan-Go一键安装脚本(Debian/Ubuntu)from ssr中文网
[9] 直接安装和docker安装的区别 from php中文网
[13] Debian/Ubuntu/Centos 防火墙放行指定端口 from SunPma’Blog
[14] Docker–删除容器实例和镜像 from 极客分享
[15] Java 服务部署后浏览器无法访问,通过 curl 确可以访问 from V2EX
[16] docker与docker-compose介绍,对比与使用 from 简书
[17] 如何在Debian 9上安装Docker Compose from 腾讯云
[19] 使用acme.sh开源项目申请 let‘s encrypt 的免费SSL证书 from Github
[21] namesilo域名通过acme.sh申请Let’s Encrypt通配符HTTPS证书 from gmloc
[22] let’s encrypt证书,Namesilo用acme申请免费永久,为网站添加ssl加密HTTPS from Bilibili
[24] 搬瓦工VPS查看、修改、新增SWAP分区的大小 from 搬瓦工VPS
[25] Cloudflare 入门教程:使用 Cloudflare 免费 CDN 加速 & 保护自己的网站 from 知乎
[26] Namesilo 域名购买及使用教程 from 知乎
[29] Debian/Ubuntu Linux搭建SVN服务器,并设置开机默认启动 from ourjs
[30] SVN运维 from Github
[31] Debian 10 创建开机自启动脚本 from 心底的河流
[32] 解决insserv: warning: script ‘服务名’ missing LSB tags and overrides的问题 from Tan9le
[33] Linux系统如何设置开机自动运行脚本 from 良许Linux
[34] Hexo搭建个人博客并使用Git部署到VPS from 简书
[36] 通过 DockerFile 打包镜像 from cnblog
[37] 如何构建 Docker 镜像 from tkestack
[38] 一文带你彻底学会 Git Hooks 配置 from segmentfault
[39] Hexo搭建个人博客并使用Git部署到VPS from 简书
[42] MySQL定时备份数据库 from 知乎
[43] 如何在生产环境下实现每天自动备份mysql数据库 from 51CTO
[44] docker 中 MySQL 备份及恢复 from learnku
[45] Linux修改系统时区 from 简书
[46] Linux升级python至3.x from CSDN
[47] 如何在Debian 10上安装pip from myfreax
[48] Linux下使用docker部署Redis from CSDN
[49] OCI runtime exec failed: exec failed:解决方法 from CSDN
[50] IntelliJ IDEA热部署插件JRebel免费激活图文教程 from 积微成著
[51] 在CenOS/Debian上搭建ReverseProxy反向代理服务 from Github
[52] Python爬虫代理IP池(proxy pool) from Github
[53] redis.exceptions.ResponseError: invalid DB index怎么解决 from Github issue
[54] Python 抓取可用代理IP from CSDN
[55] python 自定义异常和主动抛出异常(raise)的操作 from 华为云
[56] 如何在 Debian 10 上安装和卸载 OpenJDK11/OpenJDK8 from linux265
[58] Linux Docker springboot jar 日志时间不正确 from CSDN
[59] nohup执行的jar 怎么kill_Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令 from CSDN
[60] linux shell脚本 自动重启挂掉的jar包 from CSDN
[61] 使用curl获取URL的重定向目标 from QAStack
[62] docker安装oracle11g(linux环境) from CSDN
[63] Docker 快速安装&搭建 Elasticsearch 环境 from 异常教程
[64] EMQX docker安装及运行 from CSDN
[65] docker安装部署neo4j from 打瞌睡的布偶猫
[66] docker搭建elasticsearch6.8.7并开启x-pack认证 from 程序员宅基地
[67] 如何在Debian 10 Linux上安装Node.js和npm from myfreax
[68] Ubuntu下crontab的安装和使用 from CSDN
[69] Cannot stop or restart a docker container from stackoverflow
[71] 如何在ubuntu 中彻底删除docker from 腾讯云
[72] docker可视化工具Portainer部署与汉化 from WebEnh
[73] 关于docker容器内部的文件上传和下载 from 代码先锋网
[74] Linux统计文件夹下的文件数目 from SnailTyan
[75] 如何在两个服务器之间传输文件或者文件夹? from CSDN
[76] docker容器打包成镜像和压缩以及解压和载入镜像 from 程序员宝宝
[77] Linux 服务器日常巡检脚本分享 from 知乎
[79] 手把手教你Debian10安装配置Golang环境,并编译hello world程序 from 老牛博客
[80] 2021 win10下beego的正确安装方法 from ICode9
[81] 利用Dockerfile部署SpringBoot项目 from 51CTO博客
[82] 在docker下部署Python项目 from Python Free
[83] linux磁盘已满,查看哪个文件占用多 from CSDN
[84] Nvidia-smi简介及常用指令及其参数说明 from CSDN
[85] Linux shell脚本传参,传入数组 from CSDN
[86] docker在容器外执行某个容器内的某个命令 from CSDN
[87] 如何跨容器调用可执行命令 from lyer’s blog
[88] 错误:the input device is not a TTY from CSDN
[89] 如何在Debian 10上安装Anaconda Python发行版 from howtoing运维教程
[90] 10 分钟上手 Vim,常用命令大盘点 from 知乎
[92] linux 下取进程占用 cpu/内存 最高的前10个进程 from CSDN
[93] 如何在Debian 11上安装Apache Maven from 云东方
[94] curl模拟delete/put/post/get请求 from CSDN
[95] 【Docker】daemon.json的作用(八)from CSDN
[96] 清空docker container logs from 暗无天日
[98] rclone 迁移minio数据 from CSDN
[99] 使用 Logstash 同步海量 MySQL 数据到 ES from 腾讯云
[100] 使用logstash 运行配置文件,出现you must change the “path.data” setting from CSDN
[101] Linux下Python程序Killed,分析其原因 from CSDN
[102] 查询CPU、GPU相关信息 from 51CTO博客
[103] 安装elasticsearch-analysis-ik分词器插件 from CSDN
[104] Centos7.5安装java8 from 简书
[105] linux下安装ffmpeg的详细教程 from 腾讯云
[106] Elasticsearch可视化工具 from CSDN
[107] CloudFlare 关闭自适应 IPv6 解析的方法 from 老唐笔记