Docker 容器应用构建 deb 包

ai创造

背景

我们的应用发布都是以镜像为基础,git打tag触发cicd,发布对应version的镜像。现在有个应用需要部署到客户内网中,如果以导出镜像的形式,再给客户部署,是比较繁琐的。并且无法做一些额外的工作,例如安装前的环境检测,卸载时删除镜像,以及更新等。当然这些都可以通过脚本实现,但不够优雅。而同事之前做过以linux安装包的形式发布容器应用,这种方式更加正式且方便,遂复用之。

deb包介绍

deb包是 Debian 系列的应用安装包格式。

敏感信息

由于脚本涉及到一些敏感信息,所以进行了脱敏工作。

  • 公司名:google
  • 安装的应用名:chrome
  • 应用包含的镜像名:chrome-interface
    • 此脚本支持多个镜像,这种情况下,应用安装后会创建多个容器
  • 镜像在harbor仓库中的项目组:chrome-group
  • 安装包名:Chrome_On-Premise

准备deb包相关文件

目录结构

在chrome项目里增加一个build文件夹存放打包相关的文件,下面是build目录的结构。

.
├── README.md
├── deb
│   ├── DEBIAN
│   │   ├── control
│   │   ├── postinst
│   │   ├── preinst
│   │   └── prerm
│   ├── opt
│   │   └── google
│   │       └── chrome
│   │           ├── docker-compose.yml
│   │           └── chrome-interface
│   │               ├── configs
│   │               └── data
│   └── usr
│       ├── lib
│       │   └── systemd
│       │       └── system
│       │           └── chrome.service
│       └── local
│           └── bin
│               └── chrome-start.sh
└── package-deb.sh

deb包的组成结构

deb包一般分成两部分:

  • 安装的内容(deb目录下,除DEBIAN目录之外的文件),这部分类似linux的根目录,表示需要将软件安装到linux系统上的文件目录,也就是说安装时会将这个目录下的文件拷贝到目标系统。
  • 控制信息(DEBIAN目录下),通常DEBIAN目录下有如下几个文件。
    • control: 应用信息
    • copyright:版权声明
    • changlog:修改记录
    • preinst:安装之前执行的 shell 脚本
    • postinst:安装之后执行的 shell 脚本
    • prerm:卸载之前执行的 shell 脚本
    • postrm:卸载之后执行的 shell 脚本

打包脚本

build/package-deb.sh

  • 配置打包包含的镜像,以及对应版本
  • 环境检测
  • 下载镜像
  • 重新给镜像打tag,隐藏公司镜像仓库地址
  • 导出镜像
  • 构建deb包
  • 清理工作
#!/bin/bash

###############################################################################
###################### 打Deb包需要修改的变量,主要是依赖组件的版本 ################
###############################################################################
# 设置chrome当前需要发布的版本
APP_VERSION="1.0.0"
declare -A versions
# 设置chrome-interface当前组件依赖的版本
versions["chrome-interface"]="latest"

###############################################################################
########################## 后续脚本不需要修改 ####################################
###############################################################################

# 环境检测

if ! dpkg --version >/dev/null 2>&1; then
    echo "请在当前机器安装dpkg工具"
    exit 1
fi

if ! docker version >/dev/null 2>&1; then
    echo "请在当前机器安装docker"
    exit 1
fi

if ! sed --version >/dev/null 2>&1; then
    echo "请在当前机器安装sed工具"
    exit 1
fi

# 是否需要下载tag为latest的镜像,默认是需要下载的,因为latest的镜像以为者随时可能会更新。
# 如果不想下载tag为latest的镜像,可以通过执行: ./package-deb.sh --allwaysDownloadLatestImage=false来取消镜像下载
allwaysDownloadLatestImage="true"

ARGS=$(getopt -o a:: --long allwaysDownloadLatestImage:: -n "$0" -- "$@")
eval set -- "$ARGS"
while true ; do
    case "$1" in
        -a|--allwaysDownloadLatestImage) allwaysDownloadLatestImage="false" ; shift 2 ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
    esac
