docker-在 OSX 上使用 rails 应用程序编写空卷

docker-compose empty volume with a rails app on OSX

不知道怎么问这个问题,因为我不明白这个问题。另外,我不是 docker 专家,这可能是个愚蠢的问题。

我有一个使用 docker-compose 的 Rails 项目。还有2种情况。首先,我能够使用 docker-compose up 构建和 运行 应用程序,一切看起来都很好,问题是当我更改时代码没有重新加载它。二、我在docker-compose.yml添加卷时,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 not found'。

在我决定从 docker 容器中恢复 50gb 的 space 并重建所有内容之前,它一直没有问题。不确定发生了什么变化。

如果我添加卷(docker-compose),安装的卷是空的。如果我删除音量(docker-compose),代码不会像以前那样重新加载。

我使用的版本:

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

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

谢谢。

如果您完整地包含了 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标签不是[的(众多)原因之一'trustworthy'.

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

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

好的,我找到问题了。这是我用来生成 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”,所以我把它改成了“/”。