在古代的B/S架构利用中,咱们会做前后端拆散,某些前端Web服务会将编译实现的动态文件放到一个web服务器进行部署。例如,我的博客也是基于Hugo编译的动态文件来进行部署的。

那在容器化部署模式下,咱们须要基于一个web服务的根底容器(镜像)将动态文件构建成站点或者Web服务的容器镜像来进行部署。在Docker开发最佳实际中,咱们应该尽量放弃镜像足够小(Size大小)。因而,咱们应该尽量抉择满足咱们需要的web服务根底镜像足够小。

大部分状况下,咱们会抉择Nginx作为咱们的web服务器,一开始我也是这么抉择的,因为社区在Docker Hub上为咱们提供了开箱即用的容器镜像,上面来看看我用来构建动态web服务的过程。

Nginx On Alpine

咱们晓得在容器构建的实际中,咱们能够抉择基于AlpineLinux为散发零碎的镜像,其比其余(例如 ubuntu, centos等)的镜像会小很多。因而一开始咱们也是抉择基于Alpine的nginx镜像,例如 nginx:1.22-alpine。

$ docker image pull nginx:1.22-alpine$ docker image ls | grep nginxnginx    1.22-alpine    23.5MB

能够看到其大小为 23.5MB

基于该惊醒构建我的博客的公布镜像

FROM mengzyou/hugo:0.106 AS builderCOPY --chown=hugo:hugo . /home/hugo/appRUN hugoFROM nginx:1.22-alpineCOPY --from=builder /home/hugo/app/public/ /usr/share/nginx/html
$ docker build -t myblog:nginx .$ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep myblogmyblog  nginx   29MB

构建进去而最终交付镜像的大小为 29MB

Easyhttpd On Alpine

起初,我发现了一个用GoLang编写的轻量级web服务器 - easyhttpd,于是我Fork了该我的项目,编写了一个Dockerfile来构建该web服务器的镜像,具体可查看该文件内容。

镜像我已公布在mengzyou/easyhttpd。

$ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep easyhttpdmengzyou/easyhttpd      v0.0.1  13.7MB

镜像大小为 13.7MB,比 nginx:alpine 的镜像小了十几MB。应用该镜像构建来构建我的博客站点

...FROM mengzyou/easyhttpd:v0.0.1COPY --from=builder --chown=http:www /home/hugo/app/public/ /srv/www
$ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep myblogmyblog  nginx   29MBmyblog  ehttpd  19.1MB

失去的利用镜像大小为 19.1MB ,进一步缩小了利用的镜像大小。

BusyBox Httpd

最近看到了一个国外的博客文章,能够构建一个只有 ~155KB 大小的web服务器镜像,我十分好奇,向着是否能够进一步缩小我的动态站点的镜像大小。

是应用了BusyBox内置的httpd来动态文件提供web服务。于是我也学习该作者创立了一个基于busybox - httpd的web服务器镜像,将其命名为 bbhttpd,具体的构建内容请参考Github仓库 - docker-bbhttpd。

构建的镜像我也公布到Docker Hub - mengzyou/bbhttpd

$ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep bbhttpdmengzyou/bbhttpd        1.35    155kB

镜像大小的确只有 155KB,是不是挺惊人的?应用该镜像来构建我的站点

...FROM mengzyou/bbhttpd:1.35COPY --from=builder --chown=www:www /home/hugo/app/public/ /home/www/html
docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep myblogmyblog  nginx   29MBmyblog  ehttpd  19.1MBmyblog  bbhttpd 5.64MB

最终的交付镜像大小只有 1.64MB,简直也就是web服务动态文件的大小。

总结

依照Docker容器镜像构建的最佳实际,咱们应该尽量放弃最小的经销大小,而缩小镜像大小的一个办法就是抉择足够小的根底镜像。因而咱们在构建动态Web服务的时候,能够通过本人构建根底镜像的形式,大大减少最终的镜像大小。

根底镜像nginx:1.22-alpnemengzyou/easyhttpd:v0.0.1mengzyou/bbhttpd:1.35
Size23.5MB13.7MB155KB
同步公布在 Mengz's Blog