【问题标题】:Sharing precompiled assets across docker containers跨 docker 容器共享预编译资产
【发布时间】:2015-03-09 20:27:10
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails nginx docker


    【解决方案1】:

    我也有同样的问题。以下是我目前的工作:

    选项 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。还有一个宝石 (asset_sync),但它看起来很陈旧。

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

    【讨论】:

    • 选项 2 真是个好主意。我将更新我的容器以遵循此模式
    • 我已经编辑了答案以提供第三个选项,我目前正在研究。
    • 我刚刚实现了选项 2,但使用了持久的 docker 卷容器。它奏效了。谢谢
    • 您有选项 2 的示例,但格式为 docker-compose.yml 吗?
    • 再想一想,所有选项似乎都很糟糕:( - 选项 2 特别是因为它意味着应用程序启动时间极慢,选项 3 不适合开发。希望 docker 在构建期间实现共享卷。多在更高版本的 Docker 中,-stage 构建似乎是一种可能的解决方案。
    【解决方案2】:

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

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

    【讨论】:

    • 另一种选择是在构建期间为每个可能的环境预编译资产。在应用启动时编译资产意味着您的应用可能需要 1 分钟或更长时间才能启动 :(
    【解决方案3】:

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

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

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

    您可以在Managing Data in Containers User Guide找到更多帮助

    【讨论】:

      【解决方案4】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 2020-12-03
      • 1970-01-01
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多