Docker 部署 Gitlab 及 gitlab-runner 配置

1251人浏览 / 0人评论

参考

https://blog.csdn.net/weixin_53443677/article/details/125518696

https://blog.csdn.net/percylee514/article/details/130031975

安装

Linux

# 拉取镜像
docker pull gitlab/gitlab-ce

# 启动
docker run \
 -itd \
 -p 80:80 \
 -p 22:22 \
 -p 443:443 \
 -v /home/gitlab/etc:/etc/gitlab \
 -v /home/gitlab/log:/var/log/gitlab \
 -v /home/gitlab/opt:/var/opt/gitlab \
 -v /home/gitlab/certs:/root/certs \
 --restart always \
 --privileged=true \
 --name gitlab \
 gitlab/gitlab-ce

# 进入容器,查看初始密码(24小时内有效)
cat /etc/gitlab/initial_root_password

# 管理员登陆(账号:root,登录后注意修改密码)

Windows

# 创建挂载卷
docker volume create gitlab-logs
docker volume create gitlab-data

# 启动
docker run -itd -p 10000:80 -p 22001:22 -p 44300:443 -v D:\Docker\gitlab\etc:/etc/gitlab -v gitlab-logs:/var/log/gitlab -v gitlab-data:/var/opt/gitlab -v D:\Docker\gitlab\certs:/root/certs --restart always --privileged=true --name gitlab gitlab/gitlab-ce

# ci执行上传工件报错:WARNING: Uploading artifacts as "archive" to coordinator... failed id=1515 responseStatus=500 Internal Server Error status=500
## Windows下挂载卷问题,参考:https://stackoverflow.com/questions/66740594/warning-uploading-artifacts-as-archive-to-coordinator-failed-id-1515-respo
## 直接使用: -v 本地绝对路径:容器内路径 这种方式运行gitlab容器时会出现这种错误
## 解决方式是:创建挂载卷 → 启动临时容器 → 复制数据到挂载卷 → 删除临时容器 → 启动
## 因权限问题导致启动失败,执行:
docker exec -it gitlab update-permissions
docker restart gitlab
## 报错:Permissions 0755 for ‘/etc/gitlab/ssh_host_ed25519_key‘ are too open,查看下面的:升级 → 步骤

配置

配置项目地址

# 进入容器
docker exec -it gitlab /bin/bash

vi /etc/gitlab/gitlab.rb
# 加入如下
# gitlab访问地址,可以写域名。端口同外部端口,如果不写的话默认为80端口
external_url 'http://192.168.1.10' 
# ssh主机ip
gitlab_rails['gitlab_ssh_host'] = '192.168.1.10'
# ssh连接端口
gitlab_rails['gitlab_shell_ssh_port'] = 22 # 同外部端口

vi /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
#修改为如下
gitlab:
    host: 192.168.1.10
    port: 80 # 同外部端口
    https: false
 
 # 重载配置
 gitlab-ctl reconfigure

配置https

external_url 'https://gitlab.you_domain.com'

#配置http自动跳转到https协议的地址;
nginx['redirect_http_to_https'] = true

#80端口是容器内的端口,如果不配置http://宿主IP:80/将不可访问;
nginx['redirect_http_to_https_port'] = 80

nginx['ssl_certificate'] = "/root/certs/gitlab.you_domain.com.pem"
nginx['ssl_certificate_key'] = "/root/certs/gitlab.you_domain.com.key"

#配置监听容器内的443端口,注意不是外面主机的443端口
nginx['listen_port'] = 443

nginx['proxy_set_headers'] = {
   "Host" => "$http_host_with_default",
   "X-Real-IP" => "$remote_addr",
   "X-Forwarded-For" => "$proxy_add_x_forwarded_for",
   "X-Forwarded-Proto" => "https",
   "X-Forwarded-Ssl" => "on",
   "Upgrade" => "$http_upgrade",
   "Connection" => "$connection_upgrade"
}

 # 重载配置
 gitlab-ctl reconfigure

设置中文面板

配置邮件发送服务

参考:https://blog.csdn.net/qq_31417067/article/details/128517070

