如何自定义Docker基础镜像

Xy718 1,068 2023-06-30

在云原生及各种跨语言、跨架构的业务系统中 使用自定义的Docker镜像是非常基础的需求~

假设主要业务系统使用Springboot开发,而部分RPA系统使用Python|Golang开发,这个时候为了保证镜像的纯粹和瘦身,就需要为各种模块和组件准备不同的Docker镜像:

  • biz-spring:1.0.0
  • rpa-py:1.0.0
  • rpa-go:1.0.0
  • web-tengine:1.0.0

等等

制作一个Docker基础镜像主要分为以下几步

  1. 选取一个公共开源基础镜像
  2. 启动镜像及安装各种组件和操作
  3. 保存导出镜像
  4. 推送镜像到私有registry

这里模拟一个RPA项目,然后为了RPA项目中的脚本能够分离成多个镜像以及在每次CI时不用重复性的pip install而制作的基础镜像

选取一个公共开源基础镜像

这里因为RPA使用的python selenium技术,所以我们选择python:3.9-alpine为基础镜像

docker pull python:3.9-alpine

这个镜像只占47.8MB,极致之瘦!
image-1688125191659

启动镜像及安装各种组件和操作

我们需要对这个alpine镜像做各种各样的基础操作,使之可以运行我们的RPA脚本
先启动并且进入到容器

docker run --name mypython -it python:3.9-alpine /bin/sh

这里我创建了一个mypython容器用来操作
image
安装我们需要的所有依赖:

#需要的基础构件
apk add -U --no-cache --virtual=build-dependencies \
    build-base \
    freetype-dev \
    lcms2-dev \
    libgcc \
    libxslt-dev \
    linux-headers 

#相关业务运行需要的基本依赖
pip install --no-cache-dir numpy==1.24.3 opencv-python==4.7.0.72 selenium==4.9.0 requests==2.29.0

image

image-1688126354014
因为本文的业务较为简单,安装完依赖之后就没有操作了,读者可以根据实际情况再做一些自定义的操作,比如设置某些默认ENV、创建一个home目录下的readme文件、埋一些小彩蛋,之类的

保存导出镜像

使用docker commit指令将指定容器打包成镜像

docker commit -a "<you name>" <container_id> <target_image_name>

image-1688302481664
这样我们给指定特殊业务使用的基础镜像就打好了,大小在560MB

推送镜像到私有registry

这一步看情况可以省略,但是目前大部分使用云原生或容器技术的公司都会有自己的registry,这里简单介绍下

#将本地镜像修改为目标tag
docker tag my-rpa-worker <target_tag_name>
#推送image
docker push <target_tag_name>

image-1688303131458
image-1688303165015

这样你就可以在你的项目中愉快的使用该base镜像了~

像这样:

FROM <you_registry>/py-rpa-worker-base:latest
LABEL author="Xy718<jin@xy718.xyz>"

ENV TZ Asia/Shanghai

COPY xxx.py app.sh /

RUN chmod 744 /app.sh
CMD /app.sh

即可

这个基础镜像构建花了差不多有30分钟左右(视网络和母机CPU而浮动),如果每次CI构建时在项目的Dockerfile中使用RUN apk add或者RUN pip install不仅浪费时间,还消耗网络和CI算力资源,所以这个基础镜像的存在非常必要


冶心·练体·得技