Elastic BeanStalk Docker应用程序,编写本地文件

我有一个play scala应用程序,我通过AWS Elasticbeanstalk控制台将其作为通用Docker应用程序进行部署。 当我在本地运行应用程序时,我没有看到任何问题,所以我认为代码是正确的。 我需要有能力

  • 将文件写入本地磁盘
  • 在这些文件上运行一些命令行工具(如ffmpeg)

但是,我的应用程序不写入本地磁盘,也不让我执行命令行实用程序。

val localFile = new File(s"$localFilePath/$siteId/download/${fileName}.raw") s3Client.getObject(new GetObjectRequest(bucketName, summary.getKey), localFile) val cmd = s"ffmpeg -i ${localFile.getAbsolutePath} -vcodec copy ${localFile.getAbsolutePath}.mp4" cmd !; 

这是我的Dockerrun.aws.json文件

 {"AWSEBDockerrunVersion": "1","Logging": "/opt/docker/logs"} 

更新更新我的Dockerrun.aws.json文件以包含卷映射

 {"AWSEBDockerrunVersion": "1","Logging": "/opt/docker/logs","Volumes":[{"HostDirectory": "/tmp/files","ContainerDirectory": "/tmp/files"}]} 

该应用程序正在编写本地文件,但由于某种原因无法运行ffmpeg。

 Exception : Cannot run program "ffmpeg": error=2, No such file or directory 

TL; DR- ffmpeg在应用程序中找不到,因为您的代码在容器操作系统中运行时,将其安装在主机操作系统上。 要解决这个问题,通过编写一个自定义的Dockerfile来在你的容器中安装ffmpeg

软件容器

现在,为了更好地理解你的问题,你必须明白,软件容器是一种特殊的虚拟化 。 也就是说,容器内的操作系统与主机操作系统以及同一台计算机上的其他容器完全分离 ,无论是笔记本电脑还是EC2实例。 容器可能与主机操作系统或同一台机器上的其他容器共享一些信息,但是您需要执行显式操作才能实现(即Docker卷)。

Docker容器是特定types的软件容器。 有关Docker和容器的一些基本信息可以在官方的“ 什么是Docker”页面find。

容器vs虚拟机

容器与虚拟机有一点相似,但是在我看来,容器与二者之间的相似性有更多的不同。 它们是相似的,它们允许您在同一个硬件上运行多个应用程序,而每个应用程序都有自己独立的虚拟环境。 它们与虚拟机中的虚拟机不同 – 虚拟机上的应用程序与同一主机上的其他应用程序共享相同的硬件 ,容器内的应用程序共享主机的硬件和操作系统

代码在一个容器是孤立的!

Docker容器通过利用Linux操作系统的特定function ,为每个应用程序提供一个虚拟独立的环境。 每个容器都存在于一个虚拟的孤立环境中,这使得它感觉自己拥有自己的文件系统,networking,进程ID等。这意味着容器内发生的任何事情都不会影响主机,反之亦然。

因此,在使用Docker容器时,通常不会在主机上执行很多操作。 例如,在你的情况下,在主机上安装ffmpeg然后尝试从容器内使用它是错误的。 尽pipe这是可能的,但它却无法实现使用Docker的全部目的。 正确的做法是将所有依赖关系安装容器中。 它不仅可以解决您的No such file问题,还可以让您在任何地方运行您的容器(AWS,GCP,您的笔记本电脑…),并始终如一地工作。 这种可移植性对于容器来说是独一无二的,也是人们使用容器的主要原因之一,因为它可以让你的代码具有一致的行为,因为它始终运行在完全相同的环境中。

用代码打包你的环境

另一种看待它的方法是 – 使用Docker时,用代码打包执行环境。 这是以非常有效和紧凑的方式完成的 – 使用Dockerfile 。 您只需在您的代码所在的根目录中包含一个Dockerfile。 Dockerfile包含创build代码所需的环境以运行所需的所有说明。 在Dockerfile中,您可以安装依赖项,复制文件,更改权限以及执行其他许多操作。 然后,您将创build一个可以启动容器的映像

使用Dockerfiles还允许您版本控制您的依赖项,并提供Chef,Ansible和Puppet等configurationpipe理工具的一个很好的替代品。

我build议你看看Docker网站上的官方培训video 。 他们会让您更好地了解Docker是什么以及如何使用它。

结论

总之,如果您只是想在Elastic Beanstalk上运行代码,则不必使用Docker。 你也许可以让它在Beanstalk的Java环境下运行(尽pipe我自己从来没有这样做过)。 然而,如果你想Docker化你的应用程序,你首先需要更好地理解Docker,因为使用容器需要转换angular度 ,这并不总是很容易做到。