2023年最新的,使用docker搭建gitlab和gitlab-runner完成自动化部署学习

3,812 阅读3分钟

看了很多文章,发现很多文章都过时了,或者讲得不是很清楚,或者有点问题。于是决定重新弄一个教程。

环境:windows11,docker-desktop

使用docker-compose部署gitlab和runner

这里使用docker-compose部署gitlab和runner来部署,这样就一键搞定。拉取的是gitlab/gitlab-ce和gitlab/gitlab-runner官方镜像,并且设置docker network,两个容器才能通信。

在下面的GITLAB_ROOT_PASSWORD中设置root账号密码,要求大小写和数字,等一下登录gitlab的时候,就是用这个密码。

version: '3.6'
name: gitlab
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    container_name: gitlab
    restart: always
    hostname: '127.0.0.1'
    privileged: true
    environment:
      TZ: 'Asia/Shanghai'
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://127.0.0.1:30080' # web站点访问地址
        registry_external_url 'http://127.0.0.1:30080'
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
      GITLAB_ROOT_PASSWORD: 'XXXX' # 这里设置密码,要大小写和数字
    ports:
      - '30080:30080' # 注意宿主机和容器内部的端口要一致,否则external_url无法访问
      - '443:443'
      - '22:22'
    volumes:
      - './gitlab/config:/etc/gitlab'
      - './gitlab/logs:/var/log/gitlab'
      - './gitlab/data:/var/opt/gitlab'
    shm_size: '256m'
      

  gitlab-runner:
    image: 'gitlab/gitlab-runner:latest'
    container_name: gitlab-runner
    privileged: true
    restart: always
    volumes:
      # 这两步骤是为了让容器内的gitlab-runner可以访问到docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /bin/docker:/bin/dcoker
      # 将当前目录的config文件,映射到容器的/etc/gitlab-runner目录
      - ./gitlab-runner:/etc/gitlab-runner
    environment:
      # 也是指定docker
      RUNNER_EXECUTOR: "docker"
    depends_on:
      - gitlab

networks:
  gitlab:
    external: true

执行docker-compose up -d,容器跑起来后,由于gitlab还在后台安装,等待大概5分钟后,就可以访问http://localhost:30080/

本地的数据卷也挂载好了,不过此时的gitlab-runner是空的,只有创建了runner,才有config.toml配置文件,后面会用到。

image.png

image.png

账号是root,密码是docker-compose中设置的密码。

创建一个新的项目,名叫vue

image.png

在左边的setting中找到CI/CD->runners注册runner

在cmd中输入docker exec -it gitlab-runner gitlab-runner register,依次输入:

Enter the GitLab instance URL (for example, gitlab.com/):
http://gitlab:30080\color{red}{http://gitlab:30080} # 这里由于是容器通信,所以填的是容器名来代替ip地址
Enter the registration token:
3bFeD8Nsvmtxd6txzghv\color{red}{3bFeD8Nsvmtxd6txzghv} # 这里填的就是上面的runner的token
Enter a description for the runner:
runner\color{red}{runner}
Enter tags for the runner (comma-separated):
runner\color{red}{runner}
Enter an executor: docker-ssh, parallels, ssh, docker-ssh+machine, kubernetes, custom, docker, shell, virtualbox, docker+machine:
docker\color{red}{docker}
Enter the default Docker image (for example, ruby:2.6):
node:alpine\color{red}{node:alpine}

image.png 然后runner就创建成功了,刷新一下页面就可以看到多了一个runner

image.png

挂载的文件也多了一个config.toml文件

image.png

git clone拉取项目地址,出现弹窗,输入刚才的root和密码

image.png 使用npm create vite创建一个vue项目,并且把内容都移动到拉取的项目中

image.png 新增一个.gitlab-ci.yml文件

image: node:alpine

cache:
    key: ci-cache
    paths:
        - node_modules/

stages:
    - init
    - build
    - deploy

init:
    stage: init
    script:
        - npm install
    cache:
        key: ci-cache
        paths:
            - node_modules/

build:
    stage: build
    script:
        - npm run build
    cache:
        key: ci-cache
        paths:
            - node_modules/
            - dist

