跨Docker容器共享预编译资产

tom*_*ham 21 ruby-on-rails nginx docker

我有一个与我的rails容器分开的nginx容器,并且希望能够使用nginx容器从rails提供预编译资产.这听起来像卷容器的工作,但我很快就需要学习docker并无休止地阅读文档.有人不得不处理类似的情况吗?

Fáb*_*sta 17

我有同样的问题.这是我目前正在做的事情:

选项1:对nginx和app使用单个图像

这样,我可以构建一次图像(使用app,预编译资产和nginx),然后运行它的两个实例:一个运行app服务器,另一个运行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
Run Code Online (Sandbox Code Playgroud)

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

选项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
Run Code Online (Sandbox Code Playgroud)

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

选项3:在构建时将资产分配给CDN

您的Dockerfile可以将生成的资产直接上传到CDN.然后配置您的Rails应用程序以将其用作asset_host.就像是:

RUN rake assets:precompile && aws s3 sync public/assets s3://test-assets/
Run Code Online (Sandbox Code Playgroud)

我正在尝试这个选项.由于我使用的是Amazon CloudFront,看起来我可以使用AWS CLI将生成的资产同步到S3.还有一个宝石(asset_sync),但它看起来很陈旧.

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

  • 我刚刚实现了选项 2,但使用了一个持久的 docker 卷容器。它奏效了。谢谢 (2认同)

Max*_*kov 5

我建议在Docker容器中预编译资源,因为在这种情况下你可以毫无问题地将它运行到任何环境,否则在运行docker容器之前你应该将共享的预编译资产复制到新环境,只有在它运行docker容器之后才能挂载它们.

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

  • 另一种选择是在构建期间为每个可能的环境预编译资产。在应用程序启动时编译资产意味着您的应用程序可能需要 1 分钟或更长时间才能启动:( (2认同)