12

我在 OS X 上使用 boot2docker 并克隆了以下 repo:

https://github.com/enokd/docker-node-hello

它基本上有一个 Dockerfile 和一个打印 hello world 的非常简单的 express 应用程序。当我构建和运行映像时,一切都运行良好,但当然,如果我在我的 Mac 上对 index.js 进行任何更改,这些都不会反映在我正在运行的映像中。我似乎找不到任何关于如何设置 docker 的参考资料,以便我可以在我的开发环境中运行它以自动获取我的源代码更改,所以我觉得我“做错了”。有什么建议么?

这是我目前运行它的方式(我没有使用 Vagrant,并且不太确定这是否有什么不同):

$ docker build -t gasi/centos-node-hello .
$ docker run -p 49160:8080 -d gasi/centos-node-hello
$ curl localhost:49160

更新:添加了我最终所做的答案。

更新:使用 boot2docker 1.3+ 和图添加了更多当前答案。

4

4 回答 4

7

您的问题真的很有趣,并且(部分)与 Docker 无关。让我说,这里主要和最后一个问题是虚拟机的使用。

当您使用 VM(裸 Virtualbox VM、Vagrant VM、Docker boot2docker VM...)时,跟踪主机上的代码更改可能是一个挑战

VM 是 Mac(代码更改发生的地方)和应用程序堆栈(这里是运行在微型 Linux VM 上的 Docker 容器)之间的完整抽象层。

  • 您必须在 Mac 和 boot2docker 之间的 Virtualbox 中明确定义一个共享文件夹(NFS,...)。此共享文件夹将是您的代码存储库的根目录。这是第一步。

    Mac:/Users/You/stuff/approot ===> boot2docker/something


  • 然后,您必须告诉您的 Docker 容器使用绑定到 boot2docker 的(docker 术语),并将您的 Docker 应用程序指向它:
   docker run -v /something : /app/path/inside/ docker -p 49160:8080 \
     -d gasi/centos-node-hello /usr/bin/node /app/path/inside/docker/index.js


  • 让 NodeJs 检测文件更改是另一个挑战。您需要一个额外的包装器来监视文件系统并在代码更改时重新启动节点(ForeverNodemon ...)。

  • 而且,在那之后,由于更改不会发生在本地文件系统上,而是发生在共享文件夹上,您可能必须告诉 Nodejs 观察程序 (Forever/Nodemon/...) 使用轮询模式。它可以工作(或多或少),但会消耗大量 CPU。

于 2014-05-22T13:07:57.163 回答
5

关于 VirtualBox 的共享文件夹,请查看:

boot2docker 与 VirtualBox Guest Additions
如何将 /Users 挂载到 boot2docker

https://medium.com/boot2docker-lightweight-linux-for-docker/boot2docker-together-with-virtualbox-guest-additions-da1e3ab2465c

tl;dr 使用 VirtualBox Guest Additions 构建您自己的自定义 boot2docker.iso(参见链接)或下载 http://static.dockerfiles.io/boot2docker-v1.1.0-virtualbox-guest-additions-v4.3.12.iso 并保存到 ~/.boot2docker/boot2docker.iso。

编辑:更新了 boot2docker v1.1.0 的链接

于 2014-06-25T12:59:23.787 回答
4

这就是我最终做的,到目前为止似乎有效,但我仍在深入研究它:

# script located in bin/run
NS=mycompany
PROJECT=myproject

# kill and remove old container if it exists
docker kill $PROJECT
docker rm $PROJECT

# tag the previously built image
docker tag $NS/$PROJECT $NS/$PROJECT:old

# build the new image
docker build -t $NS/$PROJECT .

# remove the old image
docker rmi $NS/$PROJECT:old

docker run -dP --name=$PROJECT $NS/$PROJECT /sbin/my_init

在我的项目根目录中,我只需运行:

nodemon -x bin/run

归功于这个来源

docker 1.3 和 fig 的更新

Fig很棒,它确实从我以前的脚本中消除了很多复杂性。此外,boot2docker 现在原生支持使用 Virtual Box 的共享文件夹在 Mac OS X 上挂载卷。这就是我发现现在对我来说非常有效的方法:

