docker&gitlab-ci实现一机多用和前端自动化

image

咱们开发的流程通常是新建一个开发分支,而后开发,开发完打包部署到测试环境让测试测。可是这里有个痛点,尤为在大的团队中,咱们通常会不少人共用一台测试机,这样就致使了一个问题,一旦有人在使用这个机器,那么其余人就没法使用该机器,由于切了分支就致使另一我的的代码被切掉了,这样就致使测试机器不够用。而docker的出现,能够很好的解决这个问题。css

备注:看本文须要对docker和gitlab-ci有所理解。关于这方面的知识不懂的,须要去学习下。html

思路

咱们在每一个分支上开发准备提测的时候,就生成一个该分支特有docker镜像,该镜像基于nginx的,它会完成代码的打包和部署(到nginx上),以此来实现不一样的分支代码在不一样的docker容器上运行的目的,从而实现一个机器能够运行多个分支的代码的目的。node

第一步: 编写Dockerfile

由于咱们须要用到nginx,因此咱们的镜像是基于nginx的,若是咱们还要作到打包的操做,还须要用到node,假设咱们的项目是在/home/test.liweiji.com下(固然这里是一个git仓库,咱们须要先切换咱们的分支并拉取咱们本身的代码):nginx

Dockerfile:git

# 基于node镜像
FROM node

# 设置工做路径 相似cd /home/test.liweiji.com
WORKDIR /home/test.liweiji.com

# 打包到/home/test.liweiji.com/dist目录下,固然是否是dist看本身项目
RUN npm install \
    && npm run build

# 基于nginx镜像
FROM nginx

# 通常nginx的默认配置咱们没法直接使用,因此须要用到本身的nginx配置
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
复制代码

nginx.confdocker

# 这里根据你运行docker的用户来定,设置不对,会出现403
user root;

events {
    use epoll;
    worker_connections 102400;
}

http {
    # 这个不能少,否则会致使静态样式没法起效
    include mime.types;
    # 下面的配置根据本身的项目而定
    server {
        listen 80;
        server_name test.liweiji.com;

        location / {
            add_header Access-Control-Allow-Origin *;
            root /home/test.liweiji.com/dist;
            break;
        }
    }
}
复制代码

第二步:生成镜像并运行容器

咱们登陆到测试机,而后进入到/home/test.liweiji.com下shell

# 生成镜像,不一样的分支用不一样的tag
docker build -t <image_name>:<tag> .
# 运行容器,端口映射你们灵活配置,这里的例子是8080,不一样的分支能够用不一样的端口
docker run --name <container_name> -p 8080:80 -idt <image_name>:<tag>
复制代码

这样咱们就实现了不一样的分支代码打包到不一样的docker镜像中了。咱们可使用docker ps查看是否是在运行咱们的docker容器了。npm

备注:若是没有运行,则说明出错了,可是docker run指令并不会告诉咱们具体出错的缘由,咱们能够须要经过docker logs <container_name>来查看出错信息bash

经过上面两步,咱们就能够实现了打包不一样的分支代码到不一样的docker镜像,让测试经过不一样的镜像,测不一样的分支代码。app

可是这个方案还不够完善,还须要开发者跑到测试机去切分支拉代码,打包镜像运行容器。那么有什么方法让这些操做自动完成呢,答案是确定的,那就是gitlab-ci了。

利用gitlab-ci实现自动化

gitlab-ci可让咱们提交代码后,触发gitlab-runner去运行一系列的操做,好比安装、打包、部署等。


   image 

因此,咱们能够经过gitlab-ci来实现:当咱们提交咱们代码到远端的时候,生成该分支的最新代码对应的镜像,并运行该镜像对应的容器,从而实现自动化。

第一步:注册gitlab-runner

gitlab-ci真正的任务执行是由runner负责的,因此咱们须要在特定的机器注册runner,咱们经过gitlab-ci-multi-runner来注册runner。至于如何安装gitlab-ci-multi-runner,这里就不在讲,你们去google下。
运行gitlab-ci-multi-runner register来注册runner,咱们按照步骤一步一步输入url、token、description、tag、executor等,咱们根据咱们gitlab网站上的setting->pipeline上找到url和token。 image这里的咱们只执行shell命令,因此executor选择shell。

