导航菜单

  • 0.api
  • 0.Async
  • 0.module
  • 1.ES2015
  • 2.Promise
  • 3.Node
  • 4.NodeInstall
  • 5.REPL
  • 6.NodeCore
  • 7.module&NPM
  • 8.Encoding
  • 9.Buffer
  • 10.fs
  • 11.Stream-1
  • 11.Stream-2
  • 11.Stream-3
  • 11.Stream-4
  • 12-Network-2
  • 12.NetWork-3
  • 12.Network-1
  • 13.tcp
  • 14.http-1
  • 14.http-2
  • 15.compress
  • 16.crypto
  • 17.process
  • 18.yargs
  • 19.cache
  • 20.action
  • 21.https
  • 22.cookie
  • 23.session
  • 24.express-1
  • 24.express-2
  • 24.express-3
  • 24.express-4
  • 25.koa-1
  • 26.webpack-1-basic
  • 26.webpack-2-optimize
  • 26.webpack-3-file
  • 26.webpack-4.tapable
  • 26.webpack-5-AST
  • 26.webpack-6-sources
  • 26.webpack-7-loader
  • 26.webpack-8-plugin
  • 26.webpack-9-hand
  • 26.webpack-10-prepare
  • 28.redux
  • 28.redux-jwt-back
  • 28.redux-jwt-front
  • 29.mongodb-1
  • 29.mongodb-2
  • 29.mongodb-3
  • 29.mongodb-4
  • 29.mongodb-5
  • 29.mongodb-6
  • 30.cms-1-mysql
  • 30.cms-2-mysql
  • 30.cms-3-mysql
  • 30.cms-4-nunjucks
  • 30.cms-5-mock
  • 30.cms-6-egg
  • 30.cms-7-api
  • 30.cms-8-roadhog
  • 30.cms-9-yaml
  • 30.cms-10-umi
  • 30.cms-12-dva
  • 30.cms-13-dva-ant
  • 30.cms-14-front
  • 30.cms-15-deploy
  • 31.dva
  • 31.cms-13-dva-antdesign
  • 33.redis
  • 34.unittest
  • 35.jwt
  • 36.websocket-1
  • 36.websocket-2
  • 38.chat-api-1
  • 38.chat-api-2
  • 38.chat-3
  • 38.chat-api-3
  • 38.chat
  • 38.chat2
  • 38.chat2
  • 39.crawl-0
  • 39.crawl-1
  • 39.crawl-2
  • 40.deploy
  • 41.safe
  • 42.test
  • 43.nginx
  • 44.enzyme
  • 45.docker
  • 46.elastic
  • 47.oauth
  • 48.wxpay
  • index
  • 52.UML
  • 53.design
  • index
  • 54.linux
  • 57.ts
  • 56.react-ssr
  • 58.ts_react
  • 59.ketang
  • 59.ketang2
  • 61.1.devops-linux
  • 61.2.devops-vi
  • 61.3.devops-user
  • 61.4.devops-auth
  • 61.5.devops-shell
  • 61.6.devops-install
  • 61.7.devops-system
  • 61.8.devops-service
  • 61.9.devops-network
  • 61.10.devops-nginx
  • 61.11.devops-docker
  • 61.12.devops-jekins
  • 61.13.devops-groovy
  • 61.14.devops-php
  • 61.15.devops-java
  • 61.16.devops-node
  • 61.17.devops-k8s
  • 62.1.react-basic
  • 62.2.react-state
  • 62.3.react-high
  • 62.4.react-optimize
  • 62.5.react-hooks
  • 62.6.react-immutable
  • 62.7.react-mobx
  • 62.8.react-source
  • 63.1.redux
  • 63.2.redux-middleware
  • 63.3.redux-hooks
  • 63.4.redux-saga
  • 63.5.redux-saga-hand
  • 64.1.router
  • 64.2.router-connected
  • 65.1.typescript
  • 65.2.typescript
  • 65.3.typescript
  • 65.4.antd
  • 65.4.definition
  • 66-1.vue-base
  • 66-2.vue-component
  • 66-3.vue-cli3.0
  • 66-4.$message组件
  • 66-5.Form组件
  • 66-6.tree
  • 66-7.vue-router-apply
  • 66-8.axios-apply
  • 66-9.vuex-apply
  • 66-10.jwt-vue
  • 66-11.vue-ssr
  • 66-12.nuxt-apply
  • 66-13.pwa
  • 66-14.vue单元测试
  • 66-15.权限校验
  • 67-1-network
  • 68-2-wireshark
  • 7.npm2
  • 69-hooks
  • 70-deploy
  • 71-hmr
  • 72.deploy
  • 73.import
  • 74.mobile
  • 75.webpack-1.文件分析
  • 75.webpack-2.loader
  • 75.webpack-3.源码流程
  • 75.webpack-4.tapable
  • 75.webpack-5.prepare
  • 75.webpack-6.resolve
  • 75.webpack-7.loader
  • 75.webpack-8.module
  • 75.webpack-9.chunk
  • 75.webpack-10.asset
  • 75.webpack-11.实现
  • 76.react_optimize
  • 77.ts_ketang_back
  • 77.ts_ketang_front
  • 78.vue-domdiff
  • 79.grammar
  • 80.tree
  • 81.axios
  • 82.1.react
  • 82.2.react-high
  • 82.3.react-router
  • 82.4.redux
  • 82.5.redux_middleware
  • 82.6.connected
  • 82.7.saga
  • 82.8.dva
  • 82.8.dva-source
  • 82.9.roadhog
  • 82.10.umi
  • 82.11.antdesign
  • 82.12.ketang-front
  • 82.12.ketang-back
  • 83.upload
  • 84.graphql
  • 85.antpro
  • 86.1.uml
  • 86.2.design
  • 87.postcss
  • 88.react16-1
  • 89.nextjs
  • 90.react-test
  • 91.react-ts
  • 92.rbac
  • 93.tsnode
  • 94.1.JavaScript
  • 94.2.JavaScript
  • 94.3.MODULE
  • 94.4.EventLoop
  • 94.5.文件上传
  • 94.6.https
  • 94.7. nginx
  • 95.1. react
  • 95.2.react
  • 96.1.react16
  • 96.2.fiber
  • 96.3.fiber
  • 97.serverless
  • 98.websocket
  • 100.1.react-basic
  • 101.1.monitor
  • 101.2.monitor
  • 102.java
  • 103.1.webpack-usage
  • 103.2.webpack-bundle
  • 103.3.webpack-ast
  • 103.4.webpack-flow
  • 103.5.webpack-loader
  • 103.6.webpack-tapable
  • 103.7.webpack-plugin
  • 103.8.webpack-optimize1
  • 103.9.webpack-optimize2
  • 103.10.webpack-hand
  • 103.11.webpack-hmr
  • 103.11.webpack5
  • 103.13.splitChunks
  • 103.14.webpack-sourcemap
  • 103.15.webpack-compiler1
  • 103.15.webpack-compiler2
  • 103.16.rollup.1
  • 103.16.rollup.2
  • 103.16.rollup.3
  • 103.16.vite.basic
  • 103.16.vite.source
  • 103.16.vite.plugin
  • 103.16.vite.1
  • 103.16.vite.2
  • 103.17.polyfill
  • 104.1.binary
  • 104.2.binary
  • 105.skeleton
  • 106.1.react
  • 106.2.react_hooks
  • 106.3.react_router
  • 106.4.redux
  • 106.5.redux_middleware
  • 106.6.connected-react-router
  • 106.6.redux-first-history
  • 106.7.redux-saga
  • 106.8.dva
  • 106.9.umi
  • 106.10.ketang
  • 106.11.antdesign
  • 106.12.antpro
  • 106.13.router-6
  • 106.14.ssr
  • 106.15.nextjs
  • 106.16.1.cms
  • 106.16.2.cms
  • 106.16.3.cms
  • 106.16.4.cms
  • 106.16.mobx
  • 106.17.fomily
  • 107.fiber
  • 108.http
  • 109.1.webpack_usage
  • 109.2.webpack_source
  • 109.3.dll
  • 110.nest.js
  • 111.xstate
  • 112.Form
  • 113.redux-saga
  • 114.react+typescript
  • 115.immer
  • 116.pro5
  • 117.css-loader
  • 118.1.umi-core
  • 119.2.module-federation
  • 119.1.module-federation
  • 120.create-react-app
  • 121.react-scripts
  • 122.react-optimize
  • 123.jsx-runtime
  • 124.next.js
  • 125.1.linux
  • 125.2.linux-vi
  • 125.3.linux-user
  • 125.4.linux-auth
  • 125.5.linux-shell
  • 125.6.linux-install
  • 125.7.linux-system
  • 125.8.linux-service
  • 125.9.linux-network
  • 125.10.nginx
  • 125.11.docker
  • 125.12.ci
  • 125.13.k8s
  • 125.14.k8s
  • 125.15.k8s
  • 125.16.k8s
  • 126.11.react-1
  • 126.12.react-2
  • 126.12.react-3
  • 126.12.react-4
  • 126.12.react-5
  • 126.12.react-6
  • 126.12.react-7
  • 126.12.react-8
  • 127.frontend
  • 128.rollup
  • 129.px2rem-loader
  • 130.health
  • 131.hooks
  • 132.keepalive
  • 133.vue-cli
  • 134.react18
  • 134.2.react18
  • 134.3.react18
  • 135.function
  • 136.toolkit
  • 137.lerna
  • 138.create-vite
  • 139.cli
  • 140.antd
  • 141.react-dnd
  • 142.1.link
  • 143.1.gulp
  • 143.2.stream
  • 143.3.gulp
  • 144.1.closure
  • 144.2.v8
  • 144.3.gc
  • 145.react-router-v6
  • 146.browser
  • 147.lighthouse
  • 148.1.basic
  • 148.2.basic
  • 148.3.basic
  • 148.4.basic
  • 148.5.basic
  • 149.1.vite
  • 149.2.vite
  • 149.3.vite
  • 149.4.vite
  • 150.react-window
  • 151.react-query
  • 152.useRequest
  • 153.transition
  • 154.emotion
  • 155.1.formily
  • 155.2.formily
  • 155.3.formily
  • 155.3.1.mobx.usage
  • 155.3.2.mobx.source
  • 156.vue-loader
  • 103.11.mf
  • 157.1.react18
  • 158.umi4
  • 159.rxjs
  • 159.rxjs2
  • 160.bff
  • 161.zustand
  • 162.vscode
  • 163.emp
  • 164.cors
  • 1.前端项目最佳实践
    • 1. 工具选择
    • 2.技术栈选型
      • 2.1 固定化
      • 2.2 配置化
        • 2.2.1 编译态配置
        • 2.2.2 运行态配置
      • 2.3 约定化
    • 1.3 理念
  • 2.前端
    • 2.1. Ant Design Pro项目初始化
    • 2.2 启动项目
      • 2.2.1 安装
      • 2.2.2 目录结构
      • 2.2.3 本地开发
    • 2.3 用户注册
      • 2.3.1 先配置区块下载地址
      • 2.3.2 区块列表
      • 2.3.3 user\register\index.tsx
      • 2.3.4 user\register\locales\zh-CN.ts
      • 2.3.5 user\register\service.ts
      • 2.3.6 src\services\login.ts
    • 2.4. 用户登录
      • 2.4.1 services\login.ts
      • 2.4.2 src\services\user.ts
    • 2.5. 权限菜单
      • 2.5.1 src\models\login.ts
      • 2.5.2 src\utils\request.ts
    • 2.6 docker
      • 2.6.1 Dockerfile
      • 2.6.2 .dockerignore
      • 2.6.3 antdesign-front.conf
  • 3.后端
    • 3.1 api.js
    • 3.2 db.js
    • 3.3 config.prod.js
    • 3.4 config\config.dev.js
    • 3.5 sms.js
    • 3.6 smsConfig.js
    • 3.7 package.json
    • 3.8 Dockerfile
    • 3.9 .dockerignore
  • 4.服务器布署
    • 4.1 安装配置服务器
    • 4.2 docker是什么?
    • 4.3 安装docker
    • 4.4 阿里云加速
    • 4.5 安装git
    • 4.6 安装node和npm
    • 4.7 创建docker网络
    • 4.8 启动mongodb
      • 4.8.1 启动mongo的docker容器
      • 4.8.2 本地安装mongodb
        • 4.8.2.1 配置MongoDB的yum源
        • 4.8.2.2 安装MongoDB
        • 4.8.2.3 启动MongoDB
        • 4.8.2.4 外网访问
    • 4.9 启动后台服务器
    • 4.10 启动前台服务

