一.中间镜像

通过持续集成工具Jenkins构建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端口只是容器的内部端口,我们进行如下修改来知道容器运行时映射到服务器的端口也就是外部端口:

ports:
- "32775:80"

通过上面的设置,我们将容器的外部端口指定为32775,这样我们在构建完成以后,容器运行以后的外部端口都将会为32775,无需再次修改Nginx反向代理等配置。

四.设置镜像版本

我们的应用程序具有不同的版本号,我们不同版本的应用程序构建出来的镜像应该也是具有不同的版本的,我们可以通过设置镜像的Tag来表示不同的版本:

我们同样可以在docker compose的yml里面进行设置,这次修改的是docker-compose.yml文件,我们直接在镜像的名称后面设置Tag,语法为:

image: <镜像名称>:<Tag>

比如我设置一个名为alipaydemo的镜像Tag为V1:

image: alipaydemo:v1

完整的配置分享:

version: ''

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: ''

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: ''

services:
alipay.demo.pcpayment:
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=Production
ports:
- "32775:80"

七.Docker的重启策略

1.设置容器重启策略

这里讲的设置容器重启策略主要是通过命令来进行交互,并非第六节讲的通过docker compose来设置重启策略,是对第六节的一个扩展阅读。

我们可以在使用docker run命令时通过--restart参数来设置重启策略:

docker run -d --restart=always alipaydemo
docker run -d --restart=on-failure: alipaydemo

第一条命令代表容器退出时总是重启容器,第二条代表在容器非正常退出时重启容器,最多重启10次。

对于已经运行的容器可以通过docker update命令来指定:

docker update --restart=always alipaydemo 

2.Docker容器的重启策略

Docker容器的重启策略是面向生产环境的一个启动策略,在开发过程中可以忽略该策略。
Docker容器的重启都是由Docker守护进程完成的,因此与守护进程息息相关。
Docker容器的重启策略如下:

  • no,默认策略,在容器退出时不重启容器
  • on-failure,在容器非正常退出时(退出状态非0),才会重启容器
  • on-failure:3,在容器非正常退出时重启容器,最多重启3次
  • always,在容器退出时总是重启容器
  • unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

3.Docker容器的退出状态码

docker run的退出状态码如下:

    • 0,表示正常退出

    • 非0,表示异常退出(退出状态码采用chroot标准)
    • 125,Docker守护进程本身的错误
    • 126,容器启动后,要执行的默认命令无法调用
    • 127,容器启动后,要执行的默认命令不存在

    • 其他命令状态码,容器启动后正常执行命令,退出命令时该命令的返回状态码作为容器的退出状态码

八.设置自动交互

我们在编写Dockerfile时,可以通过RUN命令来运行一些命令,由此我们可以通过运行apt-get等命令,将一些必要的组件安装到我们的镜像之中,比如lsof等。我们有如下配置:

RUN apt-get install lsof

但是我们在安装一个组件时,非常有可能遇到交互操作,比如“Dou you want to xxx?[y/n]”等,遇到这种将会中断我们的Docker镜像构建过程,那么如何解决呢?我们可以给命令指定--assume-yes来实现自动交互:

RUN apt-get install lsof --assume-yes

持续集成自动化构建过程中,如若不设置自动交互将会被中断:

使用apt-get install命令以前,最好使用apt-get update更新一下,避免出现问题。

九.ASP.NET Core 生成图片问题

大家应该知道目前.NET Core(2.0)还是没有System.Drawing程序集,如果我们要使用Image等对象来完成生成图片验证码、图片二维码等操作只有通过第三方编写的组件,ZKWeb.System.Drawing便是其中一个,我们使用它以后,我们在windows上运行良好,无需其他额外的操作。但是我们一到Linux运行或者使用Docker(dotnet镜像使用的是ubantu环境)运行时,会发现程序无法正常生成图片,会出现异常,这是因为我们的zk在Linux/Docker下运行需要安装一个名为 libgdiplus 的组件,我们在构建Docker镜像的时候可以通过RUN命令使用apt-get命令进行安装:

RUN apt-get update
RUN apt-get install libgdiplus --assume-yes
RUN cd /usr/lib
RUN ln -s libgdiplus.so gdiplus.dll

apt-get update是非常有必要的

完整的Dockerfile配置提供给大家参考:

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 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/
RUN dotnet restore -nowarn:msb3202,nu1503
COPY . .
WORKDIR /src/Alipay.Demo.PCPayment
RUN dotnet build -c Release -o /app 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 apt-get install libgdiplus --assume-yes
RUN cd /usr/lib
RUN ln -s libgdiplus.so gdiplus.dll
ENTRYPOINT ["dotnet", "Alipay.Demo.PCPayment.dll"]


												

