Skip to main content

2 posts tagged with "nginx"

View All Tags

· 16 min read

选择 gatsby 主要有几点理由:

  • 基于 react
  • 内置 markdown 处理器
  • 生态良好,插件较丰富
  • 无后端、部署简单

比较明显的缺点应该就是需要在本地编辑文章和上传,但我也经常在本地写 markdown 文章,所以对我而言问题不大

搭建开发环境

先确保 node 已安装,然后全局安装 gatsby-cli,基于 gatsby-starter-blog 来快速开启博客页面

npm install -g gatsby-cli
gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog
cd my-blog
npm run dev

然后就可以打开 localhost:8000 访问页面了,刚开始还是一些模板代码,可以替换或者去掉

GraphQL

页面数据是通过 GraphQL 查询拿到的,在你本地启动 Gatsby 服务时,也会同步启动 GraphQL 的服务。你的文件、图片等所有资源会被 Gatsby 和一些安装的插件解析到 GraphQL 的节点上,通过特定的语法就可以按需获取需要的数据

简而言之,Gatsby 的工作原理就是通过 GraphQL 的 api 和你指定的语法完成数据的按需获取,再用获取到的数据渲染成静态网页

接入评论功能

可以通过 utterances + github issues 实现,实际上就是先拿到用户的 github 信息,然后将评论作为 issue 推送至指定的仓库。这样也就不用专门去搞个数据库存储评论数据了

  1. 创建一个存放评论信息的 github 仓库
  2. 安装 utterances 并授权
  3. 配置信息,比如按文章名作为 issue 名称。可以参考这个 https://utteranc.es/
  4. 新建一个 Comments 组件
import * as React from "react";
import { useEffect, useRef } from "react";

const Comments = () => {
const commentsRef = useRef < HTMLDivElement > null;
useEffect(() => {
const script = document.createElement("script");
script.src = "https://utteranc.es/client.js";
script.setAttribute("repo", "GitHubJackson/blog-comments");
script.setAttribute("issue-term", "title");
script.setAttribute("label", "💬");
script.setAttribute("theme", "github-light");
script.setAttribute("crossorigin", "anonymous");
script.async = true;

if (commentsRef.current) {
commentsRef.current.appendChild(script);
}

return () => {
if (commentsRef.current) {
commentsRef.current.innerHTML = "";
}
};
}, []);
return <div ref={commentsRef} />;
};

export default Comments;

src/templates/blog-post.js 中插入组件

//...
<Layout location={location} title={siteTitle}>
//...
<Comments />
</Layout>
//...

效果如图:

新增页面

直接在 pages 文件夹下新增页面即可,可以直接用 typescript 编写组件(tsx),项目已经默认支持

我的博客页面如下:

  • Archive 归档,文章归档页,按照发布时间排序
  • Categories 分类,文章分类页
  • Tags 标签,文章标签页、以标签云的方式呈现
  • About 关于,展示作者的信息、提供留言板
  • Lab 实验室,展示自己的一些小项目

上面几个是比较常见的博客页面了,还可以往后追加自己的 Github 主页等等

在文章前加上对应信息,比如:

---
title: 文章标题
createTime: "2020-10-23"
updateTime: ""
type: "js"
tags: "js,class,es6,原型,面向对象"
description: "balabala..."
---

markdown 文件会被 gatsby-plugin-remark 解析成 markdownRemark 的节点,以上描述信息会被解析到 frontmatter

可以通过修改 frontmatter 代码获取指定数据,比如我想获取文章分类,新建一个分类页面categories.tsx,参考代码如下

// categories.tsx
import { graphql } from "gatsby";
import * as React from "react";
import Layout from "../components/layout";
import "../css/categories.css";

export default ({ data, location }) => {
const siteTitle = data.site.siteMetadata?.title || `Title`;
// 拿到所有的文章数据
let posts = data.allMarkdownRemark.nodes;
let categories: any[] = [];
// 计算各分类文章的数量
posts.forEach((post) => {
const current = categories.find(
(category) => category.title === post.frontmatter.type
);
if (!current) {
categories.push({
title: post.frontmatter.type,
count: 1,
});
} else {
current.count = current.count + 1;
}
});

return (
<Layout location={location} title={siteTitle}>
{categories.map((category) => {
return (
<div key={category.title} className="category">
{category.title}{category.count}
</div>
);
})}
</Layout>
);
};

export const pageQuery = graphql`
query {
site {
siteMetadata {
title
}
}
allMarkdownRemark(
sort: { fields: [frontmatter___createTime], order: DESC }
) {
nodes {
excerpt
fields {
slug
}
// 通过该字段查询文章开头的描述信息
frontmatter {
type
}
}
}
}
`;

最终的分类页面参考 https://blog.zhouweibin.top/categories/

文章相关

toc

基于 Tocbot 为 md 文章增加一个目录

npm install tocbot

在文章代码中增加目录初始化逻辑如下:

// blog-post.tsx
useEffect(() => {
// ...
// 指定作为目录标题的标签
const headerArr = ["H1", "H2", "H3", "H4"];
const blogContentNode = document.getElementsByClassName("blog-content")[0];
if (!blogContentNode?.children?.length) {
return;
}
// 遍历文章节点,给所有的目录标题节点增加 id,可用于锚点定位
// @ts-ignore
[...blogContentNode.children].forEach((child) => {
if (headerArr.includes(child.nodeName)) {
// 去除空格以及多余标点
let headerId = child.innerText.replace(
// eslint-disable-next-line no-useless-escape
/[\s|\~|`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\||\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?|\:|\,|\。]/g,
""
);
headerId = headerId.toLowerCase();
// NOTE 需要确保name唯一,最好加个自增id
child.setAttribute("id", headerId + "-" + num);
num++;
}
});
tocbot.init({
// Where to render the table of contents.
tocSelector: ".js-toc",
// Where to grab the headings to build the table of contents.
contentSelector: ".blog-content",
// Which headings to grab inside of the contentSelector element.
headingSelector: "h1, h2, h3, h4",
});
// ...
});

通过修改对应的类名可以调节目录样式。如果感觉自己写的样式不好看,可以去掘金或者其他网站借鉴下源码 ~

参考 https://tscanlin.github.io/tocbot/

阅读时长

gatsby-transformer-remark 插件已经帮我们计算好了阅读时长,直接修改 GraphQL,再到组件代码中获取

// helper/utils.ts
export function formatReadingTime(minutes: number) {
let cups = Math.round(minutes / 5);
if (cups > 4) {
return `${new Array(Math.round(cups / 4))
.fill("🍚")
.join("")}${minutes} mins`;
} else {
return `${new Array(cups || 1).fill("🍵").join("")}${minutes} mins`;
}
}
// pages/index.tsx
// 找个合适的位置
<span style={{ marginLeft: 8 }}>{`${formatReadingTime(
post.timeToRead
)}`}</span>;
// ...
export const pageQuery = graphql`
query {
site {
siteMetadata {
title
}
}
allMarkdownRemark(
sort: { fields: [frontmatter___createTime], order: DESC }
) {
nodes {
excerpt
fields {
slug
}
timeToRead
frontmatter {
createTime(formatString: "YYYY/MM/DD")
updateTime(formatString: "YYYY/MM/DD")
title
type
tags
description
}
}
}
}
`;

效果如下:

夜间模式

借助 gatsby-plugin-use-dark-mode 来实现夜间模式,保护眼睛 ~

yarn add gatsby-plugin-use-dark-mode @fisch0920/use-dark-mode
// use-dark-mode 和 Gatsby v3 的react版本有冲突
// 所以这里使用社区的fork解决版本 @fisch0920/use-dark-mode

增加插件

// post-config.js
plugins: [
"gatsby-plugin-use-dark-mode",
// ...
];

组件就先简单用 antd 的 Switch 组件

// components/dark-mode-toggle.tsx
import * as React from "react";
import useDarkMode from "@fisch0920/use-dark-mode";
import { Switch } from "antd";

const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<Switch
checked={darkMode.value}
onChange={darkMode.toggle}
checkedChildren=""
unCheckedChildren=""
/>
);
};

export default DarkModeToggle;

在布局组件 Layout.js 中引入组件

import DarkModeToggle from "./dark-mode-toggle";
import useDarkMode from "@fisch0920/use-dark-mode";

//...
const darkMode = useDarkMode(false);
//...
<DarkModeToggle mode={darkMode} />

增加夜间模式相关的全局样式

/* src/style.css */
/* 主题模式 */
body.light-mode {
background-color: #fff;
color: #333;
transition: background-color 0.3s ease;
}
body.dark-mode {
background-color: #212121;
color: #999;
transition: background-color 0.3s ease;
}
.dark-mode .global-header {
background-color: #212121;
transition: background-color 0.3s ease;
}

上面只是实现了基础功能,DarkModeToggle 组件建议自行美化下。点击切换模式应该就能看到效果了。但实际效果可能还会有问题,比如有一些你自定义颜色或背景色的模块,需要在 src/style.css 针对性地去定义夜间模式下的颜色

其他组件

返回顶部

当文章太长时,往往需要增加一个返回顶部的小按钮,便于快速回到顶部,主要代码如下:

// blog-post.tsx
function handleScrollToTop() {
// 滚动到顶部
document.documentElement.scrollTo({
top: 0,
behavior: "smooth",
});
}
// ...
useEffect(() => {
// ...
function handleScroll(e) {
const rootElement = document.documentElement;
const scrollToTopBtn = document.querySelector(
".back-to-top"
) as HTMLElement;
const scrollTotal = rootElement.scrollHeight - rootElement.clientHeight;
if (rootElement.scrollTop / scrollTotal > 0.5) {
// 显示按钮
scrollToTopBtn.style.bottom = "36px";
scrollToTopBtn.style.opacity = "1";
} else {
// 隐藏按钮
scrollToTopBtn.style.bottom = "-36px";
scrollToTopBtn.style.opacity = "0";
}
}
document.addEventListener("scroll", handleScroll);
return (() => {
document.removeEventListener("scroll", handleScroll);
})
})

按钮样式自行发挥吧,可以简单写个过渡动画 ~

分析网站

可以通过谷歌的 Google Analytics 来分析自己的网站,包括网站流量、访客信息、访问设备、浏览次数等

其实工作原理就类似于埋点,将一段谷歌的代码注入博客网页,它会帮忙收集和分析登录网页的用户信息

教程详情参照 设置 Google Analytics(分析)全局网站代码

获取到代码后,将其注入到 components/seo.js 组件中即可

import { Helmet } from "react-helmet";

<Helmet>
{/* <!-- Global site tag (gtag.js) - Google Analytics --> */}
<script
async
src="https://www.googletagmanager.com/gtag/js?id=你的跟踪ID"
></script>
<script>
{`
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments)}
gtag('js', new Date()); gtag('config', '你的跟踪ID');
`}
</script>
</Helmet>;

这其实是 react-helmet 这个依赖帮忙将这段代码注入到网页的 head 中,感兴趣可以自行去了解 ~

sitemap

可以借助 gatsby-plugin-sitemap 插件自动生成 sitemap

// gatsby-config.js
module.exports = {
siteMetadata: {
siteUrl: `https://blog.zhouweibin.top`,
},
plugins: [`gatsby-plugin-sitemap`],
};

打包部署后,会自动在根目录下生成 sitemap 文件。我是用的 v5 版本的插件,会生成 sitemap 文件夹,存放 sitemap-index.xml(站点地图索引,会指向最终的站点地图),可以通过 'https://blog.zhouweibin.top/sitemap/sitemap-index.xml' 访问验证

之后可以上 google(google 站点地图)或百度(百度收录)上传站点地图。上传会有延迟,不代表 sitemap 失效,大概半小时生效吧

seo 优化

其实这方面已经有做了一些处理,参见 components/seo.js

部署到服务器

需要有个服务器部署博客页面(也可以试试用 CMS),我个人使用 centos 系统,服务器的话,选腾讯云阿里云的轻量服务器就行,新人可以点以下链接领取大额优惠券

还有个人域名、https 证书也都是个人网站需要的,建议在同一家云服务方按需购买

配置 nginx

配置下 nginx ,可以接入个人域名,以及配置二级域名转发等等

yum install nginx
systemctl start nginx # 启动
systemctl enable nginx # 开发自启动

nginx 配置文件目录为 /etc/nginx/nginx.conf,简单配置如下:

#...
http {
#...
server {
listen 8080;
server_name localhost;
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
root /home/blog-next; # 静态资源存放位置,比如博客项目打包生成的 public 文件
index index.html;
}
}
}

修改完,重启一下 nginx systemctl restart nginx

然后通过 http://[你的ip地址]:8080 其实就可以访问到你的页面了

追加个人域名、https 和二级域名转发的配置如下:

https 证书在腾讯云或者阿里云都有对应的免费证书可领

#...
http {
#...
server {
listen 8080;
server_name zhouweibin.top;
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
root /home/blog-next;
index index.html;
#try_files $uri $uri/ /index.html; # 单页面应用需要该配置
}
}

server {
listen 80;
server_name blog.zhouweibin.top; # 二级域名转发
location / {
proxy_pass http://127.0.0.1:8080;
#root /home/blog-next;
#index index.html;
#try_files $uri $uri/ /index.html;
}
}

# Settings for a TLS enabled server.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name blog.zhouweibin.top;
root /usr/share/nginx/html;

ssl_certificate "/etc/nginx/cert/6687351_blog.zhouweibin.top.pem"; # 指向证书存放位置
ssl_certificate_key "/etc/nginx/cert/6687351_blog.zhouweibin.top.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
proxy_pass http://127.0.0.1:8080;
}
}
}

