Docker + Jenkins + gogs 自动化部署

介绍

  docker+jenkins+gogs实现持续自动化部署。

安装 Docker

# 下载自动安装脚本
curl -fsSL get.docker.com -o get-docker.sh

# 执行脚本,并指定为阿里的镜像
sh get-docker.sh --mirror Aliyun

# 启动docker
systemctl start docker

# 设置仓库镜像地址,可以加速下载镜像
vi /etc/docker/daemon.json
# 写入内容
{
    "log-driver": "json-file",
    "log-opts": {"max-size": "500m"},
    "registry-mirrors": [
        "https://3laho3y3.mirror.aliyuncs.com"
    ],
    "data-root": "/data/app/docker"
}

# 重启docker
systemctl daemon-reload
systemctl restart docker

# 设置开机启动
systemctl enable docker

  Centos8 系统安装的时候可能会报错:

Error: 
 Problem: package docker-ce-3:19.03.13-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
  - cannot install the best candidate for the job
  - package containerd.io-1.2.10-3.2.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.13-3.1.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.13-3.2.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.2-3.3.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.2-3.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.4-3.1.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.5-3.1.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.2.6-3.3.el7.x86_64 is filtered out by modular filtering
  - package containerd.io-1.3.7-3.1.el7.x86_64 is filtered out by modular filtering

  Centos8默认使用podman代替docker,所以需要containerd.io,那我们就安装一下就好了。

yum install -y https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.12-3.1.el8.x86_64.rpm

#### 上面可能也会报错,可以先移除几个包再安装
dnf remove podman
dnf remove buildah
或
yum erase podman buildah

  阿里云alibaba cloud linux操作系统可能会报 Unsupported distribution 'alinux' 错误,解决办法只能手动执行命令:

# 安装工具包
yum install -y -q yum-utils
# 添加源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看是否有可用安装包
yum list docker-ce --showduplicates | sort -r
# 构建缓存
yum makecache
# 安装
yum install -y  docker-ce

安装 docker-composer

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

docker compose version

  参考:Install Compose on Linux

安装 htop、nginx、unzip、git

yum install -y htop nginx unzip git

安装portainer,用于在线客户化管理docker

# 创建数据卷
docker volume create portainer_data

# 启动portainer容器
docker run -d -p 8000:8000 -p 9999:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data --name=portainer --restart=always portainer/portainer-ce

# 新建 /etc/nginx/conf.d/portainer.conf,写入
server {
  listen  80;
  server_name testportainer.xxx.com;
  
  # 读取http头部的超时时间,单位秒,连接建立后,服务端接收http头部,规定时间内没收到,则超时,返回给客服端408(request time out)
  client_header_timeout 600;
  # 读取http body的超时时间,单位秒,连接建立后,服务端接收body,规定时间内没收到,则超时
  client_body_timeout   600;
  # 发送响应超时时间,单位秒,服务端向客户端发送数据包,规定时间内客户端没收到,则超时
  send_timeout          600;
  # 保持闲置连接的超时时间,单位秒,超过后服务器和浏览器都会关闭连接
  keepalive_timeout     600;
  # nginx服务器与被代理服务连接超时时间,代理超时
  proxy_connect_timeout 600;
  # nginx服务器发送数据给被代理服务器超时时间,单位秒,规定时间内nginx服务器没发送数据,则超时
  proxy_send_timeout    600;
  # nginx服务器接收被代理服务器数据超时时间,单位秒,规定时间内nginx服务器没收到数据,则超时
  proxy_read_timeout    600;

  location / {
    proxy_pass   http://127.0.0.1:9999;
    proxy_set_header    X-Real-IP        $remote_addr;
    proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
    proxy_set_header    X-Forwarded-Proto $scheme;
    proxy_redirect      default;
  }

  location /api/websocket/ {
    proxy_pass http://127.0.0.1:9999/api/websocket/;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
  }

}

新建docker的network桥接网络

docker network create docker1 
-o com.docker.network.bridge.name=docker1 
-o com.docker.network.bridge.host_binding_ipv4=0.0.0.0 
--driver=bridge --subnet=172.20.0.0/16 --gateway=172.20.0.1

docker network create --subnet=172.172.0.0/24 --gateway 172.172.0.1 nginx-proxy

查看新建网桥