vi /etc/gitlab/gitlab.rb
##加入如下内容

# 启用 smtp 服务
gitlab_rails['smtp_enable'] = true

# 配置 smtp 服务地址,这里需要填写邮件服务里面的“SMTP服务器地址”(如下是网易163邮箱的smtp服务器地址)
gitlab_rails['smtp_address'] = "smtp.163.com"

# 配置 smtp 服务的端口号(默认)
gitlab_rails['smtp_port'] = 465

# 配置发送邮件的电子邮箱名称(即刚才注册的邮箱名称)
gitlab_rails['smtp_user_name'] = "xxx@163.com"

# 配置发送邮件的电子邮箱授权密码,刚才在邮箱里面开启 SMTP 服务的时候弹框提示的那一串【授权密码】(切记:这里不是邮箱的登录密码,是SMTP的授权密码)
gitlab_rails['smtp_password'] = "xxAxxSxxDx"

# 配置 SMTP 服务的域名,和上面的smtp服务器地址一致(如下是网易163邮箱的smtp域名)
gitlab_rails['smtp_domain'] = "smtp.163.com"

# 配置 SMTP 鉴定类别(默认 login 即可)
gitlab_rails['smtp_authentication'] = "login"

# 开启纯文本通信协议扩展
gitlab_rails['smtp_enable_starttls_auto'] = false

# 开启 smtp_tls (传输安全)
gitlab_rails['smtp_tls'] = true

# gitlab 服务邮件发送来源邮箱(即发出邮件的发送方邮箱),填写刚才注册的邮箱即可
gitlab_rails['gitlab_email_from'] = 'git_xxx@163.com'

# 重新加载配置信息
gitlab-ctl reconfigure

# 重新启动服务
gitlab-ctl restart

测试

# 进入控制台
gitlab-rails console

# 执行发送邮件脚本
Notify.test_email('xxx@163.com', 'gitlab邮件测试', '啦啦啦啦啦').deliver_now

# 如果测试报错:
certificate verify failed (self signed certificate) (OpenSSL::SSL::SSLError)
# 在 /etc/gitlab/gitlab.rb 中添加:
gitlab_rails['smtp_openssl_verify_mode'] = 'none'

结果

配置邮件回复服务

配置

官方文档:https://gitlab.jbritian.com/help/administration/incoming_email.md

前提:需要有一个普通的邮箱账号,如:incoming@gitlab.jbritian.com123@qq.com

vi /etc/gitlab/gitlab.rb

# 添加如下内容:
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "incoming+%{key}@gitlab.jbritian.com"
gitlab_rails['incoming_email_email'] = "incoming"
gitlab_rails['incoming_email_password'] = "密码"
gitlab_rails['incoming_email_host'] = "gitlab.jbritian.com"
gitlab_rails['incoming_email_port'] = 143
gitlab_rails['incoming_email_ssl'] = false
gitlab_rails['incoming_email_start_tls'] = false
# iredmail 默认收件箱名称是 INBOX
gitlab_rails['incoming_email_mailbox_name'] = "INBOX"
#gitlab_rails['incoming_email_mailbox_name'] = "inbox"
gitlab_rails['incoming_email_idle_timeout'] = 60
gitlab_rails['incoming_email_delete_after_delivery'] = true
gitlab_rails['incoming_email_expunge_deleted'] = true

# 重启
gitlab-ctl reconfigure
gitlab-ctl restart

# 测试
gitlab-rake gitlab:incoming_email:check

效果

配置gitlab pages

参考:https://docs.gitlab.cn/jh/administration/pages/index.html#gitlab-pages-%E7%AE%A1%E7%90%86

添加DNS解析

pages.jbritian.com
*.pages.jbritian.com

申请泛域名证书

文档:https://github.com/linuxserver/docker-swag#migrating-from-the-old-linuxserverletsencrypt-image

注意:可以使用 cert.pem,但是推荐使用 fullchain.pem

1、启动swag容器(如果使用了 frp 内网穿透,配置了 https2https,则需要将证书挂载到本地,让 frp 也能够访问到证书文件)

# 创建挂载卷
docker volume create swag-config

