问题 在开发工作流程中使用docker


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

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

它基本上有一个Dockerfile和一个打印hello world的非常简单的快速应用程序。当我构建并运行图像时,一切都运行良好,但当然如果我对我的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+和图2添加了更多当前答案。


7415
2018-05-22 02:13


起源

我为此编写了Docker Shell。看到 dockershell.io - mzedeler


答案:


你的问题非常有趣,而且(部分)与Docker没有特别的关系。 我要说这里的主要和最后一个问题是使用虚拟机。

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

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

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

    苹果电脑:/ Users / You / stuff / approot ===> boot2docker/东西


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


  • 让NodeJ检测文件变化是另一个挑战。您需要一个额外的包装器来观察文件系统并在代码更改时重新启动Node(永远Nodemon...)。

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


7
2018-05-22 13:07



我正在寻找的答案(或者可能希望是可行的)将在主机操作系统中运行一个自动更新图像的观察器(即以某种方式重新运行ADD命令)。 - Abdullah Jibaly
是的,这就是为什么我说在我看来,当您想要共享或部署您的工作时,重建图像可能会发生:这种情况发生的频率低于每次编辑文件后的情况。 - mbarthelemy
是的,几乎所有东西都会被缓存,但是在一天结束时你最终会得到数百个缓存的中间图像。顺便说一下,如果你不想部署它,那么在每次更改后重建图像会有什么意义呢? - mbarthelemy
据我所知,基本上我对你的工作流程或多或少都感兴趣。仍然不确定你想要的是否合理(在每次代码更改时不断重建容器)。或者也许使用容器为dev&prod(系统,服务和应用程序)提供相同的环境,但是将代码保存在dev&prod上的Docker卷上。 - mbarthelemy
回答这个问题我最后做了什么,很想听到你可能有任何反馈。 - Abdullah Jibaly


关于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构建您自己的自定义boot2docker.iso   增加(见 链接)或下载    http://static.dockerfiles.io/boot2docker-v1.1.0-virtualbox-guest-additions-v4.3.12.iso并将其保存到〜/ .boot2docker / boot2docker.iso。

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


5
2018-06-25 12:59



这很酷,谢谢! - Abdullah Jibaly
很高兴有一个链接到你最新的iso而不是v1.0.1,因为它会随着时间的推移而改变 - Larry Cai


这是我最终做的,到目前为止似乎工作,但我仍然在挖掘它:

# 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的更新

 很棒,它确实从我以前的脚本中获得了很多复杂性。此外,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


4
2018-05-28 00:04



有趣的方法。所以,一旦你想部署它,你认为开发本地和构建一个docker镜像是可行的方法吗? - mattes
我实际上也在开发Docker内部并且它工作得很好。它基本上是我上面的涡轮增压版本,但不是运行 nodemon 直接我做了一个使用的脚本 nodemon 作为一个库,并在将项目发送到docker构建上下文之前做了很多事情来正确设置项目。这允许我做一些事情,比如拉动我正在同时工作的依赖项目。 - Abdullah Jibaly
@mattes FYI,我用一些非常接近我当前工作流程的内容更新了答案。 - Abdullah Jibaly
在此设置中使用文件系统观察者有没有运气或成功? - David Souther
@DavidSouther是的,我正在使用 nodemon 如上所述。它看起来像: nodemon -x bin/run - Abdullah Jibaly


Docker可以帮助进行Web开发的几种情况:

  1. 照明快速提供本地所有不同类型的服务。你想要一个干净的couchdb,运行 docker run -d -p 5984:5984 tutum/couchdb; mysql,没问题: docker run -d -p 3306:3306 tutum/mysql,一个使用firefox的selenium服务器?简单: 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-示例 关于如何使用mongodb以0秒配置运行复杂节点应用程序的项目。思考一个更复杂的模型:负载均衡器+应用程序+数据库+缓存,以旧式的方式,有大量的配置选项适合设置过程,但是,如果您将它们配置为单独的容器和 用名字链接它们每个组件都可以通过本地环境变量发现彼此,就像本地PaaS一样。

  3. 通过搜索使用应用程序的简单方法 码头指数。例如,有一个称为的简洁工具 Heartbleed检查器,您可以通过单个命令在容器中快速下载/使用它,即使不需要考虑配置,下载语言运行时,配置,卸载等。

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


0
2018-05-22 03:39



我知道你列出的3个功能,它们是很棒的功能,但我的问题确实与此无关。我真的很感兴趣如何在docker环境中完成迭代开发。我如何在我的文本编辑器或IDE中进行更改,并看到我的docker环境反映了这一点。 - Abdullah Jibaly