第二步:编写.gitlab-ci.yml

咱们须要在.gitlab-ci.yml中定义咱们要作的一系列操做,咱们这里须要上面所说的二个步骤:生成最新镜像和运行容器。可是为了保证每次打包都是最新代码,咱们须要有个清理的任务,因此有三个步骤:

# gitlab-cli各类变量查看https://docs.gitlab.com/ee/ci/variables/
# 执行job的阶段 按顺序串行执行
stages:
  - clean
  - build
  - run

# 清理镜像
job1:
  stage: clean
  only:
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    - test
  script:
    - docker stop test:$CI_COMMIT_REF_NAME
    - docker rm test:$CI_COMMIT_REF_NAME
    - docker image rm test:$CI_COMMIT_REF_NAME
  allow_failure: true #这里要容许失败,否则第一次清理是没有镜像会报错,致使后面任务没法执行
# 自定义阶段build的job流程
job2: # 自定义名字
  stage: build # 指定这阶段操做的名称
  only: # 指定那些分支会进入该处理流程
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    # 指定哪些runner执行script里面的操做,由于咱们上面注册runner的时候输入了test,因此这里就是test,固然你想其余runner也执行,这里就添加其余runner的tag
    - test
  script:
    # docker build, $CI_COMMIT_REF_NAME是分支名,变量能够查看https://docs.gitlab.com/ee/ci/variables/
    - cd page/public-sale
    - echo `docker build -t test:$CI_COMMIT_REF_NAME . | awk -F "Successfully built " '{print $2}'`
job3:
  stage: run
  only:
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    - test
  script:
    # $CI_COMMIT_REF_NAME是分支名
    - docker run --name test:$CI_COMMIT_REF_NAME -p 8000:80 -idt test:$CI_COMMIT_REF_NAME
复制代码

咱们的runner有两种类型,Specific Runners和Shared Runners,咱们一提交代码,若是.gitlab-ci.yml的job中不指定tag的话,则会执行Shared Runners,指定的话就执行tag对应的Specific Runners。

若是任务成功,咱们就能够在咱们gitlab网站的pipelines下看到咱们任务的执行了。 image

注意:这里其实正确的任务应该是生成镜像后将镜像上传到镜像仓库,而后让测试去拉取对应分支的镜像运行容器的。我这里这样作是由于gitlab-runner和测试机在同个机器。

遇到问题

问题一:docker运行nginx报403

这个问题有两个缘由,一个是权限问题,一个是首页index.html不存在,咱们遇到的是第一个缘由。其实上面也讲过,是由于咱们用root权限运行docker,可是nginx.conf里面没有配置user为root,因此nginx.conf的开头须要这样配置:

user root;
复制代码

问题二:样式下载了可是未起效

这个缘由也是nginx配置致使的,由于咱们nginx本身从新配置了,因此有些配置没作好。这里nginx若是未配置mime.types的话,默认只有application/octet-stream,因此css资源能下载可是不能起效且有Resource interpreted as Stylesheet but transferred with MIME type text/plain的警告,解决办法就是在nginx.conf的http标签下添加include mime.types;

http {
    include mime.types;
    .....
}
复制代码

问题三:docker: command not found

这个缘由是由于.gitlab-ci.yml中的job没配置tags,致使share runner执行,而share runner中没有配置docker。

问题四:su: user gitlab-runner does not exist

这个缘由是咱们的runner指定了user为gitlab-runner可是咱们的机器并无建立这个用户,全部有两种方式解决:

  1. useradd gitlab-runner
  2. 杀掉gitlab-ci-multi-runner进程,并以其余用户运行,这里换成root运行
gitlab-ci-multi-runner run --working-directory /home/gitlab-runner --config /etc/gitlab-runner/config.toml --service root--syslog --user root
复制代码

总结

docker是一个独立的容器,相互之间隔离,咱们能够给各个docker镜像部署nginx和代码,从而利用docker实现不一样开发分支下不一样的代码运行,从而实现一机多分支代码运行。gitlab-ci能够实现自动化任务,好比安装、打包、部署等一系列任务,那么咱们就能够利用gitlab-ci来实现docker镜像生成和容器运行的自动化,从而避免用户手动操做。

相关文章
相关标签/搜索