gitlab runner如何自部署,以及如何解决拉取docker镜像时失败

背景

想要在代码更新以后,自动部署到后台服务器
目前所在的组织使用的是自部署的gitlab,支持gitlab runner,类似于github workflow,理论上可以实现代码更新以后,自动对代码进行一通操作,包括部署到后台服务器

安装并注册gitlab runner

首先找到gitlab项目里,runner的配置,有两项:url和token


然后给想要用来运行gitlab runner的机器参考官方文档安装

选择对应的系统安装即可,这里很简单,照着文档走下去,安完就行

安完以后检查一下,正在运行即可

[root@localhost ~]# sudo gitlab-runner status
Runtime platform                                    arch=amd64 os=linux pid=83410 revision=9ffb4aa0 version=18.8.0
gitlab-runner: Service is running

然后将这个runner注册一下,关联到我们的项目,具体怎么写见下

# 先注册
[root@localhost ~] sudo gitlab-runner register
# 输入两个必要配置url和token                                        
Enter the GitLab instance URL (for example, https://gitlab.com/):
上面gitlab仓库那里的url
Enter the registration token:
上面gitlab仓库那里的token
# 其他配置可以一路enter跳过
Enter a description for the runner:
[localhost.localdomain]: 随便,方便自己分别runner的名字而已
Enter tags for the runner (comma-separated):
Enter optional maintenance note for the runner:
# 注意选择docker
Enter an executor: custom, virtualbox, docker, kubernetes, docker-autoscaler, shell, ssh, parallels, docker-windows, docker+machine, instance:
docker
# 随便哪个docker都行,跟你的项目没关系
Enter the default Docker image (for example, ruby:3.3):
ruby:3.3
# 以上结束后,就配置完了,会告诉你配置文件的地址,可以后续修改
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
 
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml" 

注册完以后,在gitlab项目后台就可以看到这个runner被关联上了,前面是绿的,就说明可以运行了

确保runner可以使用docker

如果你的网络环境可以直连docker官方服务器,那你就可以直接用了,如果不能,就换源

注意!
换源以后如果直接执行systemctl restart docker,会关闭其他人的容器!
换源以后如果直接执行systemctl restart docker,会关闭其他人的容器!
换源以后如果直接执行systemctl restart docker,会关闭其他人的容器!

想要重启docker systemcl却不重启docker容器,见 如何重启docker systemcl却不重启docker容器
如何给docker换源见 如何给docker换源
目前可以用的docker国内源见 国内可用docker镜像源

换源完毕以后,先在runner服务器上拉取一下镜像,确保已经拉下来了,如果拉不下来,换个docker源再拉

[root@localhost ~]# docker pull ruby:3.3
3.3: Pulling from library/ruby
Digest: sha256:5e8b64d721461f5dbd6410167f358776a24832223d9885ffa83d1535ae1abe72
Status: Image is up to date for ruby:3.3
docker.io/library/ruby:3.3

然后配置一下runner配置,配置文件的路径在注册完以后会显示,一般是在/etc/gitlab-runner/config.toml

修改里面的内容,默认设置下gitlab-runner每次都要去docker中央仓库拉image关键字指明的镜像,设置成pull_policy="if-not-present",即本地不存在 则去拉取

修改完以后大概长这样

# 前面的省略了
[[runners]]
  name = "随便"
  url = "你的url"
  id = 7
  token = "你的token"
  token_obtained_at = 2026-01-28T09:33:31Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "ruby:3.3"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    pull_policy = ["if-not-present"]
    shm_size = 0
    network_mtu = 0

至此,你的runner应该就可以跑了

如何写CI/CD文件

这一块还没太明白,简单说说


直接进仓库的CI/CD页面,通过editor就能新建、修改.gitlab-ci.yml

这里面就写好了,我们希望每次自动化都做些什么,以这个配置为例,就是使用alpine:latestdocker image,每次dev分支更新时,执行命令一大堆


stages: # List of stages for jobs, and their order of execution

- deploy


deploy-to-dev: # Deploy code to dev server when `dev` branch is updated.

stage: deploy

image: alpine:latest

only:

- dev

before_script:

# Install required tools

- apk add --no-cache openssh-client rsync bash

# Prepare SSH key (set SSH_PRIVATE_KEY in CI/CD variables)

- mkdir -p ~/.ssh

- chmod 700 ~/.ssh

- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa

- chmod 600 ~/.ssh/id_rsa

# Add known hosts: either set SSH_KNOWN_HOSTS in CI variables or fetch it automatically

- if [ -n "$SSH_KNOWN_HOSTS" ]; then echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts; else ssh-keyscan -H xxx >> ~/.ssh/known_hosts; fi

script:

# Push repo contents to remote via rsync. Exclude files listed in rsync-exclude-file.txt if present.

- echo "Starting rsync to $DEPLOY_SERVER:$DEPLOY_PATH"

- rsync -avz --progress --delete --exclude-from='rsync-exclude-file.txt' ./ "$DEPLOY_SERVER:$DEPLOY_PATH"

variables:

DEPLOY_SERVER: "root@x.x.x.x"

DEPLOY_PATH: "/data/my_path"

only:

- dev

when: on_success

environment:

name: dev

url: "ssh://$DEPLOY_SERVER"

参考