首先描述一下我想实现的什么东西。以前我发版是通过命令手动打包打镜像,然后推送到仓储里面对,然后再在服务器上从仓库里面拉最新的镜像。然而我看VS里面项目其实有可以直接发布到自己的容器注册表(我理解就是容器仓库),所以就研究了研究

1、首先肯定是先准备一个项目,项目其实很简单,没什么特别的内容,唯一说明的一下是,因为我觉得既然使用了IOC,Web就不应该再依赖Service层,所以我的Web只引用了IService层,这导致的问题就是我的Service的dll文件我需要手动拷贝进web的bin目录下,为了简化操作,于是我写了两个脚本。一个Bat(Windows下使用)和一个sh文件(Linux使用)

在建项目的时候,开始我直接建立的Web项目,添加了dockerfile支持。后续在点击发布按钮的时候可以看到日志执行了docker的命令:

docker build -f "C:\Users\txb\source\repos\CBest.B2BSupply\CBest.B2BSupply.Web\Dockerfile" --force-rm -t cbestb2bsupplyweb  --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=CBest.B2BSupply.Web" "C:\Users\txb\source\repos\CBest.B2BSupply" 

 

如果直接新建的Web工程,它的工程环境会在web那一层里面所以导致的问题就是dockerfile里面的copy命令回找不到其他工程的工程文件。指定目录貌似也没有成功过,我也没找到这个命令在哪儿配置的。

所以我的做法是先新建解决方案。然后再解决方案里面添加各个工程项目。

 

build.cmd内容,主要内容是判断模式,如果debug就用dotnet build ,release模式就用dotpublish

echo off
if %1 == "Debug" (
    dotnet build -c %1 -o %2 ../CBest.B2BSupply.Service
)  else  (
    dotnet publish -c %1 -o %2 ../CBest.B2BSupply.Service
)
echo on

 Linux的脚本也差不多类似

echo "Linux bat buiding is starting"
if [$1 == "Debug"] then 
	dotnet build -c $1 -o $2 ../CBest.B2BSupply.Service
else   then
	dotnet publish -c $1 -o $2 ../CBest.B2BSupply.Service
fi

  以上的操作思路上一直没出现问题,唯一出现的问题就是再VS生成事件上的问题,因为Linux和windows的脚本语法不一样。所以我写了cmd和sh两个,我需要对操作系统判断执行那个脚本,好像这个在这里没法实现,于是我又想了一个曲线救国的办法。我写了一个小程序程序的主要功能就是判断当前运行的操作系统去执行不同的脚本程序

 class Program
    {
        static int Main(string[] args)
        {
            Console.WriteLine("ExcuteShell Is Running.......");
            if (args.Length < 1)
            {
                Console.WriteLine("无脚本文件");
                return 0;
            }
            string batName = Path.GetFileName(args[0]);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                batName = batName + ".cmd";
            }
            else
            {
                batName = batName + ".sh";
            }
            try
            {
                var startInfo = new ProcessStartInfo()
                {
                    FileName = batName,
                    CreateNoWindow = false
                };
                for (var i = 1; i < args.Length; i++)
                {
                    startInfo.ArgumentList.Add(args[i]);
                }
                Process process = new Process() { StartInfo = startInfo };
                process.Start();
                Console.WriteLine(process.ExitCode);
                Console.WriteLine(process.StandardOutput);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return 0;
            }
            Console.WriteLine("ExcuteShell Is Ending.......");
            return 0;
        }
    }

这里又遇到问题了。。编译生成单文件的exe要门用于Windows要么用于Linux必须指定什么identityName(具体忘记什么了).所以编译成Exe程序我又存在那个脚本的问题,一个Linux程序,一个Windows程序,还是没解决我的问题。编译成跨平台的dll文件,就需要一堆其他的文件,没有单个文件方便,所以没有好的办法,我选择了一个这种的办法。把工具生成以后放入解决方案的tools目录下(放在统一的目录也好找)

最终我的生成事件命令:

执行脚本的小程序接受三个参数,

     第一个是脚本名字,不用待后缀,根据操作系统判断回加上.cmd(windows下)和.sh(liinux下),

     后面的参数是脚本的所需要的参数。一个是编译的方式(Debug或Release),一个是生成的目标目录,就是web项目的目录

dotnet ../tools/excuteshell/ExcuteShell.dll $(ProjectPath)/pp $(ConfigurationName) $(TargetDir)

 

我后面才反应过来,既然都是使用dotnet命令,我干嘛不直接在生成事件里面写dotnet build命令,用个锤子的脚本啊。还写了一个没什么用处的小程序)

所以修改后的生成事件命令:

 

dotnet build -c $(ConfigurationName) -o $(TargetDir) ../CBest.B2BSupply.Service

 

2、工程文件搞定,然后就是发布的配置

     新建配置,选择Docker容器注册表,下一步

选择其他DOckers容器注册表,如果没有私有的容器仓库,可以选择Docker Hub,不过我想应该公司都有一个自己的容器仓库把。毕竟把项目放到其他外网不安全肯定是不安全的。

 

 配置完成容器地址,点击完成,发布的配置就结束了:

 

 用户名带上,密码根据你的仓储要不要密码,可写可不写,不带用户名,好像我是发布失败了

 满怀希望的点击publish,哦豁一连串的报错开始了,什么Copy找不到文件,什么编译找不到刚配置的脚本命令各种问题。简单说一下遇到得问题

遇到得第一个问题。就是在build dockerfile得时候里面会把代码拷贝到docker进行编译。在执行COPY指令得时候回提示找不到其他项目得文件。尝试了很多解决方法。指定相对目录,指定绝对目录都不行,

后面得解决方法是先建立解决方案文件再往解决方案里面添加工程文件。一试还真成功了

后面遇到得第二个问题就是sh和bat得问题。window只识别bat文件,Linux只识别sh文件。开始再overstack上看到一个大佬说不用添加后缀会根据操作系统自动查找项目下能够执行得脚本文件,尝试过。windows进行build是没问题得。但是当我点击VS上得publish得时候就会提示找不到脚本文件。我得解决方法就绕道了写程序来判断操作系统调用不同得脚本文件

第三个就是nuget还原得问题。巨慢而且还经常掉线。偶尔行偶尔不行得。这个就看人品了,我切换了一个国内nuget源,貌似好很多。具体操作就是再dockerfile里面执行还原项目得时候指定一下国内源就可以了。还有她们说访问私有源也可以通过这个方法呢。

RUN dotnet restore "CBest.B2BSupply.Web/CBest.B2BSupply.Web.csproj" -s "https://nuget.cdn.azure.cn/v3/index.json"

上面三个问题解决以后,这个架子就搭建得差不多了。。然后激动得点击了publish按钮。

反正有点耗时。特别耗时。不过成功了,也还是值得欣慰。一步操作编译,生成,构建镜像,发送镜像库,方便是方便。但是的确是慢。也许用jekins实现自动化会好点,当个研究也是好得。

posted on 2021-03-11 15:33  糖心碎糖  阅读(2618)  评论(0编辑  收藏  举报