1.前端项目最佳实践 #

1. 工具选择 #

类别 选择
框架 react
JS语言 TypeScript
CSS语言 css-modules+less+postcss
JS编译 babel
模块打包 webpack全家桶
单元测试 jest+enzyme+puppteer+jsdom
路由 react-router
数据流 dva+redux生态
代码风格 eslint+prettier
JS压缩 TerserJS
CSS压缩 cssnano
请求库 umi-request
UI AntDesign+AntDesignPro
国际化 react-intl
hooks库 umi-hooks
静态文档 docz
微前端 qiankun
图表库 antv

2.技术栈选型 #

2.1 固定化 #

  • React框架
  • TypeScript语言
  • Less+CSS Modules
  • Eslint+Prettier+固定配置
  • 固定数据流方案dva
  • 固定babel插件
  • Jest+Enzyme
  • 框架版本不允许锁定,^前缀必须有
  • 主要依赖不允许自定义依赖版本

2.2 配置化 #

  • 不仅是框架功能,还有UI界面
  • 路由、布局、菜单、导航、面包屑、权限、请求、埋点、错误处理
  • 只管写Page页面就可以了
2.2.1 编译态配置 #
  • 给node.js使用,比如webpack、babel相关配置,静态路由配置
2.2.2 运行态配置 #
  • 给浏览器用、比如渲染逻辑、动态修改路由、获取用户信息

2.3 约定化 #

  • 国际化
  • 数据流
  • MOCK
  • 目录结构
  • 404
  • 权限策略
  • Service
  • 配置文件

1.3 理念 #

  • 通过最佳实践减少不必要的选择的差异
  • 通过插件和插件集的架构方式,满足不同场景的业务
  • 通过资产市场和场景市场着力解决70%的开发者问题
  • 通过对垂直场景采取强约束的方式,进一步提升研发效率
  • 不给选择、配置化、约定化

2.前端 #

2.1. Ant Design Pro项目初始化 #

  • pro.ant.design
  • Pro的区块
  • ant-design-pro-layout
  • ant-design-pro-layout
  • pro-blocks
  • uset-typescript-cn
  • umi-config
  • Ant Design Pro 是一个企业级中后台前端/设计解决方案,我们秉承 Ant Design 的设计价值观,致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。

2.2 启动项目 #

2.2.1 安装 #

  • 新建一个空的文件夹作为项目目录,并在目录下执行
  • python-380
npm config set python "C:/Python38/python.exe"
yarn create umi

2.2.2 目录结构 #

  • 我们已经为你生成了一个完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。
├── config                   # umi 配置,包含路由,构建等配置
├── mock                     # 本地模拟数据
├── public
│   └── favicon.png          # Favicon
├── src
│   ├── assets               # 本地静态资源
│   ├── components           # 业务通用组件
│   ├── e2e                  # 集成测试用例
│   ├── layouts              # 通用布局
│   ├── models               # 全局 dva model
│   ├── pages                # 业务页面入口和常用模板
│   ├── services             # 后台接口服务
│   ├── utils                # 工具库
│   ├── locales              # 国际化资源
│   ├── global.less          # 全局样式
│   └── global.ts            # 全局 JS
├── tests                    # 测试工具
├── README.md
└── package.json

