原创

Jenkins + Docker实践

戎码一生
4 条评论
2 人喜欢
784 次阅读
全文共 1600 预计阅读时长 7 分钟

未完待续中…

Docker和jenkins已经不是什么新东西了,两者结合起来使用也已经有很多文章给出实践了,此文只是最近升级博客的过程中,对于CI这块也是有了一些实践,对于DevOps,CI/CD等概念不做过多解释,可以参考下知乎回答 如何理解持续集成、持续交付、持续部署?

目前采用的是Docker + jenkins,辅以阿里云镜像容器,体验还算不错

为什么选择Docker?

可以看下知乎下的回答 Docker 有什么优势?

总结起来差不多就是

  • 持续交付标准化
  • 一次构建,多次交付
  • 应用隔离

而我个人其实更看重的其实是1. 快速构建部署,即轻量级 2. 是实践DevOps过程中的一个目前来说较为标准的环节,即标准化

结构图

TODO…

实践

主要给出关键步骤的实践方法和结果,对于一些基础设施的安装将给出传送门,不再赘述

前提准备

  1. Docker

基本操作,不做过多讲述,参考 CentOS Docker 安装

在mac os上是有个单独的docker application可以安装的,可以去官网看看

  1. Jenkins

jenkins的运行依赖于JDK,所以需要先装上JDK,参考 在linux服务器上安装jdk

jenkins的安装页可以参考 在linux服务器上安装Jenkins

Docker配置文件

Egg应用

node-server 是为站点提供接口的服务,是一个Egg程序

在实践的时候,因为server需要依赖于mongodbredis,所以我一直在想要不要把这两者和程序一起打包,放到一个Docker容器中去,当然经过实践,确实是可行的,容器允许你去运行多个进程,但是会有以下几个问题:

  1. 构建时间长,而且如果代码变更重新构建的话,其他的也会重新构建
  2. 镜像较大
  3. 扩展性差(容器共用)

所以我这里用了 Docker Compose 来做容器分割,运行多个容器

.dockerignore

此文件的作用有点类似.gitignore,作用就是在docker build的时候忽略掉某些文件,从而可以提升构建速度

node_modules/
.git/

主要是把node_modules.git这俩忽略掉,因为node_modules构建的时候会自动生成,.git着实没啥用

Dockerfile

FROM node:8.12.0-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package.json /usr/src/app/package.json

RUN yarn config set registry 'https://registry.npm.taobao.org'

RUN yarn install

COPY . /usr/src/app

EXPOSE 7001

CMD npm run docker

可以参考的这个issue: eggjs + docker 最佳实践

这里要注意的是最后的CMD执行的是npm run docker

"start": "egg-scripts start --daemon --title=node-server"
"docker": "egg-scripts start --title=node-server"

也就是说让程序保持前台运行,这里官方文档有说

至于为啥需要前台运行?
是因为Docker容器会把容器内的第一个金城,即pid=1的进程当做容器是否在运行的标志,如果pid=1的进程退出了或者挂了,那么Docker容器就会退出。如果以daemon方式运行,那么运行后程序会转至后台运行,此时pid=1的进程就是bash/shell,而bash/shell执行完程序启动后会退出,所以容器也就退出了,参考 这篇文章

docker-compose.yml

# TODO

然后执行

docker-compose up -d

然后docker会按depends的依赖顺序启动容器

-d:Detached mode 表示后台运行容器

其他命令

# 停止容器
docker-compose down

# 停止容器,并且移除数据卷缓存
docker-compose down -v

关于volume可以参考 什么是Docker Volume?

如果是开发模式下想利用Docker Compose启动mongoredis的话,那还需要创建一个docker-compose.dev.yml

# TODO

然后自定义compose file来启动容器

# 启动容器
docker-compose -f docker-compose.dev.yml up

# 停止容器
docker-compose -f docker-compose.dev.yml down

# 停止容器,并且移除数据卷缓存
docker-compose -f docker-compose.dev.yml down -v

-f:Specify an alternate compose file,自定义启动文件,默认是docker-compose.yml

Vue应用

vue-admin 是站点的CMS

这是一个用vue-cli 3创建的项目,官网的 cookbook 也提供了一个docker部署的配置思路,但是我需要自定义一些nginx配置,所以需要在官网的配置的基础上做一些变动

# build stage
FROM node:8.12.0-alpine as build-stage

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package.json /usr/src/app/package.json

RUN yarn config set registry 'https://registry.npm.taobao.org'

RUN yarn install

COPY . /usr/src/app

RUN npm run build

# production stage
FROM nginx:1.13.12-alpine as production-stage

COPY --from=build-stage /usr/src/app/dist /usr/share/nginx/html

COPY --from=build-stage /usr/src/app/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

在倒数第三步是将容器内WORKDIR的nginx.conf拷贝并覆盖了容器内的默认nginx配置文件,所以需要在项目的根目录下(或者其他目录,需要修改copy的路径)存放一个我们自定义的nginx配置

这个Dockfile里用了 Multi-State Build ,目的就是把一个大任务拆分成各个流水线任务,从而使Dockerfile更加易于阅读和维护

而且还有一个要注意的点就是nginx启动是需要关掉daemon的,这个原因上面已经讲到过了

Nuxt应用

jooger.me 是主站点,采用Nuxt开发

Nuxt应用其实和Nodejs应用一样,都是属于服务端程序,所以和node-server的Dockerfile配置大体一样,只不过在最后的CMD之前多了一步npm run build而已,Dockefile如下

FROM node:8.12.0-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package.json /usr/src/app/package.json

RUN yarn config set registry 'https://registry.npm.taobao.org'

RUN yarn install

COPY . /usr/src/app

EXPOSE 7000

RUN yarn build

CMD yarn start

流程完善

未完待续

阿里云镜像容器

创建jenkins job

构建脚本

构建结果通知

遇到的问题

参考文章

Docker相关

Jenkins相关

相关文章
4 条评论
Mac OS X Chrome | 72

你服务器什么配置?我服务器上 docker 就挂了。。。

3条回复

时间不在于你拥有多少,而在于你怎样使用。

—— leo12 《英雄联盟》