From 23c0301c6799a1d35a9ea42276153d203c6414e6 Mon Sep 17 00:00:00 2001 From: zh3305 Date: Mon, 16 Dec 2024 10:10:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(deploy):=E4=BF=AE=E5=A4=8Ddocker=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E8=84=9A=E6=9C=AC=E6=B7=BB=E5=8A=A0=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=92=8C=E5=A4=9A=E9=98=B6=E6=AE=B5=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除对ubuntu-zlm-ffmpeg-dotnet.tar 的依赖,重新编译zlm-ffmpeg镜像,修复新版本不支持旧的zlm的问题. - 新增 Dockerfile-zlmediakit,用于构建基础镜像 - 重构 Dockerfile-Keeper,使用多阶段构建优化镜像大小 - 添加 deploy.ps1 部署脚本,实现 keeper 和 web 服务的构建、部署和运行 - 脚本支持发布镜像到指定仓库,并添加版本标签 - 优化配置文件处理,从容器中复制配置到宿主机 --- Dockerfile-Keeper | 39 +++++-- Dockerfile-zlmediakit | 75 ++++++++++++ deploy.ps1 | 259 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+), 10 deletions(-) create mode 100644 Dockerfile-zlmediakit create mode 100644 deploy.ps1 diff --git a/Dockerfile-Keeper b/Dockerfile-Keeper index 21b2496..3255111 100644 --- a/Dockerfile-Keeper +++ b/Dockerfile-Keeper @@ -1,19 +1,38 @@ -#(author):Զ(auto-chang) -#΢ź(WeChat):Զ(auto-chang) -#ں(WeChat official account)˸Ƽ(IT-chang) -#ʱ(Time)2023422գ(Saturday, April 22, 2023) -#(DescribeΪ(Power Generation for Love) +# 使用我们的基础镜像 +FROM zlmediakit-dotnet AS keeper -FROM ubuntu-zlm-ffmpeg-dotnet AS keeper +# 设置工作目录 WORKDIR /root/src + +# 复制项目文件 COPY . . + +# 创建必要的目录 RUN mkdir -p /root/AKStreamKeeper + +# 设置工作目录到项目目录 WORKDIR /root/src/AKStreamKeeper -RUN ln -s $HOME/dotnet/dotnet /usr/bin/dotnet -f -RUN dotnet build "AKStreamKeeper.csproj" -c Release -o /app/build -RUN dotnet publish "AKStreamKeeper.csproj" -c Release -o /app/publish + +# 构建项目 +RUN dotnet build "AKStreamKeeper.csproj" -c Release -o /app/build +RUN dotnet publish "AKStreamKeeper.csproj" -c Release -o /app/publish + +# 暴露必要的端口 EXPOSE 80 EXPOSE 443 EXPOSE 6880 -RUN mv /app/publish/* /root/AKStreamKeeper + +# 移动编译后的文件到目标目录 +RUN mv /app/publish/* /root/AKStreamKeeper + +# 更新配置文件中的路径 +RUN sed -i 's|"MediaServerPath": "[^"]*"|"MediaServerPath": "/opt/media/bin/MediaServer"|' /root/AKStreamKeeper/Config/AKStreamKeeper.json && \ + sed -i 's|"FFmpegPath": "[^"]*"|"FFmpegPath": "/usr/bin/ffmpeg"|' /root/AKStreamKeeper/Config/AKStreamKeeper.json + +# 启动 MediaServer 并等待 5 秒后终止 +RUN nohup /opt/media/bin/MediaServer & \ + sleep 5 && \ + pkill MediaServer || true + +# 设置工作目录 WORKDIR /root/AKStreamKeeper \ No newline at end of file diff --git a/Dockerfile-zlmediakit b/Dockerfile-zlmediakit new file mode 100644 index 0000000..6825189 --- /dev/null +++ b/Dockerfile-zlmediakit @@ -0,0 +1,75 @@ +FROM zlmediakit/zlmediakit:master AS zlmediakit + +# 使用 ubuntu 20.04 作为基础镜像 +FROM ubuntu:20.04 + +# 设置环境变量 +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Asia/Shanghai + +# 复制 ZLMediaKit 相关文件 +COPY --from=zlmediakit /opt/media/bin/MediaServer /opt/media/bin/ +COPY --from=zlmediakit /opt/media/bin/default.pem /opt/media/bin/ +COPY --from=zlmediakit /opt/media/conf/config.ini /opt/media/conf/ +COPY --from=zlmediakit /opt/media/bin/www/ /opt/media/bin/www/ + + +# 安装基础包和依赖 +RUN apt-get update && apt-get install -y apt-transport-https ca-certificates && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + wget \ + software-properties-common \ + curl \ + gnupg \ + lsb-release \ + tzdata \ + libssl-dev \ + ffmpeg \ + gcc \ + g++ \ + gdb && \ + ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ + echo $TZ > /etc/timezone && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# 安装 Microsoft 包签名密钥和源 +RUN wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + rm packages-microsoft-prod.deb + +# 安装 .NET SDK 和运行时 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + dotnet-sdk-6.0 \ + net-tools \ + aspnetcore-runtime-6.0 && \ + # 清理 apt 缓存 + apt-get autoremove -y && \ + apt-get clean -y && \ + rm -rf /var/lib/apt/lists/* + +# 设置工作目录和环境变量 +WORKDIR /opt/media/bin +ENV PATH=/opt/media/bin:$PATH + +# 暴露服务端口 +# RTMP 端口 +EXPOSE 1935 +# RTSP 端口 +EXPOSE 554 +# HTTP 端口 +EXPOSE 80 +# HTTPS 端口 +EXPOSE 443 +# RTP 端口 +EXPOSE 10000/tcp +EXPOSE 10000/udp +# 其他端口 +EXPOSE 8000/tcp +EXPOSE 8000/udp +EXPOSE 9000/udp + +# 启动命令 +CMD ["./MediaServer","-s", "default.pem", "-c", "../conf/config.ini", "-l","0"] \ No newline at end of file diff --git a/deploy.ps1 b/deploy.ps1 new file mode 100644 index 0000000..519f654 --- /dev/null +++ b/deploy.ps1 @@ -0,0 +1,259 @@ +param ( + [Parameter()] + [switch]$keeper, + [switch]$web, + [switch]$dk, + [switch]$dw, + [switch]$rw, + [switch]$rk, + [switch]$help, + [switch]$publish, # 是否发布镜像 + [string]$registry = "", # 镜像仓库地址,默认为空 + [string]$version = "latest" # 版本标签,默认为latest +) + +$APP_KEEPER_NAME = "ak-keeper" +$APP_WEB_NAME = "ak-web" +$BASE_IMAGE_NAME = "zlmediakit-dotnet" + +function Show-Usage { + Write-Host "Usage: .\deploy.ps1" + Write-Host " -keeper : install keeper" + Write-Host " -web : install Web" + Write-Host " -dk : deploy keeper" + Write-Host " -dw : deploy Web" + Write-Host " -rw : run Web" + Write-Host " -rk : run keeper" + Write-Host " -help : show this help" + Write-Host " -publish : publish images (.\deploy.ps1 -keeper -web -publish -registry ""xxx"" -version ""1.0.0"")" + Write-Host " -registry : registry address (default: empty)" + Write-Host " -version : version tag (default: latest)" + exit 1 +} + +if ($args.Count -eq 0 -and -not ($keeper -or $web -or $dk -or $dw -or $rw -or $rk -or $help)) { + Show-Usage +} + +if ($help) { + Show-Usage +} + + +# 简化的发布函数 +function Publish-Image { + param ( + [string]$imageName, + [string]$registry, + [string]$version + ) + + # 构建目标镜像名称 + $targetImage = $imageName + if (![string]::IsNullOrEmpty($registry)) { + $targetImage = "${registry}/${imageName}" + } + $targetImage = "${targetImage}:${version}" + + # 标记镜像 + Write-Host "Tagging image as ${targetImage}..." + docker tag $imageName $targetImage + + # 推送镜像 + Write-Host "Pushing image ${targetImage}..." + docker push $targetImage + + if ($LASTEXITCODE -eq 0) { + Write-Host "Successfully published ${targetImage}" -ForegroundColor Green + } + else { + Write-Host "Failed to publish image ${targetImage}" -ForegroundColor Red + exit 1 + } +} +# 在主逻辑中添加发布功能 +if ($publish) { + Write-Host "Publishing images..." + + if ($keeper -or $dk -or $rk) { + Write-Host "Publishing keeper image..." + Publish-Image -imageName $APP_KEEPER_NAME -registry $registry -version $version + } + + if ($web -or $dw -or $rw) { + Write-Host "Publishing web image..." + Publish-Image -imageName $APP_WEB_NAME -registry $registry -version $version + } + # 发布基础镜像 + Write-Host "Publishing base image..." + Publish-Image -imageName $BASE_IMAGE_NAME -registry $registry -version $version +} + +# 添加一个用于从容器复制配置文件的函数 +function Copy-ConfigFromContainer { + param ( + [string]$configType + ) + + if ($configType -eq "keeper") { + # 创建临时容器 + Write-Host "Creating temporary keeper container..." + docker create --name temp-keeper $APP_KEEPER_NAME + + # 创建本地目录 + $targetDir = "$PWD/Docker/AKStreamKeeperConfig" + if (-not (Test-Path $targetDir)) { + New-Item -ItemType Directory -Path $targetDir -Force + } + + # 从容器中复制配置文件 + Write-Host "Copying keeper config files from container..." + docker cp "temp-keeper:/root/AKStreamKeeper/Config/AKStreamKeeper.json" "$targetDir/" + docker cp "temp-keeper:/root/AKStreamKeeper/Config/logconfig.xml" "$targetDir/" + docker cp "temp-keeper:/opt/media/bin/config.ini" "$targetDir/" + + # 删除临时容器 + docker rm temp-keeper + Write-Host "Keeper config files copied to $targetDir" + } + elseif ($configType -eq "web") { + # 创建临时容器 + Write-Host "Creating temporary web container..." + docker create --name temp-web $APP_WEB_NAME + + # 创建本地目录 + $targetDir = "$PWD/Docker/AKStreamWebConfig" + if (-not (Test-Path $targetDir)) { + New-Item -ItemType Directory -Path $targetDir -Force + } + + # 从容器中复制配置文件 + Write-Host "Copying web config files from container..." + docker cp "temp-web:/app/Config/AKStreamWeb.json" "$targetDir/" + docker cp "temp-web:/app/Config/SipClientConfig.json" "$targetDir/" + docker cp "temp-web:/app/Config/SipServerConfig.json" "$targetDir/" + docker cp "temp-web:/app/Config/logconfig.xml" "$targetDir/" + + # 删除临时容器 + docker rm temp-web + Write-Host "Web config files copied to $targetDir" + } +} + + +Write-Host "Welcome to the AKStream(c# NetCore Programming Language)" + +if ($keeper) { + Write-Host "You have chosen to install keeper" + + # 首先构建基础镜像 + Write-Host "Building base ZLMediaKit with .NET image..." + docker build -f Dockerfile -t $BASE_IMAGE_NAME . + + if ($LASTEXITCODE -eq 0) { + Write-Host "Base image built successfully, now building keeper..." + docker build -f Dockerfile-Keeper -t $APP_KEEPER_NAME . + } + else { + Write-Host "Failed to build base image. Please check the Dockerfile and try again." + exit 1 + } +} + +if ($web) { + Write-Host "You have chosen to install Web" + docker build -f Dockerfile-Web -t $APP_WEB_NAME . +} + +if ($dk) { + Write-Host "You have chosen to deploy keeper" + + # 首先复制配置文件 + Copy-ConfigFromContainer -configType "keeper" + docker ps | Where-Object { $_ -match $APP_KEEPER_NAME } | ForEach-Object { docker stop ($_ -split "\s+")[0] } + docker ps -a | Where-Object { $_ -match $APP_KEEPER_NAME } | ForEach-Object { docker rm ($_ -split "\s+")[0] } + + docker run -p 6880:6880 ` + -p 10001-10010:10001-10010 ` + -p 10001-10010:10001-10010/udp ` + -p 20002-20200:20002-20200 ` + -p 20002-20200:20002-20200/udp ` + -p 80:80 ` + -p 1935:1935 ` + -p 554:554 ` + -p 554:554/udp ` + -p 10000:10000 ` + -p 10000:10000/udp ` + -p 8000:8000/udp ` + -p 30000-30035:30000-30035/udp ` + -v "$PWD/Docker/AKStreamKeeperConfig/AKStreamKeeper.json:/root/AKStreamKeeper/Config/AKStreamKeeper.json" ` + -v "$PWD/Docker/AKStreamKeeperConfig/logconfig.xml:/root/AKStreamKeeper/Config/logconfig.xml" ` + -v "$PWD/Docker/AKStreamKeeperConfig/config.ini:/opt/media/bin/config.ini" ` + --name=$APP_KEEPER_NAME ` + --restart=always ` + -d $APP_KEEPER_NAME ` + dotnet AKStreamKeeper.dll +} + +if ($rk) { + Write-Host "You have chosen to run keeper" + # 首先复制配置文件 + Copy-ConfigFromContainer -configType "keeper" + + docker run --rm -it -p 6880:6880 ` + -p 10001-10010:10001-10010 ` + -p 10001-10010:10001-10010/udp ` + -p 20002-20200:20002-20200 ` + -p 20002-20200:20002-20200/udp ` + -p 80:80 ` + -p 1935:1935 ` + -p 554:554 ` + -p 554:554/udp ` + -p 10000:10000 ` + -p 10000:10000/udp ` + -p 8000:8000/udp ` + -p 30000-30035:30000-30035/udp ` + -v "$PWD/Docker/AKStreamKeeperConfig/AKStreamKeeper.json:/root/AKStreamKeeper/Config/AKStreamKeeper.json" ` + -v "$PWD/Docker/AKStreamKeeperConfig/logconfig.xml:/root/AKStreamKeeper/Config/logconfig.xml" ` + --name=$APP_KEEPER_NAME ` + $APP_KEEPER_NAME ` + bash +} + +if ($dw) { + Write-Host "You have chosen to deploy Web" + + # 首先复制配置文件 + Copy-ConfigFromContainer -configType "web" + docker ps | Where-Object { $_ -match $APP_WEB_NAME } | ForEach-Object { docker stop ($_ -split "\s+")[0] } + docker ps -a | Where-Object { $_ -match $APP_WEB_NAME } | ForEach-Object { docker rm ($_ -split "\s+")[0] } + + docker run -p 5800:5800 ` + -p 5060:5060 ` + -p 5060:5060/udp ` + -v "$PWD/Docker/AKStreamWebConfig/AKStreamWeb.json:/app/Config/AKStreamWeb.json" ` + -v "$PWD/Docker/AKStreamWebConfig/SipClientConfig.json:/app/Config/SipClientConfig.json" ` + -v "$PWD/Docker/AKStreamWebConfig/SipServerConfig.json:/app/Config/SipServerConfig.json" ` + -v "$PWD/Docker/AKStreamWebConfig/logconfig.xml:/app/Config/logconfig.xml" ` + --name=$APP_WEB_NAME ` + --restart=always ` + -d $APP_WEB_NAME +} + +if ($rw) { + Write-Host "You have chosen to run Web" + # 首先复制配置文件 + Copy-ConfigFromContainer -configType "web" + docker run -p 5800:5800 ` + -p 5060:5060 ` + -p 5060:5060/udp ` + -v "$PWD/Docker/AKStreamWebConfig/AKStreamWeb.json:/app/Config/AKStreamWeb.json" ` + -v "$PWD/Docker/AKStreamWebConfig/SipClientConfig.json:/app/Config/SipClientConfig.json" ` + -v "$PWD/Docker/AKStreamWebConfig/SipServerConfig.json:/app/Config/SipServerConfig.json" ` + -v "$PWD/Docker/AKStreamWebConfig/logconfig.xml:/app/Config/logconfig.xml" ` + --name=$APP_WEB_NAME ` + --restart=always ` + -d $APP_WEB_NAME +} + +Write-Host "Successful script execution, best wishes for you" \ No newline at end of file