# docker 内部挂载
docker run -d --name=swag --cap-add=NET_ADMIN -e PUID=1000 -e PGID=1000 -e TZ=Asia/Shanghai -e URL=pages.jbritian.com -e VALIDATION=dns -e SUBDOMAINS=wildcard -e DNSPLUGIN=dnspod -e EMAIL=2771732182@qq.com -e STAGING=false -p 44305:443 -p 10005:80 -v swag-config:/config --restart unless-stopped linuxserver/swag:latest

# 本地挂载
docker run -d --name=swag --cap-add=NET_ADMIN -e PUID=1000 -e PGID=1000 -e TZ=Asia/Shanghai -e URL=pages.jbritian.com -e VALIDATION=dns -e SUBDOMAINS=wildcard -e DNSPLUGIN=dnspod -e EMAIL=2771732182@qq.com -e STAGING=false -p 44305:443 -p 10005:80 -v D:\Docker\swag\config:/config --restart unless-stopped linuxserver/swag:latest

## 该container会在证书到期前30天,自动renew
## 如果30天内,没有自动renew,进入容器内 ,手动 /app/le-renew.sh

2、创建腾讯云dnspod api token

地址:https://console.dnspod.cn/account/token/token

3、配置swag容器

# 在 /config/dns-conf 目录下找到 dnspod.ini 文件,修改内容如下:
dns_dnspod_email = "2771732182@qq.com"
dns_dnspod_api_token = "token id,token 值"

# 然后重启swag容器
# 此时 /config/etc/letsencrypt/archive/pages.jbritian.com 文件夹内应该有:cert1.pem、chain1.pem、fullchain1.pem、privkey1.pem 四个文件
# 如果要在其他容器中使用,并且使用的是:“docker volume create swag-config” 方式创建的数据卷,可以将 “swag-config” 卷挂载到需要的容器,然后直接使用 “/config/etc/letsencrypt/live/pages.jbritian.com” 中的 cert.pem、privkey.pem 文件即可

4、如果挂载到本地磁盘,如:D:\Docker\swag\config,则需要指定 cert 文件名并定时更新

  • 进入容器,创建更新脚本,授权
docker exec -it swag /bin/bash
touch update_cert.sh
chmod +x update_cert.sh
  • update_cert.sh 内容如下:
#!/bin/sh
cert_dir=/config/etc/letsencrypt/archive/pages.jbritian.com
for name in cert chain fullchain privkey
do
        source_file="$cert_dir/$name.pem"
        new_file=`find $cert_dir -type f -name "$name*.pem" | sort -r | head -1`
        if [ `find $cert_dir/$name.pem` ] ; then
                if ! diff -q $source_file $new_file ; then
                        \cp $new_file $source_file
                fi
        else
                \cp $new_file $source_file
        fi
done
  • 脚本测试
./update_cert.sh

# 执行成功后 /config/etc/letsencrypt/archive/pages.jbritian.com 文件夹内会多出:cert.pem、chain.pem、fullchain.pem、privkey.pem 四个文件
  • 添加到定时任务
vi /config/crontabs/root
## 添加内容如下图最后一行,即每天零点执行一次

# 验证
crontab -e

配置

# 删除旧的gitlab容器
docker rm -f gitlab 

# 挂载证书目录并启动
## 具名挂载
docker run -itd -p 10000:80 -p 22001:22 -p 44300:443 -v D:\Docker\gitlab\etc:/etc/gitlab -v gitlab-logs:/var/log/gitlab -v gitlab-data:/var/opt/gitlab -v D:\Docker\gitlab\certs:/root/certs -v swag-config:/root/swag --restart always --privileged=true --name gitlab gitlab/gitlab-ce
## 本地挂载
docker run -itd -p 10000:80 -p 22001:22 -p 44300:443 -v D:\Docker\gitlab\etc:/etc/gitlab -v gitlab-logs:/var/log/gitlab -v gitlab-data:/var/opt/gitlab -v D:\Docker\gitlab\certs:/root/certs -v D:\Docker\swag\config\etc\letsencrypt\archive\pages.jbritian.com:/root/swag --restart always --privileged=true --name gitlab gitlab/gitlab-ce

