写在前面
容器是应用走向云端之后必然的发展趋势,因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。
本教程持续编写了2个星期左右并且一直在完善、补充具体的细节和实践,预计全部完成需要1到2个月的时间。由于编写的过程中极其费时,并且还需要配合做一些实践(有些实践存在一些坑,而且极其费时费事)。因此目前产出的速度已经跟不上发布的速度了,后续的发布节奏会放慢,请大家多多理解和多多包含。
根据目前和大家的交流,笔者针对大家的情况进行了一些修改和补充,希望对大家有所帮助。另外,对于熟悉容器服务的你,也可以参与进来,让我们一起打造这个系列教程,我们希望能够多多交流,多多分享,以帮助更多的人。同时,我们也希望得到大家的支持。
前言
内容发出来之后,有部分小伙伴有些疑惑。这里我特别说明下,Docker for windows 指的是docker官方提供的windows的安装包,并不是指的基于windows镜像开发。笔者推荐的方式是——在windows上开发和调测,托管到Linux。
Docker持续开发工作流
Docker改变了开发以及产品交付流程,以下是一般情况下的Docker应用程序的内部循环的持续开发工作流,本工作流只关注在开发人员的计算机上进行的开发工作,不包括设置环境等初始步骤,因为这些步骤只需进行一次。
应用程序一般由开发人员自己的服务代码和附加库(依赖项)组成,以下是生成 Docker 应用程序时常用的基本步骤,具体如下图所示:

在本篇教程中,我们以开源框架Magicodes.Admin为例进行讲解。
Magicodes.Admin,是心莱科技团队打造的一套高效率、易扩展、基础设施强大、代码生成完备、理念和技术先进的敏捷开发框架,同时也是一套分布式(即将提供微服务架构参考)、跨平台(linux、Docker容器支持)、多终端(包括Android、IOS、H5、小程序、微信公众号)支持的统一开发框架和解决方案。框架基于.NET Core 2.1、Angular、Ionic、EF Core、ABP和ASP.NET Zero,并在其基础上进行了封装和完善,并且编写了相关的工具(代码生成)、组件(云存储、支付、微信等等)、生成服务。
创建Dockerfile
本节内容很多,我们希望大家能够了解和使用好Dockerfile。

关于dockerfile
虽然我们可以通过docker commit命令来手动创建镜像,但是通过Dockerfile文件,可以帮助我们自动创建镜像,并且能够自定义创建过程。本质上,Dockerfile就是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它简化了从头到尾的构建流程并极大的简化了部署工作。使用dockerfile构建镜像有以下好处:
-     
像编程一样构建镜像,支持分层构建以及缓存;
 -     
可以快速而精确地重新创建镜像以便于维护和升级;
 -     
便于持续集成;
 -     
可以在任何地方快速构建镜像
 
Dockerfile指令
我们需要了解一些基本的Dockerfile 指令,Dockerfile 指令为 Docker 引擎提供了创建容器映像所需的步骤。这些指令按顺序逐一执行。以下是有关一些基本 Dockerfile 指令的详细信息。
1.FROM
FROM 指令用于设置在新映像创建过程期间将使用的容器映像。
格式:FROM
示例:
FROM nginx
FROM microsoft/dotnet:2.1-aspnetcore-runtime
2.RUN
RUN 指令指定将要运行并捕获到新容器映像中的命令。 这些命令包括安装软件、创建文件和目录,以及创建环境配置等。
格式:
RUN ["", "", ""]
RUN
示例:
RUN apt-get update
RUN mkdir -p /usr/src/redis
RUN apt-get update && apt-get install -y libgdiplus
RUN ["apt-get","install","-y","nginx"]
注意:每一个指令都会创建一层,并构成新的镜像。当运行多个指令时,会产生一些非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。因此,在很多情况下,我们可以合并指令并运行,例如:RUN apt-get update && apt-get install -y libgdiplus。在命令过多时,一定要注意格式,比如换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯。使用换行符时,可能会遇到一些问题,具体可以参阅下节的转义字符。
3.COPY
COPY 指令将文件和目录复制到容器的文件系统。文件和目录需位于相对于 Dockerfile 的路径中。
格式:
COPY
如果源或目标包含空格,请将路径括在方括号和双引号中。
COPY ["", ""]
示例:
COPY . .
COPY nginx.conf /etc/nginx/nginx.conf
COPY . /usr/share/nginx/html
COPY hom* /mydir/
4.ADD
ADD 指令与 COPY 指令非常类似,但它包含更多功能。除了将文件从主机复制到容器映像,ADD 指令还可以使用 URL 规范从远程位置复制文件。
格式:
ADD<source> <destination>
示例:
ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe
此示例会将 Python for Windows下载到容器映像的 c:\temp 目录。
5.WORKDIR
WORKDIR 指令用于为其他 Dockerfile 指令(如 RUN、CMD)设置一个工作目录,并且还设置用于运行容器映像实例的工作目录。
格式:
WORKDIR
示例:
WORKDIR /app
6.CMD
CMD指令用于设置部署容器映像的实例时要运行的默认命令。例如,如果该容器将承载 NGINX Web 服务器,则 CMD 可能包括用于启动Web服务器的指令,如 nginx.exe。 如果 Dockerfile 中指定了多个CMD 指令,只会计算最后一个指令。
格式:
CMD ["<executable", "
CMD
示例:
CMD ["c:\\Apache24\\bin\\httpd.exe", "-w"]
CMD c:\\Apache24\\bin\\httpd.exe -w
7.ENTRYPOINT
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。
格式:
ENTRYPOINT ["", ""]
示例:
ENTRYPOINT ["dotnet", "Magicodes.Admin.Web.Host.dll"]
8.ENV
ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。
格式:
ENV==...
示例:
ENV VERSION=1.0 DEBUG=on \
NAME="Magicodes"
9.EXPOSE
EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。
格式:
EXPOSE
示例:
