用Git子模块和Docker Compose实现高效开发工作流

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 本文讲的是用Git子模块和Docker Compose实现高效开发工作流,【编者的话】搭建开发环境一直让程序员们头疼,本文使用Git子模块和Docker Compose实现高效率的开发工作流,让程序员能够轻松搭建出开发环境,把精力投入到需要开发的应用本身。
本文讲的是用Git子模块和Docker Compose实现高效开发工作流 【编者的话】搭建开发环境一直让程序员们头疼,本文使用Git子模块和Docker Compose实现高效率的开发工作流,让程序员能够轻松搭建出开发环境,把精力投入到需要开发的应用本身。

问题

自我们从Continuous Software雇佣了第一位远程开发的程序员以来,我们就意识到精简开发工作流的重要性。当新入职的程序员接手由很多应用组成的复杂项目时,我们想尽量避免以下这几个问题:
  • 缺少stack模块:Node.js、PHP、PostgreSQL等
  • 不清楚项目组件/应用的总体概况
  • 本地配置冲突:监听端口、数据库配置等

此外,就我个人经验而言,我们这样的程序员太容易找不着北了。曾经,我入职一个公司的第一整天都花在搭建开发环境上,试图去理解所有的东西怎么才能一起工作,而无法直接就去理解公司开发的应用到底是怎么工作的。

方案

在具体介绍如何解决上述问题之前,我先介绍下我们项目使用的开发工作流。

我们的每个项目都在Bitbucket上有自己的Team(和GitHub上的Organization对应)。每个应用都会在Team下创建一个Repository(比如, api dashboard cpanel )。在这些子模块之上,创建了一个名为 development 的Repository。子模块的同一层级有 README.md docker-compose.yml 两个文件。
kytwb@continuous:~/path/to/<project>/$ ls -la
total 40
drwxrwxr-x 11 kytwb amine 4096 Mar 14 16:30 .
drwxr-xr-x  4 kytwb amine 4096 Nov  1 20:17 ..
drwxr-xr-x 20 kytwb amine 4096 Mar 11 14:24 api
drwxr-xr-x 11 kytwb amine 4096 Mar  3 13:21 cpanel
drwxr-xr-x 10 kytwb amine 4096 Mar 12 11:37 dashboard
-rw-r--r--  1 kytwb amine 2302 Mar  2 15:28 docker-compose.yml
drwxrwxr-x  9 kytwb amine 4096 Mar 14 16:30 .git
-rw-r--r--  1 kytwb amine  648 Dec 22 17:20 .gitmodules
-rw-r--r--  1 kytwb amine 1706 Dec 17 16:41 README.md

当新程序员加入项目时,只需在Bitbucket上浏览 development repository,根据 README.md 的步骤就可以快速搭建环境。具体步骤如下所示:
$ git -v
$ docker -v
$ docker-compose -v
$ git clone git@bitbucket.com:<project>/development.git <project> && cd <project>
$ git submodule init && git submodule update
$ git submodule foreach npm install
$ docker-compose up -d

至此,一切就都已经搭建好,并运行在本地机器上了。

实现原理

本章介绍我们是如何实现上述工作流的。

前提条件

$ git -v
$ docker -v
$ docker-compose

由于我们的开发堆栈完全基于Docker,所以,程序员需要先安装Docker。这时他们不需要特别熟悉Docker,只需要在开发时使用Docker即可,我们间接地将他们引入到了容器的世界,之后会以此为桥梁向他们解释如何使用Docker实现持续集成、持续交付等等。 README.md 中并没有详细介绍如何 安装Docker ,因为安装很简单。

当docker-compose还叫 Fig 的时候我们就已经用它来编排开发堆栈里的容器。之后Docker收购了Fig,重命名为Docker Compose。有人提议将Docker Compose合并到Docker代码里,但是基于很多原因最终并没有这么做,所以Docker Compose仍然需要单独安装。

同样地,本文没有详细介绍 Docker Compose的安装 ,因为很简单。

搭建仓库(Repository)

如前所述,需要创建一个开发仓库,以及为每个应用创建对应的仓库。这里我们创建了 api dashboard cpanel 。当创建这些仓库的时候,重点关注 development 仓库的搭建。
$ git clone git@bitbucket.com:<project>/development.git <project> && cd <project>

现在将应用程序的仓库添加为 development 仓库的子模块,只需要键入如下命令:
$ git submodule add git@bitbucket.org:<project>/api.git
$ git submodule add git@bitbucket.org:<project>/dashboard.git
$ git submodule add git@bitbucket.org:<project>/cpanel.git

这样,你的 development 仓库根目录下会创建出 .gitmodules 文件。程序员也就可以在克隆 development repository的时候一次得到所有的应用程序并运行:
$ git submodule init && git submodule update

