使用Docker构建高效Web开发环境

本文介绍如何使用 Docker 构建一个高效的 Web 开发环境(Linux+Docker+Python+JavaScript),这也是我的日常开发环境。

准备Docker

  1. 安装Docker

    https://docker.github.io/engine/installation/linux/
    不要漏了阅读 Create a Docker group 部分。

  2. 安装Docker Compose

    https://docker.github.io/compose/install/
    也可以使用 pip install docker-compose 安装。

  3. Docker Compose快捷命令

     $ which docker-compose
     /usr/bin/docker-compose
     $ cp /usr/bin/docker-compose /usr/bin/dc
    

    因为在我的系统(Arch Linux)上,dc是一个系统自带的任意精度的计算器,所以直接覆盖它。 如果你的系统没有自带dc,你也可以在~/.bashrc文件中添加alias dc=docker-compose实现。

  4. 用Google搜Docker教程,赶紧入门吧。另外,Docker官网的教程最新,最准确,最全面,非常值得去看。

Docker镜像加速

刚开始使用Docker时最烦的就是下载镜像,太!慢!了!

现在DaoCloud和阿里云都有提供免费的镜像加速服务,逐渐也有其他一些服务商提供镜像加速。

首先,需要获取一个镜像加速地址(registry-mirror),需注册后打开下面链接。
DaoCloud传送门: https://www.daocloud.io/mirror
阿里云传送门: https://cr.console.aliyun.com

如果您的系统是 Ubuntu 12.04 14.04,Debain 8 等系统,Docker 1.9 以上,编辑/etc/default/docker文件,添加或修改registry-mirror:

DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://xxxxxx.mirror.aliyuncs.com"

重启Docker:

sudo service docker restart

如果你的系统使用 systemd 作为系统和服务管理器,Docker 1.9 以上,编辑/usr/lib/systemd/system/docker.service文件,添加或修改registry-mirror:

ExecStart=/usr/bin/dockerd -H fd:// --registry-mirror=https://xxxxxx.mirror.aliyuncs.com

重启Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

可以使用服务商提供的脚本一键配置(不一定能配成功)。
另外可以参考这篇文章: Docker下使用镜像加速

PyPI镜像加速

推荐豆瓣的镜像,速度很快。

命令行使用,-i参数:

pip install -r requires.txt -i https://pypi.douban.com/simple

全局配置,编辑 ~/.config/pip/pip.conf 文件:

[global]
index-url = https://pypi.douban.com/simple

npm镜像加速

推荐淘宝镜像 https://npm.taobao.org/

命令行使用:

npm --registry=https://registry.npm.taobao.org

全局设置:

npm config set registry=https://registry.npm.taobao.org

把依赖装进Docker

Web开发,基本上都会用到数据库,缓存等等。使用Docker可以轻松的安装和控制这些依赖,这也是高效测试的基础。

通常项目结构如下(这里只介绍开发环境,生产环境以后再补充):

app/                          项目代码
docker/                       容器的初始配置
data/                         数据,日志等等
manage.py                     启动脚本
Dockerfile                    生产环境镜像
docker-compose.yml            生产环境
docker-compose-dev.yml        开发环境

首先创建一个docker-compose-dev.yml文件,这里假设依赖 MySQL 5.7 和 Redis:

version: '2'
services:
  mysql:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./data/mysql:/var/lib/mysql
    ports:
      - "3306:3306"
  redis:
    image: redis:3
    volumes:
      - ./data/redis:/data
    ports:
      - "6379:6379"

./docker/mysql/init.sql是用于创建数据库的脚本 (参考: https://hub.docker.com/_/mysql/), 为了与线上数据库编码保持一致,内容大致如下:

create database if not exists mydb character set utf8mb4 collate utf8mb4_unicode_ci;

运行以下命令,稍等片刻,所有依赖就启动好了:

dc -f docker-compose-dev.yml up

如果需要操作数据库:

dc -f docker-compose-dev.yml exec mysql mysql -uroot -proot mydb

Makefile快捷命令

Make是Linux下最常用的构建工具,构建规则都写在Makefile文件里面,主要用于C语言的项目。 这里只用到它的一小部分功能: 快捷命令, 其他功能可参考Make 命令教程

创建一个Makefile文件,内容如下(注意使用TAB缩进):

dev:
    echo "docker is awesome!"

然后执行make dev:

$ make dev
echo 'docker is awesome!'
docker is awesome!

也可以在命令前面加上@:

dev:
    @echo "docker is awesome!"

然后执行make dev,命令本身就不会显示出来了:

$ make dev
docker is awesome!

最终版本:

dev:
    @docker-compose -f docker-compose-dev.yml up

mysql:
    @docker-compose -f docker-compose-dev.yml exec mysql mysql -uroot -proot mydb

Python高效测试

我是单元测试的忠实拥护者,因为我意识到单元测试能极大的减少调试,修改BUG,重构的时间和痛苦。

当我重构一个 Python 2 的库时,因为有完善的单元测试,所有我能放心大胆的修改代码,修改之后我 只需运行一下测试就知道哪里还有问题需要修改,而不用去猜测和仔细检查代码以避免疏漏。 当全部测试通过之后,我就有信心这个库不会出大的Bug,至少能和上一个版本差不多稳定。

另一方面,我也意识到不能过度追求测试的数量和覆盖率。

过度的测试需要花费太多的时间和精力,而收到的效果甚微,95% 和 99% 的测试覆盖率其实差别不大, 99% 和 100% 的差别就更小了,但是为了达到更高的测试覆盖率,却需要仔细的构造测试用例才能执行到未测试的代码。

测试的付出和收益中有个平衡点,达到预期目标即可,简言之,点到为止:

my philosophy is to test as little as possible to reach a given level of confidence

这两篇问答很值得一读:

http://stackoverflow.com/questions/67299/is-unit-testing-worth-the-effort http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565

上面介绍的是测试之道,下面说的是测试之术。

Back

留言 - Github Issues | 主题 - The Plain