Docker镜像相关的更多相关文章

  1. 【快学Docker】Docker镜像相关操作

    前言 镜像是Docker的三大核心概念之一(另外两个分别是:容器和仓库). Docker运行容器前需要本地存在镜像,如果本地不存在镜像,Docker则会尝试从远端仓库拉去镜像.镜像是Docker一大核 ...

  2. docker镜像相关的常用操作

    1.保存镜像 #docker save 镜像名称 -o 保存的完整地址和文件名 docker save zhoushiya/zhiboyuan -o d:/zhiboyuan.tar 2.载入镜像 # ...

  3. Docker镜像相关操作

    批量导入镜像 ll *.tgz|awk '{print $NF}'|sed -r 's#(.*)#docker load -i \1#' |bash 批量打tag docker images | se ...

  4. Docker镜像

    docker镜像123? 额,由于没有实验环境,没有亲手实践,因此理解可能有不对的地方. 反正也是学习笔记,以后再修改吧... docker的镜像跟virtualbox的镜像不一样.在虚拟机中,镜像是 ...

  5. Docker镜像细节

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面: 为什么需要Docker? Docker入 ...

  6. Docker源码分析(九):Docker镜像

    1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...

  7. 3.docker镜像管理基础

    一.docker镜像相关 1.About Docker Image Docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器. 采用分层构建机制,最底层为bootf ...

  8. 管理2000+Docker镜像,Kolla是如何做到的

    根据 DockerHub 上的数据,整个 Kolla 项目管理的 镜像有 2000 多个,这么多的镜像,是怎么定义,又是如何构建的呢? 简介 我们一直在说的 Kolla,通常情况下泛指,包括了 Kol ...

  9. Docker系列教程01-使用Docker镜像

    docker系列导读 一文带你读懂什么是docker Docker安装部署 10张图带你深入理解Docker容器和镜像 前言 学习Docker,我们需要掌握它的三大核心概念:镜像.容器和仓库. 今天先 ...

随机推荐

  1. libevent源码分析:evmap_io_active_函数

    evmap_io_active_函数用于将激活指定文件描述符上的事件 void evmap_io_active_(struct event_base *base, evutil_socket_t fd ...

  2. ORA-12541:TNS:无监听程序 配置Oracle Myeclipse无法连接上 花费一天时间解决掉的

    背景:自己机子做oracle服务器,其他机子可以ping得通我的机子,但是jdbc就是连不上,后来用plsql连出现无监听程序.... 我昨天重新安装Oracle后,用PL/SQL Developer ...

  3. c字符输出

    #include<stdio.h> int main() { char c1,c2; c1 = ; c2 = ; printf("c1 = %c,c2 = %c\n", ...

  4. Unable to locate \.nuget\NuGet.exe 问题解决办法之一(转)

    问题出现的原因是项目下.nuget文件夹下NuGet.exe文件夹不存在导致的 解决办法: 1.右键编辑NuGet.targets文件 将下载NuGet.exe的配置节点DownloadNuGetEx ...

  5. phalcon无法更新分区字段解决办法

    表里面有个分区字段,更新后,保存成功,结果实际上数据库没有更新. 后来使用原生sql,解决了这个问题. 获取di中的数据库连接,直接执行sql语句即可,下面的db为注册的数据库服务名 $db = $t ...

  6. You have not concluded your merge (MERGE_HEAD exists) git拉取失败

    本文转自:http://yijiebuyi.com/blog/5b55eb51ad49ce41e2de9c85dd4513ca.html 今天获取git线上仓库代码报了这个错误: zhangzhi@m ...

  7. Ubuntu 14.04 编译 Android 4.2.2 for Tiny4412

    . . . . . 在学校里是用 Redhat 6.4 编译的 Android 4.2.2 很顺利,把源码包拷贝到笔记本上的 Ubuntu 14.04 上再编译遭遇了各种坑,所以便有了这篇博客记录解决 ...

  8. JDK1.8 重识HashMap

    摘要 JDK1.8相较于1.7对HashMap做了很大的优化,比如加入了新数据结构红黑树.Hash算法的优化和扩容的优化. 本篇结合这些区别,探索HashMap的结构实现和功能原理. 存储结构-字段 ...

  9. 解决MYSQL ERROR 1045 (28000)问题

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)   Red Hat Enterpr ...

  10. [net]netcat 做网络端口监听

    nc命令说明:https://www.cnblogs.com/nmap/p/6148306.html 如下: nc -vz -w domain/ip &> /dev/null & ...