项目中一直使用docker,但是还没有机会自己亲自制作一款,心里总有一些不痛快,最近一个小项目需要把rtsp转换为支持web原生播放的视频格式,经过多方对比最终选择了ZLMediakit,本博文就以ZLMediaKit镜像制作为例,介绍Docker镜像制作流程。
基础知识补充:什么是Docker为什么要用Docker,这个连接应该是官方的,讲的很清晰,包括在Docker制作过程中可能用到的一些命令的具体含义都可以通过该连接学习什么是 Docker · Docker -- 从入门到实践 (docker-practice.github.io)
为什么要用 Docker · Docker -- 从入门到实践 (docker-practice.github.io)
docker镜像文件使用DockerFile脚本文件完成制作。使用DockerFile脚本需要主意以下几点:
打包Docker镜像的核心步骤可以分为以下几点:
选择基础镜像
DockerFile文件编辑;
所谓制作镜像,那一定是以一个镜像为基础,在其上进行定制。基础镜像是必须指定的。而?FROM
?就是指定?基础镜像,因此一个?Dockerfile
?中?FROM
?是必备的指令,并且必须是第一条指令。如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如?ubuntu、debian、centos、fedora、alpine?等,这些操作系统的软件库为我们提供了更广阔的扩展空间。除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为?scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
FROM scratch
...
如果你以?scratch
?为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接?FROM scratch
?会让镜像体积更加小巧。使用?Go 语言?开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。
下面以一个简单的Dockerfile文件为例简绍如何制作docker镜像
FROM ubuntu:18.04 //选择基础镜像
LABEL maintainer "Dong <heibao111728@126.com>"
#shell,rtmp,rtsp,rtsps,http,https,rtp
EXPOSE 9000/tcp //暗示需要映射9000的tcp端口,这里只是提示实际映射需要通过docker run完成
EXPOSE 1935/tcp
EXPOSE 554/tcp
EXPOSE 322/tcp
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 10000/udp
EXPOSE 10000/tcp
WORKDIR /opt/media/ZLMediaKit/ //指定工作路径
COPY ZLMediaKit/ /opt/media/ZLMediaKit/ //将编译生成的可运行文件拷贝至工作路径
ENV PATH /opt/media/ZLMediaKit/:$PATH //设置环境变量
ENV LD_LIBRARY_PATH /opt/media/ZLMediaKit/:$LD_LIBRARY_PATH //设置环境变量
CMD ["MediaServer", "-c", "config.ini"] //指定运行命令
假设上面文件命名为“Dockerfile_Dong.devel”,执行下面语句完成镜像制作
docker build -t dongzlmediakit:20.04-devel-ubuntu18.04 -f ubuntu18.04/Dockerfile_Dong.devel .
这里我们使用了?docker build
?命令进行镜像构建。其格式为:
docker build [选项] <上下文路径/URL/->
在这里我们指定了最终镜像的名称 -t dongzlmediakit:20.04-devel-ubuntu18.04
,构建成功后,j就可以通过执行“docker images”查询到刚才建立的镜像。
如果注意,会看到?docker build
?命令最后有一个?.
。.
?表示当前目录,而?Dockerfile
?就在当前目录,因此不少初学者以为这个路径是在指定?Dockerfile
?所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定?上下文路径。那么什么是上下文呢?参考这个连接
使用 Dockerfile 定制镜像 · Docker -- 从入门到实践 (docker-practice.github.io)
完整的构建流程参见如下
root@jtdz:~/ZLMediaKit/docker#
root@jtdz:~/ZLMediaKit/docker# ls
build_docker_images.sh centos7 ubuntu16.04 ubuntu18.04 ZLMediaKit
root@jtdz:~/ZLMediaKit/docker#
root@jtdz:~/ZLMediaKit/docker#
root@jtdz:~/ZLMediaKit/docker# docker build -t dongzlmediakit:20.04-devel-ubuntu18.04 -f ubuntu18.04/Dockerfile_Dong.devel .
Sending build context to Docker daemon 612.6MB
Step 1/15 : FROM ubuntu:18.04
---> 5a214d77f5d7
Step 2/15 : LABEL maintainer "Dong <heibao111728@126.com>"
---> Running in 249e9a8b847b
Removing intermediate container 249e9a8b847b
---> af084624cefe
Step 3/15 : EXPOSE 9000/tcp
---> Running in 5224972f689d
Removing intermediate container 5224972f689d
---> 7df1a1e8606a
Step 4/15 : EXPOSE 1935/tcp
---> Running in e3312b4f7d33
Removing intermediate container e3312b4f7d33
---> e140d5bcf86c
Step 5/15 : EXPOSE 554/tcp
---> Running in 75c6b3ecbaa4
Removing intermediate container 75c6b3ecbaa4
---> c222f645a935
Step 6/15 : EXPOSE 322/tcp
---> Running in 9ab229366286
Removing intermediate container 9ab229366286
---> 89835fae9923
Step 7/15 : EXPOSE 80/tcp
---> Running in 2b039a3e43cf
Removing intermediate container 2b039a3e43cf
---> 22128a237e1e
Step 8/15 : EXPOSE 443/tcp
---> Running in e97519578036
Removing intermediate container e97519578036
---> 498433b3b765
Step 9/15 : EXPOSE 10000/udp
---> Running in 654b43d09f92
Removing intermediate container 654b43d09f92
---> da55d41c6dbd
Step 10/15 : EXPOSE 10000/tcp
---> Running in fb54c848b158
Removing intermediate container fb54c848b158
---> a0d92e50b1bd
Step 11/15 : WORKDIR /opt/media/ZLMediaKit/
---> Running in 0df93892ebe4
Removing intermediate container 0df93892ebe4
---> c015b8a1d154
Step 12/15 : COPY ZLMediaKit/ /opt/media/ZLMediaKit/
---> 38d458344dd5
Step 13/15 : ENV PATH /opt/media/ZLMediaKit/:$PATH
---> Running in 384e053ece61
Removing intermediate container 384e053ece61
---> cec32d237a01
Step 14/15 : ENV LD_LIBRARY_PATH /opt/media/ZLMediaKit/:$LD_LIBRARY_PATH
---> Running in f492ef041d11
Removing intermediate container f492ef041d11
---> 0bf54f8ab195
Step 15/15 : CMD ["MediaServer", "-c", "config.ini"]
---> Running in 15b5eaf6c2b7
Removing intermediate container 15b5eaf6c2b7
---> 2d19ae94d25d
Successfully built 2d19ae94d25d
Successfully tagged dongzlmediakit:20.04-devel-ubuntu18.04
root@jtdz:~/ZLMediaKit/docker#
root@jtdz:~/ZLMediaKit/docker#
root@jtdz:~/ZLMediaKit/docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dongzlmediakit 20.04-devel-ubuntu18.04 2d19ae94d25d 22 seconds ago 676MB
zlmediakit master 6d679ffa9b66 7 days ago 407MB
redis 6.2.10 46f074d948bf 11 months ago 113MB
mysql 8.0 3218b38490ce 2 years ago 516MB
ubuntu 18.04 5a214d77f5d7 2 years ago 63.1MB
ubuntu 16.04 b6f507652425 2 years ago 135MB
tomcat 8.0.18-jre8 ad9a5d210c94 8 years ago 492MB
root@jtdz:~/ZLMediaKit/docker#
其实ZLMediaKit官方提供了构建docker的Dockerfile文件和构建脚本,只是官方提供的Dockerfile文件中使用的github中的连接获取源代码,在国内执行很大概率上会执行失败,因此基于此背景,我手动改了一个基于gitee的Dockerfile,经过测试可以成功构建,文件内容如下
FROM ubuntu:18.04 AS build
#shell,rtmp,rtsp,rtsps,http,https,rtp
EXPOSE 9000/tcp
EXPOSE 1935/tcp
EXPOSE 554/tcp
EXPOSE 322/tcp
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 10000/udp
EXPOSE 10000/tcp
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" \
apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
curl \
vim \
ca-certificates \
tzdata \
libssl-dev \
libmysqlclient-dev \
libx264-dev \
libfaac-dev \
libmp4v2-dev && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth=1 https://gitee.com/xia-chu/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/
WORKDIR /opt/media/ZLMediaKit/build
RUN cmake -DCMAKE_BUILD_TYPE=Release .. && \
make
FROM ubuntu:18.04
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" \
apt-get install -y --no-install-recommends \
vim \
ca-certificates \
tzdata \
libssl-dev \
libx264-dev \
libfaac-dev \
ffmpeg \
libmp4v2-dev && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/media/bin/
COPY --from=build /opt/media/ZLMediaKit/release/linux/Release/MediaServer /opt/media/bin/MediaServer
COPY --from=build /opt/media/ZLMediaKit/release/linux/Release/default.pem /opt/media/bin/default.pem
ENV PATH /opt/media/bin:$PATH
CMD ["MediaServer", "-c", "config.ini"]