2.2.3 本地开发 #

安装依赖

git init
npm install

启动项目

npm start

2.3 用户注册 #

  • umijs-block
  • pro区块
  • pro-dashboard
  • pro-blocks下载

2.3.1 先配置区块下载地址 #

config.ts

export default {
  plugins,
+ block: {
+   defaultGitUrl: 'https://github.com/ant-design/pro-blocks',
+ },

2.3.2 区块列表 #

umi block list
UserRegister (https://preview.pro.ant.design/https://preview.pro.ant.design/user/register)

UserRegisterResult  (https://preview.pro.ant.design/https://preview.pro.ant.design/user/register/result)
请输入输出安装区块的路径 /user/register-result

2.3.3 user\register\index.tsx #

src\pages\user\register\index.tsx

  onGetCaptcha = () => {
+    const { dispatch, form } = this.props;
+    const mobile = form.getFieldValue('mobile');
+    dispatch({
+      type: 'login/getCaptcha',
+      payload: mobile,
+    })
    let count = 59;
    this.setState({ count });
    this.interval = window.setInterval(() => {
      count -= 1;
      this.setState({ count });
      if (count === 0) {
        clearInterval(this.interval);
      }
    }, 1000);
  };

+   <FormItem>
+            {getFieldDecorator('currentAuthority', {
+              rules: [
+                {
+                  required: true,
+                  message: formatMessage({ id: 'userandregister.currentAuthority.required' }),
+                }
+              ],
+            })(
+              <Select placeholder={formatMessage({ id: 'userandregister.currentAuthority.placeholder' })}>
+                <Option value="user">普通用户</Option>
+                <Option value="admin">管理员</Option>
+              </Select>
+            )}
+  </FormItem>

2.3.4 user\register\locales\zh-CN.ts #

src\pages\user\register\locales\zh-CN.ts

+  'userandregister.currentAuthority.placeholder': '角色',
+  'userandregister.currentAuthority.required': '请输入邮箱地址!',

2.3.5 user\register\service.ts #

src\pages\user\register\service.ts

import request from '@/utils/request';
import { UserRegisterParams } from './index';

export async function fakeRegister(params: UserRegisterParams) {
+  return request('/server/api/register', {
    method: 'POST',
    data: params,
  });
}

2.3.6 src\services\login.ts #

src\services\login.ts

export async function getFakeCaptcha(mobile: string) {
+  return request(`/server/api/login/captcha?mobile=${mobile}`);
}

2.4. 用户登录 #

2.4.1 services\login.ts #

src\services\login.ts

export async function fakeAccountLogin(params: LoginParamsType) {
+  return request('/server/api/login/account', {
    method: 'POST',
    data: params,
  });
}

2.4.2 src\services\user.ts #

src\services\user.ts

export async function queryCurrent(): Promise<any> {
+  return request('/server/api/currentUser');
}

2.5. 权限菜单 #

2.5.1 src\models\login.ts #

src\models\login.ts

if (response.status === 'ok') {
+        if (response.token) {
+          localStorage.setItem('token', response.token);
+        }
        const urlParams = new URL(window.location.href);

2.5.2 src\utils\request.ts #

src\utils\request.ts

const request = extend({
  errorHandler, // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});
+const baseURL = 'http://localhost:4000';
+request.interceptors.request.use((url: any, options: any) => {
+  if (localStorage.getItem('token')) {
+    options.headers.Authorization = 'Bearer ' + localStorage.getItem('token')
+  }
+  if (url.startsWith('/server')) {
+    url = baseURL + url.slice(7);
+  }
+  return { url, options };
+});

export default request;

2.6 docker #

2.6.1 Dockerfile #

FROM nginx
LABEL name="antdesign-front"
LABEL version="1.0"
COPY  ./dist/ /usr/share/nginx/html/
COPY ./antdesign-front.conf /etc/nginx/conf.d/
EXPOSE 80

2.6.2 .dockerignore #

.git
node_modules
package-lock.json
Dockerfile
.dockerignore

2.6.3 antdesign-front.conf #

antdesign-front.conf

server {
    listen       80;
    server_name  47.104.204.74;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}

3.后端 #

3.1 api.js #

let express = require("express");
let bodyParser = require("body-parser");
let jwt = require('jwt-simple');
let cors = require("cors");
let Models = require('./db');
let sendCode = require('./sms');
let session = require("express-session");
let MongoStore = require('connect-mongo')(session);
let config = process.env.NODE_ENV == 'production' ? require('./config/config.prod') : require('./config/config.dev');
let app = express();
app.use(
    cors({
        origin: config.origin,
        credentials: true,
        allowedHeaders: "Content-Type,Authorization",
        methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS"
    })
);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(
    session({
        secret: config.secret,
        resave: false,
        saveUninitialized: true,
        store: new MongoStore({
            url: config.dbUrl,
            mongoOptions: {
                useNewUrlParser: true,
                useUnifiedTopology: true
            }
        })
    })
);
app.get('/', async (req, res) => {
    res.json({ code: 0, data: `hello` });
});
app.get('/api/login/captcha', async (req, res) => {
    let mobile = req.query.mobile;
    let captcha = rand();
    req.session.captcha = captcha;
    await sendCode(mobile, captcha);
    res.json({ code: 0, data: `[仅限测试环境验证码]: ${captcha}` });
});
app.post('/api/register', async (req, res) => {
    let user = req.body;
    if (user.captcha != req.session.captcha) {
        return res.json({ code: 1, error: '验证码不正确' });
    }
    let avatarValue = require('crypto').createHash('md5').update(user.mail).digest('hex');
    user.avatar = `https://secure.gravatar.com/avatar/${avatarValue}?s=48`;
    user = await Models.UserModel.create(user);
    res.send({ status: 'ok', currentAuthority: 'user' });
});
app.post('/api/login/account', async (req, res) => {
    let user = req.body;
    let query = {};
    if (user.type == 'account') {
        query.mail = user.userName;
    } else if (user.type == 'mobile') {
        query.mobile = user.mobile;
        if (user.captcha != req.session.captcha) {
            return res.send({
                status: 'error',
                type: user.type,
                currentAuthority: 'guest',
            });
        }
    }
    let dbUser = await Models.UserModel.findOne(query);
    if (dbUser) {
        dbUser.userid = dbUser._id;
        dbUser.name = dbUser.mail;
        let token = jwt.encode(dbUser, config.secret);
        res.send({ status: 'ok', token, type: user.type, currentAuthority: dbUser.currentAuthority });
    } else {
        return res.send({
            status: 'error',
            type: user.type,
            currentAuthority: 'guest',
        });
    }
});

app.get('/api/currentUser', async (req, res) => {
    let authorization = req.headers['authorization'];
    if (authorization) {
        try {
            let user = jwt.decode(authorization.split(' ')[1], config.secret);
            user.userid = user._id;
            user.name = user.mail;
            res.json(user);
        } catch (err) {
            res.status(401).send({});
        }
    } else {
        res.status(401).send({});
    }

});
app.listen(4000, () => {
    console.log('服务器在4000端口启动!');
});

function rand() {
    let min = 1000, max = 9999;
    return Math.floor(Math.random() * (max - min)) + min;
}

3.2 db.js #

db.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = Schema.Types.ObjectId;
let configs = process.env.NODE_ENV == 'production' ? require('./config/config.prod') : require('./config/config.dev');
const conn = mongoose.createConnection(configs.dbUrl, { useNewUrlParser: true, useUnifiedTopology: true });
const UserModel = conn.model('User', new Schema({
    userid: { type: String },//邮箱
    name: { type: String },
    mail: { type: String, required: true },//邮箱
    password: { type: String, required: true },//密码
    mobile: { type: String, required: true },//手机号
    avatar: { type: String, required: true },//头像
    currentAuthority: { type: String, required: true }//当前用户的权限
}));

module.exports = {
    UserModel
}

3.3 config.prod.js #

config\config.prod.js

module.exports = {
    secret: 'zhufengcms',
    dbUrl: "mongodb://antdesign-mongo:27017/zhufengcms",
    origin: ["http://47.104.204.74", "http://47.104.204.74:8000"]
}

3.4 config\config.dev.js #

config\config.dev.js

module.exports = {
    secret: 'zhufengcms',
    dbUrl: "mongodb://localhost:27017/zhufengcms",
    origin: ["http://localhost:8000"]
}

3.5 sms.js #

sms.js

const axios = require('axios');
const smsConfig = require('./smsConfig');
//http://docs.ucpaas.com/doku.php?id=%E7%9F%AD%E4%BF%A1:sendsms
module.exports = async (mobile, captcha) => {
    const url = 'https://open.ucpaas.com/ol/sms/sendsms';
    let result = await axios({
        method: 'POST',
        url,
        data: {
            sid: smsConfig.sid,
            token: smsConfig.token,
            appid: smsConfig.appid,
            templateid: smsConfig.templateid,
            param: captcha,
            mobile
        },
        headers: {
            "Content-Type": "application/json;charset=utf-8",
            "Accept": "application/json"
        }
    })
    return result;
}

3.6 smsConfig.js #

smsConfig.js

module.exports = {
    sid: '32548fb951ac0df279db0e6e9a515566',      //开发者账号id
    token: 'aa0309c08920ca38201de69eb3c745b6',    //开发者token
    appid: '16129d504b7c484c9e8f09b4ec929983',    //应用id
    templateid: '387675'                          //短信模板id
}

3.7 package.json #

package.json

  "scripts": {
    "start": "node api.js"
  },

3.8 Dockerfile #

Dockerfile

FROM node
ENV NODE_ENV production
LABEL name="antdesign-server"
LABEL version="1.0"
COPY . /app
WORKDIR /app
RUN npm install
EXPOSE 4000
CMD npm start

3.9 .dockerignore #

.dockerignore

.git
node_modules
package-lock.json
Dockerfile
.dockerignore

4.服务器布署 #

4.1 安装配置服务器 #

#升级所有包同时也升级软件和系统内核
yum update  -y
#只升级所有包,不升级软件和系统内核
yum upgrade 

4.2 docker是什么? #

  • Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。
  • Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样

dockercontainer

4.3 安装docker #

yum install -y yum-utils   device-mapper-persistent-data   lvm2
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io

4.4 阿里云加速 #

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
}
EOF
# 重载所有修改过的配置文件
systemctl daemon-reload
systemctl restart docker

4.5 安装git #

yum install git -y

4.6 安装node和npm #

  • nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash

source /root/.bashrc
nvm ls-remote
nvm install v12.13.1
npm i cnpm -g

4.7 创建docker网络 #

docker network create --driver bridge antdesign
docker network connect  antdesign antdesign-mongo
docker network inspect antdesign

4.8 启动mongodb #

4.8.1 启动mongo的docker容器 #

docker pull mongo:latest
docker images
docker run -d --name antdesign-mongo -p 27017:27017 --net antdesign mongo
docker ps
docker exec -it antdesign-mongo bash
mongo

4.8.2 本地安装mongodb #

4.8.2.1 配置MongoDB的yum源 #
vim /etc/yum.repos.d/mongodb-org-4.0.repo
#添加以下内容:
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=0
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc

#这里可以修改 gpgcheck=0, 省去gpg验证
[root@localhost ~]# yum makecache
4.8.2.2 安装MongoDB #
yum -y install mongodb-org
whereis mongod
vim /etc/mongod.conf
4.8.2.3 启动MongoDB #
systemctl start mongod.service #启动
systemctl stop mongod.service #停止
systemctl status mongod.service #查看状态
4.8.2.4 外网访问 #
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动

4.9 启动后台服务器 #

git clone https://gitee.com/zhufengpeixun/antdesign-server.git
cd antdesign-server
docker build -t antdesign-server .
docker image ls
docker run  -d --name antdesign-server -p 4000:4000 --net antdesign antdesign-server
curl http://localhost:4000

4.10 启动前台服务 #

git clone https://gitee.com/zhufengpeixun/antdesign-front.git
cd antdesign-front
cnpm install
cnpm run build

docker build -t antdesign-front .
docker run -d --name antdesign-front -p 80:80  --net antdesign antdesign-front

访问验证

请输入访问令牌

Token不正确,请重新输入