文章目录
  1. 1. 写在前面的话
  2. 2. daocloud介绍
  3. 3. 持续集成简单的html5应用
    1. 3.1. 本小节使用场景
    2. 3.2. 什么是「简单的html5应用」
    3. 3.3. 部署大致解决方案
    4. 3.4. 构建应用前的准备
      1. 3.4.1. 应用目录结构
      2. 3.4.2. 创建Dockerfile文件
      3. 3.4.3. 配置在docker中使用的nginx配置文件。
    5. 3.5. 使用daocloud进行持续构建镜像以及发布
    6. 3.6. 发布完成之后需要做的工作
  4. 4. 持续集成依赖外部服务的应用
    1. 4.1. 本文适用的场景
    2. 4.2. 依赖外部服务的应用
    3. 4.3. 构建前的准备
      1. 4.3.1. 项目结构
      2. 4.3.2. Dockerfile文件编写
      3. 4.3.3. Makefile文件编写
      4. 4.3.4. 静态文件支持
      5. 4.3.5. 通过环境变量来连接服务
    4. 4.4. 使用daocloud部署构建好的taikang项目

写在前面的话

来自维基百科的:货殖崇拜编程

为因GFW屏蔽访问不了维基百科的同学准备的:

货物崇拜编程(Cargo Cult Programming)是一种计算机程序设计中的反模式,其特征为不明就里地、仪式性地使用代码或程序架构。货物崇拜编程通常是程序员既没理解他要解决的bug、也没理解表面上的解决方案的典型表现。

这个名词有时也指不熟练的或没经验的程序员从某处拷贝代码到另一处,却不太清楚其代码是如何工作的,或者不清楚在新的地方是否需要这段代码。也可以指不正确或过份的应用设计模式、代码风格或编程方法,却对其原理不明就里。

货物崇拜编程来源于“货物崇拜”这个词。其衍生词还有“货物崇拜软件工程”。

在阅读任何教程类的文章时,都不要有编程上的货殖崇拜,有些内容是需要你根据自己的实际情况修改一些内容的,需要你理解它,如果不理解某些内容,就需要先熟悉一下相关的知识。

daocloud介绍

daocloud提供基于docker进行持续集成的服务,使用它可以很方便的完成项目的自动化构建以及持续发布等功能。

当然,如果要使用daocloud持续化集成应用,首先你需要注册一个daocloud账号。如果你效力于某个公司的话,还要通知该公司把你的账号拉到公司用户组里,这样才能使用该公司的资源。

持续集成简单的html5应用

本小节使用场景

  • 拥有自己的主机
  • 将主机添加到了daocloud上
  • 只使用daocloud的自动构建和部署功能
  • 镜像也要部署到自己的主机上。

什么是「简单的html5应用」

只有前端页面,并且使用nginx提供服务。

部署大致解决方案

本文假设一个使用场景:拥有自己的主机,并且绑定到了daocloud上,然后想通过daocloud进行持续化地部署到自己的主机上。如果想要部署一个纯前端项目,需要把nginx集成进去,然后使用nginx来提供服务。

构建应用前的准备

应用目录结构

因为daocloud是基于daocker的,在使用daocloud之前,我们需要按照docker的规范,把自己的项目改成支持打包成镜像的应用,对于html5项目来说,就是添加Dockerfile文件和配置好所需要的nginx配置文件。比如我有一个应用叫jinli,其目录结构为(你的目录结构和这个可能也不一样):

1
2
3
4
5
6
7
8
9
jinli/ # 项目根目录
├── jinli/ # 具体的应用目录
│   ├── images/ # 图片
│   ├── index.html # 默认的检索html
│   ├── scripts/ # js文件夹
│   └── styles/ # 存放css的文件夹
├── Dockerfile # Dockerfile
├── jinli.conf # 本应用的nginx配置文件
└── log/ # log文件

在这个目录结构中,和docker镜像构建是就是Dockerfile这个文件,jinli.conf是个将要一起打包放入docker镜像中的文件,其他的都是应用本身的文件。

创建Dockerfile文件

Dockerfile,就是一个daocker的规则文件,就像make的Makefile一样。Dockerfile描述了将自己的应用构建成docker镜像的过程。
在本例中,Dockerfile的内容如下:

1
2
3
4
5
6
7
8
9
10
11
# 选择nginx服务
FROM nginx:1.9.5
# copy代码
COPY . /src
# 添加nginx配置文件
COPY jinli.conf /etc/nginx/conf.d/
# 去掉默认的nginx配置文件
RUN rm /etc/nginx/conf.d/default.conf

Dockerfile解释:

  • 首先,想象将要构建的docker镜像包含一个linux操作系统。
  • FROM nginx:1.9.5 的意思就是,将1.9.5版本的nginx服务集成到自己的镜像中(其实操作系统就是在这一步引入的,nginx本身也是一个镜像,它是建立在一个linux操作系统之上的,拉取nginx的时候,会连把nginx连带其附着的linx系统整个一起拉下来)。
  • COPY . /src 的意思是将当前目录下的代码复制到镜像中(的操作系统中)的 /src目录下
  • COPY jinli.conf /etc/nginx/conf.d/ 的意思是,将当前目录下写好的nginx配置文件,复制到镜像(的操作系统)中的相应目录下。
  • 删掉原来默认的nginx配置(因为默认配置文件会占用掉localhost,不知道有没有更好的解决办法)

配置在docker中使用的nginx配置文件。

本示例中,nginx配置文件命名为jinli.conf。把它打包到镜像中,来给html5应用提供服务,这与平时直接在服务器上部署没有什么很大的差别,需要注意的就是:

  • server_name 为 localhost,因为这个server_name是在docker容器内部使用的。
  • location 中的root文件夹是docker容器中的地址,不是宿主机的地址
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name localhost;
access_log /src/log/jinli.access.log;
error_log /src/log/jinli.error.log;
# 这里你还可以选择根据需要配一些gzip等选项
location / {
root /src/jinli/;
}
}

然后将应用提交到github上,比如具体为:xiaohuruwei/jinli.git

以上已经包含全部必须的材料了,下面进入daocloud环节。

使用daocloud进行持续构建镜像以及发布

因为前面的步骤已经构建好了一个支持docker的代码版本,而且不需要外联像mysql这样的外部服务,因此可以直接将其当做一个单应用的镜像来构建。

在这方面,daocloud已经有了完善的文档,可以直接参考其中的创建新项目章节,以及持续集成章节。

在上面的过程中,核心部分如下:

  • 绑定git源
  • 选择要部署的git仓库,并构建成镜像
  • 部署到自有主机
  • 将后续自动持续部署的设置打开
    • 在「代码构建」具体项目的「设置」中,将持续集成打开,设置好镜像和持续集成的触发规则,比如:在向docker-support分支提交代码时,就触发自动持续集成。
    • 在「应用列表」中的「发布」设置中,将自动发布打开。

发布完成之后需要做的工作

发布完成之后,可以在daocloud上看到所创建的容器的具体信息。包括映射到宿主机上的端口号等等,点击端口号后可以看到该应用的访问地址,打开可以测试是否部署成功了

为方便后面的叙述,这里假设映射出的端口号为8888。因为是发布到自己的主机上,所以还需要自己配置域名以及nginx反向代理来对外提供访问服务。假设有一个域名已经绑定在了自己的主机上,这里假设为xiaohuruwei.com.

登陆自己的主机,并配置nginx文件,如果是使用apt-get一类的包管理工具安装的,那么应该是在/etc/nginx/conf.d/目录下添加 jinli.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name xiaohuruwei.com;
access_log /var/log/nginx/jinli.access.log;
error_log /var/log/nginx/jinli.error.log;
client_max_body_size 200m;
# 可以根据需要设置其他配置项
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8888;
}
}

然后访问xiaohuruwei.com就可以看到内容了

另外,需要在使用daocloud的时候,将自动构建和持续发布都打开,这样下次使用时,只需要往github推代码时,触发了你设定的更新规则,就会持续构建镜像并发布了。


持续集成依赖外部服务的应用

以django应用为例

本文适用的场景

  • 拥有自己的主机
  • 将主机添加到了daocloud上
  • 只使用daocloud的自动构建和部署功能
  • 所依赖的外部服务已经(以daocke容器)存在于自己的主机上,镜像也要部署在自己的主机上。在部署的同时连接主机上已经存在的外部服务(如mysql,redis等)。

依赖外部服务的应用

在docker领域中,如果一个docker镜像自身需要其他镜像来提供服务,就说这个镜像是带外部服务的。

以一个简单的django应用为例,如果这个django应用自身无法完成任务,而需要mysql或者其他数据库作为数据的持久化服务,那么这个django应用就是依赖外部服务的。

构建前的准备

准备同html5接近,因为需要连接外部服务,而且因为uwsig服务默认不支持静态文件的处理,所以多了一些对原代码的改造。

项目结构

首先是django应用的目录,比如有一个应用叫taikang,目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
taikang # 项目根目录
├── Dockerfile # Dockerfile文件
├── logs
├── manage.py
├── Makefile # makefile文件
├── requirements.txt # 应用依赖的python库
├── templates
└── taikang # 应用目录
├── __init__.py
├── models.py
├── settings.py # django的配置文件
├── urls.py
├── views.py
└── wsgi.py

Dockerfile文件编写

Dockerfile文件的含义和html5部署中是完全相同的,这里为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 使用python2.7.10版本作为基础服务
from python:2.7.10
将当前项目中的内容全copy到镜像中的 /src 目录下
COPY . /src
# 安装django应用依赖的库,这里设置为豆瓣的pypi源
RUN cd /src; pip install -r requirements.txt -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
# 镜像暴露出8000端口
EXPOSE 8000
# 设置工作目录为代码所在目录
WORKDIR /src
# 设置应用启动命令
CMD ["make", "start-uwsgi"]

