热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Docker实战,配合使用TravisCI进行持续集成

什么是CI持续集成服务(ContinuousIntegration),简称CI。一般来说是负责拉取代码库中的代码,

什么是CI

持续集成服务(Continuous Integration),简称CI。一般来说是 负责拉取代码库中的代码,然后执行我们预置定义好的一些操作脚本,然后通过一系列的编译操作构建的过程。常用工具有Gitlab CIGithub CIJenkinsTravis CI等。可能大家经常看见的就是Jenkins
因为后续打算会推出一个从0到1,用docker + Jenkins + Kubernetes搭建一个CI/CD流程的文章。 本文先通过Travis CI,进行持续集成,进行一个热身。原因就是Travis CI开源 且 操作简单。

一、Docker

Docker是一个开源的应用容器引擎。开发者可以将自己的应用打包在自己的镜像里面,然后迁移到其他平台的Docker中。镜像中可以存放你自己自定义的运行环境,文件,代码,设置等等内容,再也不用担心环境造成的运行问题。镜像共享运行机器的系统内核。
同样,Docker也支持跨平台。你的镜像也可以加载在WindowsLinux,实现快速运行和部署。

Docker 的优势在于 快速,轻量,灵活。开发者可以制作一个自己自定义的镜像,也可以使用官方或者其他开发者的镜像来启动一个服务。通过将镜像创建为容器,容器之间相互隔离资源和进程不冲突。但硬件资源又是共享的。 创建的镜像也可以通过文件快速分享,也可以上传到镜像库进行存取和管理。

安装 Docker

docker安装

安装完Docker后,你可能会发现自己可以打开一个Docker的应用窗口。其实这个窗口没什么用处,通常我们都是通过CLI命令行的方式操作Docker的,就像Git一样。

运行 Docker

接下来我们搭建一个能够托管静态文件的 Nginx 服务器

具体步骤如下:

  1. 创建项目目录
  2. 创建 Dockerfile 文件,用其打包一个镜像 (类似前端的package.json文件)
  3. 镜像创建容器
  4. 容器运行程序

创建目录

我们创建一个 hello-docker 的目录,在该目录的根目录下 创建一个 index.html 文件:

Hello docker

然后再在目录中创建一个Dockerfile文件:

FROM nginx

COPY ./index.html /usr/share/nginx/html/index.html

EXPOSE 80

目录结构如下

hello-docker
  |____index.html
  |____Dockerfile

打包镜像

cd hello-docker/ # 进入刚刚的目录
docker image build ./ -t hello-docker:1.0.0 # 打包镜像

注意!Docker 中的选项(Options)放的位置非常有讲究,
docker —help imagedocker image —help是完全不同的命令

docker image build ./ -t hello-docker:1.0.0的意思是:基于路径./(当前路径)打包一个镜像,镜像的名字是hello-docker,版本号是1.0.0。该命令会自动寻找Dockerfile来打包出一个镜像。

运行容器

上面已经创建了镜像,接下来用这个镜像创建容器:

docker container create -p 2333:80 hello-docker:1.0.0
docker container start xxx # xxx 为上一条命令运行得到的结果

然后在浏览器打开127.0.0.1:2333,你应该能看到刚刚自己写的index.html

Docker实战,配合使用Travis CI进行持续集成
启动效果.png

在上边命令中
1.使用docker container create来创建基于hello-docker:1.0.0镜像的一个容器,使用-p来指定端口绑定——将容器中的80端口绑定在宿主机的2333端口。执行完该命令,会返回一个容器ID
2.使用docker container start启动这个容器,启动后,就能通过访问本机的2333端口来达到访问容器内80端口的效果了。(也可以在docker的界面操作 直接点击按钮启动容器)

当容器运行后,可以通过如下命令进入容器内部:

docker container exec -it xxx /bin/bash # xxx 为容器ID

原理实际上是启动了容器内的/bin/bash,此时你就可以通过bash shell与容器内交互了。就像远程连接了SSH一样。

总结

  1. 写一个Dockerfile
  2. 使用docker image build来将Dockerfile打包成镜像
  3. 使用docker container create来根据镜像创建一个容器
  4. 使用docker container start来启动一个创建好的容器
Docker实战,配合使用Travis CI进行持续集成
步骤图.png

二、Travis CI

接下来我们实战部署一个 Vuejs 写的纯静态 SPA 单页站点:
在 Github,可以有免费的 CI 资源用,它就是 Travis CI,它可以帮助我们,在我们每次更新代码时打包出一个镜像。

首先新建一个vue项目vue create dockertest(示例用,你们可以直接使用自己开发的小项目测试效果)react同理。

然后在项目的根目录上 添加文件.travis.yml 内容为:

language: node_js
node_js:
  - "12"
services:
  - docker

before_install:
  - npm install

script:
  - npm run build
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
  - docker build -t chenjing0823/dockertest:latest .
  - docker push chenjing0823/dockertest:latest

