目的
- db 和 redis 都跑在容器里,避免在本地直接安装。
- 前端和 nodejs 代码编译也跑在容器里。
Docker 入门
Docker Compose
`docker compose`
是把多个 docker 管理起来的工具。包括统一启动、关闭、打印输出、标注依赖等。通过 `docker-compose.yaml`
文件配置。
对于本文想达到的目的来看,需要:
- webpack 的 container。
- nodemon 和 babel 的 container。
- mysql 的 container。
- redis 的 container。
把 `docker-compose.yaml`
直接贴出来,可能一下子看不懂,有点被吓到了,但别急,我们慢慢来解释。
1version: '3' 2services: 3 web: 4 image: "dev-node" 5 command: ["npm", "run", "dev"] 6 ports: 7 - "5858:5858" 8 - "3000:3000" 9 volumes: 10 - /Users/xxx/xxx/nodeapp:/app 11 - node_modules:/app/node_modules 12 depends_on: 13 - fe 14 - db 15 - redis 16 fe: 17 image: "dev-fe" 18 command: ["npm", "run", "dev:fe"] 19 volumes: 20 - /Users/xxx/xxx/nodeapp:/app 21 - node_modules:/app/node_modules 22 redis: 23 image: "redis:alpine" 24 ports: 25 - "6379:6379" 26 db: 27 image: "db" 28 environment: 29 MYSQL_USER: test 30 MYSQL_PASSWORD: test1234 31 MYSQL_ROOT_PASSWORD: test1234 32 ports: 33 - "3306:3306" 34volumes: 35 node_modules: 36 external: 37 name: node_modules 38
`version`
就是使用第 3 版本配置文件格式的意思,这个忽略吧,不重要。
再看其他最外层的字段,首先看 `volumes`
,这个字段定义了要用到的 `docker volumes`
。上面的配置就定义了一个叫 `node_modules`
的 volume,通过 volume 下的 `external`
设置它外接一个已有的叫 `node_modules`
的 volume。可以把 volume 看作移动硬盘,以后的 node 模块都会安装到里面,安装了之后,就可以即插即用了。
另外一个重要的字段是 `services`
。在这个字段的下一级,定义了四个字段,看字面意思应该都知道其作用。值得注意的是 `volumes`
和 `depends_on`
字段。
volumes 字段的值是上上段文字里提到的最外层的 `volumes`
下定义好的 `node_modules`
和`/Users/xxx/xxx/nodeapp:/app`
。后者是直接把本机目录映射成容器里面的一个目录,可以达到在容器里直接访问代码目录的效果。
`depends_on`
是把这一切串联起来的关键,标注好依赖后,只要运行 `docker-compose up`
就可以把 `web`
以及其依赖容器 `fe`
, `db`
, `redis`
一起启动起来。
这个但是如何互相访问这些串联在一起的容器呢?这已经被 `docker-compose`
考虑得很周到。docker 会给上面的 service 名字设置 host。比如,上面的配置有一个 service 叫 db,里面运行的是 mysql,那就可以这样访问:`mysql://db:3306`
。
vscode debug
node 程序跑在 docker 里面之后,只能用 `attach`
的方式去 debug 了。配置如下:
1{ 2 "version": "0.2.0", 3 "configurations": [ 4 { 5 "type": "node", 6 "request": "attach", 7 "name": "Attach", 8 "address": "localhost", 9 "localRoot": "${workspaceRoot}/src/app", 10 "remoteRoot": "/app/src/app", 11 "sourceMaps": true, 12 "restart": true, 13 "port": 5858 14 } 15 ] 16} 17
启动 node 程序的 `npm script`
里面这样写:
1nodemon --watch ./src/app --delay 1.5 ./src/app --exec babel-node --inspect=0.0.0.0:5858 --out-dir ./dist/app 2
注意 `--insepect`
参数的值 `0.0.0.0:5858`
,必须是 `0.0.0.0`
加上端口,原因位置,也许和容器以及宿主的网络连接方式有关。
最后
容器如何划分的思路来源于慕课网的这篇利用Docker容器搭建高效的Node.js开发环境。
总结来说,前端构建、node 代码检测编译和重启、db、redis 分别在四个不同的容器。之间的链接都走 `docker-compose`
自动配置的 host。debug 就走 attach 模式。