docker network ls
docker network inspect docker1

使用docker运行redis

# 新建 /root/docker/redis/docker-compose.yml
version: "3"
networks:
  docker1:               ### 自建的network
    external: true
services: 
  redis:
    image: redis:5
    container_name: my_redis
    hostname: leeze-redis
    command: redis-server --requirepass yourpassword
    restart: always
    networks:
      docker1:
        ipv4_address: 172.20.0.3               ###容器固定ip 
    ports:
      - "6379:6379"
    volumes:
      - ./data:/data:cached
    logging: 
      driver: "json-file"
      options: 
        max-size: "500m"
  
# 运行
docker-compose up -d --build

使用docker运行mysql

# 新建 /root/docker/mysql/docker-compose.yml
version: "3"
networks:
  docker1:               ### 自建的network
    external: true
services: 
  mysql:
    image: mysql:8
    container_name: mysql
    hostname: leeze-mysql
    command: mysqld --default-authentication-plugin=mysql_native_password
    restart: always
    networks:
      docker1:
        ipv4_address: 172.20.0.4               ###容器固定ip 
    ports:
      - "3306:3306"
    environment:
      - MYSQL_PORT=3306 
      - MYSQL_DATABASE=leeze 
      - MYSQL_USER=admin 
      - MYSQL_PASSWORD=sysadmin 
      - MYSQL_ROOT_PASSWORD=sysadmin 
    volumes:
      - ./data:/var/lib/mysql:cached
      - ./conf:/etc/mysql/conf.d:cached
      
      - ./data:/var/lib/mysql 
      - ./conf/mysql/my.cnf:/etc/my.cnf 
      - ./conf/mysql/conf.d:/etc/mysql/conf.d 
      - ./conf/mysql/mysql.conf.d:/etc/mysql/mysql.conf.d
    security_opt:
      - seccomp:unconfined
    logging: 
      driver: "json-file"
      options: 
        max-size: "500m"
      
# 运行
docker-compose up -d --build

# 设置允许远程访问
use mysql;
update user set host='%' where user ='root';
FLUSH PRIVILEGES;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

# 设置最大连接数
set GLOBAL max_connections=2048;
# 查看最大连接数
show variables like '%max_connections%';

生成ssh密钥,免密拉取代码

# 生成密钥
ssh-keygen -t rsa 
ssh-keygen -m PEM -t rsa  # 低版本

# 将id_rsa.pub内容添加到代码服务器
cd ~/.ssh/
cat id_rsa.pub

使用docker安装Jenkins

# 新建 /root/docker/jenkins/docker-compose.yml
version: "3"
networks:
  docker1:               ### 自建的network
    external: true
services: 
  jenkins:
    image: jenkinsci/blueocean
    container_name: jenkins
    hostname: leeze-jenkins
    restart: always
    networks:
      docker1:
        ipv4_address: 172.20.0.5               ###容器固定ip 
    ports:
      - "49999:8080"
      - "50000:50000"
    environment:
      JAVA_OPTS: "-Duser.timezone=Asia/Shanghai"
    volumes:
      - ./data:/var/jenkins_home:cached
    logging: 
      driver: "json-file"
      options: 
        max-size: "500m"

# 运行
docker-compose up -d --build

# 解决权限错误问题
chown -R 1000:1000 data

  权限问题解决之后,Jenkins会自动运行,并打印出一串随机密码:

  打开浏览器进入127.0.0.1:49999, 输入日志中的密码完成账号初始化

  选择要安装的插件

  安装插件

  安装publish over ssh插件

  配置publish over ssh插件

  拉到最下面,新增服务器

  配置 gogs webhook

  1. 过滤分支,只处理dev分支,
  2. 设置参数构建,区分测试和正式,这个参数后面的publish over ssh 插件要用

  设置构建后操作

  点击高级按钮,设置把branch参数传入

  同样在ssh server选项中也点击高级,并设置label为test,表示如果构建的时候选择test,则会进入当前这个server,这样就可以针对不同的构建参数选择不同的主机进行相关操作。需要注意Exec command 的命令是到远程服务器上执行的,而不是Jenkins所在的机器。

  配置完毕,开始构建测试吧

  可以看到默认是构建test,这个参数就是我们刚刚配置的。

  设置钩子,提交代码之后触发自动更新