基于eShopOnContainers学习ASP.NET Core之使用 docker-compose.yml 定义多容器应用程序
前言
docker相关知识和docker-compose相关知识就不再本文说明了。
本文主要参考
官方示例使用 docker-compose.yml 定义多容器应用程序
和使用 ASP.NET Core 构建优化的 Docker 镜像
环境准备
添加docker支持和容器业务流程协调程序支持即docker-compose
然后就会出现
如果出现如下错误
Unable to load schema from 'https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json': getaddrinfo ENOENT raw.githubusercontent.com.(768)
则参考https://www.jianshu.com/p/d273d9a35b11解决
简单的Web服务API容器
关注单个容器的 SystemInfo.Api
定义如下
systeminfo.api:
image: zhao56/systeminfoapi
environment:
- ConnectionString=server=localhost;user=root;password=[PLACEHOLDER];database=zhao56
expose:
-80
ports:
- "5101:80"
depends_on:
- sqldata
特点:
- 基于自定义镜像,这就意味着必须提前生成zhao56/systeminfoapi这个镜像
- 定义了 ConnectionString环境变量,会覆盖对应微服务中的appsettings.json中的ConnectionString
- 依赖于数据库容器
sqldata
,使用的名称。无需知道数据库容器内部的ip
使用多个 docker-compose 文件
针对不同的环境是应该使用多个docker-compose
文件
重写docker-compose文件来处理多个环境
Visual Studio创建docker支持的时候会创建三个文件
- .dockerignore - 用于忽略文件
- docker-compose.yml - 用于撰写微服务
- docker-compose.override.yml - 用于配置微服务环境
通常:
docker-compose.yml
中包含基本配置和其他静态设置 ,即不会随着环境的改变而变化
docker-compose.override.yml
中包含可替代基本配置的配置,用来应对各个环境的不同,也可以创建不同名称的重写文件
针对多个环境
典型的用例是定义多个 compose 文件时,可针对多个环境,如生产、暂存、CI 或开发环境。 为支持这些差异,可将 Compose 配置拆分成多个文件,如图 6-12 所示。
先定义基本不变的docker-compose.yml
文件
version: '3.4'
services:
systeminfo.api:
image: zhao56/systeminfoapi:${TAG:-latest}
build:
context: .
dockerfile: SystemInfo.Api/Dockerfile
depends_on:
- sqldata
sqldata:
image: mysql:8.0.25
其次是docker-compose.override.yml
文件来应对环境的不同
version: '3.4'
services:
systeminfo.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- "80"
- "443"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
sqldata:
environment:
- SA_PASSWORD=[PLACEHOLDER]
- ACCEPT_EULA=Y
ports:
- "5433:1433"
当执行docker-compose up
或者从 Visual Studio 启动时,会将两个文件合并
如何使用特定重写文件进行部署
如果需要为生产环境配置具有不同端口、配置值或者连接串的另外一个compose
文件,如创建docker-compose.prod.yml
可执行如下命令
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
在 docker-compose 文件中使用环境变量
用.env文件定义主机环境,环境不同修改对应的值即可格式为: ${MY_VAR}
如在 docker-compose.override.yml中定义连接字符串的环境变量
systeminfo.api:
environment:
- ConnectionString=${SYSTEMINFO_DB}
环境变量中修改添加值
SYSTEMINFO_DB=server=localhost;user=root;password=root;database=zhao56
生成优化的DockerFile
编写常规的DcokerFile可能如下所示
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["SystemInfo.Api/SystemInfo.Api.csproj", "SystemInfo.Api/"]
COPY ["SystemInfo.Service/SystemInfo.Service.csproj", "SystemInfo.Service/"]
COPY ["SystemInfo.Repositories/SystemInfo.Repositories.csproj", "SystemInfo.Repositories/"]
COPY ["SystemInfo.Entities/SystemInfo.Entities.csproj", "SystemInfo.Entities/"]
COPY ["SystemInfo.Core/SystemInfo.Core.csproj", "SystemInfo.Core/"]
COPY ["Services.Common/Services.Common.csproj", "Services.Common/"]
RUN dotnet restore "SystemInfo.Api/SystemInfo.Api.csproj"
COPY . .
WORKDIR "/src/SystemInfo.Api"
RUN dotnet build "SystemInfo.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "SystemInfo.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "SystemInfo.Api.dll"]
此种情况下所有的步骤都放到了同一个镜像中,镜像也包含了源代码,虽然简单,但是仍可以优化,以便重新发布的时候达到最少的停机时间
动态编译
日常部署的过程中不会每次都将程序全部替换,而是采用增量发布的方式来进行的。
容器是不可变的,预先优化
在使用容器的场景中,不会关闭容器或休眠容器,而是Kill掉容器,所以就重新发布时,镜像就准备好了,这样会节省很多时间,即当需要重新发布容器时,程序已经预先编译好了
所以当前存在几个基本镜像:
- sdk:用于开发和生成方案
- aspnet:用于 ASP.NET 生产方案( 部署ASP.NET Core应用程序 )
- runtime:用于 .NET 生产方案( 部署.NET Core控制台程序 )
- runtime-deps:用于 自包含应用程序的生产方案
创建一个 build.sh 脚本
#!bin/bash
dotnet restore
#如果有测试需要执行
#dotnet test xxxx
#删除发布文件夹
rm -rf $(pwd)/app/publish/API/SystemInfo
dotnet publish "SystemInfo.Api.csproj" -c Release -o $(pwd)/app/publish/API/SystemInfo
使用构建脚本编译和发布项目
进入到解决方案根目录
运行命令(容器用完即删)
docker run -it --rm -v "$PWD/\:/src" --workdir /sln/sln/src/Services/SystemInfo/SystemInfo.Api mcr.microsoft.com/dotnet/sdk:5.0 sh ./build.sh
或者可以使用docker-compose
来封装我们的构建脚本
添加docker-compose-build.yml
添加如下内容
version: '3.4'
services:
SystemInfo-build:
image: mcr.microsoft.com/dotnet/sdk:5.0-buster-slim
volumes:
- /usr/local/test/zhao56.microservices.demo/:/sln
working_dir: /sln/src/Services/SystemInfo/SystemInfo.Api
entrypoint: ["sh", "./build.sh"]
运行来构建
docker-compose -f docker-compose-build.yml up
构建结果如下
[root@manager zhao56.microservices.demo]# docker-compose -f docker-compose-build.yml up
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Recreating zhao56microservicesdemo_SystemInfo-build_1 ... done
Attaching to zhao56microservicesdemo_SystemInfo-build_1
SystemInfo-build_1 | ./build.sh: 1: ./build.sh: : not found
SystemInfo-build_1 | Could not execute because the specified command or file was not found.
SystemInfo-build_1 | Possible reasons for this include:
SystemInfo-build_1 | * You misspelled a built-in dotnet command.
does not exist._1 | * You intended to execute a .NET program, but dotnet-restore
SystemInfo-build_1 | * You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on the PATH.
SystemInfo-build_1 | Microsoft (R) Build Engine version 16.10.2+857e5a733 for .NET
SystemInfo-build_1 | Copyright (C) Microsoft Corporation. All rights reserved.
SystemInfo-build_1 |
SystemInfo-build_1 | Determining projects to restore...
SystemInfo-build_1 | Restored /sln/src/Services/SystemInfo/SystemInfo.Service/SystemInfo.Service.csproj (in 9.39 sec).
SystemInfo-build_1 | Restored /sln/src/Services/SystemInfo/SystemInfo.Repositories/SystemInfo.Repositories.csproj (in 14 ms).
SystemInfo-build_1 | Restored /sln/src/Services/SystemInfo/SystemInfo.Entities/SystemInfo.Entities.csproj (in 8 ms).
SystemInfo-build_1 | Restored /sln/src/Services/SystemInfo/SystemInfo.Core/SystemInfo.Core.csproj (in 1.87 sec).
SystemInfo-build_1 | Restored /sln/src/Services/SystemInfo/SystemInfo.Api/SystemInfo.Api.csproj (in 39.84 sec).
SystemInfo-build_1 | Restored /sln/src/Services/CommonSupport/Services.Common/Services.Common.csproj (in 2 ms).
SystemInfo-build_1 | Services.Common -> /sln/src/Services/CommonSupport/Services.Common/bin/Release/net5.0/Services.Common.dll
SystemInfo-build_1 | SystemInfo.Entities -> /sln/src/Services/SystemInfo/SystemInfo.Entities/bin/Release/net5.0/SystemInfo.Entities.dll
SystemInfo-build_1 | SystemInfo.Core -> /sln/src/Services/SystemInfo/SystemInfo.Core/bin/Release/net5.0/SystemInfo.Core.dll
SystemInfo-build_1 | /usr/share/dotnet/sdk/5.0.302/Microsoft.Common.CurrentVersion.targets(2202,5): warning
SystemInfo-build_1 | SystemInfo.Api -> /sln/src/Services/SystemInfo/SystemInfo.Api/app/publish/API/SystemInfo/
zhao56microservicesdemo_SystemInfo-build_1 exited with code 0
查看挂载目录
[root@manager SystemInfo]# ll
总用量 10304
-rw-r--r--. 1 root root 168 8月 5 14:26 appsettings.Development.json
-rw-r--r--. 1 root root 1318 8月 5 14:26 appsettings.json
-rw-r--r--. 1 root root 291 8月 5 14:26 Dockerfile
...........省略........
[root@manager SystemInfo]# pwd
/usr/local/test/zhao56.microservices.demo/src/Services/SystemInfo/SystemInfo.Api/app/publish/API/SystemInfo
成功编译
构建优化图像
将项目中的DockerFile改为
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY . .
ENTRYPOINT ["dotnet", "SystemInfo.Api.dll"]
总结
1.使用docker-compose.yml
定义基本的信息,不会随环境改变的信息
2.使用docker-compose.*.yml
配置主机环境相关的信息
3.使用构建脚本编译和发布项目,最后将发布后的程序添加到对应的生产镜像中
本文来自博客园,作者:zhao56,转载请注明原文链接:https://www.cnblogs.com/zhao56/p/15099356.html