.Net Core in Docker极简入门(下篇)
<p>Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章。</p><p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>前言</li><li>开始<ul><li>Docker-Compose<ul><li>代码修改</li><li>yml file</li><li>up & down</li></ul></li><li>镜像仓库</li></ul></li><li>最后</li></ul></div><p></p>
<h1 id="前言">前言</h1>
<p>上一篇【.Net Core in Docker极简入门(上篇)】讲解了docker的一些基本命令和操作,并成功构建了自己的asp.net core web应用的镜像,启动容器。本篇继续。</p>
<h1 id="开始">开始</h1>
<p>上一篇的项目例子非常简单,通常我们的实际项目要复杂的多。项目中会依赖各种组件服务,比如数据库,MQ,缓存等等。这就会涉及到多个容器,如果手动用docker命令去一个一个的启动就很麻烦了,那么这时候就可以使用Docker-Compose来完成多个容器的管理。</p>
<h2 id="docker-compose">Docker-Compose</h2>
<p>什么是Docker Compose?</p>
<blockquote>
<p>Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。</p>
</blockquote>
<p>简单来理解,Compose类似一个批量工具,可以执行一组命令,支持批量构建镜像,批量启动容器,批量删除容器等等功能。</p>
<p>Windows的Docker Desktop中已经包括了Compose,Linux下Compose则需要单独安装一下。</p>
<p>下面在项目中添加一些数据库操作的相关代码便于测试,使用EF Core+SQL Server。</p>
<h3 id="代码修改">代码修改</h3>
<p>安装EF Code相关的包:</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721113041488-941061223.png" alt="" loading="lazy"></p>
<p>修改代码:</p>
<pre><code class="language-csharp">public class WeatherForecast
{
public int Id { get; set; }
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF { get; set; }
public string Summary { get; set; }
}
</code></pre>
<pre><code class="language-csharp">public class DemoContext : DbContext
{
public DemoContext(DbContextOptions<DemoContext> options)
: base(options)
{
}
public DbSet<WeatherForecast> WeatherForecasts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//初始化种子数据
modelBuilder.Entity<WeatherForecast>().HasData(new WeatherForecast
{
Id = 1,
Date = DateTime.Now,
Summary = "none",
TemperatureC = 20,
TemperatureF = 32 + (int)(20 / 0.5556)
}, new WeatherForecast
{
Id = 2,
Date = DateTime.Now.AddDays(1),
Summary = "none",
TemperatureC = 25,
TemperatureF = 32 + (int)(25 / 0.5556)
});
}
}
</code></pre>
<pre><code class="language-csharp">public class Startup
{
......
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<DemoContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DemoContext")));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DemoContext context)
{
//自动迁移
context.Database.Migrate();
......
}
}
</code></pre>
<pre><code class="language-csharp">public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
private readonly DemoContext _context;
public WeatherForecastController(ILogger<WeatherForecastController> logger, DemoContext context)
{
_logger = logger;
_context = context;
}
public IEnumerable<WeatherForecast> Get()
{
return _context.WeatherForecasts.ToArray();
}
}
</code></pre>
<p>appsettings.json添加数据库连接字符串配置:</p>
<pre><code class="language-json">{
......
"ConnectionStrings": {
"DemoContext": "Server=sql-server;Database=DemoDB;User Id=sa;Password=Password@2020;"
}
}
</code></pre>
<p>注意:Server=sql-server,这个sql-server是需要在docker-compose.yml中定义的,下面再说。</p>
<p>添加迁移:</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721144943560-1897298717.png" alt="" loading="lazy"></p>
<h3 id="yml-file">yml file</h3>
<p>右键项目-添加-容器业务流程协调程序支持</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721095027287-1541923640.png" alt="" loading="lazy"></p>
<p>添加后会生成docker-compose相关文件:</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721145135508-2012645134.png" alt="" loading="lazy"></p>
<p>其中的docker-compose.yml文件需要修改一下:</p>
<pre><code class="language-yaml">version: '3.4'
services:
webapplication1:
image: ${DOCKER_REGISTRY-}webapplication1
build:
context: .
dockerfile: WebApplication1/Dockerfile
ports:
- '5000:80'
networks:
- my-net
depends_on:
- sql-server
sql-server:
image: mcr.microsoft.com/mssql/server:2019-CU5-ubuntu-18.04
ports:
- '1434:1433'
environment:
ACCEPT_EULA: Y
SA_PASSWORD: Password@2020
networks:
- my-net
networks:
my-net:
driver: bridge
</code></pre>
<p>services下定义了2个服务webapplication1、sql-server,相当于2个容器。webapplication1是基于WebApplication1/Dockerfile构建的镜像${DOCKER_REGISTRY-}webapplication1来启动,depends_on用于指定依赖的服务,这里的webapplication1服务依赖于sql-server服务。networks用于指定网络,因为docker中容器之间默认是无法直接通信的,这里创建了一个bridge模式的网络my-net,webapplication1和sql-server都在my-net网络中,那么他们之间就可以通过服务名来通信。所以在上面webapplication1的数据库连接字符串中就可以写:Server=sql-server。通常数据库的数据目录会挂载到主机上,防止容器发生意外导致数据丢失。</p>
<p>上一篇有小伙伴问容器内能不能访问容器外的数据库,这个是可以访问的。访问宿主机的话直接用IP访问就可以,或者用<code>host.docker.internal</code>,这个host.docker.internal是docker安装时会写入到你的hosts文件里的一个主机名,实际还是指向你的主机IP。</p>
<p>以上的yml内容还是比较简单,yml文件是使用Compose必不可少的,语法可以自行学习一下。掌握其语法关键字后,你就可以在docker-compose.yml文件中定义更复杂的环境。</p>
<h3 id="up--down">up & down</h3>
<p>来到项目根目录,启动PowerShell或cmd执行docker命令。</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721153646176-1760174103.png" alt="" loading="lazy"></p>
<p>执行<code>docker-compose up</code>,也可以加-d参数,让他在后台运行</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721153830988-2058859466.png" alt="" loading="lazy"></p>
<p>启动完成后,浏览器访问:http://localhost:5000/weatherforecast</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721154058075-1491616276.png" alt="" loading="lazy"></p>
<p>成功。这里省略了<code>docker-compose build</code>命令,你也可以在up前先执行build。</p>
<p>docker-compose是不是很方便呢,即使你的系统环境部署再复杂,也只需要一个up指令。</p>
<p>如果你想摧毁这个环境只需要执行<code>docker-compose down</code>即可</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721155008767-597745884.png" alt="" loading="lazy"></p>
<p>同样的,以上操作也可以直接在vs2019中完成,无需手动执行指令,只需要将docker-compose项目设为启动项,然后直接运行即可,还支持代码调试哦。不过由于网络等问题,可能会遇到一些坑。。。</p>
<h2 id="镜像仓库">镜像仓库</h2>
<p>我们也可以把自己的镜像推送到远程仓库,然后在其他机器上直接就能通过命令拉取了。国内阿里云之类的都有docker镜像仓库服务,也可以搭建私有仓库,本文就推送到docker的官方仓库docker hub。首先需要在docker官网https://www.docker.com/注册账号。</p>
<p>重新构建镜像:<code>docker build -t xhznl/webapp1 -f ./WebApplication1/Dockerfile .</code></p>
<p>其中xhznl是我的docker用户名。</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721200613757-1841259185.png" alt="" loading="lazy"></p>
<p>登录docker:<code> docker login</code>,输入自己的用户名密码。</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721200744941-1546213685.png" alt="" loading="lazy"></p>
<p>登录成功后即可推送镜像,执行:<code>docker push xhznl/webapp1</code></p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721200943979-977254262.png" alt="" loading="lazy"></p>
<p>推送成功,在docker官网可以查看镜像:</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200721201025080-134863490.png" alt="" loading="lazy"></p>
<p>这样在其他机器的docker中也可以通过<code>docker pull xhznl/webapp1</code>来拉取这个镜像。</p>
<p>修改docker-compose.yml文件,将webapplication1服务的image改为xhznl/webapp1,然后把这个docker-compose.yml文件放到任何装有docker的机器上,只需执行<code>docker-compose up</code>,即可启动程序的所有环境,是不是很神奇。</p>
<pre><code class="language-yaml">services:
webapplication1:
image: xhznl/webapp1
ports:
- '5000:80'
networks:
- my-net
depends_on:
- sql-server
</code></pre>
<p>最后推荐一波vs code,安装docker相关插件,无论是编写yml文件还是管理docker都很方便, 很多操作都不用手敲命令啦。。。</p>
<p><img src="https://img2020.cnblogs.com/blog/610959/202007/610959-20200722100153719-1559793559.png" alt="" loading="lazy"></p>
<h1 id="最后">最后</h1>
<p>Docker作为当今最流行的容器技术,是很多技术架构的基础。它有很多的优点,使用中也会面临各种问题,希望本篇入门文章能够帮助到一些初学的小伙伴。</p>
</div>
<div id="MySignature" role="contentinfo">
<p style="font-size:12px;text-align:right;font-style: italic;padding: 10px;margin: 10px 0;border-top: 1px solid #ccc;">——本文使用【Typora】+【EasyBlogImageForTypora】编辑</p>
<div style="border: #c0c0c0 2px dashed;padding:20px;">
<p>欢迎关注我的公众号,一起学习。 </p>
<p>如果本文对您有所帮助,您可以点击右下方的【推荐】按钮支持一下;文中如有不妥之处,还望指正,非常感谢!!!</p>
<img src="https://images.cnblogs.com/cnblogs_com/xhznl/1786441/o_2006130816545ee48a5d08000_5ee48a5f18c90.png">
<hr style="margin: 10px 0;"/>
<p>作者:xhznl</p>
<p>出处:http://www.cnblogs.com/xhznl/</p>
<p>文章可以转载,但请注明出处 </p>
</div><br><br>
来源:https://www.cnblogs.com/xhznl/p/13357781.html
頁:
[1]