更多子模块的信息,请参考 Git官方文档

Docker化一切

现在我们已经搭建好了 development 仓库,可以通过 cd 的方式访问所有不同的应用程序。接下来我们要用之前提到的编排工具:Docker Compose来容器化所有的应用及其配置。

首先从 api 应用程序开始。打开 docker-compose.yml ,为API声明一个容器,并为这个容器选择基础镜像。本示例中的代码基于Node.js,因此选择官方Node.js镜像:
api:
image: dockerfile/nodejs

这时,运行命令 docker-compose up -d 会创建出一个名为 &lt;project>_api_1 的容器,这个容器什么也不做(启动后立即退出)。运行命令 docker-compose ps 可以得到由 docker-compose.yml 编排的所有容器的信息。

接下来配置 api 容器,使其多一些功能。为了实现这个目的,我们需要:
  • 将源代码挂载到容器中
  • 声明用什么命令运行应用
  • 暴露合适的端口以供访问应用

这样配置文件类似:
api:
image: dockerfile/nodejs
volumes:
- ./api/:/app/
working_dir: /app/
command: npm start
ports:
- "8000:8000"

现在再运行 docker-compose up -d ,就启动了 api 应用,可以在 http://localhost:8000 访问它。这个程序可能会崩溃,可以使用 docker-compose logs api 检查容器日志。

这里,我怀疑 api 的崩溃是因为它连不上数据库。因此需要添加 database 容器,并让 api 容器能够使用它。
api:
image: dockerfile/nodejs
volumes:
- ./api/:/app/
working_dir: /app/
command: npm start
ports:
- "8000:8000"
links:
- database
database:
image: postgresql
ports:
- "5432:5432"

通过创建 database 容器,并将其连接到 api 容器,我们就可以在 api 容器里找到 database 。要想展示API的环境(比如, console.log(process.env) ),必须使用如下变量,比如 POSTGRES_1_PORT_5432_TCP_ADDR POSTGRES_1_PORT_5432_TCP_PORT 。这是我们在API的配置文件里使用的关联到数据库的变量。

通过link指令,这个数据库容器被认为是API容器的依赖条件。这意味着Docker Compose在启动API容器之前一定会先启动数据库容器。
现在我们用同样的方式描述其它应用程序。这里,我们可以通过环境变量 API_1_PORT_8000_TCP_ADDR API_1_PORT_8000_TCP_PORT ,将 api 连接到 dashboard cpanel 应用。
- ./api/:/app/
working_dir: /app/
command: npm start
ports:
- "8000:8000"
links:
- database
database:
image: postgresql
dashboard:
image: dockerfile/nodejs
volumes:
- ./dashboard/:/app/
working_dir: /app/
command: npm start
ports:
- "8001:8001"
links:
- api
cpanel:
image: dockerfile/nodejs
volumes:
- ./api/:/app/
working_dir: /app/
command: npm start
ports:
- "8002:8002"
links:
- api

就像之前为数据库修改API配置文件一样,可以为dashboard和cpanel应用使用类似的环境变量,从而避免硬编码。

现在可以再次运行 docker-compose up -d 命令和 docker-compose ps 命令:
kytwb@continuous:~/path/to/<project>$ docker-compose up -d
Recreating <project>_database_1...
Recreating <project>_api_1...
Creating <project>_dashboard_1...
Creating <project>_cpanel_1...
kytwb@continuous:~/path/to/<project>$ docker-compose ps
Name                     Command              State      Ports           
----------------------------------------------------------------------------------
<project>_api_1         npm start            Up         0.0.0.0:8000->8000/tcp
<project>_dashboard_1   npm start            Up         0.0.0.0:8001->8001/tcp
<project>_cpanel_1      npm start            Up         0.0.0.0:8002->8002/tcp
<project>_database_1    /usr/local/bin/run   Up         0.0.0.0:5432->5432/tcp

应用应该就已经启动并运行了。
http://localhsot:8000 可以访问api。
http://localhsot:8001 可以访问dashboard。
http://localhsot:8002 可以访问cpanel。

更进一步

本地路由

