结合网上查询的资料, 使用阿里云个人镜像服务实现业务的自动更新部署

服务器需求

  • 系统: Alibaba Cloud Linux 3
  • 项目适应规模: 微服务dubbo架构, 多服务适配
  • 开通阿里云的镜像服务个人版,并创建好命名空间: xu81-docker, 具体见https://www.aliyun.com/product/acr

部署内容

安装docker

Lang: bash
 1# 移除原有docker安装
 2yum remove docker docker-client docker-client-latest \
 3docker-common docker-latest docker-latest-logrotate \
 4docker-logrotate docker-engine
 5
 6# 安装依赖工具
 7yum install -y yum-utils device-mapper-persistent-data lvm2
 8
 9# 安装docker repo仓库
10yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
11
12# 安装docker
13yum install docker-ce docker-ce-cli containerd.io
14
15# 修改docker加速
16cat > /etc/docker/daemon.json << EOF
17{
18    "registry-mirrors": [
19            "https://docker.1ms.run"
20    ]
21}
22EOF
23systemctl daemon-reload
24systemctl restart docker

docker加速镜像更新见: https://xuanyuan.me/blog/archives/1154

基础服务

zookeeper

Lang: bash
1docker run -d \
2-e TZ="Asia/Shanghai" \
3-p 2181:2181 \
4-v /deploy/zookeeper/data:/data \
5--name zookeeper \
6--restart always \
7--label=com.centurylinklabs.watchtower.enable=false \
8zookeeper

--label=com.centurylinklabs.watchtower.enable=false
移除自动更新watchtower监控, 即不自动更新zookeeper镜像

emqx

Lang: bash
 1# 创建具名卷用于持久化数据
 2docker volume create emqx_data
 3docker volume create emqx_etc
 4# 运行
 5docker run -d --name emqx \
 6-p 1883:1883 -p 8083:8083 \
 7-p 8084:8084 -p 8883:8883 \
 8-p 18083:18083 \
 9-v emqx_data:/opt/emqx/data \
10-v emqx_etc:/opt/emqx/etc \
11--label=com.centurylinklabs.watchtower.enable=false \
12emqx/emqx:5.8.1

rocketmq

nameserver

Lang: bash
1docker volume create rmqnamesrv_data
2docker run -d --name rmqnamesrv \
3-p 9876:9876 \
4-v rmqnamesrv_data:/home/rocketmq \
5--label=com.centurylinklabs.watchtower.enable=false \
6apache/rocketmq:5.3.1 sh mqnamesrv

broker

Lang: bash
 1# 创建数据配置目录和文件
 2mkdir -p /data/rocketmq & cd /data/rocketmq
 3echo "brokerIP1=127.0.0.1" > broker.conf
 4# 在/data/rocketmq目录下执行
 5docker run -d --name rmqbroker \
 6-p 10912:10912 -p 10911:10911 \
 7-p 10909:10909 -p 8080:8080 \
 8-p 8081:8081 \
 9-e "NAMESRV_ADDR=rmqnamesrv:9876" \
10-v $PWD/broker.conf:/home/rocketmq/rocketmq-5.3.1/conf/broker.conf \
11--label=com.centurylinklabs.watchtower.enable=false \
12apache/rocketmq:5.3.1 sh mqbroker \
13--enable-proxy -c /home/rocketmq/rocketmq-5.3.1/conf/broker.conf

dashboard

Lang: bash
1docker run -d --name rocketmq-dashboard \
2-e "JAVA_OPTS=-Drocketmq.namesrv.addr=10.0.0.105:9876" \
3-p 8082:8080 \
4--label=com.centurylinklabs.watchtower.enable=false \
5-t apacherocketmq/rocketmq-dashboard:latest

postgresql:13

Lang: bash
1# 创建数据卷
2docker volume create postgres_data
3docker run -id --name=postgresql \
4-v postgre-data:/var/lib/postgresql/data \
5-p 5432:5432 \
6-e POSTGRES_PASSWORD=<数据库管理密码> \
7-e LANG=C.UTF-8 \
8--label=com.centurylinklabs.watchtower.enable=false \
9postgres:13

gitlab-runner服务器配置阿里云docker镜像服务登录

Lang: bash
1 # docker push var
2export ALIYUN_DOCKER_USERNAME=用户名
3export ALIYUN_DOCKER_PASSWD=阿里云密码
4export ALIYUN_DOCKER_URL=registry.cn-shenzhen.aliyuncs.com

具体见acr仓库内详细说明

redis:4

Lang: bash
 1# 创建数据卷
 2docker volume create redis_data
 3# 创建配置目录
 4mkdir -p /data/redis && cd /data/redis
 5# 创建redis.conf文件, 具体见[redis.conf](#redis.conf)
 6touch redis.conf
 7docker run -d --name redis \
 8-p 6379:6379 --restart always \
 9-v redis_data:/data \