文件内容非常简单,就是使用npm run build编译静态产出后,打包一个镜像并且push到远程。
下面两点详细说明一下:

  • 为了能够让镜像上传到服务器,你需要在hub.docker.com中注册一个账号,然后替换代码中的chenjing0823/dockertest:latest,其意义对应的是 用户名/包名:latest
  • 使用Github登录Travis CI后,在左边点击+加号添加自己的Github仓库后,需要移步到Setting为项目添加DOCKER_USERNAMEDOCKER_PASSWORD环境变量。具体对应到上面.travis.yml 文件内脚本登录部分。 具体如下图
Docker实战,配合使用Travis CI进行持续集成
Travis CI 配置.png

我们上面提到docker打包镜像这时候就派上用场了。
同样需要在根目录上 添加Dockerfile文件来描述如何打包docker镜像,内容为:

FROM nginx

COPY ./dist/ /usr/share/nginx/html/

EXPOSE 80
  • tips: 按照.travis.yml的命令次序,在打包镜像时,npm run build已经执行过了,项目产出已经有了。不必在Docker容器中运行npm installnpm run build之类的,所以直接复制文件即可。.travis.yml内的命令次序可以参考Travis CI Tutorial

本例中的静态站点是一个SPA单页应用,需要增加额外的Nginx配置来保证请求都能打到index.html。下边是编写的vhost.nginx.conf Nginx配置文件,将不访问文件的请求全部重定向到/index.html

server {
    listen 80;
    server_name localhost;
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        proxy_set_header Host $host;

        if (!-f $request_filename) {
          rewrite ^.*$ /index.html break;
        }

    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

更新Dockerfile:

  FROM nginx

  COPY ./dist/ /usr/share/nginx/html/
+ COPY ./vhost.nginx.conf /etc/nginx/conf.d/dockertest.conf

  EXPOSE 80

最后执行git push后,可以在Travis CI看到CI的编译结果。如果编译没问题,远程实际上就有了chenjing0823/dockertest:latest这个镜像。可以在https://hub.docker.com/上看到镜像。

Docker实战,配合使用Travis CI进行持续集成
image.png

Travis CI自动编译打包的编译结果:

Docker实战,配合使用Travis CI进行持续集成
编译打包.png

同时也可以在本地试试看该镜像工作是否正常:

docker image pull chenjing0823/dockertest:latest
docker container create -p 8082:80 chenjing0823/dockertest:latest:latest
docker container start xxx # xxx 为上一条命令执行的返回值

可以通过http://localhost:8082/看到我们的dockertest成功运行

Docker实战,配合使用Travis CI进行持续集成
效果

最后的最后,就可以登录远程VPS服务器,安装Docker,执行同样的命令。然后访问远程 VPS服务器的公网IP + 8082端口号,应该就可以看到和本地相同的效果了。

Tips: 在VPS上安装docker,你可能需要参考安装教程的Linux的安装方式.

三、Nginx 反向代理

目前已经将容器挂到了8082端口,但是线上的环境上是不可能说让用户手动输入8082端口访问。但是如果一股脑的直接将容器挂到80端口上,虽然这样操作后用户可以直接不加端口直接访问,但是以后出现第二个,第三个,第n个容器呢?
这时候就需要在宿主机跑一个Nginx,由它来独占80端口,然后根据域名来讲请求分发给响应的容器。如下图:

Docker实战,配合使用Travis CI进行持续集成
nginx

这就是传说中的“反向代理”。

登录VPS服务器,安装Nginx
此时本地通过浏览器访问VPS的公网IP 可用看到Nginx的欢迎页面

Docker实战,配合使用Travis CI进行持续集成
Nginx 页.png

然后在VPS服务器的/etc/nginx/conf.d/中建立一个vhost.conf文件,配置如下:

server {
    listen 80;
    server_name chenjing0823.info;

    location / {
        proxy_pass http://127.0.0.1:8082;
    }
}

一个简单的配置,监听80端口,若访问域名是chenjing0823.info(替换为你自己的域名),则全部转发到http://127.0.0.1:8082中。配置完成后,重启 Nginx 服务器。

配置成功后,访问chenjing0823.info会看到和VPS公网IP:8082相同的效果.

整个发布流程为:

  • 本地修改代码,执行git push
  • 等待 CI 编译完成
  • 登录VPS服务器,执行:
docker image pull chenjing0823/dockertest:latest
docker container create -p 8082:80 chenjing0823/dockertest:latest:latest # 得到 yyy
docker container stop xxx # xxx 为当前运行的容器ID,可用 docker container ls 查看
docker container start yyy # yyy 第二条命令返回值

推荐阅读
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Linux磁盘的分区、格式化的观察和操作步骤
    本文介绍了如何观察Linux磁盘的分区状态,使用lsblk命令列出系统上的所有磁盘列表,并解释了列表中各个字段的含义。同时,还介绍了使用parted命令列出磁盘的分区表类型和分区信息的方法。在进行磁盘分区操作时,根据分区表类型选择使用fdisk或gdisk命令,并提供了具体的分区步骤。通过本文,读者可以了解到Linux磁盘分区和格式化的基本知识和操作步骤。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
author-avatar
手机用户2502935311
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有