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

时间:2019-07-17 21:57:02

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

由于我无法理解问题,因此不确定如何提出此问题。另外,我不是Docker专家,这可能是一个愚蠢的问题。

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

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库组成的大项目。我们使用“回购”工具对此进行管理。

运行 docker-compose build app 运行正常,我可以看到捆绑软件安装日志。然后 docker-compose up应用退出,错误“找不到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项目,但没有这个问题。有任何想法吗?我会继续寻找。

谢谢。

2 个答案:

答案 0 :(得分:0)

您的问题将受益于完整包含docker-compose.yaml文件,以便我们了解您的工作。

根据您所包括的内容,我有(但并非互斥)假设:

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

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

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

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

最佳实践

更改容器映像中的源文件被认为是 not 的一种好习惯。容器经常使用的一种做法是不可变的基础结构。这个想法是,尽管数据可能会更改,但容器的应用程序| embin 不会更改。

如果今天给我golang:1.12,应该总是一样。如果对Golang 1.12进行了更改-即使将其重命名为一个变量-Go团队也会升级该版本并创建Golang 1.12.1。然后,我希望有一个新的容器映像golang:1.12.1

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

因此,最佳实践是在源文件更改时每 次重新构建映像。

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

答案 1 :(得分:0)

好的,我发现了问题。这是我用来生成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”,因此我将其更改为“ /”。