deploy:
    stage: deploy
    image:
        name: docker:stable
    services:
        - name: docker:dind
          alias: dockerhost
    cache:
        key: ci-cache
        paths:
            - node_modules/
            - dist

    script:
        - whoami
        - docker ps
        - docker build -t web-image .
        - if [ $(docker ps -aq --filter name=web-container) ]; then docker rm -f web-container;fi
        - docker run -d -p 9000:80 --name web-container web-image

    only:
        - main

然后提交代码,并推送到仓库中

image.png 查看流水线,发现在pending。回到runner,修改runner配置

image.png

image.png 勾选上后保存。回到流水线,就已经在runner了

image.png 2分钟后失败了

image.png 点进去查看原因:

image.png 问题一:地址错误 出现这个问题,就卡住了。 image.png 查了很多资料,才找到了一个解决办法。原来是当gitlab和gitlab-runner都是用docker的容器跑的时候,那么拉取的地址就要用本机的ip地址。 这里是查到的资料:forum.gitlab.com/t/gitlab-ru…

输入cmd,ipconfig查看本机的ip地址

image.png 前面有好几个地址都是虚拟出来的,由于我是用wifi,所以ip地址是这个192.168.31.210。然后到刚才挂载的gitlab-runner里面修改地址

image.png

在当前的runner中添加clone_url = "http://192.168.31.210:30080" ,就可以拉取仓库代码了。由于每次构建docker,都是从网上拉取,为了提高构建速度,使用本地的镜像,加上pull_policy = "if-not-present"。 image.png

问题二:无法连接Docker daemon

跑起来又显示Cannot connect to the Docker daemon at tcp://docker:2376. Is the docker daemon running?

image.png 查了很久,原来是要到刚才的gitlab-runner/config.toml中添加一行配置"/usr/bin/docker:/usr/bin/docker", "/var/run/docker.sock:/var/run/docker.sock"

image.png 完整配置如下:

[[runners]]
  name = "runner"
  url = "http://gitlab:30080"
  token = "k-b5JQFhK-ZPYQYP6zEs"
  executor = "docker"
  clone_url = "http://192.168.31.210:30080"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/certs/client", "/cache","/usr/bin/docker:/usr/bin/docker", "/var/run/docker.sock:/var/run/docker.sock"]
    pull_policy = "if-not-present"
    shm_size = 0

修改配置后,重新跑流水线,就可以了。 image.png

image.png

docker for desktop也有相对应的容器

image.png 点击访问,也是正常访问

image.png

该CI/CD的适用场景

注意,该CI/CD的适用场景,只适合gitlab和部署的服务器在同一个服务器,如果是不同的内外网服务器,则需要修改方案。

多项目编排

推送项目不仅能触发自己的gitlab-runner,还能触发其他项目的runner,进行多项目编排。例如git提交前端代码,触发自身runner部署的同时,还触发后端项目的runner部署。git提交后端代码,触发自身runner部署的同时,触发前端项目的runner部署。

能够有效的保证部署的前后端项目的版本都是最新的。

以及触发多前端项目部署,比如一个前端项目iframe嵌套了另一个前端项目的页面,能够有效的保证两个项目的同步。(博主自己就经历过,用iframe内嵌了另一个项目,部署的时候老是忘了部署另一个,而出现了一些线上错误)

方法也很简单,给另一个项目也配置一个runner,然后在原来的gitlab-ci.yml文件上,添加一个trigger任务就行了,比如:

job:deploy-java:
    stage: java
    trigger:
        project: root/java
        branch: main
        strategy: depend

结合之前的,完整内容就是:

default:
    tags:
        - vue

image: node:alpine

cache:
    key: ci-cache
    paths:
        - node_modules/

stages:
    - java
    - init
    - build
    - deploy

job:deploy-java:
    stage: java
    trigger:
        project: root/java
        branch: main
        strategy: depend

job:init:
    stage: init
    script:
        - npm install
    cache:
        key: ci-cache
        paths:
            - node_modules/

job:build:
    stage: build
    script:
        - npm run build
    cache:
        key: ci-cache
        paths:
            - node_modules/
            - dist

job:deploy:
    stage: deploy
    image:
        name: docker:latest
    cache:
        key: ci-cache
        paths:
            - node_modules/
            - dist

    script:
        - whoami
        - docker ps
        - docker build -t web-image .
        - if [ $(docker ps -aq --filter name=web-container) ]; then docker rm -f web-container;fi
        - docker run -d -p 9000:80 --name web-container --restart=always web-image

    only:
        - main

提交代码的时候,就能看到: image.png