一. 前言
最近一直在研究和实践 ASP.NET Core,Docker, 持续集成. 在 ASP.NET Core 和 Dcoker 结合下遇到了一些坑, 在此记录和分享, 希望对大家有一些帮助.
二. 中间镜像
我前面写过一个 ASP.NET Core & Docker 零基础持续集成 的教程. 里面我们通过持续集成工具 Jenkins 构建 Docker 镜像并运行容器, 采用的是 Docker Compose 来进行编排构建运行的 (Visual Studio 2017 添加 Docker 支持是采用的 Docker Compose). 细心的朋友可能会发现, 每次构建完毕以后通过 docker images 命令查询, 可以发现多了许多没有名称() 的镜像. 这些都是构建过程中的中间镜像, 我们可以在构建完成以后 进行统一删除.
删除所有无名称镜像:
docker rmi $(docker images -f "dangling=true" -q)
此命令应当加在构建的最后一步, 示例:
- echo ---------------Remove-Orphans------------------
- docker-compose -f src/docker-compose.yml -f src/docker-compose.override.yml -p alipaydemo down --rmi local --remove-orphans
- echo ---------------Publishing...------------------
- docker-compose -f "src/docker-compose.yml" -f "src/docker-compose.override.yml" -p alipaydemo up -d --build
- echo ---------------Clear-Images...------------------
- docker rmi $(docker images -f "dangling=true" -q)
执行之后会看到以下效果:
这是非常有必要的, 因为如果每次构建都残留一些中间镜像, 会额外消耗我们的磁盘空间的.
三. 固定容器外部端口
这里主要讲的是在自动化构建的过程中, 通过 docker compose 来运行容器的外部端口, 而不是直接通过 docker run 命令来指定.
我们通过 Visual Studio 2017 添加 Docker 支持(Docker Compose), 通过 Docker Compose 编排构建运行容器, 我们会发现每次构建以后, 运行的容器的外部端口都不是固定的, 比如 32774,32775,32776 等等. 这对于我们设置了 Nginx 反向代理和 API Gateway 等配置的肯定是十分不方便的, 我们每次构建完毕以后还要去改这些配置, 不是扯淡吗. 所以我们需要固定我们容器运行的外部端口, 我们可以通过改变 docker compose 的 yml 文件来固定容器的外部端口.
Visual Studio 2017 添加的 Docker 支持所生成的文件有如下结构:
我是用的版本为 VS2017 15.6.5. 如果是更早的版本添加 Docker 支持可能会多出一个
docker-compose.ci.build.yml
文件, 其实这一步没必要, 目前的最新的 VS2017 已经移除了该文件.
我们固定容器外部端口需要修改的是
docker-compose.override.yml
文件, 我们需要修改的是 ports. 默认为:
ports: - "80"
这个 80 端口只是容器的内部端口, 我们进行如下修改来知道容器运行时映射到服务器的端口也就是外部端口:
- ports:
- - "32775:80"
通过上面的设置, 我们将容器的外部端口指定为 32775, 这样我们在构建完成以后, 容器运行以后的外部端口都将会为 32775, 无需再次修改 Nginx 反向代理等配置.
四. 设置镜像版本
我们的应用程序具有不同的版本号, 我们不同版本的应用程序构建出来的镜像应该也是具有不同的版本的, 我们可以通过设置镜像的 Tag 来表示不同的版本:
我们同样可以在 docker compose 的 yml 里面进行设置, 这次修改的是 docker-compose.yml 文件, 我们直接在镜像的名称后面设置 Tag, 语法为:
image: <镜像名称>:<Tag>
比如我设置一个名为 alipaydemo 的镜像 Tag 为 V1:
image: alipaydemo:v1
完整的配置分享:
- version: '3'
- services:
- alipay.demo.pcpayment:
- image: alipaydemopcpayment:v1
- container_name: alipaydemocontainer
- build:
context: .
dockerfile: Alipay.Demo.PCPayment/Dockerfile
五. 设置容器名称
我们在通过 docker compose 运行的容器将会被指定一个默认的容器名称, 如果是第四节的配置, 那么容器的默认名称为
alipaydemopcpayment.alipay.demo.pcpayment.build_1
, 具有非常一长串, 此时我们可以自己来指定这个容器的名称, 同样我们需要修改 docker-compose.yml 文件, 设置容器名称的命令格式为:
container_name: <容器名称>
完整的配置分享:
- version: '3'
- services:
- alipay.demo.pcpayment:
- image: alipaydemopcpayment:v1
- container_name: alipaydemocontainer
- build:
context: .
dockerfile: Alipay.Demo.PCPayment/Dockerfile
通过上面的配置我们将容器名称设置为了
alipaydemocontainer
六. 设置容器重启策略
某一天我对服务器进行了重启, 重启以后发现通过 Docker 运行的服务无法访问了, 然后查看原因, 发现 Docker 服务没有开机自启, 启动了 Docker 以后发现容器又没有自动启动.
1. 设置 Docker 开机自启
我们可以直接通过 chkconfig 命令来设置 Docker 开启自启:
chkconfig docker
执行成功如下:
2. 设置容器随 Docker 启动
我们要让容器随 Docker 启动, 就必须设置容器的重启策略为 always, 我们通过 docker compose 来运行容器时可以在 yml 里面指定. 打开
docker-compose.override.yml
文件, 添加配置:
restart: always
完整的配置示例:
- version: '3'
- services:
- alipay.demo.pcpayment:
- restart: always
- environment:
- - ASPNETCORE_ENVIRONMENT=Production
- ports:
- - "32775:80"
七. Docker 的重启策略
1. 设置容器重启策略
- docker run -d --restart=always alipaydemo
- docker run -d --restart=on-failure:10 alipaydemo
- FROM microsoft/aspnetcore:2.0 AS base
- WORKDIR /app
- EXPOSE 80
- FROM microsoft/aspnetcore-build:2.0 AS build
- WORKDIR /src
- COPY Alipay.Demo.PCPayment.sln ./
- COPY Alipay.Demo.PCPayment/Alipay.Demo.PCPayment.csproj Alipay.Demo.PCPayment/
- FROM build AS publish
- RUN dotnet publish -c Release -o /app
- FROM base AS final
- WORKDIR /app
- COPY --from=publish /app .
- RUN apt-get update
- RUN cd /usr/lib
- RUN ln -s libgdiplus.so gdiplus.dll
- ENTRYPOINT ["dotnet", "Alipay.Demo.PCPayment.dll"]
来源: https://www.cnblogs.com/stulzq/p/9059108.html