大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说app的前端用什么写_python写网页前端,希望您对编程的造诣更进一步.
先来交代下应用场景,我觉得看这篇文章的同学大部分是网上找不到
Docker + Node + Nginx + Mysql
这种组合的配置教学,包括我在研究这个项目的时候找了很久只有国外几篇有价值的文章,文末我也会把一些参考贴出来供大家学习。这个项目的起底是因为团队内部希望有一个自己的云平台,上面搭载一些如图片上传、OSS 管理、发布管理、钉钉推送服务、语音合成等,并且这些服务在我们的预想当中是完全不需要后端来参与的。团队内部同学的服务端水平不一,同一种架构十个人能配出十种环境出来(这个我相信是大部分前端甚至后端 Team 的通病),在这种契机下,我尝试用 Docker 去包裹着我们这一套体系。
如果你已经了解过 Docker,只是在寻找一种解决方案,想看 DockerFile,可以直接跳到编写 Docker-Compose 的地方。
另外,我已经准备好了一个模板库,可以根据这个模板库来作为基底来构建你的项目,也欢迎大家围观吃瓜学习、issue、star(点我就可以啦)
粗暴的讲一下Docker
还记得在上学的时候学校机房里的 VMware Workstation
吗?他可以让我们在 windows 或 mac 上运行许多系统的虚拟机,而VMware Workstation
里重要的一个概念就是宿主机-虚拟机
。
初学者可以先把Docker
理解为跟VMware Workstation
类似的产品,但如果需要深究他们区别在哪,我们则需要记住:他们相似的仅仅是提供了在系统上运行另外一个隔离系统。
通常情况下,虚拟机的性能相对差,对电脑配置、服务器配置本身要求高,而Docker
降低了那个门槛,性能接近裸机。
我们要虚拟机干啥?直接啥应用都往服务器上坨不行吗?Docker 的具体应用在哪里?
我先来说说为啥要用 Docker:
- 一致的运行环境(多个开发之间、开发与生产环境以及其他的任意环境)
- 更高效的交付部署流程
- 易于拓展、迁移(现有系统可直接成为镜像,分布式拓展简易)
- 更轻松的维护:你的 nginx 配置、node配置、mongo配置全都是活性化且可统一的管理
- 比其他虚拟机产品性能更好,速度更快,系统利用率更高
在这些优点的对立面,尤其是部署和环境统一这个问题,就足够让非 Docker 体系的工程成本提高。
安装 Docker
如果是你 MacOS 或 Windows ,直接下载Docker Desktop,下载很慢的话,可以去 DaoCloud。 如果是 linux 的话,需要以下几个步骤,如果你的服务器没有yum
的话,需要先去安装 yum
,安装yum
篇幅不小就不在这边展开。 以防万一,清理 Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
设置 yum 源(可以任意其他的,我这里用的阿里)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新缓存
sudo yum makecache fast
安装 Docker-ce(CE 是指社区版,免费使用,Docker 还有 EE 版)
sudo yum -y install docker-ce
启动 Docker
sudo systemctl start docker
测试命令
docker -v
到这里安装就完成了。下面我们开始安装 Docker-Compose
Docker-Compose
传统的Docker
,一个容器需要一个Dockerfile
来描述,如果说一个项目比较大,用到了较多的技术,就会有很多个容器,如果需要挨个执行 Dockerfile
,甚至启动的时候也是挨个去启动,开发会累死,运维也会累死。Docker-Compose
解决了这个问题,为每个项目提供一个描述文件,并且批处理项目中的所有容器。
安装docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
验证
$ docker-compose -v
> docker-compose version 1.24.1, build 4667896b
项目架构
首先看一下我们项目目录是如何编排的,需要注意的是,项目存放的位置对于 Docker 的配置是有影响的。我们的 node
框架使用了阿里的Egg.js
.
├── docker-compose.yml ## docker-compose 配置入口
├── logs ## 日志存放位置
│ └── nginx
│ ├── access.log
│ └── error.log
├── mongo ## mongo 配置入口
│ ├── Dockerfile ## Mongo的 Dockerfile
│ └── mongo.conf ## mongo 配置
├── nginx ## nginx 配置
│ ├── cert ## SSL 证书存放目录
│ ├── conf.d
│ │ └── MicroServer.conf ## nginx 下我们服务的配置文件
│ ├── Dockerfile ## nginx 的 Dockerfile
│ └── nginx.conf
└── node ## node 项目存放目录
├── Dockerfile
└── Microservice ## 项目目录 以下为 Egg 的架构目录
├── app
│ ├── controller
│ ├── database
│ │ ├── init.js
│ │ └── schemas
│ ├── extend
│ │ └── application.js
│ ├── middleware
│ │ ├── gzip.js
│ │ └── jwt_error_handler.js
│ ├── public
│ └── router.js
├── app.js
├── appveyor.yml
├── config
│ ├── config.default.js
│ └── plugin.js
├── config.js
├── jsconfig.json
├── logs
├── node_modules
├── package.json
├── README.md
├── test
└── typings
然后先讲一下 Dockerfile
是个啥,里面配置了虚拟机里的镜像底层系统是什么,用了什么端口,跑什么命令,然后 Docker 会根据这些命令生成一个镜像包。
整体上架构比较清晰,这边我们打算给每一个程序都单独起一个容器,node
是 node
的,nginx
是 nginx
的,mongo
是 mongo
的。Do it,上大菜。
nginx 的 Dockerfile
# 使用社区里的 nginx:alpine 为基础镜像
FROM nginx:alpine
# 拷贝 nginx 全局配置文件
COPY nginx.conf /etc/nginx/
# apk 国内源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories
# 安装 nginx
RUN apk update \
&& apk upgrade \
&& apk add --no-cache openssl \
&& apk add --no-cache bash
# 启动 nginx
CMD nginx
# 暴露 80 端口和 443 端口给容器外部
EXPOSE 80 443
node 的 Dockerfile
# 这里我用的镜像是 node 的稳定版
FROM node:10.16.3-alpine
# 拷贝项目文件进行构建
WORKDIR /app/Microservice
COPY ./Microservice/package.json ./
RUN npm install --registry=https://registry.npm.taobao.org
# 拷贝项目文件
COPY ./Microservice/* ./
# 启动服务
CMD ["npm","run","dev"]
# 暴露 7001 端口到宿主机
EXPOSE 7001
需要注意的是,这里我们跑的是npm run dev
,因为 docker 的进程需要你的程序跑在前台,如果用了npm run start
,容器内没有东西持续占用输出,会导致容器认为程序已经执行完毕。 另外这里我们单独把 package.json
拷了一份,是为了应对下面我们需要单独为node_modules
创建一个映射卷而做的。下面会说为什么需要单独为node_modules
做一个卷
mongo 的 Dockerfile
# 使用 mongo 最新版镜像
FROM mongo:latest
# 把宿主机的 Mongo 配置文件拷贝到容器内
COPY mongo.conf /usr/local/etc/mongo/mongo.conf
# 映射外部 DB 的存储文件到容器内
VOLUME /data/db /data/configdb
# 启动 mongo
CMD ["mongod"]
# 暴露 27017 端口到宿主机
EXPOSE 27017
在docker-compose.yml中编写Node/Nginx/Mongo的配置文件
version: "3"
networks: # 自定义网络
my-network: # 网络名字
driver: bridge # 由网关驱动
volumes: # 创建自定义卷
node_modules: # 卷名
mongo_data:
services: # 定义每个服务的容器
### nginx #################
nginx: # nginx 容器 这里的名字可以当做变量使用
build: # 定义需要构建的内容
context: ./nginx # 选取 nginx 文件夹
ports: # 映射端口
- 80:80
- 443:443
volumes: # 挂载文件夹,配置我们可以写在宿主机,然后挂载进去
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/cert:/etc/nginx/cret
- ./logs/nginx:/var/log/nginx
restart: always # 服务挂了的时候始终自动重启
depends_on: # 定义容器启动顺序 附带容器间的依赖关系
- nodejs
networks: # 使用我们上面定义的网络
- my-network
### node ##############
nodejs:
build:
context: ./node # 构建 node 目录 他会去 node 下面寻找 Dockerfile
ports:
- 127.0.0.1:7001:7001 # 映射 7001
volumes:
- ./node/Microservice:/app/Microservice # 项目文件映射
- node_modules:/app/Microservice/node_modules # 单独处理 node_modules
restart: always
depends_on:
- mongo
networks:
- my-network
### mongoDB ########################
mongo:
build:
context: ./mongo
ports:
- 127.0.0.1:27017:27017
volumes:
- mongo_data:/data/db # 这里的 mongo_data 用的是上面的自定卷
restart: always
networks:
- my-network
以上有几个点需要注意:
1、内部端口防火墙:
ports
端口的地方,如果我们在前面的端口前加上127.0.0.1
,docker 会阻止外网访问这个端口,只允许内部访问,像上面我们给数据库和 node 加了,正常数据库是不允许外网访问的,node
我们也用 nginx
做过了代理所以不需要直接访问,你可以根据自己的需要来决定是否开放。
2、node_modules
单独处理:
nodejs
的node_modules
需要单独处理,这里是为了我们本地开发的时候用的,当我们在本地开发的时候,容器起来了,我们去写业务代码,不需要再build 容器,docker 会自动映射进去,但 node_modules
是我们每次执行 node
的npm run install
跑出来的,这个文件夹只会在容器内产生,不会在宿主机产生,而我们更改宿主机的业务代码需要自动同步到容器内,这个同步的操作因为我们宿主机是没有node_modules
的,那么同步的时候也会导致容器里的node_modules
也没了,代码就不能正常运行。把node_modules
作为独立卷拎出来以后,除开需要更新依赖包包我们要重新 build
镜像,正常更改应用代码只需要保存即可。
运行
OK,至此你的环境基本上是准备好了,执行
docker-compose up -d
看看是否在正常跑
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bedfab2a306 front-end-microservice_nginx "/bin/sh -c nginx" 18 seconds ago Up 15 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp front-end-microservice_nginx_1
d1d539672df5 front-end-microservice_nodejs "docker-entrypoint.s…" 20 seconds ago Up 18 seconds 127.0.0.1:7001->7001/tcp front-end-microservice_nodejs_1
8f1b1401a4dc front-end-microservice_mongo "docker-entrypoint.s…" 24 seconds ago Up 20 seconds 127.0.0.1:27017->27017/tcp front-end-microservice_mongo_1
完成,你的项目应该跑起来了,接下来送佛送到西,我们配上 mongo 看看 进入 mongo 的容器
docker exec -it front-end-microservice_mongo_1 /bin/sh
进入到容器后打开mongo shell
$ mongo
// 用户表
> use admin
// 创建管理员
> db.createUser(
{
user: "admin", // 用户名
pwd: "admin", // 密码
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
> use test // 创建 test 数据库
> db.createUser( // 创建 test 库账号
{
user: "test",
pwd: "test",
roles: [
{ role: "readWrite", db: "test" } #读写帐号
]
}
)
ok ,然后打开你的mongo
连接工具,我这边用的是 mongo
官方的 MongoDB Compass 链接成功即可 然后本地用 Postman 访问 127.0.01:7001
,你的任意一个接口 配置已经完成。
部署上线
得益于 Docker
,我们部署上线非常简单,只需要在服务器上也安装好 Docker
、docker-compose
(其实我相信这些都不用你装,公司的后端正常是需要这玩意的,加上公司运维也搞这个…),然后跑一句
docker-compose up -d
其他要修改的,无非是你的配置,如 nodejs 里链接数据库的域名、端口,以及数据库跟上面一样,配置好账号密码。额外说一下,由于我们用 docker-compose
注册了 mongo
的变量名,所以在 nodejs
中,我们可以直接使用 mongo
这个名字充当主机名,比如我的在 Node
中的配置文件.env
就是这样的:
DB_USER=test
DB_PASSWD=#test
DB_HOST=mongo
DB_PORT=27017
DB_NAME=test
这样他会自动链接跟 node 在一起的本地 mongo。
Nginx
部分,你只需要修改我们在 nginx 文件下的 nginx.conf,里面定义好你自己的 nginx 配置,需要注意的是,在这个文件中你编写的路径需要是容器内的路径,比如我们引用 SSL 文件,SSL 文件在宿主机的完整路径是: /data/front-end-microservice/nginx/cert/xxx.crt
,经过 Docker 拷贝后,我们容器内的位置是: /etc/nginx/cret/xxx.crt
这是因为,我们在docker-compose.yml
中有指定镜像卷:
nginx:
build:
context: ./nginx
ports:
- 80:80
- 443:443
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/cert:/etc/nginx/cret
- ./logs/nginx:/var/log/nginx
restart: always
depends_on:
- nodejs
networks:
- my-network
每次修改完nginx相关配置文件,需要重启一下 nginx: docker-compose restart nginx
。
以上,基本就完成整个开发-生产的流程,所有的代码都可以在模板库里找到:egg-docker-template.
如果有错误欢迎指正,另外也希望有更多的架构师能一起交流前端领域的架构、工程化,欢迎加我的微信(t1556207795)拍砖、聊前端。
参考资料:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12895.html