# 修改配置文件
vi /etc/gitlab/gitlab.rb
## 添加如下内容
gitlab_pages['enable'] = true
pages_external_url "https://pages.jbritian.com/"
pages_nginx['redirect_http_to_https'] = true
pages_nginx['ssl_certificate'] = "/root/swag/fullchain.pem"
pages_nginx['ssl_certificate_key'] = "/root/swag/privkey.pem"
gitlab_rails['pages_path'] = "/var/opt/gitlab/gitlab-rails/shared/pages"

# 重启
gitlab-ctl reconfigure
gitlab-ctl restart

测试

1、创建 page-test 仓库(可见性级别随意)。

2、新建 index.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>gitlab page 测试</title>
</head>
<body style="text-align: center;">
    <h1>成功啦!</h1>
</body>
</html>

3、新建 .gitlab-ci.yml 文件

pages:
  stage: deploy
  tags:
    - DESKTOP-A9ORD1T
  script:
    - cd ..
    - mkdir public
    - cp -r $CI_PROJECT_DIR/* public
    - mv public $CI_PROJECT_DIR/public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

说明:

设置的路径为 public,所以要将静态文件复制到根目录 public 文件夹下。

DESKTOP-A9ORD1T 是共享runner。

4、浏览器访问:https://root.pages.jbritian.com/page-test

升级

参考:https://zhuanlan.zhihu.com/p/531244799?utm_id=0

说明

比如要从 14.6.1 版本升级到目前最新版本 latest,根据官方给定的升级路线:https://docs.gitlab.com/ee/update/index.html#15111,要依次进行 7 次升级。

可以使用 GitLab 提供的升级路径工具:https://gitlab-com.gitlab.io/support/toolbox/upgrade-path/?target=16.4.2&distro=docker&auto=true&edition=ce&downtime=true

步骤

# 进入容器
docker exec -it gitlab /bin/bash

# 备份
gitlab-rake gitlab:backup:create
## 在gitlab.rb和gitlab-secrets.json文件中包含敏感数据,在备份中并没有包含这两个文件,需要手动保存一下,在恢复备份的时候会需要这两个文件(如果是在本机更新,则不备份这两个文件也没关系,如果是备份了在另一台机器安装gitlab并恢复数据,则需要在另一台机器覆盖这两个文件)。这两个文件放在/etc/gitlab目录下。

# 退出并删除容器
exit
docker rm -f gitlab

# 如果当初启动时用的是当时的 latest 版本,应删除该版本,然后重新拉取当前最新版本。

# 使用原先的部署命令重新启动容器,只需修改版本到下一个版本
docker run \
 -itd \
 -p 80:80 \
 -p 22:22 \
 -p 443:443 \
 -v /home/gitlab/etc:/etc/gitlab \
 -v /home/gitlab/log:/var/log/gitlab \
 -v /home/gitlab/opt:/var/opt/gitlab \
 -v /home/gitlab/certs:/root/certs \
 --restart always \
 --privileged=true \
 --name gitlab \
 gitlab/gitlab-ce:14.9.5-ce.0
 
# 查看启动情况
docker logs -f gitlab
 
# 出现如下信息则本次升级成功
Running handlers:
Running handlers complete
Chef Infra Client finished, 326/1407 resources updated in 05 minutes 40 seconds
gitlab Reconfigured!
Checking for unmigrated data on legacy storage

# 如果出现:Permissions 0755 for ‘/etc/gitlab/ssh_host_ed25519_key‘ are too open.
# 参考:https://blog.csdn.net/wzl19870309/article/details/114293452
docker exec -it gitlab /bin/bash
cd /etc/gitlab/
chmod 600 ssh_host_ed25519_key
chmod 600 ssh_host_rsa_key
chmod 600 ssh_host_ecdsa_key
gitlab-ctl restart

# 重复进行上述步骤

# 访问页面出现500错误,首先确定服务完全启动,然后尝试重启,实在不行参考:https://www.likecs.com/show-306388640.html

# 如果提交文件失败,出现:config value 'safe.directory' was not found.
# 参考:https://forum.gitlab.cn/t/topic/1262/5
docker exec -it gitlab /bin/bash
chown git.git -R /var/opt/gitlab/git-data/repositories

Gitlab Runner

官方文档:https://docs.gitlab.com/runner/install/

关键字参考:https://docs.gitlab.com/ee/ci/yaml/index.html

Windows

下载:https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-amd64.exe

下载完成将文件重命名为:gitlab-runner.exe

常用命令

# 所有命令都需要在PowerShell管理员窗口运行

# 注册到gitlab
./gitlab-runner.exe register --non-interactive --executor "shell" --url "http://192.168.1.10" --registration-token "hpEaqbanmCD4hnzv9wYt" --description "runner-test" --tag-list "build,deploy,test" --run-untagged="true" --locked="false"

# 注册到Windows服务
./gitlab-runner.exe install

# 启动
./gitlab-runner.exe start

# 停止
./gitlab-runner.exe stop

# 查看帮助
./gitlab-runner.exe -h

执行shell报错

ERROR: Job failed (system failure): prepare environment: failed to start process: exec: "pwsh": executable file not found in %PATH%. Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information

解决方案:https://stackoverflow.com/questions/68050125/gitlab-runner-prepare-environment-failed-to-start-process-pwsh-in-windows

方案一:

winget install Microsoft.PowerShell

方案二:

# 修改runner配置
[[runners]]
  name = "ci-runner"
  url = "http://xxx.yyy.xx/"
  token = "XXXXX"
  executor = "shell"
  shell = "powershell"
  
  # 重启runner
  ./gitlab-runner.exe restart

执行Windows本地其他程序或脚本权限不够

右击 gitlab-runner.exe → 属性 → 兼容性 → 更改所有用户的设置 → 勾选“以管理员身份运行此程序” → 应用 → 确定。

然后进入管理员命令窗口,重新启动 gitlab-runner 即可。

Linux

https://docs.gitlab.com/runner/install/linux-repository.html

安装

# 安装最新版
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
sudo yum install gitlab-runner -y

# 安装指定版本
yum list gitlab-runner --showduplicates | sort -r
sudo yum install gitlab-runner-15.11.0-1

# 使用 shell 执行器
gitlab-runner register \
	--non-interactive \
	--executor "shell" \
	--url "http://192.168.1.10" \
	--registration-token "hpEaqbanmCD4hnzv9wYt" \
	--description "runner-test" \
	--tag-list "build,deploy,test" \
	--run-untagged="true" \
	--locked="false"

权限不够

参考:https://blog.csdn.net/qq_39940674/article/details/127616784

# 方案一
sudo visudo
# 添加以下内容:
gitlab-runner ALL=(ALL) NOPASSWD: ALL
# 然后在 .gitlab-ci.yml 文件中使用 sudo

# 方案二
# 重新安装将用户更改为root
gitlab-runner uninstall
gitlab-runner install --user=root --working-directory=/home/gitlab-runner
sudo service gitlab-runner restart
##查看结果
ps aux|grep gitlab-runner

# 方案三
# 所有文件操作都在 /home/gitlab-runner 目录下执行

# 执行docker命令提示权限不足
sudo usermod -aG docker gitlab-runner

Docker

https://docs.gitlab.com/runner/install/docker.html

命令

mkdir -p /home/gitlab-runner/config

# 运行容器
docker run -itd --restart=always \
	--name gitlab-runner \
	--privileged=true \
	-v /home/gitlab-runner/config:/etc/gitlab-runner \
	-v /var/run/docker.sock:/var/run/docker.sock \
	gitlab/gitlab-runner:latest

# 修改配置
vim /home/gitlab-runner/config.toml
修改:volumes = ["/cache"]
结果:volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock", "/data/.m2:/root/.m2:rw"]
此行下面追加:pull_policy = "if-not-present"
docker restart gitlab-runner

# 进入容器
docker exec -it gitlab-runner /bin/bash

# 注册到gitlab
gitlab-runner register  --non-interactive \
	--executor "docker" \
	--docker-image docker \
	--docker-privileged \
	--url "http://192.168.1.10" \
	--registration-token "U5Wjpg-A2j24xxNbszTz" \
	--description "公司-个人" \
	--tag-list "build,deploy,test" \
	--run-untagged="true" \
	--locked="false"

gitlab 预定义的变量

官方文档:https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

变量名 gitlab版本 runner版本 说明
CI_BUILDS_DIR all 11.10 执行生成的顶级目录。
CI_CONCURRENT_ID all all 单个执行器中生成执行的唯一ID。
CI_JOB_ID 9.0 all 作业的内部ID,在GitLab实例中的所有作业中都是唯一的。
CI_JOB_NAME 9.0 0.5 作业的名称。
CI_PROJECT_DIR all all 存储库克隆到的完整路径,以及作业的运行位置。如果设置了GitLab Runner builds_dir参数,则此变量是相对于builds_dir的值设置的。有关更多信息,请参阅: 高级GitLab Runner配置

.gitlab-ci.yml 文件示例

部署mysql

variables:
    worker_dir: "/home/gitlab-runner/mysql"
    container_name: "mysql"
    image: "mysql:8.0"
    port: "3306"
    password: "123456"

stages:
    - build

build:
    stage: build
    only: 
      - master
    script:
      - docker rm -f $container_name
      # 挂载文件夹 -d 文件夹 -f 文件
      - if [ -d "$worker_dir" ]; then
          rm -rf $worker_dir/conf;
          rm -rf $worker_dir/shell;
        fi
      - mkdir -p $worker_dir/conf/conf.d;
      - mkdir $worker_dir/shell;
      - if [ ! -d "$worker_dir/data" ]; then 
          mkdir $worker_dir/data;
        fi
      # 复制文件到挂载文件夹
      - cp my.cnf $worker_dir/conf
      - cp my.cnf.fallback $worker_dir/conf
      - cp docker.cnf $worker_dir/conf/conf.d
      - cp mysql.cnf $worker_dir/conf/conf.d
      - cp init.sh $worker_dir/shell
      # 启动容器
      - docker run -d
        -p $port:3306
        -v $worker_dir/conf:/etc/mysql
        -v $worker_dir/data:/var/lib/mysql
        -v $worker_dir/shell:/docker-entrypoint-initdb.d
        -e MYSQL_ROOT_PASSWORD=$password
        --restart=always --privileged
        --name $container_name $image

部署redis

variables:
    worker_dir: "/home/gitlab-runner/redis"
    container_name: "redis"
    image: "redis"
    port: "6379"

stages:
    - build

build:
    stage: build
    only:
      - master
    script:
      - docker rm -f $container_name
      # 挂载文件夹 -d 文件夹 -f 文件
      - if [ -d "$worker_dir" ]; then
          rm -rf $worker_dir/conf;
        fi
      - mkdir -p $worker_dir/conf;
      - if [ ! -d "$worker_dir/data" ]; then
          mkdir $worker_dir/data;
        fi
      # 复制文件到挂载文件夹
      - cp redis.conf $worker_dir/conf
      # 启动容器
      - docker run -d
        -p $port:6379
        -v $worker_dir/conf/redis.conf:/etc/redis/redis.conf
        -v $worker_dir/data:/data
        --restart=always --privileged
        --name $container_name $image
        redis-server /etc/redis/redis.conf

部署springboot项目

variables:
  project_name: "tools-0.0.1-SNAPSHOT.jar"
  worker_dir: "/home/gitlab-runner/tools"

stages:
  - build
  - deploy

build:
  stage: build
  only: 
    - master
  before_script:
    # -d 文件夹 -f 文件
    - if [ ! -d "$worker_dir" ]; then
        mkdir $worker_dir;
      else
        rm -rf $worker_dir/*;
      fi
  script:
    - mvn17 clean package
    - cp Dockerfile $worker_dir
    - cp *.sh $worker_dir
    - cp target/$project_name $worker_dir

deploy:
  stage: deploy
  only: 
    - master
  script:
    - cd $worker_dir
    - chmod 777 start.sh
    - ./start.sh

全部评论