跨 docker 个容器共享预编译资产

Sharing precompiled assets across docker containers

我有一个与我的 rails 容器分开的 nginx 容器,我希望能够使用 nginx 容器提供来自 rails 的预编译资产。这听起来像是卷容器的工作,但在快速需要学习 docker 并无休止地阅读文档后,我感到困惑。有没有人不得不处理类似的情况?

我建议在 Docker 容器内预编译资产,因为在这种情况下你可以毫无问题地 运行 它到任何环境,否则在 运行 docker 容器你应该将共享的预编译资产复制到新环境,安装它们并且仅在它之后 运行 docker 容器。

另一个与资源版本相关的问题。我的意思是您的代码必须使用与其兼容的资产,否则您将遇到 CSS 和 JS 的不同问题。所以,这就是为什么你应该在 Docker 容器内预编译资产的第二点。

对于生产,@maxd 是正确的:您应该将已编译的资产添加到您的图像中。但是,对于发展,我认为您是对的。使用由以下人员使用的卷容器:

  • 用于存储预编译资源的rails容器
  • 为资产提供服务的 nginx 容器

另一种方法是将主机目录挂载到容器中。

您可以在 Managing Data in Containers User Guide

中找到更多帮助

我遇到了同样的问题。这是我目前正在做的事情:

选项 1:为 nginx 和应用程序使用单个图像

这样,我可以构建一次图像(使用应用程序、预编译资产和 nginx),然后 运行 它的两个实例:一个 运行 连接应用程序服务器,另一个用于nginx 前端:

docker build -t hello .
docker run --name hello-app hello rackup
docker run --name hello-web -p 80:80 --link hello-app:app hello nginx

不漂亮,但很容易设置和升级。

选项 2:使用共享卷,并将资产预编译为作业

共享卷无法在构建过程中更新,但可以通过容器实例更新。因此我们可以 运行 我们的 rake 任务在 运行 应用程序之前预编译资产:

docker build -t hello .
docker run -v /apps/hello/assets:/app/public/assets hello rake assets:precompile
docker run --name hello-app hello rackup
docker run --name hello-web -p 80:80 --link hello-app:app -v /apps/hello/assets:/usr/share/nginx/html/assets nginx

这看起来像是一个更强大的选项,但需要更复杂的检测。但是,我倾向于这个选项,因为无论如何我们都需要一个单独的数据库迁移作业。

选项 3:在构建时将资产分发到 CDN

您的 Dockerfile 可以将生成的资产直接上传到 CDN。然后配置 Rails 应用程序以将其用作 asset_host。类似于:

RUN rake assets:precompile && aws s3 sync public/assets s3://test-assets/

我目前正在试用此选项。由于我使用的是 Amazon CloudFront,看起来我可以使用 AWS CLI 将生成的资产同步到 S3。还有一个 gem(asset_sync),但它看起来陈旧。

缺点是您必须将所需的 AWS 凭据发送到构建上下文或 Dockerfile 本身——如果您使用的是自动构建,这可能需要将它们提交到您的源存储库。

Define a VOLUME in Dockerfile

And then use --volumes-from during run of another container