2017年12月23日

用Docker部署dotnet core网站

作者 非鱼

UCloud推出了按量收费的容器服务CAAS,测试一下。将之前开发的生成图片二维码的Api接口的dotnetcore网站做成容器。

在Mac里安装Docker,启动。

新建一个目录,将publish发布到linux-x64版本的目标文件夹放到该目录下,在该目录下新建Dockerfile文件,内容如下:

# Build runtime image
FROM microsoft/dotnet:2.0-runtime-jessie
WORKDIR /app
COPY ./unfish_api/ .
ENV ASPNETCORE_ENVIRONMENT Development
ENTRYPOINT ["dotnet", "ArtQRCodeWeb.dll"]
RUN apt-get update
RUN apt-get install -y libgdiplus
RUN apt-get clean

该文件的内容是经常N多次尝试之后才终于成功的一次。试了官方的各种镜像,以及下面的各种安装步骤。其中unfish_api目录就是放程序发布目录的文件夹名称。

然后生成自己的镜像:

sudo docker build -t qrcodeapi .

其中qrcodeapi就是镜像的名字。(没加sudo的时候会报错)

然后启动镜像:

sudo docker run -d -p 5000:5000 --name qrcoderun qrcodeapi

然后本机访问http://localhost:5000,就可以看到效果了,测试图片生成的Api接口也没有问题。

然后根据UCloud的官方文档上传镜像:

到UHub中新建自己的镜像库,然后本地通过docker login登录,然后docker tag标记镜像,然后docker push上传。
然后就可以到CAAS管理界面新建一个服务,新建一个Pod配置(Pod配置是用来指定使用哪些镜像的,一个Pod配置可以包含多种镜像,同步启动)。

然后在服务里面新建副本集,选定要使用的Pod配置,要使用的Pod节点数和每个节点的配置,Pod配置中的所有镜像都会分别启动在每个Pod节点中,然后设定转发端口和转发优先级(不同副本使用不同的转发优先级就可以做灰度发布),完成后Pod节点启动,容器就在运行了。

可以访问每个Pod自己的IP+你的端口来测试,然后使用整个服务的IP+端口来正式使用里面的服务。以后根据使用量来增加副本集和Pod数就可以做到随时扩容了。

不过要在生产环境上使用,还得在前面再加一个nginx代理来隐藏端口调用。


续:因为dotnetcore发布到linux的时候,把所有的依赖的系统dll都放到了发布目录,所以整个项目虽然非常简单,几乎啥代码也没有,但是发布项目有100M,而既然你只改了一行代码重新编译发布,只有项目的主Dll发生了一点点变化,实际只有一个20K的文件发生了变化,但是如果你使用这个Dockerfile重新build镜像,那生成的镜像的差异版本依然有100M,因为它把copy文件这一步作为一个整体的差异镜像,相应的,需要上传到ucloud的镜像也要上传100M的文件。

解决方案:
建一个子docker项目,写个新的Dockerfile,使用自己的镜像作为源镜像,也就是第一行改成:
FROM qrcodeapi

把项目本身的dll和网页文件放在这个子目录下的文件目录里,copy命令只复制这个文件夹。
当然,相应的执行Build命令的时候要使用一个新的image名字了。这样重新生成以后需要上传的镜像文件文件就只有3M了。(如果是纯接口类站点没有静态文件的话,只有20K)

另外,基于这个源镜像,其它所有的同类dotnetcore网站都可以这样操作,只复制本项目自己的文件,因为其它的系统依赖文件基本上是一模一样的。