静态WEB容器镜像最小化实践

M Mengz visibility 36 event 2023-01-17 access_time 9 months ago language 中文

在现代的B/S架构应用中,我们会做前后端分离,某些前端Web服务会将编译完成的静态文件放到一个web服务器进行部署。例如,我的博客也是基于Hugo编译的静态文件来进行部署的。


那在容器化部署模式下,我们需要基于一个web服务的基础容器(镜像)将静态文件构建成站点或者Web服务的容器镜像来进行部署。在Docker开发最佳实践中,我们应该尽量保持镜像足够小(Size大小)。因此,我们应该尽量选择满足我们需求的web服务基础镜像足够小。


static-webserver-container


大部分情况下,我们会选择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

More from Kontext
copyright This page is subject to Site terms.
comment Comments
No comments yet.

Please log in or register to comment.

account_circle Log in person_add Register

Log in with external accounts