Nginx部署网站&Docker&自动更新部署

发布时间 2024-01-09 08:42:08作者: sanhuamao

一 搭建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

检查是否能看到默认页面。如果只是想配置静态页面,这一步就可以结束了。之后修改静态文件有两种方式:

  1. 进入nginx默认配置的root目录,替换掉文件
  2. 修改nginx配置,让根目录指向你的静态文件目录

image.png

二 创建服务及配置

以nodejs为主

2.1 安装Nodejs

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放到服务器
  1. 如果把公钥放在云服务器平台,在本地通过私钥可以连接远程云服务器
ssh root@<your_IP>  # root表示用户名 根据自身情况修改
ssh -i ~/.ssh/id_rsa root@<your_IP>  # 使用 ssh 命令连接到远程服务器
# -i 指定要使用的密钥文件
  1. 如果把公钥放在代码托管平台(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