Docker是一项具有划时代意义的开源项目,它在服务端开发以及部署中大放异彩,本着对优秀技术的不断学习态度,非常建议将Docker作为你下一项学习的技术。
本文作为Docker在前端中应用的背景篇章,会对Docker及其优势做精简的介绍,然后列举一些前端开发、测试、部署过程中遇到的问题,希望可以借助Docker优雅地解决。
场景
一、在开发过程中,有没有遇到过以下场景:
需要自己配置proxy解决跨域请求问题 接手一个新项目之后,想要跑起来,并没有想象中的那么流畅,除了前端依赖,还要配置若干系统内容 npm i npm start Error XXX服务未配置
一个Node服务(比如SSR、打印服务、普通的数据处理服务),在部署的时候,脚本控制权并不在前端手中,容易出现一些配合问题 后端项目需要在本地运行,你需要安装全部的后端环境,然后这些环境在你开发下一个项目的时候,你还在考虑如何能清理干净。 MySql MongoDb Java PHP Redis Nginx ...
二、在搭建团队基础服务过程中,有没有遇到过以下场景:
需要在服务器上部署一个项目要安装若干的基础服务 你发现系统上已经存在了旧版本的服务,你不确定升级该服务,会影响系统上的哪些应用,但是不升级,你的应用不支持安装
三、在学习过程中,是否有过以下场景:
搭建一个普通的博客,都需要花费大量时间安装一些基础服务: PHP环境 Apache 各种数据库服务
如果有一天你不需要了,还要花费时间去清理 -
项目开发完之后,还要考虑服务端的环境问题 你的一个Demo项目,希望在任何服务器都能快速部署
需求总结
我们将我们的需求汇总一下,我们希望的功能有:
开发所需的非前端环境一键配置 所需的服务方便配置、简单移除 项目开发配置完成后,方便部署在不同平台并且运行效果一致 其他人接手项目后,能够快速搭建好环境,并且运行起项目
Docker介绍
Docker的官方化介绍,可以在其官网[1]中了解到,对于我们来说Docker就是一个将项目运行所需所有环境打包到一个虚拟化容器中的工具, 同时,借助Docker,我们也可以非常方便的获取所需的依赖环境。
举个例子:我的项目需要在本地安装MySQL服务。
只需要在命令行使用Docker使用mariadb镜像启动一个容器即可。
docker run \
--name some-mariadb --rm \
-p 3306:3306 -e MYSQL_ROOT_PASSWORD=password \
mariadb:latest
复制代码
使用用户名root
,密码:password
即可成功连接MySQL。
如果想停止,直接按下Ctrl+\,服务又从电脑中移除,非常干净。
★备注:为何这里不是Ctrl+C来终止命令,可以参阅本文[3]
”
该命令中有几个参数具体分享一下:
--rm 容器结束时,移除container,与之相对的有-d -p 映射容器端口到主机端口,主机端口:容器端口 -e Env 环境变量 -d --detach 后台运行,和--rm不能同时使用 -v 挂载数据卷,bind的方式
接着启动数据库的例子,我们会发现,在结束掉服务后,下次再启动会发现数据全没了,我们如果希望将自己的数据保存在本地,那么可以增加-v参数。
docker run \
--name some-mariadb --rm \
-p 3306:3306 -e MYSQL_ROOT_PASSWORD=password \
-v /you/data/path:/var/lib/mysql
mariadb:latest
复制代码
这样本地路径/you/data/path
就会将MySQL产生的数据持久化保存了,每次启动MariaDB都会还原之前的数据了。
以上我们便体验了Docker的一大特点快速部署,即快速将MySQL服务部署到你的电脑上,无论是Windows/OSX/Linux系统,都是一段命令搞定,大大节省了时间和精力。
这样在我们的开发服务器上,只需要存储一些配置和数据文件,执行文件完全交由Docker管理。
举个例子:我需要使用Nginx做一个接口转发
我们需要在开发中需要用到该接口:https://yapi.thisjs.com/mock/21/antd/games
,我需要使用nginx对其进行一些代理配置,这样我们只需要创建一个.conf文件,然后使用Docker启动一个Nginx挂载该conf文件到conf.d/
目录下即可。
# proxy.conf 复制代码
server { listen 8080; location / { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header Cache-Control private; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; proxy_pass yapi.thisjs.com/mock/21/ant… } } 复制代码
在配置目录下执行该命令
docker run \
--name proxy-server \
-v "$(pwd)/proxy.conf":/etc/nginx/conf.d/proxy.conf:ro \
-d -p 8080:8080 \
nginx
复制代码
这时候,我们即可访问 http://localhost:8080/games
,即可获取到所需要的数据。
当我们开发/调试结束后,如果需要将nginx容器停止并移除可以参考以下命令。
# 查看正在运行中的container
docker ps
# 停止名称为 proxy-server 的container
docker stop proxy-server
# 删除名称为 proxy-server 的container
docker container rm proxy-server
复制代码
至此,Docker已经基本满足了我们的两个需求:
开发所需的非前端环境一键配置 所需的服务方便配置、简单移除
但是还没有完全达到,我们希望所需环境一键配置,而不是一键又一键的配置,因此希望能在下一个篇章里介绍Docker更轻松维护服务的相关内容。
安装Docker
看到这,你可能还没有安装Docker,其实Docker安装非常的简单。比如Mac,只需要下载镜像然后直接安装即可:
其他系统的Docker安装都非常的简单,可以参考这篇文章介绍:
安装完之后
安装完之后,不如尝试启动一个普通的前端项目。
docker run \
-p 80:80 --name react-demo \
--rm \
mrxf/craantdbasic:latest
复制代码
这是一个基于create react app的前端项目,启动之后直接访问 localhost
即可看到页面。
结语
不能为了用Docker而用Docker,否则会出现Docker也成了我们开发中的一项没有必要的服务。遇到问题,还是要以前端的方式解决。
以下以2个场景进行分析:
1.开发中的代理请求
如果是单一的代理请求来解决跨域问题的场景,那么最佳方案是以前端的方案解决
在现代前端框架脚手架中都集成了非常方便的proxy方案,以Create React App[2]为例,就提供了http和https代理功能,在未eject的项目的package.json
文件中增加一项配置即可。
"proxy": "http://url.to.poxy",
复制代码
Creact React App在执行eject之后,与其他基于Webpack的项目都可以通过配置webpack.config.js
,在devServer
中新增proxy即可。
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {'^/api' : ''}
}
}
复制代码
只有在遇到比较特殊的情况下,我们才会去配置Nginx
项目请求多个URL,我们需要将某些地址做转发,以阻止其访问原来的地址。 直播数据流地址
对于场景1,我们需要Nginx + Hosts的配合来实现。首先修改Hosts将原来的访问地址转发到本地,然后使用nginx来将其指向目标地址。
{
listen 80;
server_name api.serverurl.com;
location / {
...其他配置...
proxy_pass http://127.0.0.1:4300;
}
}
复制代码
2.前端项目部署问题
前端线上部署到底要不要用Docker?纯静态前端项目完全不需要,因为前端项目更依赖网络资源和浏览器资源,因此常规场景下,CDN才是纯静态项目的部署方案。
附录
[1]Docker: Empowering App Development for Developers