在这容器化的世界里,我们已经很少直接通过文件发布来运行asp.net core程序了。现在大多数情况下,我们都会使用docker来运行程序。在使用docker之前,我们往往需要打包我们的应用程序。asp.net core程序的镜像打包,网上有很多教程,其中大多数是使用sdk这个镜像来直接打包。打出来的包有好几百MB,3.1 SDK打出来的包甚至超过了1GB。那么有什么办法来缩小我们打出来的镜像吗?最小能缩小到多少呢?这篇文章就来介绍下如何缩小asp.net core 打包出来镜像的大小。 新建asp.net core 程序 新建一个asp.net core应用程序,用来演示打包。首先我们演示下如果使用dotnet sdk5.0来打包 docker 镜像。 sdk:5.0
1 2 3 4 5 6 7 8 |
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /app COPY /. /app RUN dotnet restore -s https://nuget.cdn.azure.cn/v3/index.json WORKDIR /app/CoreDockerImageSizeTest RUN dotnet publish -o ./out -c Release EXPOSE 5000 ENTRYPOINT ["dotnet", "out/CoreDockerImageSizeTest.dll"] |
在项目根目录下新建一个Dockerfile文件,文件内容如上。这个Dockerfile比较简单,使用dotnet sdk:5.0最为底层包来构建,这也是最傻瓜的打包方式。那么看看这个镜像打出来有多大吧。
1 |
docker build . -t coredockerimagesizetest_0.1 |
使用docker build命令进行打包。
1 2 |
REPOSITORY TAG IMAGE ID CREATED SIZE coredockerimagesizetest_0.1 latest 14aea8e0c1d5 5 seconds ago 643MB |
使用docker images命令来查看镜像列表,我们发现我们打出来的镜像居然有643MB,真的很大。如果是内网还好一点,如果在镜像存在docker hub等第三方仓库,这得下半天。显然这个镜像太大了,接下来看我们如何进行优化。 sdk:5.0-buster-slim 最新的VisualStudio内置了docker工具,可以自动为我们生成Dockerfile文件。我们来看看它生成的镜像文件有多大。 右键解决方案=>添加=>Docker支持=>Linux 。 选择完成后VS会为我们自动添加一个Dockerfile在根目录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base WORKDIR /app EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build WORKDIR /src COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"] RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj" COPY . . WORKDIR "/src/CoreDockerImageSizeTest" RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"] |
这个自动生成的Dockerfile使用了sdk:5.0-buster-slim这个镜像进行build跟publish,使用aspnet:5.0-buster-slim这个runtime级别的镜像做为final底包。从名字来看,很明显slim代表着轻量。让我们试试这个Dockerfile打出来的包有多大。
1 2 |
REPOSITORY TAG IMAGE ID CREATED SIZE coredockerimagesizetest_0.2 latest 0a24618f6ece 11 seconds ago 210MB |
使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为210MB。果然比上面的镜像小了很多。那么是否还能继续缩小镜像的大小呢?继续往下看。 5.0-alpine 除了使用buster-slim镜像,我们还可以选择更加小巧的alpine镜像来打包。alpine镜像是继续alpine linux创建的镜像,所以它更加轻量级更加小巧。 关于alpine linux可以查看这篇:Alpine Linux 与 CentOS 有什么区别? 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base WORKDIR /app EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build WORKDIR /src COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"] RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj" COPY . . WORKDIR "/src/CoreDockerImageSizeTest" RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"] |
修改Dockerfile使用aspnet:5.0-alpine及sdk:5.0-alpine来构建这个镜像。
1 2 |
REPOSITORY TAG IMAGE ID CREATED SIZE coredockerimagesizetest_0.3 latest db34d613e21a 12 seconds ago 108MB |
使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为108MB。现在这个镜像已经比我们第一次打包减少了500多MB了。那么还能更小吗?请往下看。 runtime-deps:5.0-alpine 最新的.net core程序支持自宿主及单文件发布。如果采用以上发布形式,那么我们可以选择使用runtime-deps:5.0-alpine做为最终底包来打包我们的镜像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base WORKDIR /app EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build WORKDIR /src COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"] RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj" COPY . . WORKDIR "/src/CoreDockerImageSizeTest" RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish \ --runtime alpine-x64 \ --self-contained true \ /p:PublishTrimmed=true \ /p:PublishSingleFile=true FROM mcr.microsoft.com/dotnet/runtime-deps:5.0-alpine AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["./CoreDockerImageSizeTest"] |
修改Dockerfile,使用/runtime-deps:5.0-alpine做为final镜像。
1 2 |
REPOSITORY TAG IMAGE ID CREATED SIZE coredockerimagesizetest_0.5 latest dab1289626f9 6 seconds ago 54.6MB |
使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为54.6MB。 总结 通过以上演示,我们的镜像大小从一开始的600多MB缩小到了54MB。一般生产我主要选择buster-slim这个镜像来打包。如果选择runtime-deps打包,打出来的包是最小的,虽然演示项目是可以运行的,但是本人没有在生产使用过,还请谨慎使用。 代码在这:CoreDockerImageSizeTest from:https://www.cnblogs.com/kklldog/p/netcore-docker-image-size.html
View Details此问题中缺少的一个关键信息是使用Azure。因为aspnetcore是在Azure devops管道中发布程序包所必需的,所以可能要使用微软的源或者更新一些配置: 故此通过 curl https://packages.microsoft.com/config/rhel/7/prod.repo > ./microsoft-prod.repo sudo cp ./microsoft-prod.repo /etc/yum.repos.d/ yum update -y 可以解决。 ———————————————— 版权声明:本文为CSDN博主「Zero_77」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Zero_77/article/details/115902042
View DetailsTo get started with Docker Engine on CentOS, make sure you meet the prerequisites, then install Docker. Prerequisites OS requirements To install Docker Engine, you need a maintained version of CentOS 7 or 8. Archived versions aren’t supported or tested. The centos-extras repository must be enabled. This repository is enabled by default, but if you have disabled it, you need to re-enable it. The overlay2 storage driver is recommended. Uninstall old versions Older versions of Docker were called docker or docker-engine. If these are installed, uninstall them, along with associated dependencies.
1 2 3 4 5 6 7 8 |
$ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine |
It’s OK if yum reports that none […]
View Detailscontainerd是容器虚拟化技术,从docker中剥离出来,形成开放容器接口(OCI)标准的一部分。 docker对容器的管理和操作基本都是通过containerd完成的。Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。Containerd 可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管理、存储和网络等。详细点说,Containerd 负责干下面这些事情: •管理容器的生命周期(从创建容器到销毁容器) •拉取/推送容器镜像 •存储管理(管理镜像及容器数据的存储) •调用 runC 运行容器(与 runC 等容器运行时交互) •管理容器网络接口及网络 注意:Containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用。 我们可以从下面几点来理解为什么需要独立的 containerd: •继续从整体 docker 引擎中分离出的项目(开源项目的思路) •可以被 Kubernets CRI 等项目使用(通用化) •为广泛的行业合作打下基础(就像 runC 一样) docker安装后containerd默认已安装,containerd包含如下命令组件: •containerd:高性能容器运行时。 •ctr:containerd的命令行客户端。 •runc:运行容器的命令行工具。 docker、containerd、docker-shim、runC关系: docker:docker本身而言,包括了docker client和dockerd,dockerd实属是对容器相关操作的api的最上层封装,直接面向操作用户。 containerd:dockerd实际真实调用的还是containerd的api接口(rpc方式实现),containerd是dockerd和runC之间的一个中间交流组件。 docker-shim:一个真实运行容器的载体,每启动一个容器都会起一个新的docker-shim的进程。它通过指定三个参数:容器ID、boundle目录(containerd对应某个容器生成目录)、运行时二进制(默认是runC)来调用runC的api创建一个容器。 runC:一个命令行工具端,根据OCI的标准来创建和运行容器。 containerd应用 docker镜像和containerd镜像通用,但组织方式和存放目录不同,导致docker与ctr命令不通用,各自管理自己的镜像和容器。 此外k8s还有客户端命令crictl,用法与docker基本相同,可crictl -h查看用法。 containerd的默认配置文件为/etc/containerd/config.toml,可通过命令:
1 |
containerd config default |
输出默认配置,可参考文档https://github.com/containerd/containerd/blob/master/docs/ops.md
1 2 3 4 |
root = "/var/lib/containerd" state = "/run/containerd" oom_score = 0 …… |
root键值用于存储containerd持久化数据。 state键值用于存储containerd临时性数据,设备重启后数据丢失。 显示containerd镜像
1 |
sudo ctr images ls |
拉取hello-world镜像
1 |
sudo ctr images pull docker.io/library/hello-world:latest |
注:必须全路径,从dockerhub上下载默认hello-world镜像。 运行容器
1 2 |
sudo ctr run docker.io/library/hello-world:latestmy_hello-world sudo ctr run -t docker.io/library/busybox:latestmybusybox_demosh |
参考: 1.https://github.com/containerd/containerd 2.https://containerd.io/docs/getting-started/ 3.Containerd 简介 4.Docker组件介绍(一):runc和containerd from:https://www.cnblogs.com/embedded-linux/p/10850491.html
View Details1、从容器里面拷文件到宿主机? 答:在宿主机里面执行以下命令 docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径 示例: 假设容器名为testtomcat,要从容器里面拷贝的文件路为:/usr/local/tomcat/webapps/test/js/test.js, 现在要将test.js从容器里面拷到宿主机的/opt路径下面,那么命令应该怎么写呢? 答案:在宿主机上面执行命令
1 |
docker cp testtomcat:/usr/local/tomcat/webapps/test/js/test.js /opt |
2、从宿主机拷文件到容器里面 答:在宿主机里面执行如下命令 docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径 示例:假设容器名为testtomcat,现在要将宿主机/opt/test.js文件拷贝到容器里面的/usr/local/tomcat/webapps/test/js路径下面,那么命令该怎么写呢? 答案:在宿主机上面执行如下命令
1 |
docker cp /opt/test.js testtomcat:/usr/local/tomcat/webapps/test/js |
3、在这里在记录一个问题,怎么看容器名称? 执行命令:docker ps,出现如图所示,其中NAMES就是容器名了。 4.需要注意的是,不管容器有没有启动,拷贝命令都会生效。 from:https://www.cnblogs.com/areyouready/p/8973495.html
View Details一直想试试docker,但是docker高度依赖Linux内核,Windows7的机子用起来比较麻烦,由于某些契机还是用了起来。Windows想用docker的话,需要借助虚拟机,Windows7不像Windows10自带Hyper虚拟机,所以要用docker只有Docker Toolbox这个选择了。具体安装过程就不具体说了,官网也有详细的教程,不过让我最气的是联想的本本一直进入不了bios,最后Fn+F2进入bios启用虚拟设置。 Docker ToolBox安装 1、安装前,需要去bios启用虚拟设置,这样虚拟机才能运行。 2、安装,安装可选的工具: Kitematic,docker的界面化,没什么太大需要 Git,本来已安装的话也不用安装 3、修改 Docker QuickStart 快捷方式,将里面的Git的位置换成你的Git的安装位置(或者可以直接Git进入Docker Toolbox安装位置,运行./start.sh) 替换默认docker machine的存储位置 我相信大部分人都是直接安装官网的教程或者上面的安装方式直接安装的,但是将虚拟机安装在系统盘可能会带来各种问题,所以趁docker的镜像还没膨胀的时候赶快迁移吧。下面步骤可以在安装前做,这样可以减少删除已安装的default docker虚拟机。 1、在Windows的系统环境添加MACHINE_STORAGE_PATH ,指向虚拟机的位置(我推荐D:\VM\machines) 2、复制boot2docker.iso到虚拟机的位置同级目录cache上(D:\VM\cache),如果不是最新的话需要下载最新。 下面分两种情况: 如果还没安装default docker虚拟机,可以进入Docker QuickStart直接安装。 已安装了default docker虚拟机,需要先删除原来的,再安装到指定位置。 删除default docker虚拟机 1、进入Docker QuickStart命令行(Docker QuickStart不能进的话,用Git命令行) 2、运行docker-machine stop default,停止运行中的虚拟机 3、运行docker-machine rm default,删除默认的虚拟机 创建docker虚拟机 1、运行docker-machine create --driver=virtualbox default,等待创建完成 2、创建完成后,运行docker run hello-world测试。可以看到出现问题了:
1 |
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.36/version: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running. |
3、运行docker-machine env default,可以看到docker server的变量,copy变量在命令行中运行。 4、再次运行docker run hello-world测试,这次应该没问题。 修改docker 的配置 嫌弃官网的docker源太慢需要使用国内的源加速的话,要怎么配置呢? 1、运行docker-machine ssh default连接虚拟机 2、修改
1 2 3 4 5 6 7 |
docker@default:~$ sudo tee /var/lib/boot2docker/etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://registry.docker-cn.com" ] } EOF |
3、退出ssh,重启docker-machine restart default from:https://www.cnblogs.com/ginponson/p/8601320.html
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
文本摘自此文章 1、kafka需要zookeeper管理,所以需要先安装zookeeper。 下载zookeeper镜像 $ docker pull wurstmeister/zookeeper 2、启动镜像生成容器 ## docker run -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper $ docker run -d --restart=always --log-driver json-file --log-opt max-size=100m --log-opt max-file=2 --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper 3、下载kafka镜像 $ docker pull wurstmeister/kafka 4、启动kafka镜像生成容器 ## docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=172.16.0.13:2181/kafka -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.13:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime wurstmeister/kafka $ docker run -d --restart=always --log-driver json-file --log-opt max-size=100m --log-opt max-file=2 --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=172.16.0.13:2181/kafka -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.13:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime wurstmeister/kafka 参数说明: -e KAFKA_BROKER_ID=0 在kafka集群中,每个kafka都有一个BROKER_ID来区分自己 -e KAFKA_ZOOKEEPER_CONNECT=172.16.0.13:2181/kafka 配置zookeeper管理kafka的路径172.16.0.13:2181/kafka -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.16.0.13:9092 把kafka的地址端口注册给zookeeper,如果是远程访问要改成外网IP,类如Java程序访问出现无法连接。 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 配置kafka的监听端口 -v /etc/localtime:/etc/localtime 容器时间同步虚拟机的时间 5、验证kafka是否可以使用 5.1、进入容器 $ docker exec -it kafka bash 5.2、进入 /opt/kafka_2.12-2.3.0/bin/ 目录下 $ cd /opt/kafka_2.12-2.3.0/bin/ 5.3、运行kafka生产者发送消息 $ ./kafka-console-producer.sh --broker-list localhost:9092 --topic sun 发送消息 > {"datas":[{"channel":"","metric":"temperature","producer":"ijinus","sn":"IJA0101-00002245","time":"1543207156000","value":"80"}],"ver":"1.0"} 5.4、运行kafka消费者接收消息 $ ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning |
from:https://www.cnblogs.com/linjiqin/p/11891776.html
View Details由于工作和学习需要,经常要开一个虚拟机开测试和开发,虚拟机我选择Oracle公司的VirtualBox(用了几年了,感觉不错的一款产品),经常开着这个窗口感觉有些浪费资源,这样隐藏窗口就在需求了。 将VirtualBox里安装的虚拟机在后台运行方法(在状态栏隐藏窗口) 开始=>运行=>cmd进入DOS窗口
1 2 3 |
d: cd D:\Program Files\VirtualBox D:\Program Files\VirtualBox> .\VBoxManage.exe startvm master --type headless |
这在Linux系统和MAC上同样适用,只要替换成相应的命令即可 解释:其中 master 是这个虚拟机的名称 Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。<br>Headless模式针对在该模式下工作,尤其是服务器端程序开发者。因为服务器(如提供Web服务的主机)往往可能缺少前述设备,但又需要使用他们提供的功能,生成相应的数据,以提供给客户端(如浏览器所在的配有相关的显示设备、键盘和鼠标的主机)。 from:https://www.cnblogs.com/foonsun/p/5709784.html
View Details平时使用Docker,主要是用客户端 Kitematic,但 Kitematic 只实现了基本的使用功能,如果想更深入的使用Docker,命令行还是必不可少的。 前两课中,已经介绍过几个Docker命令:
1 2 3 4 5 6 7 8 |
docker pull:从镜像仓库中拉取镜像 。 docker run:通过镜像创建一个新的容器,并运行。需要注意的是,如果本地没有指定的镜像,会直接去镜像库下载,一定要保证拼写正确。 docker stop:停止一个容器 。 docker start:启动一个容器 。 docker restart:重启一个容器 。 docker ps:列出当前运行的容器机器状态 。 docker images 或 docker image ls:列出本地镜像。 docker build:使用Dockerfile创建自己的镜像。 |
这里记录几个Docker使用过程中,最容易用的的基础命令,包括镜像构建,镜像操作,容器使用。 镜像构建: docker build [OPTIONS] PATH | URL | – -t name:tag 表示给镜像命名,并指定标签(相当于版本号) -f Dockerfile 指定Dockerfile文件,默认为’PATH/Dockerfile’,即当前目录下的Dockerfile-t name:tag 表示给镜像命名,并指定标签(相当于版本号) PATH 表示本地工作目录(也就是命令最后的 . ,我这里是项目文件夹) 示例:(注意命令的执行目录和工作目录) docker build -t slide-verify:1.0 . 镜像操作命令: 查看本机镜像:docker images 移除指定镜像: docker image rm 镜像ID docker rmi 镜像ID 清除无效镜像:docker image prune(清除没有名称且未被使用的镜像) 查看镜像信息:docker inspect 镜像ID 容器操作命令: 运行容器:docker run -it -p 5000:80 --name slide-verify10 slide-verify:1.0 查看运行中的容器: docker ps docker container ls 查看全部容器:docker ps -a 移除容器:docker container rm 容器ID 启动容器:docker start 容器ID 关闭容器:docker stop 容器ID 重启容器:docker restart 容器ID 进入容器:docker exec -it 容器ID /bin/bash (相当于远程登录虚拟机) 退出容器:exit […]
View Details今天聊一聊Dockerfile,docker build,希望通过这篇文章,能让你对docker镜像构建过程有一个认识。 事情还得从一次Docker镜像创建失败说起。 问题背景: 环境VS2017,dotnet 2.1 版本 ,使用默认生成的Dockerfile文件,当我使用docker build命令创建镜像的时候,竟然报错了
1 2 |
Step 6/16 : ...... COPY failed: stat /mnt/sda1/var/lib/docker/tmp/docker-builder802544848/EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj: no such file or directory |
错误信息是,第6步,找不到指定的文件或文件夹,由于我执行docker build命令的路径与 项目文件(xxx.csproj)在同一目录下,所以,这个文件找不到也很正常,那到底是哪里出问题了呢?我们来捋一捋。 执行docker build命令的路径与项目文件(xxx.csproj)在同一路径。 docker build 命令如下:
1 |
docker build -t slide-verify:1.0 . |
Dockerfile内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY ["EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj", "EasySlideVerificationDemoServer/"] RUN dotnet restore "EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj" COPY . . WORKDIR "/src/EasySlideVerificationDemoServer" RUN dotnet build "EasySlideVerificationDemoServer.csproj" -c Release -o /app FROM build AS publish RUN dotnet publish "EasySlideVerificationDemoServer.csproj" -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "EasySlideVerificationDemoServer.dll"] |
Docker镜像生成原理: Docker镜像与操作系统镜像本质上是一样的,首先需要一个基础镜像,然后在基础镜像上搭建所需环境,安装软件,最后生成一个新的镜像,新的镜像就可以在Docker中进行部署,生成容器实例,从而开始运行服务。 Dockerfile中的命令: 从上面Dockerfile中,我们可以看到有这几个命令:FROM,WORKDIR,EXPOSE,COPY,RUN,ENTRYPOINT,大概了解一下这几个命令的意思。 FROM: 指定一个基础镜像 WORKDIR: 在镜像内指定一个目录,作为当前工作目录 EXPOSE: 指定端口号 COPY: 从一个目录(这个目录可以是本地目录或中间镜像的目录)中复制文件或者目录到容器里指定路径 RUN: 在镜像内执行相应命令 ENTRYPOINT: 入口点,与RUN类似,同样是执行程序命令,表示容器启动时需要执行的命令。 Dockerfile文件解读: 我们来解读一下这个Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
将镜像 microsoft/dotnet:2.1-aspnetcore-runtime 作为基础镜像 (base) 指定镜像内工作目录为:/app 指定端口号为:80 将镜像 microsoft/dotnet:2.1-sdk 作为系统构建中间镜像(build) 指定镜像内工作目录为: /src 复制项目文件 "EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj" 到镜像目录 "EasySlideVerificationDemoServer/" 执行dotnet restore命令: dotnet restore "EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj" 复制当前目录下所有文件到镜像的工作目录(/src)下:COPY . . 指定新的工作目录: "/src/EasySlideVerificationDemoServer" 执行dotnet build命令: dotnet build "EasySlideVerificationDemoServer.csproj" -c Release -o /app 将构建好的中间镜像(build) 作为发布中间镜像(publish) 执行dotnet publish命令: dotnet publish "EasySlideVerificationDemoServer.csproj" -c Release -o /app 将基础镜像(base)作为最终镜像(final) 指定工作目录: /app 复制发布中间镜像(publish)中的/app目录到工作目录:COPY --from=publish /app . 指定入口点命令:ENTRYPOINT ["dotnet", "EasySlideVerificationDemoServer.dll"] |
解读完之后,我们了解了这个Dockerfile究竟做了哪些事情。 镜像构建命令: 然后看一下Docker镜像构建命令:docker build。 命令行输入:docker build --help,可查看完整使用方式,此处省略。 Usage: docker build [OPTIONS] PATH | URL | – 下面是我使用的构建命令:
1 |
docker build -t slide-verify:1.0 . |
-t name:tag 表示给镜像命名,并指定标签(相当于版本号) -f Dockerfile 指定Dockerfile文件,默认为’PATH/Dockerfile’,即当前目录下的Dockerfile PATH 表示本地工作目录(也就是命令最后的 . ,我这里是项目文件夹) 发现问题: 到这里不难发现,由于镜像构建命令的执行目录与项目文件所在目录一致,并且命令中PATH指定的是当前目录(.),也就是项目文件所在目录,而Dockerfile中文件复制命令明显是在项目文件的上一级,即解决方案文件夹目录, 这样问题似乎就容易解决了,将构建命令改成下面的格式,果不其然,构建成功。
1 |
docker build -t slide-verify:1.3 -f Dockerfile .. |
然后执行docker run命令,运行构建好的镜像,启动成功,浏览器访问:http://192.168.99.100:5008/ ,项目成功运行。
1 |
docker run -it -p 5008:80 --name slide-verify13 slide-verify:1.3 |
使用进阶: 我们回头再看一下Dockerfile文件,文件中的5到14行命令,包含了源码复制,项目还原(restore),构建(build),发布(publish)几个步骤。
1 2 3 4 5 6 7 8 9 10 |
FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY ["EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj", "EasySlideVerificationDemoServer/"] RUN dotnet restore "EasySlideVerificationDemoServer/EasySlideVerificationDemoServer.csproj" COPY . . WORKDIR "/src/EasySlideVerificationDemoServer" RUN dotnet build "EasySlideVerificationDemoServer.csproj" -c Release -o /app FROM build AS publish RUN dotnet publish "EasySlideVerificationDemoServer.csproj" -c Release -o /app |
[…]
View Details