💦从零开始搭建站点 - 前后端
某日,心血来潮,想将hexo
搭建的站点移除,从零开始搭建自己的站点。
涉及的内容包含👇:
-
购买服务器
-
站点前后端分析
-
服务器环境搭建
-
发布前端项目
-
发布后端项目
-
关联域名
站点提前体验地址:
戳地址:jimmyarea.com
购买服务器
这里选择了腾讯云的服务器,你也可以选择阿里云之类的。
相关的云服务器的配置如下:
# 操作系统
CentOS 7.5 64位
# CPU
1核
# 内存
2GB
# 公网带宽
1Mbps
基础配置(1核2GB)的机型适合有一定的访问量的网站;当然,也可以选择入门配置(1核1GB)的机型,它适用起步阶段的个人网站。
PS:本次的搭建没有特殊说明均在腾讯云上完成✅,并基于CentOS 7.5 64位
站点前后端分析
站点采用前后端分离思想,前后端独立上线,方便开发和维护等~
站点前端
目前的功能有
✅ 登陆
✅ 注册
✅ 重置密码
✅ 社交列表
✅ 个人简介
✅ 文章列表
✅ 留言功能
❌ 技能图 COMING SOON
❌ 发表文章功能【管理端】COMING SOON
ETC
前端使用了业界成熟的UI框架 -- ANT DESING。
弹性布局,能兼容移动端设备~
项目使用ANT DESIGN PRO V5
进行初始化,直接对请求的request
进行抽离改造,利于维护。
# src/utils/request.ts
// 默认的框架请求
import { getStore } from '@/utils/storage';
import { extend } from 'umi-request';
import type { ResponseError } from 'umi-request';
import { notification } from 'antd';
// @see https://beta-pro.ant.design/docs/request-cn
const codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、邮箱、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
405: '请求方法不被允许。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
/**
* 异常处理程序
*/
const errorHandler = (error: ResponseError) => {
const { response, data } = error;
if (response && response.status) {
const errorText = data.msg || codeMessage[response.status] || response.statusText;
// const { status, url } = response;
const { status } = response;
notification.error({
message: `请求错误 ${status}`,
description: errorText,
});
}
if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
}
throw error;
};
/**
* 配置request请求时的默认参数
*/
const request = extend({
errorHandler, // 默认错误处理
credentials: 'include', // 默认请求是否带上cookie
timeout: 5000,
prefix: '',
});
// 请求拦截器
request.interceptors.request.use((url, options) => {
const token = getStore('token') || '';
const theOptions = options || {};
if (token) {
theOptions.headers = {
// 处理header中的token
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${token}`,
};
}
return {
url,
options: { ...theOptions },
};
});
request.interceptors.response.use(async (response: any) => response);
export default request;
对授权登陆进行移除等,形成一个纯净的,符合设计的jimmyarea站点的功能需求。
前端开发完,运行脚手架自带的命令行yarn run build
或者 npm run build
生成一个dist
文件。这个文件就是你要发布到服务器上的文件了~
当然,完成前端的开发,如果你对性能有所要求,可以进行相关的优化。这里,我对moment.js
进行了优化,剔除不必要的local,压缩了相关的图片等等...具体的你可以通过运行yarn run analyze
来观察优化
Nginx上开启了gzip 别忘了哦
站点后端
后端使用的是KOA2
框架去开发,本地使用nodemon
运行服务调试,线上采用pm2
来启动服务。
目前的接口有:
✅ 登陆
✅ 注册
✅ 加密盐
✅ 重置密码
✅ 社交列表
✅ 文章列表
✅ 留言功能
✅ 邮件发送
❌ 发表文章功能【管理端】COMING SOON
ETC
我们从零开始搭建一个NODE
的服务端项目,目录结构如下:
backend
├── config
| ├── default.json
| ├── production.json # 生产环境的配置
| └── test.json # 测试环境配置
├── src # 主要代码存放地方
| ├── controllers
| | ├── user.js
| | └── ...
| ├── middlewares
| | ├── auth.js
| | └── ...
| ├── models
| | └── mongo
| | ├── schema
| | | ├── User.js
| | | └── ...
| | └── index.js
| ├── router
| | └── index.js
| ├── service # 第三方服务
| | └── index.js
| ├── utils
| | ├── bcrypt.js
| | └── ...
| ├── app.js
| └── index.js # 入口文件
├── .babelrc # 处理babel
├── apidoc.json # 生成接口文档的配置
├── package.json # 依赖
├── pm2.json # pm2 线上运行的配置
└── README.md 项目说明
其中, package.json
的内容如下:
{
"version": "1.0.0",
"author": "Jimmy",
"scripts": {
"start": "NODE_ENV=development node src/index.js",
"dev": "NODE_ENV=development nodemon src/index.js",
"nodepro": "yarn run build && NODE_ENV=production node app/index.js",
"pm2pro": "yarn run build && NODE_ENV=production pm2 start pm2.json",
"clean": "rm -rf app/",
"compile": "babel src/ --out-dir app/ --retain-lines",
"build": "yarn run clean && yarn run compile",
"docs": "apidoc -i src/controllers -o apidoc/"
},
"dependencies": {
"bcrypt": "^5.0.1",
"bluebird": "^3.7.2",
"config": "^3.3.6",
"jsonwebtoken": "^8.5.1",
"koa": "^2.13.1",
"koa-bodyparser": "^4.3.0",
"koa-convert": "^2.0.0",
"koa-json": "^2.0.2",
"koa-jwt": "^4.0.1",
"koa-logger": "^3.2.1",
"koa-router": "^10.0.0",
"koa-session": "^6.2.0",
"mongodb": "^3.6.7",
"mongoose": "^5.12.7",
"nodemailer": "^6.6.0",
"uuid": "^8.3.2",
"xss": "^1.0.8"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-plugin-add-module-exports": "^0.1.4",
"babel-plugin-transform-runtime": "^6.8.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2015-loose": "^7.0.0",
"babel-preset-stage-3": "^6.5.0",
"babel-register": "^6.26.0",
"nodemon": "^2.0.7"
}
}
当然,你也可以使用成熟的框架EGGJS
。
数据库是MongoDB
,对象模型工具Mongoose
。
下面是一个连接数据库查询文章列表的接口:
# src/models/mongo/schema/Article.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
// 定义文章字段
let ArticleSchema = new Schema({
title: String, // 文章标题
url: String, // 文章url
count: String, // 文章阅读量
thumb: String, // 文章点赞量
meta: {
createAt: {
type: Date,
default: Date.now()
},
updateAt: {
type: Date,
default: Date.now()
}
}
})
mongoose.model('Article', ArticleSchema)
# src/router/index.js
// 文章部分
router.get('/public/article', Article.getArticleData)
# src/controllers/article.js
let mongoose = require('mongoose')
let Article = mongoose.model('Article')
/**
* @apiGroup Article
* @api {get} /public/article 查看社交信息
* @apiVersion 1.0.0
*
*
* @apiSuccessExample {json} 返回成功
* HTTP/1.1 200
* {
* "code": 0,
* "msg": "ok",
* "data": [{
* "key": "value"
* }]
* }
*
* @apiSampleRequest off
*/
exports.getArticleData = async (ctx, next) => {
let data = await Article.find({})
ctx.body = {
results: data,
current: 1
}
}
上面示例,线上的接口地址是https://jimmyarea.com/api/public/article ,感兴趣的话可以点击此链接感受下。
嗯~到这里,我们服务器也买了,本地上前端项目和后端项目都跑起来了,那么,我们可以考虑将我们的项目上线了。
服务器环境搭建
在项目上线前,我们得做好准备,这涉及Nginx代理,数据库,后端node
等环境。
安装数据库MongoDB
基于成本的考虑,我们将数据库和应用都放在同一台云服务器上面。
如果是公司企业的话,建议购买云数据库等
演示的是:服务器操作系统为 CentOS 7.5 64位
mongodb的安装教程: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/
当然,你也可以在文章Linux Centos 7安装MongoDB(简单!详细!) 按照指引完成数据库的安装。
安装完数据库之后,建议开启权限验证及设置用户名密码,不然什么人都可以访问你的数据库,那很是尴尬😅
比如:
db.createUser(
{
user: "simpleUser",
pwd: “123456”,
roles: [“readWrite”,”dbAdmin”,”userAdmin”]
}
)
安装Nginx
基于centos
的yum
源操作
# 安装nginx 卸载[yum -y remove nginx]
yum -y install nginx
# 查看版本
nginx -v
# 启动nginx
systemctl start nginx.service
# 访问 默认端口是80
your_ip:80
# 配置
cd /etc/nginx/conf.d
... 有待补充
# 以下是nginx常用命令
# 启动nginx服务
systemctl start nginx.service
# 停止nginx服务
systemctl stop nginx.service
# 重启nginx服务
systemctl restart nginx.service
# 重新读取nginx配置(这个最常用, 不用停止nginx服务就能使修改的配置生效)
systemctl reload nginx.service
- 相关启动命令也可如下
nginx -t #测试配置文件是否有语法错误
nginx -s reopen #重启Nginx
nginx -s reload #重新加载Nginx配置文件,然后以优雅的方式重启Nginx
nginx -s stop #强制停止Nginx服务
nginx -s quit #优雅地停止Nginx服务(即处理完所有请求后再停止服务)
nginx -c [配置文件路径] #为 Nginx 指定配置文件
配置Nginx
查看Nginx配置文件nginx.conf
vi /etc/nginx/nginx.conf
检查是否有如下语句:
include /etc/nginx/conf.d/*.conf
如果存在,说明nginx的配置文件均设置在conf.d文件夹下,我们进入到conf.d文件夹
cd /etc/nginx/conf.d/
在 conf.d 目录下新建一个站点的配置文件,例如:test.com.conf:
vi test.com.conf
配置内容这样设置(按Insert键进入编辑模式):
server {
# 监听80端口
listen 80;
# 服务器名称(随意)
server_name www.test.com test.com;
# 路由匹配
location / {
# 文件目录,即你存放静态资源的地方
root /usr/share/nginx/test.com;
# 设置首页为根目录下index.html文件
index index.html;
}
}
写好后,按ESC键退出编辑模式,输入 :wq 保存并退出编辑
:wq
检查配置文件是否有误
nginx -t
重启Nginx服务
systemctl start nginx
或者
nginx -s reload
接着我们将静态资源存放在定义的 /usr/share/nginx/test.com 目录下。
这里我们仅做测试,于是在该目录下创建一个测试网页index.html
文件,你可以尝试下,看浏览器页面地址有没有访问到这个index.html
文件。
Nginx处理CORS
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
}
发布前端项目
第一种方式
将前端项目打包,生成dist
文件夹,之后放在/usr/share/nginx指定的目录中即可。
第一种方式比较繁琐,我们用第二种方式。
第二种方式
方式二:直接拉取代码仓库,打包即可
现在,我们用github
为进行项目托管,那么我们可以在自己都买的服务环境中将Git
和Github
进行SSH
连接。
首先在服务器上面安装版本控制系统GIT
。
yum install git
之后配置git与github关联:
git config --global user.name "your_name"
git config --global user.email "your_email"
然后用ssh生成公钥:
ssh-keygen -t rsa -C "your_email"
之后一直回车即可(如果你要更改文件命名,可按提示修改)。
最后,将公钥添加到github中
-
在
.ssh
文件夹中找到id_rsa.pub
这个文件,复制里面的所有内容。 -
登陆
github
账号,点击头像旁的小三角展开,点击Settings - SSH and GPG keys - New SSH key
,在Title
中取一个名字(任意),Key
中粘贴你刚刚复制的内容。然后点击Add SSH key
即可。
详细内容可以直接戳官方教程使用 SSH 连接到 GitHub
完成之后,我们可以在/usr/share/nginx
下指定的目录进行操作:
# clone
git clone your_github_repository_url
# 安装依赖
yarn install || npm install
# 打包
yarn run build
后期如果有新文件加入,重新拉取打包即可。
发布后端项目
这里是NODE
项目,那么我们得先准备自己相关的NODE
环境。
安装包文件nodejs
# 使用EPEL安装
yum install epel-release
# 安装node js
sudo yum install nodejs
# 查看安装版本
node -v
# v6.13.3
# 版本过低,升级到最新稳定版
# 安装n,n是nodejs管理工具
npm install -g n
# 安装nodejs最新版本
n latest
# 稳定版 n node的稳定版版本号
# 之后切换nodejs版本即可
n
上面是一种安装方式,读者可以尝试其他的安装方式,这里不展开了
其他安装
-
安装yarn包管理器,比npm性能优越
npm install -g yarn
-
安装pm2的node进程管理工具
npm install pm2 -g
或yarn global add pm2
pm2 让 Nodejs 服务常驻
配置nginx反向代理
比如:
upstream api {
server 127.0.0.1:6000;
keepalive 2000;
}
server {
location /api {
proxy_pass http://api;
}
}
发布
发布的操作也是通过git拉区在github上的后端项目,然后运行本项目自定义的yarn run pm2pro
启动项目即可。
你可以通过命令行pm2 list
查看服务运行的情况。
pm2 list
id | name | mode | ↺ | status | cpu | memory |
---|---|---|---|---|---|---|
0 | jimmy-server | cluster | 880 | online | 0% | 56.5mb |
关联域名
我们成功发布了前后端项目,配置好nginx
代理之后,项目就能够通过 IP
地址进行访问了,本项目的服务器的ip地址是111.230.192.27。
为了用户友好体验,我们是不是考虑买个域名了呢?
这里我购买的域名是jimmyarea.com, 还顺带买了证书 - 用于开启https
。
购买域名
这里使用的是腾讯云提供的服务。
购买完域名后,根据指引去实名进行认证。运营商有很详细的操作指南,毕竟要用户,这里不详细说明。
域名解析
这里采用的是腾讯云服务器和腾讯域名,你可以参考这个 - 快速添加域名解析 来完成✅
Nginx并配置SSL证书
-
https证书申请
-
将证书上传到服务器的指定目录
# 用命令行上传
scp -r local_dir username@servername:remote_dir
# 例子
scp -r test root@192.168.0.101:/var/www/ 把当前目录下的test目录上传到服务器的/var/www/ 目录
具体可以参考官方- Nginx 服务器 SSL 证书安装部署 进行操作,这里不赘述。
- 域名备案,以腾讯为例,域名申请n个自然日后可以提交申请备案了。域名不备案,通过域名访问不稳定~囧 😅
亲测域名备案前后需要两个星期 审核-修改-审核
后话
至此,可以美滋滋地对项目进行迭代开发--上线。当然,如果你想更加工程化,方便点,你可以引入jenkins
啥的 从零开始搭建JENKINS+GITHUB持续集成环境【多图】,docker啥的。
成品地址: jimmyarea.com,感兴趣可以体验下。
仓库代码地址不公开,毕竟里面涉及到数据库账号密码等个人信息,我全部设置为privacy
了。
最后,打个广告!
最近打算换工作,有哪位大佬,可以推荐下经验3-5年的前端开发职位 BASE珠三角 。感激不尽~ 逃💨