【问题标题】:docker-compose empty volume with a rails app on OSX在 OSX 上使用 rails 应用程序 docker-compose 空卷
【发布时间】:2019-11-26 19:11:41
【问题描述】:

不知道如何问这个问题,因为我无法理解这个问题。另外,我不是码头专家,这可能是一个愚蠢的问题。

我有一个带有 docker-compose 的 Rails 项目。而且有2种情况。首先,我能够使用 docker-compose up 构建和运行应用程序,一切看起来都很好,问题是当我更改代码时代码没有重新加载。其次,当我在docker-compose.yml中添加一个volume时,docker-compose up因为找不到Gemfile而退出,挂载的文件夹是空的。

Dockerfile 和 docker-compose.yml 提取,我重命名了一些东西:

# File: Dockerfile.app
FROM ruby:2.5-slim-stretch

RUN apt-get update -qq && apt-get install -y redis-tools
RUN apt-get install -y autoconf bison build-essential  #(..etc...)

RUN echo "gem: --no-document" > ~/.gemrc
RUN gem install bundler

ADD . /docker-projects
WORKDIR /docker-projects/project1/core
ENV BUNDLE_APP_CONFIG /docker-projects/project1/core/.bundle
RUN /bin/sh -c bundle install --local --jobs

# File: docker-compose.yml
app:
  build: .
  dockerfile: Dockerfile.app
  command: /bin/sh -c "bundle exec rails s -p 8080 -b 0.0.0.0"
  ports:
    - "8080:8080"
  expose:
    - "8080"
  volumes:
    - .:/docker-projects
  links:
    - redis
    - mysql
    - memcached

我的 'docker-projects' 是一个由不同的 rails_engines 和 gems 库组成的大项目。我们使用“repo”工具来管理它。

运行 docker-compose build app 工作正常,我可以看到捆绑安装日志。然后 docker-compose up app 退出并出现错误“未找到 Gemfile”。

直到我决定从 docker 容器中恢复 50gb 的空间并重建所有东西之前,它都可以正常工作。不确定发生了什么变化。

如果我添加卷(docker-compose),安装的卷是空的。如果我删除卷(docker-compose),代码不会按原样重新加载。

我正在使用的版本:

Docker version 18.09.7, build 2d0083d
OSX 10.14.5
docker (through brew) with xhyve driver

我尝试了一个新的基本 docker-compose 项目,但没有遇到这个问题。有任何想法吗?我会继续寻找。

谢谢。

【问题讨论】:

  • 你是否在 docker 文件中使用了复制指令,它将你的本地卷推送到容器卷中
  • docker-compose up exit,那你怎么知道mounted folder是空的?
  • @atline 我收到错误“找不到 Gemfile”,我也能够运行 bash 并看到没有文件。
  • 您不需要|想要复制 Dockerfile ADD . /docker-projectsWORKDIR /docker-projects 与 docker-compose.yml volumes: - .:/docker-projects
  • 如果您将WORKDIR 移动到ADD 之前(并修改路径),那么您应该能够将前5 个RUN 语句组合成一个RUN ... && ... && ... 语句。每个RUN 语句都会生成一个新的 docker 层。除非您需要这些不同的层,否则将它们组合起来会更有效。您可以使用rm -rf /var/lib/apt/lists/* 完成此RUN 块以清除已安装的软件包。

标签: ruby-on-rails docker docker-compose volumes


【解决方案1】:

如果您将docker-compose.yaml 文件完整包含在内,您的问题将会受益,以便我们了解您在做什么。

根据您所包含的内容,我有(不相互排斥的)假设:

可能性#1:图像构建可能只运行一次,而不是每次运行docker-compose。当您运行docker-compose 时,如果它在本地找到相关图像,则不会重建它们。如果您删除本地图像,或者您强制更改,则图像将被重建。

如果不重建图像,则不会反映对源的更改。

可能性#2:您的Dockerfile 使用ADD . /app。构建此映像时,当前目录 (.) 中的文件将复制到映像的 /app 文件夹中。这仅在构建期间发生。

可能性 #3:您引用了 volumes/app,但此挂载点已存在于您为其包含 Dockerfile (ADD . /app) 的容器映像中。我不确定这种行为的后果是什么,但您可能会覆盖容器的/app 目录(其中包含您ADD . /app 的文件)。这是多余的。

最佳实践

在容器映像中更改源文件被认为是不是的好习惯。容器经常使用的一种做法是不可变的基础设施。这个想法是,虽然数据可能会改变,但容器的应用程序|进程|二进制文件不会改变。

如果今天给我golang:1.12,它应该总是完全一样的。如果 Golang 1.12 有变化——即使它是一个变量重命名——Go 团队也会升级版本并创建可能的 Golang 1.12.1。然后我会期待一个新的容器镜像golang:1.12.1

这种做法由 docker 标签强制执行,这是 docker 标签不“值得信赖”的(众多)原因之一。

因此,最佳做法是每次在源文件更改时重建图像。

您会经常看到——而且这是一个很好的机制——人们将为每个 e.g. git 提交。提交的哈希值通常也用于标记容器映像,但这是可选的。

【讨论】:

  • 我更新了问题。每次我添加测试或检查一些小改动后是否有工作都需要很长时间进行重建。我说的是rails应用程序代码。我知道其余的图像(mysql、redis 等)应该保持不变。
【解决方案2】:

好的,我发现了问题。这是我用来生成 docker-machine 的命令:

docker-machine create default \
--driver xhyve \
--xhyve-cpu-count 4 \
--xhyve-memory-size 12288 \
--xhyve-disk-size 256000 \
--xhyve-experimental-nfs-share \
--xhyve-boot2docker-url https://github.com/boot2docker/boot2docker/releases/download/v18.06.1-ce/boot2docker.iso 

我可能在中间进行了升级,因为不再工作了。 docker-maching 显示了一些关于 NFS 与我现有的 /etc/exports 定义冲突的警告,但机器已创建。

四处搜索后,我意识到我必须像这样重写上面的命令:

docker-machine create default \
--driver=xhyve \
--xhyve-cpu-count=4 \
--xhyve-memory-size=12288 \
--xhyve-disk-size=256000 \
--xhyve-boot2docker-url="https://github.com/boot2docker/boot2docker/releases/download/v18.06.1-ce/boot2docker.iso" \
--xhyve-experimental-nfs-share=/Users \
--xhyve-experimental-nfs-share-root "/"

“=”旁边的区别在于 *-nfs-share 选项。我评论了我的 /etc/exports 以避免冲突警告,并重新创建了机器。现在它像以前一样工作。

--xhyve-experimental-nfs-share-root 选项默认是“/xhyve-nfsshares”,所以我把它改成了“/”。

【讨论】:

    猜你喜欢
    • 2018-06-05
    • 1970-01-01
    • 2018-02-14
    • 2018-01-31
    • 2021-08-19
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多