10-v $PWD/redis/redis.conf:/etc/redis/redis.conf \
11-v $PWD/redis/logs:/logs \
12--label=com.centurylinklabs.watchtower.enable=false \
13redis:4 redis-server /etc/redis/redis.conf

redis.conf

Lang: bash
 1port 6379
 2requirepass 000000
 3daemonize no
 4appendonly yes
 5timeout 60
 6maxclients 10000
 7tcp-keepalive 300
 8
 9save 900 1
10save 300 10
11save 60 10000
12
13tcp-backlog 511
14
15databases 4
16
17appendonly yes
18appendfsync everysec
19no-appendfsync-on-rewrite no
20auto-aof-rewrite-percentage 100
21auto-aof-rewrite-min-size 64m
22
23slowlog-log-slower-than 10000
24slowlog-max-len 128
25
26syslog-enabled yes
27
28loglevel notice
29
30logfile stdout
31
32hash-max-ziplist-entries 512
33hash-max-ziplist-value 64
34list-max-ziplist-entries 512
35list-max-ziplist-value 64
36set-max-intset-entries 512
37zset-max-ziplist-entries 128
38zset-max-ziplist-value 64

应用部署

自动更新监控

Lang: bash
1docker run -d --name watchtower \
2--restart always \
3-v /deploy/config.json:/config.json \
4-v /var/run/docker.sock:/var/run/docker.sock \
5--label=com.centurylinklabs.watchtower.enable=false \
6containrrr/watchtower \
7--cleanup \
8--interval 6
Lang: json
1// config.json
2{
3    "auths": {
4        "registry.cn-shenzhen.aliyuncs.com": {
5            "auth": "秘钥信息"
6        }
7    }
8}

秘钥生成方法: echo -n 'acr账号:acr密码' | base64
具体见: https://rumosky.com/archives/724/

vue前端

项目目录下新建docker目录, 新建docker/Dockerfile文件, 新建docker/default.conf文件

Dockerfile

Lang: dockerfile
 1# 设置基础镜像
 2FROM nginx
 3#设置CTS时区
 4RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
 5# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
 6COPY dist/ /usr/share/nginx/html/
 7#用本地的 default.conf 配置来替换nginx镜像里的默认配置
 8COPY docker/default.conf /etc/nginx/conf.d/default.conf
 9EXPOSE 80
10CMD ["nginx","-g","daemon off;"]

default.conf

Lang: nginx
 1# vue页面配置
 2server {
 3    listen       80;
 4    server_name  test.example.com;
 5
 6    #charset koi8-r;
 7    access_log  /var/log/nginx/host.access.log  main;
 8    error_log  /var/log/nginx/error.log  error;
 9
10    location / {
11        root   /usr/share/nginx/html;
12        index  index.html index.htm;
13        try_files $uri $uri/ /index.html;
14    }
15
16    #error_page  404              /404.html;
17
18    # redirect server error pages to the static page /50x.html
19    #
20    error_page   500 502 503 504  /50x.html;
21    location = /50x.html {
22        root   /usr/share/nginx/html;
23    }
24}
25# 后端接口配置
26server {
27        listen 80;
28        server_name test-api.example.com;
29
30        access_log  /var/log/nginx/host.api.access.log  main;
31        error_log  /var/log/nginx/error.api.log  error;
32
33        location /iot {
34                proxy_pass http://10.0.0.105:8099;
35                proxy_set_header Host $host;
36                proxy_set_header X-real-ip $remote_addr;
37                proxy_set_header REMOTE-HOST $remote_addr;
38                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
39                add_header Access-Control-Allow-Methods POST,GET,OPTIONS,DELETE,PUT;
40                add_header Access-Control-Allow-Credentials true;
41                add_header Access-Control-Allow-Headers Content-Type,Token,Origin,X-Requested-With,Authorization,Accept;
42                add_header Access-Control-Allow-Max-Age 1728000;
43        }
44}

gitlab-ci.yml

Lang: yaml
 1stages:
 2  - package
 3  - build
 4  - push
 5
 6variables:
 7  image: "xu81-docker/xu81-ui"
 8
 9package:
10  stage: package
11  only:
12    refs:
13      - tags
14    variables:
15      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
16  tags:
17    - dev
18  script:
19    - npm install
20    - npm run build
21  artifacts:
22    paths:
23      - dist/
24      - docker/
25
26build:
27  stage: build
28  only:
29    refs:
30      - tags
31    variables:
32      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
33  tags:
34    - dev
35  script:
36    - last_version=$(git describe --abbrev=0 --tags|awk '{print substr($1,9)}')
37    - echo $image:$last_version
38    - docker build -f docker/Dockerfile -t $image:$last_version .
39
40product push:
41  stage: push
42  only:
43    refs:
44      - tags
45    variables:
46      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
47  script:
48    - last_version=$(git describe --abbrev=0 --tags|awk '{print substr($1,9)}')
49    - echo $image:$last_version
50    - docker login --username=$ALIYUN_DOCKER_USERNAME --password=$ALIYUN_DOCKER_PASSWD $ALIYUN_DOCKER_URL
51    - image_id=$(docker images | grep $image | grep $last_version | awk '{print $3}')
52    - echo "docker tag $image_id $ALIYUN_DOCKER_URL/$image:$last_version"
53    - docker tag $image_id $ALIYUN_DOCKER_URL/$image:latest
54    - docker push $ALIYUN_DOCKER_URL/$image:latest
55  tags:
56    - dev

- $CI_COMMIT_REF_NAME =~ /^release_.*$/
基于提交的标签内容出发gitlab-ci流程, 并自动提取版本号, 如release_v1.0.0提取版本号为: v1.0.0

注: 打包的runner服务器必须提前安装好对应版本node

node 高版本无法使用问题

具体见: https://www.javaai.org/a/c892d1e98fd94a64018ff4a88ec9000c

Lang: bash
1wget -O node-standalone-v18.20.3.tar.gz https://www.javaai.org/uploads/file/20240608/1717796384652070055.gz
2tar xzvf node-standalone-v18.20.3.tar.gz
3node-standalone/patchelf-recurse/patchelf-repaire-ld-linux.sh node-standalone/node-v18.20.3-linux-x64/
4export PATH=/root/node-standalone/node-v18.20.3-linux-x64/bin:$PATH

运行

Lang: bash
1docker run -d --name xu81-ui \
2--label com.centurylinklabs.watchtower.enable=true \
3-v /var/run/docker.sock:/var/run/docker.sock \
4-v /deploy/xu81-docker/ui/conf:/etc/nginx/conf.d \
5-p 80:80 \
6registry.cn-shenzhen.aliyuncs.com/xu81-docker/xu81-ui:latest

--label com.centurylinklabs.watchtower.enable=true
使用watchtower监控项目docker镜像更新, 成功完成gitlab-ci流程后, 自动更新镜像到阿里云镜像仓库同时watchtower会自动更新镜像并重启服务

后端

项目目录下新建docker目录, 新建docker/Dockerfile文件, 复制src/main/resources/application.properties文件到docker/conf/application.properties文件

Dockerfile

Lang: dockerfile
1FROM docker.1ms.run/library/openjdk:8-jdk-alpine
2MAINTAINER xu81 "xu81@xu81.com"
3VOLUME /tmp
4# 
5COPY target/*.jar /app.jar
6ADD docker/conf /conf
7EXPOSE 8099
8ENTRYPOINT ["java", "-Xms256m", "-Xmx256m", "-jar", "/app.jar", "--spring.config.location=/conf/application.properties"]

gitlab-ci.yml

Lang: yaml
 1stages:
 2  - package
 3  - build
 4  - push
 5
 6variables:
 7  image: "xu81-docker/xu81-web"
 8
 9package:
10  stage: package
11  only:
12    refs:
13      - tags
14    variables:
15      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
16  script:
17    - mvn clean package -Dmaven.test.skip=true
18  tags:
19    - dev
20  artifacts:
21    paths:
22      - target/*.jar
23
24build:
25  stage: build
26  only:
27    refs:
28      - tags
29    variables:
30      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
31  script:
32    - last_version=$(git describe --abbrev=0 --tags|awk '{print substr($1,9)}')
33    - echo $image:$last_version
34    - docker build -f docker/Dockerfile -t $image:$last_version .
35  tags:
36    - dev
37
38product push:
39  stage: push
40  only:
41    refs:
42      - tags
43    variables:
44      - $CI_COMMIT_REF_NAME =~ /^release_.*$/
45  script:
46    - last_version=$(git describe --abbrev=0 --tags|awk '{print substr($1,9)}')
47    - echo $image:$last_version
48    - docker login --username=$ALIYUN_DOCKER_USERNAME --password=$ALIYUN_DOCKER_PASSWD $ALIYUN_DOCKER_URL
49    - image_id=$(docker images | grep $image | grep $last_version | awk '{print $3}')
50    - echo "docker tag $image_id $ALIYUN_DOCKER_URL/$image:$last_version"
51    - docker tag $image_id $ALIYUN_DOCKER_URL/$image:latest
52    - docker push $ALIYUN_DOCKER_URL/$image:latest
53  tags:
54    - dev

运行

Lang: bash
1docker run -d --name xu81-web \
2--label com.centurylinklabs.watchtower.enable=true \
3-v /var/run/docker.sock:/var/run/docker.sock \
4-v /deploy/xu81-docker/web/conf:/conf \
5-v /deploy/xu81-docker/web/logs:/logs \
6-p 8099:8099 \
7registry.cn-shenzhen.aliyuncs.com/xu81-docker/xu81-web:latest

查看日志

Lang: bash
1docker ps|grep "xu81-web"|awk '{print $1}'
21424eeeb1518
3docker logs -f 1424eeeb1518

docker logs参数说明

-f 保持日志输出

–since 从指定时间开始2023-07-22T15:00:00

-t 显示时间戳

–tail 显示倒数多少行

–details 显示日志额外信息

–until 显示直到时间的日志 2023-07-22T15:00:00