差点就放弃了。搞这些东西没有什么意义。
有个java项目,需要开启ffmpeg拉流,然后想将这个程序部署在docker。不料颇多波折。幸而最后成功,差点就放弃了。记录如下。
一、基本情况
1、我们写了个视频拉流控制程序,依赖JDK1.8。运行过程中,需要启动操作系统的ffmpeg进行拉流。
2、部署环境是统信欧拉版(UOS Euler) + docker。统信欧拉版是基于华为的OpenEuler(其前身是华为的服务器操作系统EulerOs),是将OpenEuler的内核 + 统信的桌面操作模块DDE。
“统信 UOS 欧拉版采用 Linux kernel 4.19、GCC 7.3、Glibc2.28 等组件作为系统运行的基础环境,搭载统信自研 DDE 桌面环境,可提供良好的人机交互功能,并针对华为鲲鹏系列处理器的稳定性和运行性能参数进行了深度调优,可应用于云、虚拟化、容器、大数据、人工智能等场景。”
如果完全是统信自己的版本,基于debian;而统信欧拉内核不一样,感觉统信欧拉更像CentOs。
二、问题描述
像其他jar包一样,构建镜像,生成并运行容器,按部就班,一帆风顺。但在Portainer上看运行日志,傻眼了,说找不到”ffmpeg“这个命令。在命令前面加上绝对路径,”/usr/bin/ffmpeg“,还是说No such file or Diectory。
怎么可能呢?忽然想起,jar包运行在容器里,容器本身相当于一个简单版的虚拟机,跟宿主机是隔开的,ffmpeg装在宿主机上,docker容器里的程序无法访问很正常。
那docker容器里的程序怎样才能访问到ffmpeg呢?
1、采用挂载的方式,将ffmpeg所在路径挂到docker容器里?不行,各种环境依赖没有。
2、构建镜像时,先用ffmpeg作为基础镜像,然后再以JDK8为基础镜像?不行,构建镜像,虽然Dockerfile支持写多个FROM,但却以最后一个为准。前面的基础镜像,其实只适合做临时性的过渡脚垫,用完即弃。可以拷贝到构建中的镜像,然而并没有什么卵用,我试了,出来的镜像没有ffmpeg。
#然而并没有什么卵用
FROM jrottenberg/ffmpeg:4.4-alpine AS FFmpeg
FROM node:16-alpine
COPY --from=FFmpeg / /
- 1
- 2
- 3
- 4
- 5
3、真正有用的是构建镜像时,安装ffmpeg。
但是,docker里怎么安装ffmpeg? Dockerfile这样写:
FROM java:8
RUN yum install ffmpeg
EXPOSE 9977
- 1
- 2
- 3
提示无法识别 yum 命令。
改成apt可以识别,但提示无法找到ffmpeg包。遵照网上教程,安装前先升级apt:
RUN apt update && apt install ffmpeg
- 1
然而并没有什么卵用,apt无法升级,连接到debian,有个包找不着,404。
网上见到有用 apk add 的方式,但仍然提示无法识别apk这个命令。
4、最后发觉是基础镜像问题。不应该 FROM java:8,应该FROM openjdk:8-jdk-alpine,这个基础镜像支持apk。
三、部署步骤
修改Dockerfile如下:
FROM openjdk:8-jdk-alpine
RUN apk add --no-cache ffmpeg
EXPOSE 9977
- 1
- 2
- 3
构建、运行,OK。
四、小结
感觉openjdk:8-jdk-alpine就是为java程序部署在docker上准备的,当然我还没有去查一下它是啥东东。时间太紧了,太多东西不会。