在使用 docker-compose up -d 运行所有容器之后,可以通过 http://localhost:<application_port> 访问我们的应用。基于当前配置,我们可以很容易地使用 jwilder/nginx-proxy 加上本地路由功能,这样就可以使用和生产环境类似的URL访问本地应用了。比如,通过 http://api.domain.local 访问 http://api.domain.com 的本地版本。
jwilder/nginx-proxy 镜像将一切变得很简单。只需要在 docker-compose.yml 里加上描述去创建一个名为 nginx 的新容器。根据 jwilder/nginx-proxy 的README文件(挂载Docker守护进程socket,暴露80端口)配置该容器就可以了。之后,在现有容器里再添加额外的环境变量 VIRTUAL_HOST VIRTUAL_PORT ,如下:
api:
image: dockerfile/nodejs
volumes:
- ./api/:/app/
working_dir: /app/
command: npm start
environment:
- VIRTUAL_HOST=api.domain.local
- VIRTUAL_PORT=8000
ports:
- "8000:8000"
links:
- database
database:
image: postgresql
dashboard:
image: dockerfile/nodejs
volumes:
- ./dashboard/:/app/
working_dir: /app/
command: npm start
environment:
- VIRTUAL_HOST=dashboard.domain.local
- VIRTUAL_PORT=8001
ports:
- "8001:8001"
links:
- api
cpanel:
image: dockerfile/nodejs
volumes:
- ./api/:/app/
working_dir: /app/
command: npm start
environment:
- VIRTUAL_HOST=cpanel.domain.local
- VIRTUAL_PORT=8002
ports:
- "8002:8002"
links:
- api
nginx:
image: jwilder/nginx-proxy
volumes:
- /var/run/docker.sock:/tmp/docker.sock
ports:
- "80:80"

nginx 容器会检查所有运行在Docker守护进程之上(通过挂载的 docker.sock 文件)的容器,为每个容器创建合适的nginx配置文件,并设置 VIRTUAL_HOST 环境变量。

要想完成本地路由的搭建,还需要在 etc/hosts 里添加所有的 VIRTUAL_HOST 。我是手动用node.js的 hostile 包来完成这个工作的,不过我猜应该可以自动化实现,就像 jwilder/nginx-proxy 可以根据nginx配置文件动态变化一样。这里需要再研究一下。

现在可以再次运行 docker-compose up -d ,然后使用和生产环境一样的url访问应用程序,只需用 .local TLD代替 .com TLD。

建议

本文发表在AirPair上,如果你对更进一步这一章有任何建议,请随意fork并修改它。如果你发现本文有任何错误,也请帮忙修改。

原文链接:Efficient development workflow using Git submodules and Docker Compose(翻译:崔婧雯)  
===========================
译者介绍
崔婧雯,现就职于VMware,高级软件工程师,负责桌面虚拟化产品的质量保证工作。曾在IBM WebSphere业务流程管理软件担任多年系统测试工作。对虚拟化,中间件技术有浓厚的兴趣。

原文发布时间为:2015-03-20
本文作者:崔婧雯 
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:用Git子模块和Docker Compose实现高效开发工作流
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
29天前
|
存储 机器学习/深度学习 中间件
快速上手 Elasticsearch:Docker Compose 部署详解
本文介绍了如何使用Docker Compose快速搭建Elasticsearch学习环境。Elasticsearch是一款用于实时搜索和分析的分布式中间件,适用于多种场景,如搜索、日志分析、机器学习等。首先,创建docker网络,拉取最新版8.12.2镜像。接着,编写docker-compose.yml文件,配置单节点集群,设置端口映射、内存限制及数据卷挂载。然后,创建并配置数据卷目录,允许远程访问和跨域。最后,启动服务并验证,通过浏览器访问确认服务运行正常。本文为初学者提供了一个简便的Elasticsearch部署方法。
158 4
快速上手 Elasticsearch:Docker Compose 部署详解
|
1月前
|
关系型数据库 MySQL Java
Docker Compose详细教程(从入门到放弃)
Docker Compose详细教程(从入门到放弃)
165 0
|
2月前
|
存储 持续交付 Docker
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
39 0
|
1月前
|
Java Docker 微服务
如何使用Docker和Docker Compose部署微服务
【2月更文挑战第12天】
224 0
|
8天前
|
Linux 开发工具 git
还不会 Git 子模块操作?一文教你学会 git submodule 的增、删、改、查!
还不会 Git 子模块操作?一文教你学会 git submodule 的增、删、改、查!
|
13天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
25天前
|
缓存 自然语言处理 Docker
[Docker] DevContainer高效开发(第一篇):基于remote container开发
VS Code的Dev Containers简化了Python的容器化开发,将开发环境与应用一同打包在Docker中,消除环境配置问题。这种方式使得多语言、多版本开发变得整洁高效。
29 0
|
1月前
|
应用服务中间件 nginx Docker
简述 Docker 在 Python WEB 开发中的作用。
【2月更文挑战第27天】【2月更文挑战第95篇】简述 Docker 在 Python WEB 开发中的作用。
|
1月前
|
Shell Docker 容器
Docker的常用命令:加速你的容器化开发与部署
Docker的常用命令:加速你的容器化开发与部署
55 0
|
2月前
|
Docker 容器
Docker Compose的安装与配置
Docker Compose的安装与配置
130 2
Docker Compose的安装与配置