在Ubuntu上使用Docker Machine、Docker Compose和Volumes

17

我已经在我的Ubuntu 14.04 LTS主机上使用本地VirtualBox提供程序(其中包含boot2docker)一段时间来开发,现在我使用docker-compose。

最近我决定尝试使用docker-machine(因为它与Pycharm集成),但我遇到了一些问题,例如当我保存一些新代码时,docker容器不再自动更新,我认为这是因为我在我的docker-compose.yml web服务中注释掉了我的卷,但如果我不这样做,我会得到一个manage.py not found错误,所以我在这里理解应该将其注释掉,根据 这里的解释。

我已经在网上阅读了很多内容,想知道是否有一个好的简单方法让docker-machine在Ubuntu上与docker-compose协同工作。

DockerFile

FROM ubuntu:14.04.3
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y \
  build-essential \
  git-core \
  python2.7 \
  python-pip \
  python-dev \
  libpq-dev \
  postgresql-client-9.3 \
  libjpeg-dev \
  binutils \
  libproj-dev \
  gdal-bin
RUN mkdir /vagrant
WORKDIR /vagrant
RUN mkdir requirements
COPY requirements requirements
RUN pip install -r requirements/local.txt
COPY . /vagrant/

docker-compose.yml

postgis:
  image: mdillon/postgis:9.3
  ports:
    - "5432:5432"
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: "postgres"
#  volumes:
#    - /etc/postgresql
#    - /var/log/postgresql
#    - /var/lib/postgresql

web:
  build: .
  dockerfile: Dockerfile
  command: python manage.py runserver 0.0.0.0:8000 --settings=xxx.settings.local
#   https://dev59.com/-Y3da4cB1Zd3GeqPxkj0#31567743
#  volumes:
#    - .:/vagrant
  ports:
    - "8000:8000"
  links:
    - "postgis:postgis"

更新:

当我在我的虚拟机内运行mount命令时,我得到以下输出:

tmpfs on / type tmpfs (rw,relatime,size=918096k)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
/dev/sda1 on /mnt/sda1 type ext4 (rw,relatime,data=ordered)
cgroup on /sys/fs/cgroup type tmpfs (rw,relatime,mode=755)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu type cgroup (rw,relatime,cpu)
cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,relatime,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,relatime,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,relatime,net_prio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb)
/dev/sda1 on /mnt/sda1/var/lib/docker/aufs type ext4 (rw,relatime,data=ordered)
none on /mnt/sda1/var/lib/docker/aufs/mnt/137fb1ad9a432a3f4fa47667ecc9991c10149b71f02dfc06a8134fc348532a3d type aufs (rw,relatime,si=462e07a762a4065f,dio,dirperm1)
shm on /mnt/sda1/var/lib/docker/containers/137fb1ad9a432a3f4fa47667ecc9991c10149b71f02dfc06a8134fc348532a3d/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
mqueue on /mnt/sda1/var/lib/docker/containers/137fb1ad9a432a3f4fa47667ecc9991c10149b71f02dfc06a8134fc348532a3d/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
nsfs on /var/run/docker/netns/2e4dbeed7a66 type nsfs (rw)

我的共享文件夹在用户界面中显示的文件夹路径是/home


正如链接问题所解释的那样,主机卷挂载是相对于运行Docker的“主机”而言的。如果您的Docker机器在外部提供程序中运行,则该卷不会是来自本地机器的数据。Docker机器在哪里运行? - Andy Shinn
我正在VirtualBox中运行Docker机器 @AndyShinn - psychok7
你能否登录到VM (docker-machine ssh <name>) 并获取挂载(mount),看看主机中是否有任何内容被挂载在VM上?如果没有,则无法使用VM实现此目的。你需要以某种方式与VM共享主机文件夹,以使容器能够访问它。 - Andy Shinn
2
我从您的主机上无法看到VM中的/home挂载点。这就是为什么从主机挂载到容器中的任何内容都无法被挂载的原因。您正在尝试使用主机-> VM->容器方法。目前只挂载了VM->容器,而VM没有这些文件(项目根目录)。这听起来有道理吗?不幸的是,我并不真正知道如何解决或排除问题,因为我还没有在Linux工作站上足够地使用boot2docker或docker-machine。/home文件夹可能需要一个新的问题。 - Andy Shinn
你能通过 docker-compose run web bash 进入容器并在其中运行命令吗?ls -la 命令的输出是什么样子的? - schmunk
显示剩余2条评论
3个回答

2

很不幸,您最安全(并且最兼容)的选择是对每次更改重新构建镜像并重新部署容器(即docker-compose build && docker-compose up -d或类似操作)。这样做的好处是还可以用于远程Docker守护程序(当您探索docker-machine的功能时,由于易于使用,这变得更加诱人)。


1
这看起来不太对劲...每次开发时都要这样做会很麻烦。这让我想起了C语言,你需要在每次更改时手动编译。你知道未来是否有计划改变这种行为吗? - psychok7
1
好的,实际上在虚拟机内运行应用程序,我们基本上谈论的是远程绑定挂载。我知道Vagrant有很多连接器来帮助促进这种事情(我认为它具有从vboxsf到sshfs一直到来回使用rsync的所有内容),这些都值得检查。尝试NFS也可能值得一试(特别是因为您的主机也是Linux)。 - tianon

1

@AndyShinn的评论和@tianon的回复已经回答了我认为的问题。

然而,如果您正在运行Ubuntu主机,可以尝试在裸机上运行,而不是在虚拟机中运行。现在,您可以通过--userns-remap标志以非root用户身份运行docker容器,因此您可以稍微放心一些安全性问题。您处于独特的位置,因为尽管大多数教程和文档都将docker-machine VM列为先决条件,但他们的目标受众主要是无法在OS X或Windows上运行docker而必须使用VM的人。不要因为森林而忽略了树木——虚拟化程序(尤其是Virtualbox)会导致IO性能差、内存使用过多和启动速度较慢。这就是我们有docker的原因 :)


我理解“如果我使用Linux,最好在我的主机上运行它”的意思,但是我不明白的是OS X和Windows用户如何处理“这个问题”。为什么要将Docker Machine宣传为替代或改进我们以前的方式(即使在Linux主机上),如果您不能简单地在保存时更新代码而无需再次构建它?OS X用户每次进行小的代码更改时都需要构建吗? - psychok7
个人而言,每次运行新代码时我都会重新构建。通常情况下,除非代码库中有一些奇怪的科学软件无法在OS X上运行...我在本地OSX机器上工作100%,然后在满意并且我的测试通过后打包一个容器。如果您想在VM上的容器中运行(本地或其他方式),则需要将您的工作目录与VM共享,以便它可以与容器共享。远程VM的过程类似,只是您需要使用sshfs、nfs或其他网络协议来通过网络同步文件。 - pnovotnak

0

docker-machine 会尝试分享用户目录,使得在你运行 VirtualBox 的机器和默认的本地 docker VM(像 boot2docker 一样)之间可以共享。如果你没有运行默认的 VM,则需要创建 vmshare 并自己挂载它。

在 Windows 上,C:\Users,在 mac 上,/Users 将被挂载到 default docker VM 中,并作为 /Users。Linux 将分享 /home 并作为 /home 挂载。

vmhost$ docker-machine ssh default
vm$ mount | grep User
Users on /Users type vboxsf (rw,nodev,relatime)
vm$ exit

列出本地用户目录

vmhost$ ls -1 /Users/me/docker
compose_env_file
registry_push_test

将本地目录作为容器卷挂载到虚拟机中。
vmhost$ docker run -v /Users/me/docker:/test busybox ls /test
compose_env_file
registry_push_test

同样的代码在虚拟机上也能运行,因为以上命令实际上是在虚拟机中执行的。

vm$ docker run -v /Users/me/docker:/test busybox ls /test
compose_env_file
registry_push_test

如果您希望从您的机器进行的更改出现在您的虚拟机中,则必须从您的用户目录工作,并在Docker Compose中使用相对路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接