Docker Compose帮助你运行多容器应用程序。在本教程中,我们将用Docker Compose扩展一个只有一个Docker文件的Docker项目。在你继续之前,请确保你已经正确设置了Docker。如果你还没有安装docker-compose依赖项,你可以在MacOS上用Homebrew在命令行上执行以下指令:
brew install docker-compose
我们将使用以下来自Node.js与Docker项目的Docker文件作为基础。但也可以随意使用其他项目的Docker文件(例如,使用create-react-app的React或使用Webpack的自定义React)。我们的Docker文件应该看起来像下面这样:
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
注意我们在这个Dockerfile中不再有EXPOSE 或CMD 语句。这个Docker文件只是为了将应用程序创建为Docker镜像。没有暴露任何端口,也没有任何命令来运行它。这就是Docker Compose发挥作用的地方。首先,在你项目的根目录下通过命令行创建一个docker-compose.yml文件:
touch docker-compose.yml
然后给它添加以下内容:
version: '3'
services:
dev:
build:
context: .
ports:
- 4680:3000
command: npm start
在Docker Compose文件中,你可以定义所谓的服务。我们的第一个服务将只启动应用程序,并通过重新映射源端口将其暴露在一个新的端口上。在命令行中运行接下来的命令,用Docker文件中的基本镜像构建Docker服务,并最终运行该服务:
docker-compose build devdocker-compose up dev
在我们能够在浏览器中访问我们的应用程序之前,我们需要找出我们运行的Docker引擎的IP地址:
docker-machine ip default
-> 192.168.99.100
最后你应该能够访问http://192.168.99.100:4680 。请注意,你的IP地址和端口可能会有所不同。恭喜你,你已经用Docker Compose在Docker容器中运送了你的第一个应用程序。
然而,与之前的Docker设置没有什么不同。我们不再仅仅依靠Docker文件,而是使用Docker Compose来构建和运行我们的容器。但它仍然只有一个容器(这里是一个服务)在运行。让我们通过在docker-compose.yml文件中添加另一个Docker Compose服务来改变这种情况。
version: '3'
services:
dev:
build:
context: .
ports:
- 4680:3000
command: npm start
test:
build:
context: .
environment:
- CI=true
command: npm test
注意:如果你还没有在你的Node.js项目中设置任何测试脚本,或者根本没有任何测试,你可能想跟随这些Node.js测试教程之一。Mocha,Chai,和Sinon或Jest。否则,你可能想使用你手中的任何其他脚本,用于Docker Compose文件中的第二个服务。
我们使用CI=true标志,只运行所有的测试一次,因为一些测试运行器(如Jest)会在观察模式下运行测试,因此永远不会退出进程。最后,你可以把这个服务作为一个Docker容器启动。它只为测试目的而存在;这就是为什么它与为开发目的而启动你的应用程序的dev 服务明确分开。我们使用--rm 标志,在这个服务终止后自动删除容器。
docker-compose build testdocker-compose run --rm test
你所有的测试都应该运行通过。此外,有时你想让你的Docker容器能够回写到你的Docker主机。意思是说。在Docker容器中发生的所有事情和生成的新文件都应该复制到你的项目源代码中。这就是卷的作用:
version: '3'
services:
dev:
build:
context: .
ports:
- 4680:3000
command: npm start
test:
build:
context: .
environment:
- CI=true
command: npm test
volumes:
- './:/usr/src/app'
现在,发生在Docker容器(./usr/src/app )中的一切都被写到Docker主机(./ ),反之亦然。Docker容器的相对路径应该与Docker文件中的WORKDIR 。就我个人而言,我不得不使用这种技术在Docker容器中模拟React的可视化回归测试,同时能够将结果写回到我的源代码中。
恭喜你,你已经能够用Docker Compose在一个Docker文件的基础上运行两个Docker服务。其中一个服务从Docker环境中模拟开发环境,另一个服务则在Docker环境中运行所有的测试。现在你能够水平地扩展你的服务。最后,你的CI可以接管并并行地执行测试服务、刷新服务和其他服务。