Nginx部署网站&Docker&自动更新部署
一 搭建web服务器
lsb_release -a # 查看Linux版本
Linux不同版本的操作方式会有所不同,注意区分。我是在阿里云买的,用的是AlibabaCloud,所以文章的大部分命令会以这个系统为准。
1.1 安装与启动Nginx
# Debian/Ubuntu
apt install nginx
service nginx start # 启动
service nginx enable # 自启
# AlibabaCloud/CentOS
yum install nginx
systemctl enable nginx
systemctl start nginx
检查
nginx -t # 判断配置是否正确
ps aux | grep nginx # 判断进程运行情况
1.2 配置防火墙
# Debian/Ubuntu
sudo ufw status
suoo ufw allow http # 放行http ---> 禁止: ufw reject http
sudo ufw allow https # 放行https
# sudo ufw enable # 自启防火墙 ---> 关闭自启: ufw enable http
# AlibabaCloud/CentOS
sudo systemctl start firewalld
sudo firewall-cmd --permanent --zone=public --add-service=http # 允许Nginx的HTTP端口(80)
sudo firewall-cmd --permanent --zone=public --add-service=https # 允许Nginx的HTTPS端口(443)
sudo firewall-cmd --reload
判断是否放行成功
netstat -nltp |grep -E '80|443'
在云环境中,可以通过配置安全组规则来实现防火墙的功能(以阿里云为例)
1.3 测试默认页
# 查看配置
cat /etc/nginx/nginx.conf
# 修改配置
vi /etc/nginx/nginx.conf
检查是否能看到默认页面。如果只是想配置静态页面,这一步就可以结束了。之后修改静态文件有两种方式:
- 进入nginx默认配置的root目录,替换掉文件
- 修改nginx配置,让根目录指向你的静态文件目录
二 创建服务及配置
以nodejs为主
2.1 安装Nodejs
# Ubuntu
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - &&\
sudo apt-get install -y nodejs
# Debian
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - &&\
apt-get install -y nodejs
# AlibabaCloud/CentOS
curl -fsSL https://rpm.nodesource.com/setup_lts.x | bash -
yum install -y nodejs
如果想换其他版本:
# 查看当前安装的版本
yum list installed | grep node
# 卸载掉上面列出的版本
yum remove <node_name>
# 清除 Node.js 存储库配置
sudo rm -f /etc/yum.repos.d/nodesource*.repo
# 使用新的版本号配置 Node.js 存储库
curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
# 安装
sudo yum install nodejs -y
2.2 安装Git(可选)
apt-get install git
apt install git
yum install git
初始化仓库
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin <your_repo>
git push -u origin main
2.3 创建服务
有两个例子
2.3.1 nodejs app
# 随便找个目录放项目
mkdir /var/www/app
cd /var/www/app
git init
touch app.js # 创建一个本地服务器 端口号为3001
npm init -y
vi app.js
内容如下:
const http = require('http');
const PORT = 3001;
http.createServer((req, res) =>{
res.write("Hello");
res.end();
}).listen(PORT)
console.log("Server running on port "+PORT);
按
ESC
进入一般模式,接着按i
进入命令模式,再输入wq,按Enter
可保存文件
node app.js # 启动
如果关掉终端,也希望服务启动怎么办?-->使用pm2
pm2:管理nodejs应用程序
sudo npm i -g pm2 # 全局安装
pm2 start app.js # 让程序在后台运行 即便关掉了shell
pm2 list
pm2 save # 将当前的进程状态保存到配置文件中
pm2 startup # 启动PM2服务器,监视和管理Node.js应用程序的多个进程,并在它们崩溃时重启它们
pm2 stop app # 停止
2.3.2 websocket
https://github.com/sanhuamao1/websock_test
cd /var/www
git clone https://github.com/sanhuamao1/websock_test.git
cd websock_test
node app.js
2.4 配置Nginx
# 根据系统的不同找一个合适的文件夹放配置,我选择的是以下目录
cd /etc/nginx/sites-include
2.4.1 代理配置
nodejs app 对应的配置
vi node_app
server{
listen 80;
listen [::]:80;
location / {
proxy_pass http://127.0.0.1:3001; # 对应于nodejs服务,你的nodejs监听的是哪个端口,就用哪一个
}
}
websocket 对应的配置
vi ws_app
server{
listen 80;
listen [::]:80;
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://127.0.0.1:3001; # 对应于websocket服务
}
}
2.4.2 静态页面配置
vi default
server{
listen 80;
listen [::]:80;
server_name <域名>;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /40x.html{
}
error_page 500 502 503 504 /50x.html;
location = /50x.html{
}
}
只是把原本写在
/etc/nginx/nginx.conf
的默认配置移了出来,方便切换配置
更简单的版本
server{
listen 80;
listen [::]:80;
server_name <域名>;
root /var/www/docs; # 根据情况。我这里创建了一个目录,放博客的静态文件
index index.html;
}
2.5 更改配置
sudo vi /etc/nginx/nginx.conf
# 找include关键字,通过include来引入配置,其他不用的注释即可
include /etc/nginx/sites-include/docs;
2.6 检查与重启
sudo nginx -t # 检查配置是否出错
# 二选一重启nginx
sudo service nginx restart
systemctl reload nginx.service
现在就可以检查web服务是否正常了
2.7 本地域名配置(可选)
# windows 进入以下目录
C:/Windows/System32/drivers/etc
点击左上角的文件,点击以管理员身份打开
# 编辑文件,加上想要的域名解析
notepad hosts
# hosts
<ip> <域名>
三 Ssh免密
生成秘钥,并把公共秘钥放在远程服务器上
cd ~/.ssh
ssh-keygen -t rsa -C "yours@qq.com" # 生成密钥,包括private key和public key
cat ~/.ssh/id_rsa.pub # 拿public key放到服务器
- 如果把公钥放在云服务器平台,在本地通过私钥可以连接远程云服务器
ssh root@<your_IP> # root表示用户名 根据自身情况修改
ssh -i ~/.ssh/id_rsa root@<your_IP> # 使用 ssh 命令连接到远程服务器
# -i 指定要使用的密钥文件
- 如果把公钥放在代码托管平台(github/gitee),就可以免密操作远程仓库
git clone <ssh连接>
四 Docker
- 作用:使用容器来打包应用程序,使得应用程序可以独立于基础架构运行。
- 思路:把项目所需要的依赖都打包到镜像里(比如nodejs等),然后通过镜像创建容器,运行容器就相当于运行服务。
- 好处:不用关心本地的环境是否与项目环境一致。它将创建一个虚拟容器,来配置和安装好项目所需要的环境和依赖。
以上方的nodejs app服务为例
4.1 安装docker
# 不同Linux系统有不同操作方式
apt install docker.io
# OR
yum install docker
4.2 创建Dockerfile文件
cd /var/www/app # 进入项目目录
vi Dockerfile # 创建镜像文件
写入一下配置
# 指定nodejs版本
FROM node:18-alpine
# 设置工作目录
WORKDIR /usr/src/app
# 复制应用代码到工作目录
COPY . .
# 安装应用依赖
RUN npm install
# 暴露应用运行的端口
EXPOSE 3001
# 定义启动命令
CMD ["node", "app.js"]
FORM 后面支持的版本可在 nodejs镜像 查询
4.3 构建镜像和容器
# /var/www/app
# 1.构建镜像
# 使用 Dockerfile 构建名为 node-app 的 Docker 镜像
docker build -t node-app . # 等同于 docker build -t node-app /var/www/app
# 2.构建容器
# -p 3001:3001,左侧主机,右侧容器,把容器的端口 3001 映射到主机的端口 3001
# -d 以后台模式运行
docker run -d -p 3001:3001 node-app
Docker其他操作
# 查看镜像
docker image ls
# 删除镜像
docker rmi <image_id>
# 查看容器
docker ps -a # 查看所有容器
docker ps -q # 查看正在运行的容器
# 操作容器
docker start <container_id> # 运行某个已经存在的容器
docker stop <container_id> # 停止容器
docker kill <container_id> # 关掉正在运行的容器
docker rm <container_id> # 删除容器
docker run -d -p <host_port>:<container_port> <image_name> # 构建与运行容器
五 CI/CD
- Countinuous intergration:代码修改被验证过,且合并进主分支
- Continuous delivery:代码修改后会自动构建
- Continuous deployment:构建的代码自动部署到生产环境
Vuepress博客示例:定时更新仓库构建静态文件,并把构建好的内容部署到服务器上
注意降低node版本, 之前使用20.x时,build的时候会报错,后面改成了14.x
5.1 编写脚本
# 随便找个文件夹创建一个脚本和日志
cd /var
mkdir time
# /var/time/
touch docs_gitee.log # 日志文件
vi docs_gitee.sh # 脚本文件
内容如下:
#! /usr/bin/bash
# 仓库所在位置(根据实际情况改写)
repos_path=/var/www/repos/vuepress_docs
# nginx配置的根目录:'/var/www/docs' (根据实际情况改写)
www_path='/var/www' # nginx放内容的目录
folder_name=docs # 某一个网站的目录
# 清空日志
echo "" > $(pwd)/docs_gitee.log
# 更新仓库
cd ${repos_path}
git pull
# 最后一次提交的hash
commit_hash=$(git log -1 --pretty=format:%H)
# 最后一次提交的时间戳
commit_timestamp=$(git log -n 1 --format=%ct ${commit_hash})
# 格式化时间
formatted_commit_time=$(date -d @$commit_timestamp +"%Y-%m-%d %H:%M:%S")
# 最后一次描述
commit_des=$(git log -n 1 --format=%s ${commit_hash})
# 安装依赖
echo -e "=============== Start to install... ===============\n"
if npm install; then
echo "npm install succeeded."
else
echo "npm install failed."
exit
fi
# 开始构建 (vuepress默认情况下会把生产文件放在 docs/.vuepress/dist/ 中)
echo -e "=============== Start to build... ===============\n"
if npm run build; then
echo "npm run build succeeded."
else
echo "npm run build failed."
exit
fi
# 整理文件结构
mv ${repos_path}/docs/.vuepress/dist ${www_path} # 把构建好的文件夹 移动到nginx目录中
cd ${www_path} # 进入nginx的目录
rm -rf ${folder_name} # 删除原来的网站目录(docs)
mv dist ${folder_name} # 把构建好的文件夹dist 重命名为网站目录(docs)
echo "Success!"
# 编写一个版本文件
cd ${www_path}/${folder_name}
touch version.html
{
echo "==============================<br>"
echo "Last changed time: ${formatted_commit_time}<br>"
echo "Last deployed time: $(date)<br>"
echo "Last commit SHA: ${commit_hash}<br>"
echo "Last commit message: ${commit_des}<br>"
echo "==============================<br>"
} >> version.html
echo $(cat version.html)
5.2 检验脚本
sh /var/time/docs_gitee.sh
如果执行不了:1.确认所有者;2.确认权限
5.3 定时执行脚本
crontab -e # 创建定时器 (执行这个)
crontab -l # 查看运行的定时器
crontab -r # 清空定时器
内容如下:
*/5 * * * * sh /var/time/docs_gitee.sh > /var/time/docs_gitee.log 2>&1
# 每五分钟执行一次,并把输入内容写入docs_gitee.log中
前面的时间规定可在这里查询含义:crontab.guru
5.4 查看日志
cat /var/time/docs_gitee.log
tail -f /var/time/docs_gitee.log