乐趣区

关于devops:静态WEB容器镜像最小化实践

在古代的 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 nginx
nginx    1.22-alpine    23.5MB

能够看到其大小为 23.5MB

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

FROM mengzyou/hugo:0.106 AS builder
COPY --chown=hugo:hugo . /home/hugo/app
RUN hugo

FROM nginx:1.22-alpine
COPY --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 myblog
myblog  nginx   29MB

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

Easyhttpd On Alpine

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

镜像我已公布在 mengzyou/easyhttpd。

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

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

...
FROM mengzyou/easyhttpd:v0.0.1
COPY --from=builder --chown=http:www /home/hugo/app/public/ /srv/www
$ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep myblog
myblog  nginx   29MB
myblog  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 bbhttpd
mengzyou/bbhttpd        1.35    155kB

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

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

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

总结

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

根底镜像 nginx:1.22-alpne mengzyou/easyhttpd:v0.0.1 mengzyou/bbhttpd:1.35
Size 23.5MB 13.7MB 155KB

同步公布在 Mengz’s Blog

退出移动版