• dotne发布运行


    一 HTTP Error 400. The request hostname is invalid.

    1. 在当前项目的工程路径下,找到.vs\config 文件夹下面的applicationhost.config 这个文件。
    2. 在找到applicationhost.config 文件后,打开,在文件中找到site 那个节点,修改bindings 属性,如下图所示;这其实给在iis中编辑绑定是一样的意思。
      在这里插入图片描述
    3. 具体修改的内容有几点注意的:
      a. 如果用实际公网域名
      , localhost 直接换成公网域名即可,vs不需要使用管理员权限打开
      b. 如果用自定义域名
      localhost 替换为自定义域名,如果是管理员权限打开不需要编辑系统的hosts文件,如果是普通权限打开,需要编辑hosts文件;
      我是win7系统,hosts文件在 C:\Windows\System32\drivers\etc 下面,是隐藏的,所以要从系统菜单-工具-文件夹选项-的显示中选择显示隐藏的文件夹。
      我在修改的时候,安装的杀毒软件小红伞阻止修改host,选择允许就可以保存了,不然会提示有其他文件正在打开,不让保存。
      c. 如果使用局域网ip
      将localhost 换成具体的ip即可,注意一定要用管理员权限打开vs。不然还是不能的。我是需要使用局域网ip,在此处新增了一条binding属性,如下图所示:
      在这里插入图片描述
    4. 修改完毕config后,重启下VS,重启的时候选择是否以管理员的身份运行

    二 .NET Core CLI Interface

      .NET Core CLI 概述
      使用.NET Core CLI 实现 .NET Core 入门

    1 CLI命令

      dotnet工具(称为驱动程序)作为cli命令的入口,能够接收并执行命令。同时,它可以选择要使用的cli的sdk版本,如果未指定版本,默认使用最新的sdk版本,如果要指定版本使用dotnet --fx-version 命令。

    2 常用命令

    dotnet --info
      查看当前安装的版本。
    指定项目使用的SDK版本
      dotnet new global.json --sdk-version ,要注意的是最后的参数是SDK版本,不是.NET Core版本。
    dotnet new
      用于创建一个新项目,关于项目类型,可以用命令:dotnet new --help查看。
    dotnet restore
      恢复项目的依赖项和工具。
      dotnet restore命令使用NuGet还原project.json文件中被指定的依赖项,以及特定于项目的工具。默认情况下,依赖项和工具的还原是并行完成的。
    对于依赖项,你可以在还原操作时使用–packages参数指定还原包的位置。
    如果没有指定,则默认使用NuGet包缓存。它可以在所有的操作系统上的用户目录下的.nuget/packages目录中找到(例如,Linux上的/home/user 或者是Wndows上的C:\Users\user)。Windows下可以使用%HOMEPATH%/.nuget/packages访问目录。
    对于特定项目的工具,,dotnet restore 首先还原该工具包,然后继续还原在项目文件中指定的工具依赖项。
    dotnet restore 选项如下。
    -s,–source[SOURCE]
    指定一个在还原操作期间使用的源。这覆盖所有在NuGet.config文件中指定的源。多个源可以通过多次指定该选项来提供。
    –packages[DIR]
    指定放置还原包的目录。
    –disable-parallel
    禁用并行还原多个项目。
    –configfile[FILE]
    用于还原操作的配置文件(NuGet.config)
    –verbosity[LEVEL]
    使用日志详细级别。允许的值:Debug,Verbose,Infomation,Minimal,Warning或者Error。
    可以使用dotnet restore -h 来查看命令的帮助。
    dotnet build

    #创建MVC工程
    [zebra Desktop]$mkdir work && cd work
    [zebra work]$dotnet new console -n Zebra.Liu.Console
    #添加Nuget包,这是添加了mysql的驱动包
    [zebra work]$cd Zebra.Liu.Console/
    [zebra Zebra.Liu.Console]$dotnet add package Pomelo.EntityFrameworkCore.MySql
    [zebra Zebra.Liu.Console]$ls
    Program.cs Zebra.Liu.Console.csproj  obj
    #编译工程,输出到build文件夹中
    [zebra Zebra.Liu.Console]$dotnet build -o build/
    [zebra Zebra.Liu.Console]$ls
    Program.cs Zebra.Liu.Console.csproj build obj
    #多了一个build文件夹,用于存放编译后的文件
    [zebra Zebra.Liu.Console]$ls build/
    Zebra.Liu.Console.dll  #二进制文件(中间语言IL)
    Zebra.Liu.Console.pdb  #symbol文件,用于调试
    Zebra.Liu.Console.deps.json # *.deps.json中列出应用程序的依赖项
    Zebra.Liu.Console.runtimeconfig.dev.json
    Zebra.Liu.Console.runtimeconfig.json # 指定共享运行时以其版本
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

      上面的试验可以看出build命令最后的产物,如果有项目使用了第三方的依赖,如像上面一样使用了NuGet中的MySQL驱动,那么在执行build命令时,只会从本机的NuGet缓存库中解析依赖项,也就是说,生成的dll文件,不包含MySQL的驱动。这样build的dll文件,从本机拷贝到另外的机器上,可能不能运行。如果要将依赖项也打包,可以使用另一个命令dotnet publish。
      publish命令和build命令最大的区别在于:publish命令将应用程序的依赖项,从NuGet缓存复制到输出文件夹中。
      build后的程序是否为可执行,主要看.csproj文件中的选项

    <!-- .csproj文件内容 -->
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <!--
          OutputType 输出类型设置为Exe,说明这个工程,可执行
          可执行的dll和不可执行的dll文件最大的区别在于,有没有入口点以及是否可执行
         -->
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.1</TargetFramework>
      </PropertyGroup>
    </Project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    dotnet watch run
      dotnet watch 是一个开发阶段在源文件发生变动的情况下使用 dotnet 命令的工具。 当代码发生变动的时候可以用来执行编译,运行测试,或者发布操作。
    dotnet clean
      清除上一个生成的输出,包括中间文件夹(obj)和最终输出文件夹(bin)中的文件
    dotnet sln
      使用dotnet sln命令,可以在*.sln,文件中添加,删除,获取项目。

    dotnet sln [] add  
    dotnet sln [] add 
    dotnet sln [] remove  
    dotnet sln [] remove 
    dotnet sln [] list
    
    • 1
    • 2
    • 3
    • 4
    • 5

      注意:dotnet sln命令只会对solution_name.sln文件中操作,要生成*.sln文件,可以使用dotnet new sln命令
    dotnet add/remove/list reference
      管理项目之间的引用关系

    # 项目1引用项目2
    [zebra work]$dotnet add 项目1 reference 项目2
    
    • 1
    • 2

    3 使用CLI创建多项目的解决方案

      本章将用cli,按照DDD的分层架构来创建包含多个项目的解决方案,方案的结构大致如下:

    # 工程目标结构
    - Shopping.sln
     |- Shopping.UI
     |- Shopping.Application
     |- Shopping.Domain
     |- Shopping.Infrastructure
    
    # 工程引用关系
    Shopping.UI
        |
        V
    Shopping.Application
        |           \
        V            \
    Shopping.Domain   \
        |              \
        V               V
    Shopping.Infrastructure
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

      脚本如下:

    # 创建目录
    [zebra ~]$mkdir Shopping && cd Shopping
    # 创建工程 UI为MVC类型,其余全部是classlib
    [zebra Shopping]$dotnet new mvc -n Shopping.UI
    [zebra Shopping]$dotnet new classlib -n Shopping.Application
    [zebra Shopping]$dotnet new classlib -n Shopping.Domain
    [zebra Shopping]$dotnet new classlib -n Shopping.Infrastructure
    # 添加工程之间的引用
    [zebra Shopping]$dotnet add Shopping.UI reference Shopping.Application
    [zebra Shopping]$dotnet add Shopping.Application reference Shopping.Domain
    [zebra Shopping]$dotnet add Shopping.Application reference Shopping.Infrastructure
    [zebra Shopping]$dotnet add Shopping.Domain reference Shopping.Infrastructure
    # 创建Shopping.sln文件,将工程文件加入到解决方案(.sln)文件中
    [zebra Shopping]$dotnet new sln -n Shopping
    [zebra Shopping]$dotnet sln add Shopping.*
    # 添加NuGet依赖包,这里以在Shopping.Infrastructure工程中添加MySQL驱动为例
    [zebra Shopping]$cd Shopping.Infrastructure/
    [zebra Shopping.Infrastructure]$dotnet add package Pomelo.EntityFrameworkCore.MySql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    4 使用CLI创建web项目

    dotnet new web
    dotnet run
    code .
    http://localhost:5000
    
    • 1
    • 2
    • 3
    • 4

    三 MSBuild

      MSBuild 是 Microsoft Build Engine 的缩写,MSBuild 是 Visual Studio 的生成系统。我们在VS中使用“生成解决方案”的背后就是依赖MSBuild来实现,但我们完全可以在cmd中使用MSBuild来完成应用的构建。
      它不仅仅是一个构造工具,应该称之为拥有相当强大扩展能力的自动化平台。MSBuild平台的主要涉及到三部分:执行引擎、构造工程、任务。其中最核心的就是执行引擎,它包括定义构造工程的规范,解释构造工程,执行“构造动作”;构造工程是用来描述构造任务的,大多数情况下我们使用MSBuild就是遵循规范,编写一个构造工程;MSBuild引擎执行的每一个“构造动作”就是通过任务实现的,任务就是MSBuild的扩展机制,通过编写新的任务就能够不断扩充MSBuild的执行能力。所以这三部分分别代表了引擎、脚本和扩展能力。
      MSBuild 在如何处理和生成软件方面是完全透明的,使开发人员能够在未安装 Visual Studio 的生成实验室环境中组织和生成产品。
      MSBuild 引入了一种新的基于 XML 的项目文件格式,这种格式容易理解、易于扩展并且完全受 Microsoft 支持。MSBuild 项目文件的格式使开发人员能够充分描述哪些项需要生成,以及如何利用不同的平台和配置生成这些项。另外,项目文件的格式还使开发人员能够创作可重用的生成规则,这些规则可以分解到不同的文件中,以便可以在产品内的不同项目之间一致地执行生成。以下各节描述了 MSBuild 项目文件格式的一些基本要素。

    1 构造工程(脚本文件)

      先说说构造工程,只要通过Notepad打开任何一个Visual Studio下的C#工程(csproj)文件,就知道构造工程到底是怎么回事了。

    
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <Root>$(MSBuildStartupDirectory)Root>
      PropertyGroup>
      <Target Name="Build">
        
        <ItemGroup>
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Common\Gimela.Common.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Infrastructure\Gimela.Infrastructure.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Management\Gimela.Management.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Security\Gimela.Security.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Tasks\Gimela.Tasks.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Text\Gimela.Text.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Net\Gimela.Net.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\ServiceModel\Gimela.ServiceModel.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Data\Gimela.Data.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Presentation\Gimela.Presentation.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Media\Gimela.Media.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Foundation\Streaming\Gimela.Streaming.sln" />
          <ProjectToBuild Include="$(Root)\..\src\Crust\Gimela.Crust.sln" />
        ItemGroup>
        <MSBuild Projects="@(ProjectToBuild)" Targets="Build" Properties="Configuration=Debug;">
          <Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
        MSBuild>
    
      Target>
    Project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

      在构造工程中我们可以定义和使用变量(通过Property/PropertyGourp/Item/ItemGroup等元素),可以使用条件分支(通过Choose/When/Otherwise等元素)、能够在运行时给变量赋值(通过执行任务,获取其返回类型参数的方式)、能够定义执行块(通过Target元素,相当于函数)、能够进行异常处理(通过OnError元素)、还可以复用已有工程定义的内容(通过Import元素)。拥有这些能力和高级语言已经相差无几了,所以笔者认为构造工程不是描述性语言,而是脚本语言。
      这里还需要强调一点的是,项目级元素(Property)可以在元素下定义,也可以在构造过程中作为外部参数传入,这是一个非常有用的特性,一般编译时选择配置项(Debug或者Release)就是利用这个特性实现的。

    2 Project元素

      这是每一个项目文件的最外层元素,它表示了一个项目的范围。如果缺少了这一元素,MSBuild会报错称Target元素无法识别或不被支持。
      Project元素拥有多个属性,其中最常用到的是DefaultTargets属性。我们都知道,在一个项目的生成过程中可能需要完成几项不同的任务(比如编译、单元测试、check-in到源代码控制服务器中等),其中每一项任务都可以用Target来表示。对于拥有多个Target的项目,你可以通过设置Project的DefaultTargets(注意是复数)属性来指定需要运行哪(几)个Target,如果没有这个设置,MSBuild将只运行排在最前面的那个Target。

    3 Property元素

      在项目中你肯定需要经常访问一些信息,例如需要创建的路径名、最终生成的程序集名称等。以name/value的形式添加进Property,随后就可以以$(PropertyName)的形式访问。这样你就无须为了改动一个文件名称而让整个项目文件伤筋动骨了。比如上面代码中的Bin就是将要创建的路径名称,而AssemblyName则是最终要生成的程序集名称。这些属性的名称不是固定的,你完全可以按自己的习惯来进行命名。在使用时,你需要把属性名称放在”$(“和”)”对内(不包括引号),以表示这里将被替换成一个Property元素的值。
      另外,如果Property元素数量比较多,你还可以把它们分门别类地放在不同的PropertyGroup里,以提高代码的可阅读性。这对Property本身没有任何影响。

    <PropertyGroup>
      <Configuration Condition=" '$(Configuration)' == '' ">DebugConfiguration>
      <Platform Condition=" '$(Platform)' == '' ">AnyCPUPlatform>
      <ProductVersion>8.0.30703ProductVersion>
      <SchemaVersion>2.0SchemaVersion>
      <ProjectGuid>{6C2561FB-4405-408F-B41B-ACE5E519A26E}ProjectGuid>
      <OutputType>LibraryOutputType>
      <AppDesignerFolder>PropertiesAppDesignerFolder>
      <RootNamespace>Gimela.Infrastructure.PatternsRootNamespace>
      <AssemblyName>Gimela.Infrastructure.PatternsAssemblyName>
      <TargetFrameworkVersion>v4.0TargetFrameworkVersion>
      <FileAlignment>512FileAlignment>
    PropertyGroup>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4 Item元素

      在整个项目文件中你肯定要提供一些可被引用的输入性资源(inputs)信息,比如源代码文件、引用的程序集名称、需要嵌入的图标资源等。它们应该被放在Item里,以便随时引用。语法是:
      其中Type属性可以被看作是资源的类别名称,比如对于.cs源文件,你可以把它们的Type都设置为Source,对于引用的程序集把Type都设置为Reference,这样在随后想引用这一类别的资源时只要引用这个Type就可以了,方法是@(TypeName)。可千万别和Property的引用方法弄混了。
    既然Type是资源的类名,那么Include就是具体的资源名称了,比如在上面的示例代码中,Include引用的就是C#源代码文件的名称。你也可以用使用通配符*来扩大引用范围。比如下面这行代码就指定了当前目录下的所有C#文件都可以通过@(Source)来引用:
      另外,你也可以通过与PropertyGroup类似的方法把相关的Item放在ItemGroup里。

    <ItemGroup>
      <Reference Include="System" />
      <Reference Include="System.Core" />
      <Reference Include="System.Data" />
      <Reference Include="System.ServiceModel" />
      <Reference Include="System.Xml" />
    ItemGroup>
    <ItemGroup>
      <Compile Include="Commands\CommandBase.cs" />
      <Compile Include="Commands\DuplexCommandBase.cs" />
      <Compile Include="Commands\ICommand.cs" />
      <Compile Include="Commands\IDuplexCommand.cs" />
      <Compile Include="Extensions\BitConverterExtensions.cs" />
      <Compile Include="Extensions\ConcurrentDictionaryExtensions.cs" />
      <Compile Include="Extensions\StopwatchExtensions.cs" />
      <Compile Include="Extensions\TimeSpanExtensions.cs" />
      <Compile Include="Flyweight\FlyweightObjectPool.cs" />
      <Compile Include="Singleton\StaticSingleton.cs" />
      <Compile Include="Properties\AssemblyInfo.cs" />
      <Compile Include="SmartQueue\ISmartQueueMapper.cs" />
      <Compile Include="SmartQueue\SmartQueue.cs" />
      <Compile Include="SmartQueue\SmartQueueBase.cs" />
      <Compile Include="SmartQueue\SmartQueueMapper.cs" />
      <Compile Include="UnitOfWork\IUnitOfWork.cs" />
      <Compile Include="UnitOfWork\IUnitOfWorkFactory.cs" />
      <Compile Include="UnitOfWork\UnitOfWork.cs" />
      <Compile Include="WeakActions\IWeakActionExecuteWithObject.cs" />
      <Compile Include="WeakActions\WeakAction.cs" />
      <Compile Include="WeakActions\WeakActionGeneric.cs" />
      <Compile Include="WeakFuncs\IWeakFuncExecuteWithObjectAndResult.cs" />
      <Compile Include="WeakFuncs\WeakFunc.cs" />
      <Compile Include="WeakFuncs\WeakFuncGeneric.cs" />
    ItemGroup>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    5 Target元素

      Target表示一个需要完成的虚拟的任务单元。每个Project可以包括一个或多个Target,从而完成一系列定制的任务。你需要给每个Target设置一个Name属性(同一Project下的两个Target不能拥有同样的Name)以便引用和区别。
      举例来说,在你的项目生成过程中可能需要完成三个阶段的任务:首先check-out源代码,接下来编译这些代码并执行单元测试,最后把它们check-in。那么通常情况下你可以创建三个不同的Target以清晰划分三个不同的阶段:

    <Target Name=”CheckOut” >Target>
    <Target Name=”Build”  DependsOnTargets=”CheckOut”> <Task Name=”Build”.../> <Task Name=”UnitTest” ... />Target>
    <Target Name=”CheckIn” DependsOnTargets=”CheckOut;Build”>Target>
    
    • 1
    • 2
    • 3

      这样,你就可以非常清晰地控制整个生成过程。为了反应不同Target之间的依赖关系(只有Check-in后才能编译,只有编译完成才可能Check-out……),你需要设置Target的DependsOnTargets属性(注意是复数),以表示仅当这些Target执行完成之后才能执行当前的Target。当MSBuild引擎开始执行某项Target时(别忘了Project的DefaultTargets属性),会自动检测它所依赖的那些Target是否已经执行完成,从而避免因为某个生成环节缺失而导致整个生成过程发生意外。
      你可以通过Project的DefaultTargets属性指定MSBuild引擎从哪(几)个Target开始执行,也可以在调用MSBuild.exe时使用t开关来手动指定将要运行的Target,方法如下:MSBuild /t:CheckOut 这样,只有CheckOut(以及它所依赖的Target,在上文中没有)会被执行。

    6 Task元素

      这可能是整个项目文件中最重要的,因为它才是真正可执行的部分(这也是为什么我在上面说Target是虚拟的)。你可以在Target下面放置多个Task来顺序地执行相应的任务。

    四 发布

    1 ASP.NET Core Web Api发布到Linux(CentOS 7 64)

      在Linux上安装需要的环境,然后将上面成功运行的项目发布:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
      将文件夹拷贝到linux下,进入文件夹运行:dotnet WebApplication1.dll

    2 linux下ASP.Net core打包docker镜像

      在上面发布的core2.2版本文件夹下面创建名称为Dockerfile的文件,内容:

    FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
    EXPOSE 8080
    
    WORKDIR /app
    COPY . /app
    ENTRYPOINT ["dotnet", "WebApplication1.dll"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      对于core3版本:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    EXPOSE 80
    COPY . /app
    ENTRYPOINT ["dotnet", "demoapi.dll"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

      FROM是指定该镜像的运行环境;然后指定容器映射端口8080;最后dotnet运行项目。
      把目录文件通过dockerfile加载到docker镜像:docker build -t gateway:1.0 .
      调用命令 docker images 会发现已经有这个镜像了。
    在这里插入图片描述
      最后,运行镜像:docker run -p 8080:8080 testsite:1.0(8080:8080表示的是容器内端口映射容器外端口)。

    3 vs2019创建docker支持

      选中"启用Docker支持“,这样可以自动生成Dockerfile文件,这个文件是用来生成Docker镜像;如果没有选中"启用Docker支持“,也可在项目生成后,右击项目-添加-Docke支持;
      选择Docker运行系统,代码编写阶段Dockerfile文件可以随意修改和删除,使用Docker调试或生成镜像时重新添加一个就行了。
    在这里插入图片描述
      生成了Dockerfile文件。生成的内容一大堆,在不修改情况下使用VS自带的Docker运行没有问题,但部署时却有麻烦,简化一下就行了;

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    COPY . .
    ENTRYPOINT ["dotnet", "SamruoFrame.Service.Cache.Redis.dll"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      Dockerfile文件默认在发布时不会复制到发布文件夹中,属性修改为:始终复制。

    4 编辑程序并生成镜像

      程序以正常发布生成,使用”文件夹”模式,以上几个发布方式需要Azure,本文不涉及此内容(主要是没钱)
    在这里插入图片描述
      生成镜像有多种方式,我使用本地生成;进入发布目录,运行Powershell,使用命令行生成镜像

    docker build -t samruo/redis:1.1 .
    
    //语法:docker build [OPTIONS] PATH | URL | -
    //--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
    //需要注意的是 1:name不能用大写;2:语句最后必须加“ .” 且前面要有一个空格。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
      这里出现了一个错误信息:
      SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have ‘-rwxr-xr-x’ permissions. It is recommended to double check and reset permissions for sensitive files and directories.
      经查是因为我在Windows下生成,但将使用在Linux下,所以有个目录权限问题。考虑到我的程序只用来做服务,且采用集群,不会在本地保存文件,理论上不会有此问题,就先使用这个方法。

    5 将镜像放到阿里仓库

      为方便集群化部署,以及后继运维方便,将镜像放到仓库中是个好办法。实现Docker仓库的方法有很多,国内和国外都的,Docker Hub速度太慢,我使用阿里的镜像仓库,因为本身服务器是在阿里云。
      首先要有个阿里云帐号;登录后进入控制台,搜索”容器镜像服务“,首次使用需要开通服务,根据阿里云的使用经验,貌似使用容器镜像服务免费,还有个”弹性容器实例ECI“是需要收费的,其实就是个Docker,按秒计费的。
      第一步:创建命名空间
    在这里插入图片描述
      第二步:创建镜像仓库
    在这里插入图片描述
      仓库创建后,点击仓库名称进入详情页
    在这里插入图片描述

    6 上传镜像和版本更新

      1、 登录阿里云Docker Registry

    sudo docker login --username=【这里是阿里云登录帐号】 registry.cn-hangzhou.aliyuncs.com
    
    • 1

    在这里插入图片描述
      2、将镜像推送到Registry

    sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/samruo_docker/redis:[镜像版本号]
    sudo docker push registry.cn-hangzhou.aliyuncs.com/samruo_docker/redis:[镜像版本号]
    
    • 1
    • 2

      正确执行命令后,镜像将出现在”镜像版本“之中;
    在这里插入图片描述
      版本更新只需要修改命令行后面的”镜像版本号“即可,非常简单。到此,镜像仓库部署完成。

    7 在Linux的Docker中使用镜像

      建立了镜像后在部署操作将非常简单。执行以下命令前需要执行登录操作,见上节上传镜像,如已登录则无需执行。

    //从Registry中拉取镜像,在一台服务器中,同一个版本的镜像只需要拉取一次即可
    docker pull registry.cn-hangzhou.aliyuncs.com/samruo_docker/redis:[镜像版本号]
    
    • 1
    • 2

    在这里插入图片描述

    //部署镜像
    //语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    
     docker run --name samruo-redis-1 -d -p 5902:80 registry.cn-hangzhou.aliyuncs.com/samruo_docker/redis:1.1
    
    // --name="nginx-lb": 为容器指定一个名称;
    // -d: 后台运行容器,并返回容器ID;
    // -p: 指定端口映射,格式为:主机(宿主)端口:容器端口;这里和80端口与Dockerfile文件中的EXPOSE 80对应;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
      在同一台宿主服务器上只要”主机(宿主)端口“不重复,可以部署多个同一镜像,不会相互干扰,这也将用于集群化需求。成功执行后将只返回容器ID;
      查看镜像部署情况:docker ps -a
    在这里插入图片描述

    8 参考

      微软文档:ASP.NET Core 的 Docker 映像

    9 使用VS2019发布镜像到Docker仓库

      1.Dockerfile完全不需要修改,可保持自动创建时的内容.EXPOSE可根据开放端口不同,自行调整.
      2.使用"发布"->“容器注册表”:首次发布需要创建发布模板,如下:
    在这里插入图片描述
      在下图中填写阿里容器仓库地址:
      格式为:https://服务区域地址/命名空间 (具体见自己开通仓库的公网地址)
      注意不要填写仓库名称,仓库名称VS将自动补充,也就是项目名称,这也是唯一于手工上传相比不可控之处.
      填写用户名和密码,好像没什么用,最好在上传时,以代码登录一下.见以下内容.
    在这里插入图片描述
      保存后分发镜像模板就完成了,以后只要点击发布就能自动上传到私有仓库中.
    在这里插入图片描述
      每次发布镜像最好区分版本号,见上图"图像标记"(话说这翻译也是够直接),修改上图所未标记后,点击"发布"即可.
      VS自动创建的Dockerfile文件有20行,发布需要点时间,这时可以打开PowerShell 运行 登录阿里云Docker Registry命令:$ sudo docker login --username=[阿里帐号] registry.cn-hangzhou.aliyuncs.com
      我这里执行手动登录的原因,是遇到发布时提示帐号验证错误,应该是VS调用本地Docker Desktop来执行上传,但Docker Desktop本身未登录,所以会执行出错.
      好了,现在每次发布新的版本只需要点一下"发布"并修改一下版本号,就可以方便的更新程序镜像了。

    10 串口映射到docker

      将物理机的串口映射到容器中去:docker run --rm -it --device /dev/ttyS1:/dev/ttyS0 ubuntu:14.04 /bin/sh
      将物理机的串口映射到Web镜像容器中去:docker run --rm -it --device /dev/ttyS1:/dev/ttyS0 -p 9600:9694 gateway:1.0

  • 相关阅读:
    k8s 灰度发布(未完)
    整理SpringBoot整合MyBatisPlus+Dubbo问题解决方法
    GameStop NFT 市场分析
    docker的再定义镜像和上传阿里云
    【ONE·R || R与C++混合编程简单介绍 】
    flink技术总结待续
    swiper第一个、最后一个滑块按钮disabled时(.swiper-button-disabled),点击触发下层点击事件的问题
    axios的安装使用
    打patch 命令
    三、搭建 VLC,实战点播功能
  • 原文地址:https://blog.csdn.net/essity/article/details/114141026