打包上传

npm run build

将打包生成的 public 文件夹上传到服务器 nginx 指定的静态资源文件夹,比如我是放在 /home/blog-next。接下来就可以通过 https://blog.zhouweibin.top 访问了

服务器相关操作可以参考我之前总结的文章 - 服务器环境入门级搭建

快速上传文件可以用 FileZilla 可视化界面直接操作

自动部署

可以借助 github 和 jenkins 实现一个简单的自动部署能力

  1. 先创建一个 github 项目,与本地项目关联上
  2. 搭建 jenkins 环境。这个可以参考我之前写的文章 - 服务器环境入门级搭建
  3. github 给项目添加一个 webhook,和 jenkins 关联上

jenkins shell 脚本如下:

#!/bin/sh
cd /var/lib/jenkins/workspace/blog-next
rm -rf node_modules public
npm config set registry https://registry.npmmirror.com/ # 也可以在项目中增加 npmrc 文章指定默认源
npm install #安装项目中的依赖
npm run build
cd public
cd /home #进入web项目根目录
if [ ! -d "blog-next" ]; then
sudo mkdir blog-next
fi
cd /home/blog-next #进入web项目根目录
sudo rm -rf *
sudo mv /var/lib/jenkins/workspace/blog-next/public/* ./ #移动刚刚打包好的项目到web项目根目录

接下来就可以尝试提交代码(git push),测试下自动部署的能力了

最后

接下来,就可以开始经营你的个人博客了,写博客、实现更多的功能(文章目录、分类等)、增加其他页面,等等...这篇文章也会在后续持续更新,带来更多的玩法 ~!

参考

· 11 min read

其实之前读书期间就折腾了好长时间在整服务器,主要就是做自己的博客网页,这篇文章算是把之前磕磕绊绊的经验稍微总结了一下吧,入个门应该还是可以的 ~

购置

服务器

操作系统看个人喜好吧,我选择的是 centos 7.6,因为比较熟悉..下面也是基于这个操作系统来讲的

域名

个人网站需要

https 证书

  • FreeSSL。可以申请免费的证书
  • 腾讯云和阿里云也都可以申请一年期限的免费证书

腾讯云免费证书申请 https://console.cloud.tencent.com/ssl

远程连接

mac 远程连接服务器,终端软件推荐使用 iterm2,FTP 软件推荐使用 FileZilla

具体连接过程参考 https://github.com/GitHubJackson/efficient-mac/blob/master/frontend-dev.md

yum

linux 的包管理工具,常用命令如下:

# -- 检索(会同时列出 Installed Packages 和 Available Packages)
yum list nodejs
yum list installed # 单独列出 Installed Packages
yum search nodejs # list 只搜索软件包名称,而 search 不光搜索包名,还包括摘要和描述

# -- 安装
yum install nodejs (加 -y 可自动应答 yes)

# -- 更新
yum check-update # 列出每个包可升至的版本
yum update
yum update nodejs

# -- 查看详情(可查看安装的也可查看未安装的包)
yum info nodejs

列出全部/可用/不可用仓库
yum repolist enabled

# -- 卸载
yum remove nodejs

# -- 缓存
yum clean all 清除缓存
yum makecache 生成新的缓存

详情参考 https://wangchujiang.com/linux-command/c/yum.html

zsh

因为我自己在本地使用的是 zsh,而且 zsh 也兼容 bash,为了保持一致,先配置一下 zsh 吧(当然,你要是觉得麻烦,完全可以继续用 bash 或者其他 Shell,想知道 zsh 优势的话,可以参考这篇文章 https://zhuanlan.zhihu.com/p/19556676 ~)

yum install git // 后续需要从git仓库下载插件
yum install zsh
which zsh
chsh -s /usr/bin/zsh // 切换 shell

安装 oh my zsh(命令记忆、补全能力和主题太香了 ~)

sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

安装插件和配置的具体过程跟本地配置类似,参考 https://github.com/GitHubJackson/efficient-mac/blob/master/tools.md

前端环境搭建

这个网站主要是放前端相关的项目,所以必备的环境得先搭建好

nvm

管理 node 版本

curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash

node/npm

nvm install stable
node -v
npm -v

jenkins

用于搭建 CI/CD,主要是拉取 github 项目,将其部署到服务器上。在提交代码到 github 时,可以通过 webhook 触发 jenkins 自动部署 ~

  1. 安装好 java 环境和 jenkins
yum install -y java
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
yum install -y jenkins
  1. 修改 jenkins 的默认端口
// /etc/sysconfig/jenkins
JENKINS_HOME -- Jenkins的主目录
JENKINS_USER -- Jenkins的用户,拥有$JENKINS_HOME和/var/log/jenkins的权限
JENKINS_PORT -- Jenkins的端口,默认端口是8080,建议改变,防止占用端口冲突
  1. 启动服务和开机自启
systemctl start jenkins
systemctl enable jenkins
  1. 安装插件和创建管理员用户

安装 ssh 插件Publish Over SSH,可以验证服务器是否开启远程登录

nginx

做子域名映射和负载均衡 balabala...

yum install nginx
systemctl start nginx
systemctl enable nginx

nginx 配置文件目录为/etc/nginx/nginx.conf

其他常用命令:

systemctl restart nginx
systemctl status nginx
systemctl stop nginx

pm2

为 node 应用守护进程,比如博客后台、ssr 服务等...

npm -g install pm2

创建软链接:

ln -s [pm2命令位置,which pm2] /usr/bin/pm2

开启 nextjs 应用

pm2 start npm --name "my-next" -- run start

搭建 CI/CD

一个简单的 CI/CD 流程主要有几点:

  1. 设置 github 项目 webhook
  2. github 代码更新,触发 webhook
  3. jenkins 执行脚本
    1. 拉取最新代码到指定目录(覆盖)
    2. 安装依赖
    3. 执行项目

项目配置

node 应用

  1. 关联 github 仓库
    1. Github 项目填写对应的 url(非仓库 url)
    2. 源码管理选择 Git(如果是私有仓库,要创建带 ssh 秘钥的凭据,通过 ssh 方式连接仓库)
    3. 构建触发器选择 GitHub hook trigger for GITScm polling
    4. 构建环境选择 node,需要先配置 nodejs 插件
    5. 构建脚本选择 shell,脚本可以参考下面的代码片段

ssh 方式连接仓库,需要先在主机生成 ssh key,cd /.ssh 查看密钥,pub结尾的为公钥,追加到在 settings > SSH And GPG keys的 ssh keys 列表中

ssh-keygen -t rsa -b 4096 -C "your email"
ll /.ssh
  1. 构建环境选择 ==node==
  2. 开始构建,执行 shell 脚本
# 以下的_name_都要替换成你实际的项目名
# 要先在 /var/lib/jenkins/workspace 创建项目,name跟jenkins项目名保持一致
#!/bin/bash
cd /var/lib/jenkins/workspace/blog-server
rm -rf node_modules
node -v
npm -v
npm install
tar -zcvf blog-server.tar.gz *

cd /home/servers
if [ ! -d "blog-server" ]; then
sudo mkdir blog-server
fi
cd /home/servers/blog-server
npm run prd
# pm2 start app --watch
sudo mv /var/lib/jenkins/workspace/blog-server/blog-server.tar.gz ./
sudo tar -zxvf blog-server.tar.gz -C ./
sudo rm -rf blog-server.tar.gz
# pm2 -v
# pm2 restart all --watch # 第一次要先手动将项目添加进pm2进程

如果遇到 pm2: command not found,就找到 pm2 的地址,做一个软连接到/usr/bin/

ln -s [pm2地址,可用 whereis pm2 查找] /usr/bin/pm2

如果是运行 ts 代码,需要先在主机给 pm2 安装 ts 和 ts-node,执行以下命令即可

pm2 install typescript
# "start": "NODE_ENV=production ts-node app --port $PORT",
pm2 start npm --name 'node' -- run start --watch
  1. 触发自动构建

a.先关联 github server 并测试连接。这一步是先建立主机和 github 的信任

image.png

b.新建凭据。setting --> Personal Access Token --> Generate new token,需要配置读写权限,之后会生成一个 token,作为凭据的内容(secret key)。

c.在 github > settings 配置 webhook。这一步是为了后续 github 项目在触发对应节点时能发送请求给 jenkins。在[项目仓库] > settings > webhooks 里面新增一个,Payload URL 格式类似于

http://[ip]:[jenkins port]/github-webhook/

之后可以在 Recent Deliveries 里面看最近的触发记录

d.git push 触发自动构建试试!

域名解析

目标是将 http://x.x.x.x:3001/api/test 替换成 http://blog-api.jacksonzhou.com:3001/api/test

  1. 申请域名
  2. 解析二级域名,记录值填 ip,主机记录填写 blog-api(自行定义)

nginx 重定向域名

目标是将 http://blog-api.jacksonzhou.com:3001/api/test 替换成 http://blog-api.jacksonzhou.com/api/test

编辑 nginx.conf,一般在 /etc/nginx

server {
listen 80;
location /api/ {
proxy_pass http://x.x.x.x:3001;
}
}

重启 nginx 试试

systemctl restart nginx

https 配置

目标是将 http://blog-api.zhouweibin/api/test 替换成 https://blog-api.zhouweibin/api/test

  1. 申请证书。可以到腾讯云或阿里云申请免费的证书(这里是用的 pem 与 key 文件)
  2. 安装 Nginx 的 SSL 模块。可以使用 nginx -V 检查是否已安装(在输出中查找–with-http_ssl_module
  3. 在 nginx 目录新建 cert 文件夹存放证书文件。将证书文件上传(可以使用scp命令或者 FileZilla 软件)
  4. Nginx.conf 配置

先新增 https server

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name zhouweibin.top www.zhouweibin.top;
root /usr/share/nginx/html;

ssl_certificate "/etc/nginx/cert/zhouweibin.top.pem";
ssl_certificate_key "/etc/nginx/cert/zhouweibin.top.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
proxy_pass http://nextblog;
# root /home/blog;
# index index.html;
}

location /api/ {
proxy_pass http://127.0.0.1:3001;
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

将 http 重定向到 https

server {
listen 80;
server_name zhouweibin.top www.zhouweibin.top;
return 301 https://$server_name$request_uri;
}
  1. 重启 nginx

SPA

部署单页面应用的步骤如下:

  1. build 生成静态页面
  2. nginx 配置端口,用来访问这个静态页面
  3. 注意重定向到 index.html(spa history 模式)

搭建 ci:

  1. github 项目配置 webhook
  2. jenkins 新增项目(jenkins 配置参照之前的 node 项目即可)
  3. shell 脚本
#!/bin/sh
cd /var/lib/jenkins/workspace/_name_
rm -rf node_modules dist
node -v
npm -v
npm config set registry https://registry.npm.taobao.org/
npm install #安装项目中的依赖

#!/bin/sh
npm run build
cd dist
rm -rf _name_.tar.gz #删除上次打包生成的压缩文件
tar -zcvf _name_.tar.gz * #把生成的项目打包成压缩包,方便移动到项目部署目录

cd /home #进入web项目根目录
if [ ! -d "_name_" ]; then
sudo mkdir _name_
fi
cd /home/_name_ #进入web项目根目录
sudo mv /var/lib/jenkins/workspace/_name_/dist/_name_.tar.gz ./ #移动刚刚打包好的项目到web项目根目录
sudo tar -zxvf _name_.tar.gz -C ./ #解压项目到dist目录
sudo rm -rf _name_.tar.gz #删除压缩包
  1. nginx 配置

next 应用(ssr)

部署 next 应用的步骤如下:

  1. next build
  2. next start

搭建 ci:

  1. github 项目配置 webhook
  2. jenkins 新增项目(jenkins 配置参照之前的 node 项目即可)
  3. shell 脚本
#!/bin/sh
cd /var/lib/jenkins/workspace/next-blog
tar -zcvf next-blog.tar.gz

cd /home/next-blog
sudo mv /var/lib/jenkins/workspace/next-blog/next-blog.tar.gz ./
sudo tar -zxvf next-blog.tar.gz -C ./
sudo rm -rf next-blog.tar.gz

rm -rf node_modules .next
node -v
npm -v
npm config set registry https://registry.npm.taobao.org/
npm install

npm run build
pm2 restart next-blog --watch
  1. nginx 配置代理
upstream nextblog {
server 127.0.0.1:3000; # next-blog
keepalive 64;
}
server {
# ...
location / {
proxy_pass http://nextblog;
}
}