首先,Dockerfile

FROM ubuntu:14.04

# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

# Set debconf to run non-interactively
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections

# Install base dependencies
RUN apt-get update && apt-get install -y -q --no-install-recommends \
        build-essential \
        ca-certificates \
        curl \
        git \
        libssl-dev \
        python \
        rsync \
        software-properties-common \
        wget \
    && rm -rf /var/lib/apt/lists/*

ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 0.10.33

# Install nvm with node and npm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.20.0/install.sh | bash \
    && source $NVM_DIR/nvm.sh \
    && nvm install $NODE_VERSION \
    && nvm alias default $NODE_VERSION \
    && nvm use default

ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH      $NVM_DIR/v$NODE_VERSION/bin:$PATH

CMD ["npm", "start"]

fig.yml: _

app:
    image: myNodeImage
    working_dir: /home/myProject
    volumes_from:
     - myvols

这是新的bin/run

#!/usr/bin/env bash
# This is the the bin/run script

docker run --rm --volumes-from myvols myNodeImage \
    rsync \
        --delete \
        --recursive \
        --safe-links \
        --exclude .git  --exclude node_modules  \
    /data/myProject/ /home/myProject

fig up

我还有一个执行依赖项安装的bin/install脚本。node_modules这假设我已经在我的主机上完成了 npm 安装,以便任何私有包都可以工作。此外,这适用于 npm 链接,您只需要在您的容器中创建一个符号/home/linkedProject链接$NODE_PATH/linkedProject

#!/usr/bin/env bash
# This is the the bin/install script

docker run --rm --volumes-from myvols myNodeImage \
    rm -rf /home/myProject && \
    rsync \
        --delete \
        --recursive \
        --safe-links \
        --exclude .git \
        /data/myProject/ /home/myProject && \
    cd /home/myProject && \
    npm rebuild

所以,把这一切放在一起,这里是按顺序排列的步骤:

  1. 创建我的数据卷容器:

    docker run -v $HOME/data:/data:ro \ -v /home \ -v /path/to/NODE_PATH \ --name myvols myNodeImage echo Creating my volumes

  2. 运行我的安装脚本:cd ~/data/myProject && ./bin/install

  3. 运行我的运行脚本:nodemon -x bin/run

于 2014-05-28T00:04:09.377 回答
0

docker 可以在以下几种情况下帮助 Web 开发:

  1. 快速在本地提供各种不同的服务。你想要一个干净的couchdb,运行docker run -d -p 5984:5984 tutum/couchdb;mysql,没问题:docker run -d -p 3306:3306 tutum/mysql,一个带firefox的selenium服务器?easy: sudo docker run -p 4444:4444 -d lzhang/selenium,您将立即获得它们,并且它们可以在docker kill您不想要它们的下一秒被销毁。非常适合本地测试场景,无需担心如何配置它们。

  2. 管理软件依赖关系。例如,您想在不同的节点版本(0.8、0.10、0.10.25 等)下运行您的节点应用程序,只需通过 找到 nodejs docker 镜像docker search nodejs,并通过将您的应用程序目录挂载为卷来创建容器,您可以运行多个容器这是彼此隔离的。看看我的keystonejs-example项目,了解如何在 0 配置下使用 mongodb 在几秒钟内运行复杂的节点应用程序。考虑一个更复杂的模型:负载均衡器 + 应用程序 + 数据库 + 缓存,以老派的方式,有大量的配置选项来适应设置过程,但是,如果你将它们配置为单独的容器并通过名称链接它们,每个组件可以通过本地环境变量发现彼此,就像本地 PaaS 一样。

  3. 通过搜索docker index来使用应用程序的简单方法。例如,有一个名为Heartbleed checker的简洁工具,您可以通过单个命令快速下载/在容器中使用它,并准备好配置,甚至无需考虑配置、下载语言运行时、配置、卸载等。

根据 boot2docker,我假设您使用的是 OSX,因此您最好选择支持 hostonly 网络配置的 v0.9.2+ 版本,然后您可以通过 hostonly 网络访问在 VM 内运行的容器。

于 2014-05-22T03:39:56.997 回答