done
if [ "${allwaysDownloadLatestImage}" == "true" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 更新tag为latest的镜像,并重新制作其镜像压缩包\n"
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 忽略更新tag为latest的镜像,继续使用之前制作的镜像压缩包\n"
fi

SHELL_PATH=$(cd "$(dirname "$0")"||exit;pwd)
SCRIPT_START_TIME=$(date +%s)

# 镜像仓库地址
HARBOR_ADDR="1.1.1.1"

# 镜像
declare -A images
images["chrome-interface"]="chrome-group/chrome-interface:${versions["chrome-interface"]}"

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 开始下载镜像"
START_IMAGE_DOWNLOAD_TIME=$(date +%s)
for name in ${!images[*]}; do
    {
        image="${HARBOR_ADDR}/${images[$name]}"
        version=${versions[$name]}
        # 如果镜像不存在才下载镜像
        if ! docker image inspect "${image}" >/dev/null 2>&1 || ([ "${allwaysDownloadLatestImage}" == "true" ] && [ "$version" == "latest" ]); then
            echo "[$(date "+%Y-%m-%d %H:%M:%S")] 下载镜像:${image}"
            if ! docker pull "${image}"; then
                echo "[$(date "+%Y-%m-%d %H:%M:%S")] 下载镜像:${image} 失败"
            fi
        fi
        if ! docker image inspect "${images[$name]}" >/dev/null 2>&1 || [ "$version" == "latest" ]; then
            echo "[$(date "+%Y-%m-%d %H:%M:%S")] 执行: docker tag ${image} ${images[$name]}命令,重新打Tag,隐藏镜像仓库地址"
            docker tag "${image}" "${images[$name]}"
        fi
    }&
done
wait
END_IMAGE_DOWNLOAD_TIME=$(date +%s)
EXECUTING_TIME=$((END_IMAGE_DOWNLOAD_TIME - START_IMAGE_DOWNLOAD_TIME))

allImageDownloadSuccessful="true"
for image in ${images[@]}; do
    if ! docker image inspect "$image" >/dev/null 2>&1; then
        allImageDownloadSuccessful="false"
    fi
done
if [ "$allImageDownloadSuccessful" == "false" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 部分镜像下载失败,请重新此脚本下载镜像,或者手动下载镜像\n"
    exit 1
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 所有镜像下载完成,共消耗:$EXECUTING_TIME 秒\n"
fi

# 创建保存镜像压缩包目录
imageDir="${SHELL_PATH}/deb/opt/google/docker"
echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 镜像打包目录为:${imageDir}\n"
if [ ! -d "${imageDir}" ]; then
    mkdir -p "${imageDir}"
fi

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 开始打包镜像为tar压缩包"
START_IMAGE_TAR_TIME=$(date +%s)
for name in ${!images[*]}; do
    {
        image=${images[$name]}
        version=${versions[$name]}
        path="${imageDir}/${name}_${version}.tar"
        deleteFiles=$(ls "${imageDir}" | grep "${name}" |grep -v "${name}_${version}.tar")
        for element in ${deleteFiles[@]}; do
            file="${imageDir}/${element}"
            echo "[$(date "+%Y-%m-%d %H:%M:%S")] 删除无用的镜像压缩包:${file}"
            rm -f "${file}"
        done
        # 如果镜像压缩包不存在或者tag为latest,都需要打包
        if ([ "${allwaysDownloadLatestImage}" == "true" ] && [ "$version" == "latest" ]) || [ ! -f "$path" ]; then
            rm -f "$path"
            echo "[$(date "+%Y-%m-%d %H:%M:%S")] 打包镜像为tar压缩包:$image, 压缩包路径为:$path"
            if ! docker save -o "${path}" "${image}"; then
                echo "[$(date "+%Y-%m-%d %H:%M:%S")] 打包镜像${image}为${path}压缩包失败!!!"
            fi
        fi
    }&
done
wait
END_IMAGE_TAR_TIME=$(date +%s)
EXECUTING_TIME=$((END_IMAGE_TAR_TIME - START_IMAGE_TAR_TIME))

allImageTarSuccessful="true"
for name in ${!images[*]}; do
    version=${versions[$name]}
    path="$imageDir/${name}_${version}.tar"
    # 如果镜像压缩包不存在或者tag为latest,都需要打包
    if [ ! -f "$path" ]; then
        allImageTarSuccessful="false"
    fi
done
if [ "$allImageTarSuccessful" == "false" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 部分镜像打包失败,请重新此脚本打包镜像,或者手动打包镜像\n"
    exit 1
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 所有镜像打包完成, 打包镜像共消耗:$EXECUTING_TIME 秒\n"
fi

# 替换变量
controlPath="$SHELL_PATH/deb/DEBIAN/control"
sed -i "s/^Version.*/Version: ${APP_VERSION}/" "$controlPath"
preinstPath="$SHELL_PATH/deb/DEBIAN/preinst"
sed -i "s/APPVERSION/${APP_VERSION}/g" "$preinstPath"
prermPath="$SHELL_PATH/deb/DEBIAN/prerm"
sed -i "s/APPVERSION/${APP_VERSION}/g" "$prermPath"

postinstPath="$SHELL_PATH/deb/DEBIAN/postinst"
for name in ${!images[*]}; do
    image="${images[$name]}\""
    version=${versions[$name]}
    cmd="docker/${name}_${version}.tar"
    sed -i "s@docker/${name}.*tar@${cmd}@" "$postinstPath"
    sed -i "s@image/${name}.*@${image}@" "$postinstPath"
    sed -i "s@image/${name}.*@${image}@" "$prermPath"
done
sed -i "s/APPVERSION/${APP_VERSION}/g" "$postinstPath"

composePath="${SHELL_PATH}/deb/opt/google/chrome/docker-compose.yml"
sed -i "s@x-appVersion:.*@x-appVersion: \"${APP_VERSION}\"@" "$composePath"

for name in ${!images[*]}; do
    image=${images[$name]}
    array=(${image//:/ })
    prefix=${array[0]}
    sed -i "s@image:.*${prefix}.*@image: ${image}@" "$composePath"
done

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 删除遗留 deb 包"
rm -f *.deb

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 开始制作deb包,由于镜像较大,dpkg打包时间比较长,在4核16G的机器上打包大概需要10分钟,请根据实际的打包机器资源耐心等待!!!"
BUILD_DEB_START_TIME=$(date +%s)

dpkg -b "${SHELL_PATH}/deb"
dpkg-name "deb.deb"

BUILD_DEB_END_TIME=$(date +%s)
EXECUTING_TIME=$((BUILD_DEB_END_TIME - BUILD_DEB_START_TIME))
echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 制作deb包共消耗:$EXECUTING_TIME 秒\n"

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 删除导出的镜像"
rm -rf deb/opt/google/docker

mv chrome_${APP_VERSION}_amd64.deb Chrome_On-Premise_V${APP_VERSION}.deb

SCRIPT_END_TIME=$(date +%s)
EXECUTING_TIME=$((SCRIPT_END_TIME - SCRIPT_START_TIME))
echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行此脚本共消耗:$EXECUTING_TIME 秒\n"

应用信息

build/deb/DEBIAN/control

Package: chrome
Version: 1.0.0
Section: utils
Prioritt: standard
Architecture: amd64
Maintainer: xxx@gmail.com
Description: Chrome On-Premise

安装前执行的脚本

build/deb/DEBIAN/preinst

  • 环境检测
  • 磁盘空间检测
  • 内存空间检测
#!/bin/bash
set -e

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 开始执行Chrome_On-Premise_VAPPVERSION.deb的preinst脚本,dpkg传入参数为:[$*]\n"

if ! df --version >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器未安装df工具,无法检测磁盘容量,不能保证应用正常安装,请联系管理员安装df工具\n"
    exit 1
fi

if ! awk --version >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器未安装awk工具,无法检测磁盘容量,不能保证应用正常安装,请联系管理员安装awk工具\n"
    exit 1
fi

if ! grep --version >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器未安装grep工具,无法检测磁盘容量,不能保证应用正常安装,请联系管理员安装grep工具\n"
    exit 1
fi

if ! free --version >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器未安装free工具,无法检内容容量,不能保证应用正常运行,请联系管理员安装free工具\n"
    exit 1
fi

if ! docker compose version >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器安装的docker过低,请安装23.0.0以上的docker版本"
    exit 1
fi

if ! dpkg-name --help >/dev/null 2>&1; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器未安装dpkg-dev工具,无法构建deb包,不能保证应用正常运行,请联系管理员安装dpkg-dev工具\n"
    exit 1
fi

# 磁盘空间检测
total=$(df / | grep "/$" | awk '{print $2}')
totalG=$((${total}/1024/1024))

used=$(df / | grep "/$" | awk '{print $3}')
usedG=$((${used}/1024/1024))

available=$(df / | grep "/$" | awk '{print $4}')
availableG=$((${available}/1024/1024))

if [ `echo ${availableG} | awk -v tem=50 '{print($1<tem)? "1":"0"}'` -eq "1" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前磁盘空间根目录总共分配${totalG}G,已使用${usedG}G,剩余${availableG}G; 当前机器根目录可用磁盘空间不足50G,无法安装应用,请保证根目录可用磁盘空间大于50G!!!\n"
    exit 1
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前磁盘空间根目录总共分配${totalG}G,已使用${usedG}G,剩余${availableG}G; 磁盘可用空间充足,可以正常安装!!!\n"
fi

# 内存检测
total=$(free | sed '1d;3d' | awk '{print $2}')
totalG=$(echo ${total} 1024 1024 | awk '{print("%.2f",$1/$2/$3)}' | awk '{print $2}')

used=$(free | sed '1d;3d' | awk '{print $3}')
usedG=$(echo ${used} 1024 1024 | awk '{print("%.2f",$1/$2/$3)}' | awk '{print $2}')

available=$(free | sed '1d;3d' | awk '{print $7}')
availableG=$(echo ${available} 1024 1024 | awk '{print("%.2f",$1/$2/$3)}' | awk '{print $2}')

if [ `echo ${totalG} | awk -v tem=15 '{print($1<tem)? "1":"0"}'` -eq "1" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器内存总共分配${totalG}G,已使用${usedG}G,剩余${availableG}G; 当前机器分配内存小于16G,无法保证应用正常运行,请增加内存!!!\n"
    exit 1
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器内存总共分配${totalG}G,已使用${usedG}G,剩余${availableG}G; 可以正常安装!!!\n"
fi

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] dpkg开始解压Deb包,请耐心等待!!!\n"

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行Chrome_On-Premise_VAPPVERSION.deb的preinst脚本结束\n"

安装后执行的脚本

build/deb/DEBIAN/postinst

  • 创建应用存放数据的目录
  • 导入镜像
  • 创建容器
  • 启动容器
  • 注册应用为系统服务,设置开机启动
    • 本来只要docker开启启动,容器就会自动启动,但是我们有个需求是运维手动停止了容器的情况下,重启机器后,也要自动启动容器。
#!/bin/bash

action=$(echo $* | awk '{print $1}')
if [ "${action}" == "abort-upgrade" ] || [ "${action}" == "abort-install" ]; then
    exit 0
fi

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 开始执行执行Chrome_On-Premise_VAPPVERSION.deb的postinst脚本,dpkg传入参数为:[$*]\n"

if ! docker version >/dev/null 2>&1; then
    echo "请在当前机器安装docker"
    exit 1
fi

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 解压deb完成,开始安装应用!!!\n"

mkdir -p /var/google/chrome/chrome-interface/logs
if [ ! -d "/var/google/chrome/chrome-interface/data" ]; then
  echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 本地库不存在,拷贝安装包里的数据库\n"
  mv /opt/google/chrome/chrome-interface/data /var/google/chrome/chrome-interface
else
  echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 本地库已存在,删除安装包里的数据库\n"
  rm -rf /opt/google/chrome/chrome-interface/data
fi

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 检查internal网络"
if ! docker network ls | grep internal >/dev/null 2>&1; then
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器没有创建internal网络, 创建internal网络"
    if ! docker network create internal --driver=bridge --subnet=169.254.253.0/24; then
        echo "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器创建internal网络出错"
        exit 1
    fi
fi

declare -A archives
archives["chrome-interface"]="/opt/google/docker/chrome-interface.tar"

declare -A images
images["chrome-interface"]="image/chrome-interface:latest"

IMPORT_IMAGE_START_TIME=$(date +%s)
for name in ${!archives[*]}; do
    loadImage=${archives[$name]}
    image=${images[$name]}
    array=(${image//:/ })
    subfix=${array[1]}
    if [ "${subfix}" == "latest" ] ||  ! docker image inspect "${image}" >/dev/null 2>&1; then
            echo "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器导入${image}镜像..."
        if ! docker load -i "${loadImage}"; then
            echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行: docker load -i ${loadImage}导入到当前机器镜像失败,请联系管理员排查具体失败原因\n"
        else
            rm -f "${loadImage}"
            echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器导入${image}镜像成功,将移除${loadImage}镜像压缩包!!!\n"
        fi
    else
        echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器已经导入${image}镜像,跳过导入\n"
    fi
done
IMPORT_IMAGE_END_TIME=$(date +%s)
EXECUTING_TIME=$((IMPORT_IMAGE_END_TIME - IMPORT_IMAGE_START_TIME))
echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 导入镜像共消耗:${EXECUTING_TIME}秒\n"

allImageDownloadSuccessful="true"
for image in ${images[@]}; do
    if ! docker image inspect "${image}" >/dev/null 2>&1; then
        allImageDownloadSuccessful="false"
        echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 镜像${image}未找到,请联系管理员\n"
    fi
done
if [ "$allImageDownloadSuccessful" == "false" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 部分镜像导入失败,应用安装失败,请联系管理员排查具体原因\n"
    exit 1
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 当前机器所有镜像导入成功,共消耗:$EXECUTING_TIME 秒\n"
fi

composePath="/opt/google/chrome/docker-compose.yml"
if [ ! -f "${composePath}" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] ${composePath}文件不存在,请联系管理员,应用安装失败"
    exit 1
fi

if ! docker compose --file $composePath create chrome-interface; then
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 创建容器失败,请联系管理员"
    exit 1
else
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 创建容器成功"
fi

if ! docker compose --file $composePath up -d; then
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 容器启动失败,请联系管理员"
    exit 1
else
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 容器启动成功"
fi

if ! (systemctl daemon-reload && systemctl enable chrome); then
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 设置应用开机启动失败,请联系管理员"
    exit 1
else
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] 设置应用开机启动成功"
fi

systemctl status chrome | cat

rm -rf "/opt/google/docker"

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 安装完成,请用浏览器访问 http://<IP>:8000 进行激活"

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行Chrome_On-Premise_VAPPVERSION.deb的postinst脚本结束\n"

卸载前执行的脚本

build/deb/DEBIAN/prerm

  • 停止、删除容器
  • 删除应用相关的镜像
  • 删除应用文件(没有删除应用数据,因为更新时会先执行卸载脚本)
#!/bin/bash

action=$(echo $* | awk '{print $1}')
if [ "${action}" == "abort-upgrade" ] || [ "${action}" == "abort-install" ]; then
    exit 0
fi

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 开始执行Chrome_On-Premise_VAPPVERSION.deb的prerm脚本,dpkg传入参数为:[$*]\n"

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 移除应用相关的所有镜像"

composePath="/opt/google/chrome/docker-compose.yml"
if [ ! -f "${composePath}" ]; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] ${composePath}文件不存在,无法删除应用使用的容器\n"
fi

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 停止运行应用所有组件\n"
if ! docker compose --file $composePath down; then
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 停止应用容器异常\n"
else
    echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 停止应用所有容器成功!!!\n"
fi

declare -A images
images["chrome-interface"]="image/chrome-interface:latest"

for name in ${!images[*]}; do
    {
        image=${images[$name]}
        if docker image inspect "${image}" >/dev/null 2>&1; then
             echo "[$(date "+%Y-%m-%d %H:%M:%S")] 移除当前机器导入的${image}镜像..."
            if ! docker rmi -f $image; then
                echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行: docker rmi -f ${image}移除当前镜像失败\n"
            else
                echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 镜像${image}移除成功\n"
            fi
        fi
    }&
done
wait

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 删除/opt/google/chrome\n"
rm -rf /opt/google/chrome

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 应用成功卸载!\n"

echo -e "[$(date "+%Y-%m-%d %H:%M:%S")] 执行Chrome_On-Premise_VAPPVERSION.deb的prerm脚本结束\n"

应用容器的docker-compose文件

build/deb/opt/google/chrome/docker-compose.yml

  • 应用数据/var/google/chrome
  • 挂载docker.sockos-release是业务需要
version: "3.3"
x-appVersion: "1.0.0"
services:
  chrome-interface:
    image: 1.1.1.1/chrome-group/chrome-interface:latest
    container_name: chrome-interface
    restart: always
    volumes:
      - "/var/google/chrome/chrome-interface/data:/app/data"
      - "/var/google/chrome/chrome-interface/logs:/app/logs"
      - "./chrome-interface/configs:/app/configs"
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "/etc/os-release:/etc/os-release"
    ports:
      - "8000:8000"
    command:
      - "./server"
      - "-conf"
      - "./configs/config.yaml"
      - "-logLevel"
      - "info"

注册系统服务,设置开机启动

build/deb/usr/lib/systemd/system/chrome.service

[Unit]
Description=chrome
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/chrome-start.sh

[Install]
WantedBy=multi-user.target

build/deb/usr/local/bin/chrome-start.sh

#!/bin/bash

/usr/bin/docker compose --file /opt/google/chrome/docker-compose.yml create chrome-interface && /usr/bin/docker compose --file /opt/google/chrome/docker-compose.yml up -d

构建deb包

  1. 进入chrome/build目录

  2. 拷贝初始库到 deb 包(业务用到了本地数据库)

    cp -r ~/data/* deb/opt/google/chrome/chrome-interface/data

  3. 拷贝对应环境的配置文件到 deb 包

    cp ../deploy/interface/test/configs/* deb/opt/google/chrome/chrome-interface/configs

  4. 设置发布版本

    vim package-deb.sh

  5. 构建 deb 包

    ./package-deb.sh

安装或者更新 deb 包

dpkg -i Chrome_On-Premise_V1.0.0.deb

安装要求

  1. 内存至少 16G
  2. 磁盘空间至少 50G

查看已安装的 deb 包

dpkg -l|grep chrome

卸载 deb 包

  1. 卸载应用:dpkg -P chrome
  2. 删除本地数据:rm -rf /var/google/chrome
作者:Yuyy
博客:https://yuyy.info

评论

  1. ryan
    Macintosh Chrome
    9月前
    2023-9-08 16:05:48

    博主,你的网站证书过期了

    • Yuyy
      博主
      ryan
      Macintosh Chrome
      9月前
      2023-9-10 16:11:42

      感谢提醒,已处理

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