Makefile文件编写

可以注意到,上述最后的启动命令中使用了make命令,这也是前面目录结构中Makefile文件的作用所在。有关makefile的知识,这里不再详述.
总之可以让你更方便的管理应用,这里直接贴出makefile文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# uwsig启动的host和端口
host:=0.0.0.0
port:=8000
# debug的时候直接使用django自带的服务启动
debug:
./manage.py runserver $(host):$(port)
# 启动uwsgi服务
start-uwsgi:
uwsgi --socket $(host):$(port) \
--chdir $(shell pwd) \
--wsgi-file taikang/wsgi.py \
--master \
--process 4 \
--pidfile $(shell pwd)/uwsgi.pid
# 停止uwsgi服务
stop-uwsgi:
uwsgi --stop uwsgi.pid
# 重载uwsgi服务
reload-uwsgi:
uwsgi --reload uwsgi.pid
# 收集静态文件
collectstatic:
./manage.py collectstatic --noinput
.PHONY: debug \
collectstatic \
reload-uwsgi \
start-uwsgi \
stop-uwsgi

静态文件支持

在uwsgi提供服务时,静态文件需要单独进行处理,目前推荐使用django的whitenoise库 。可以方便的提供静态文件服务,仅仅需要几行配置。

通过环境变量来连接服务

在使用docker部署项目,当需要连接外部的服务时,一般通过link + 环境变量的参数进行。而为了支持环境变量的形式,我们的django应用也要做一些相应的改变。具体就是修改settings.py中的配置。

修改settings.py文件,以mysql为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 原来的mysql配置文件
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'starding_taikang',
# 'USER': 'root',
# 'PASSWORD': 'your_password_here',
# 'HOST': 'localhost',
# 'PORT': '3306'
# }
#}
# 通过获取环境变量的形式来获取服务
import os # 导入os库
mysql_name = os.environ.get('MYSQL_INSTANCE_NAME') or "taikang" # 获取数据库名称
mysql_user = os.environ.get('MYSQL_USERNAME') or "root" # 获取mysql用户名
mysql_password = os.environ.get('MYSQL_PASSWORD') or "your_password" # 获取密码
mysql_host = os.environ.get('MYSQL_ADDR') or "127.0.0.1" # 获取服务地址
mysql_port = "3306"
# 直接使用上面的变量代替字符串
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': mysql_name,
'USER': mysql_user,
'PASSWORD': mysql_password,
'HOST': mysql_host,
'PORT': mysql_port
}
}

使用daocloud部署构建好的taikang项目

步骤基本同html5部署,假设你完成镜像构建之后,产生的镜像地址为:

1
daocloud.io/xiaohuruwei/taking:latest

下一步在使用镜像部署的时候,需要连接外部服务,具体是手动编辑yaml文件。

1
2
3
4
5
6
7
8
9
takang_test:
image: daocloud.io/xiaohuruwei/taking:latest
restart: always
external_links:
- mysql1:mysql # 前面的mysql1是你主机上已经存在的mysql的容器实例,冒号后面是别名
ports:
- '8000'
environment: # 环境变量
- MYSQL_ADDR=mysql

但是我发现这种方法似乎有一些bug,如果上面的方法不成功,那么你就先直接部署,部署成功之后,再去修改yaml文件成为上面描述的样子。在修改yaml文件的时候,daocloud会提示重新部署,选择确定即可。

至此,django项目也部署完成了。然后同html5项目部署一样,把各种自动构建,自动发布的功能打开就行了。

注意: 由于django项目是使用uwsgi部署的,直接访问daocloud给出的地址是错误的,这个时候必须配置nginx反向代理。

附上uwsgi部署的django nginx代理配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 80;
server_name xiaohuruwei.com;
access_log /var/log/nginx/taikang.access.log;
error_log /var/log/nginx/taikang.error.log;
client_max_body_size 200m;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:32801;
}
}
文章目录
  1. 1. 写在前面的话
  2. 2. daocloud介绍
  3. 3. 持续集成简单的html5应用
    1. 3.1. 本小节使用场景
    2. 3.2. 什么是「简单的html5应用」
    3. 3.3. 部署大致解决方案
    4. 3.4. 构建应用前的准备
      1. 3.4.1. 应用目录结构
      2. 3.4.2. 创建Dockerfile文件
      3. 3.4.3. 配置在docker中使用的nginx配置文件。
    5. 3.5. 使用daocloud进行持续构建镜像以及发布
    6. 3.6. 发布完成之后需要做的工作
  4. 4. 持续集成依赖外部服务的应用
    1. 4.1. 本文适用的场景
    2. 4.2. 依赖外部服务的应用
    3. 4.3. 构建前的准备
      1. 4.3.1. 项目结构
      2. 4.3.2. Dockerfile文件编写
      3. 4.3.3. Makefile文件编写
      4. 4.3.4. 静态文件支持
      5. 4.3.5. 通过环境变量来连接服务
    4. 4.4. 使用daocloud部署构建好的taikang项目