You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
services:
...server:
image: node:12.16.3-alpinedepends_on:
- dbvolumes:
- ./:/usr/src/eggenvironment:
- NODE_ENV=production
- docker_db=dbworking_dir: /usr/src/eggcommand: /bin/sh -c "npm i && npm run start" # not works: npm i && npm run start and not support bashports:
- "7001:7001"volumes:
nodemodules:
说明:
depends_on 表示依赖的容器,docker 会等待依赖项先启动。
volumes 映射本地目录到容器,这样本地修改了也能影响到容器。
environment 可以在 process.env 拿到。
working_dir 设置 pwd,不像 Dockerfile,不存在是会自动创建。
command 启动容器后执行的命令行。
踩坑4:command: npm i && npm run start 不支持 &&。alpine 镜像不支持 bash,egg-bin dev 会报错 Error: Cannot find module '/bin/bash'。
玩转 docker
原文链接
背景
最近在捯饬一个前端性能上报分析的项目,前端由
react
全家桶,打包部署公司有专门的发布系统,这块就没什么顾虑。前端团队的后端没有什么规范或通用流程,就想自己先技术选型从0到1,决定使用
egg + mongodb
,后续也许会追加nginx + redis + Kafka
相关配置。docker
!目标
总体目标不外乎几点:简单、快速、安全。
docker
的优势。CI
。行动
PS:搜索搜的头秃,以下很多关键知识点收集自 google + github issue + Stack Overflow + docker 官方文档 + 英文博客。英文有障碍真是影响效率。
接下来说说实践中遇到的问题。
无 docker
步骤:
换台电脑或协同其他小伙伴开发时,得把你的动作重复一遍。不同的操作系统和下的不同 node 或 db 版本,都有可能导致系统运行不起来。
你肯定听过这句话:我的电脑上是好的啊。
初探 docker
约束不了团队众多软件的安装和版本的控制,要求安装一定范围的
docker
还是简单的吧。例如启动 mongodb 服务
这里我们启动了一个 mongo 最新稳定版本的 docker 容器。简单说明下:
run
运行镜像,本地没有会自动拉取。-p
端口映射,本地 27017 映射容器 27017 端口,就可以通过访问本地端口而访问 docker mongo 的服务了。-v
本地<LocalDirectoryPath>
映射容器目录/data/db
,用来持久化数据库,不然容器删除数据也丢失了。--name
给容器取个名字,匿名容器可以通过docker container prune
删除。-d
后台运行mongo:4.2.6
docker hub官方镜像:版本接下来本地启动跟无 docker 效果是一样的。
egg 镜像化
编写
Dockerfile
文件编写
.dockerignore
文件忽略
node_modules
:docker build -t node:egg .
docker ps # 查看运行容器,获取CONTAINER ID,-a 可以查看所有包括停止的容器
踩坑2:在 docker 中运行记得把
package.json
中的egg-scripts start --daemon
中的--daemon
删掉。需要理解前台、后台运行进程的概念,docker 中的 shell 脚本必须以前台方式运行。
优化镜像大小
上文看到,可能源代码就几百K,镜像包却超过1G。看看能有哪些优化手段。
也许你并不需要 docker node 提供完整的例如 bash、git 等工具。只需要基本的 node 运行环境即可,则可以使用
alpine
镜像。docker build -t node:simplfy .
镜像包从
1.12G
降到了132MB
,node_modules
从214MB
降到了44.5M
。踩坑3:
alpine
镜像容器不支持bash
。你如果需要
bash、git
可以这么做 issue或不想臃肿你的镜像 issue,其实你可以使用
sh
docker exec -it container_id sh
你真的需要 egg 镜像吗?
在无 docker 本地开发时,你可以使用
egg-mongoose
这样连接数据库`mongodb://127.0.0.1/your-database`
使用 docker 后,容器的
127.0.0.1
或localhost
与你本地的环境是不通的。有两种方式连接 docker mongo:
mongodb://192.1.2.3/your-database
例如在
Dockerfile
中设置真实IP连接 url
`mongodb://${process.env.docker_db}/your-database`
对于每一个开发都得不停更换网络IP,对开发不友好。
思考:
node_modules
冲突?镜像包还面临一个存储问题,不小心发到开源 docker hub 仓库,可能导致源码泄漏。
自建仓库?
大多数教程一上来,必然或大篇章都是
Dockerfile
构建镜像。介于以上种种,能不能换种思路,放弃构建 image。docker-compose
docker-compose
用来编排多容器的启动部署。mongo 配置
docker-compose.yml
文件。简单说明:
version: "3"
,不是指你的应用配置版本,而是指 docker 支持的版本,详情说明。MONGO_INITDB_ROOT_USERNAME
、MONGO_INITDB_ROOT_PASSWORD
环境变量用来开启授权,docker 自动创建一个数据库超管角色。docker mongo 启动容器时会执行
/docker-entrypoint-initdb.d/
中的*.js
脚本,例如这里init-mongo.js
来初始化数据库角色。MONGO_INITDB_DATABASE
数据库就是*.js
中默认的db
对象,这里指向admin
。./mongo-volume:/data/db
映射目录或卷,持久化数据库文件。init-mongo.js
secrets
文件,node 也读取改文件?),有点麻烦,读者有更好的方案还望不吝赐教。node 配置
说明:
depends_on
表示依赖的容器,docker 会等待依赖项先启动。volumes
映射本地目录到容器,这样本地修改了也能影响到容器。environment
可以在process.env
拿到。working_dir
设置pwd
,不像Dockerfile
,不存在是会自动创建。command
启动容器后执行的命令行。踩坑4:
command: npm i && npm run start
不支持&&
。alpine
镜像不支持bash
,egg-bin dev
会报错Error: Cannot find module '/bin/bash'
。`mongodb://${process.env.docker_db}/your-database`
大部分教程都是用
links
来解决,但官方不推荐并准备废弃。推荐使用networks
。这里并没有配置networks
。这是因为 docker 会默认创建名称为
projectname_default
的networks
,用来docker-compose
容器间的通信。node_modules
?docker-compose.yml
文件目录下文件运行docker-compose
。docker-compose
文件来区分环境,例如开发时,没有必要每次启动时执行一次npm i
。创建
docker-compose.notinstall.yml
文件npm i
带来的消耗。如果你使用匿名卷,则node_modules
每个容器相互独立无法共享,导致报错。更多多文件使用,查看文档 Share Compose configurations between files and projects
最后借助
package.json scripts
优化记忆命令行。结果
开发部署问题暂时告一段落,项目还在开发当中,线上运行一段时间后再来分享。水平有限,有错误欢迎指出,有更好的建议也欢迎补充。
参考
The text was updated successfully, but these errors were encountered: