使用docker设置开发环境

iam*_*nat 17 docker

我在为我的团队设置开发环境的docker时面临一些问题.至今:

  1. 我使用基本图像来启动容器

    docker run -t -i ubuntu:latest "/bin/bash"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我在其中安装了所有编译和构建工具

  3. 我提交了该图像并将其推送到我们的本地docker服务器

    docker commit e239ab... 192.168.10.100:5000/team-dev:beta
    
    Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.现在,作为团队成员:

  1. 我在我的计算机上拉开了开发环境图像

    docker pull 192.168.10.100:5000/team-dev:beta
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我开始一个容器:

    docker run -t -i 5cca4... "/bin/bash"
    
    Run Code Online (Sandbox Code Playgroud)

在这一点上,我正在考虑将我的容器作为一种远程机器,我可以通过SSH连接并工作.

我尝试git clone从容器内部做一个,但由于一个公钥问题,这会失败.我手动将id_rsa*文件复制到docker中,克隆工作正常.然后我尝试编辑一些源文件,但我的vim配置,bash配置,一切都被抛弃了,因为这是一个全新的OS环境.什么工作真的很好我的整个依赖版本的构建环境.


这些是我想要帮助我解决这个问题的可能解决方案.

  1. 拉动基本映像后,使用dockerfile将所有环境变量从主机添加到docker.

    缺点:每次我的主机环境改变bash/vim/git我需要更新dockerfile

  2. 使用主机到容器的卷.Git克隆并编辑主机中的文件.从docker内部运行构建脚本和编译.

    缺点:如果需要,数据卷中的内容不能用于更新图像.我不知道这是否是我应该关心的事情.

或者我是以错误的方式接近这个?

Aur*_*rel 36

作为一个年轻的docker用户,我将尝试解释我对它的使用.我主要将它用于两件事:隔离服务和容纳复杂的环境.

1.隔离服务

抽象

分离关注原则

为什么?对于可重用性可伸缩性(顺便说一下,调试和维护).
例如,要为PHP Laravel网站设置开发环境,我会运行几个容器:

  • Mysql的
  • Apache的PHP
  • Redis的
  • ..

这些容器(服务)中的每一个都将彼此链接,以便它们可以一起工作.例如:

Apache <== Mysql (3306 port).
Run Code Online (Sandbox Code Playgroud)

Apache容器现在可以通过公开的 3306端口打开与Mysql容器的TCP连接.

类似的项目将依赖于单个Docker镜像,但将在不同的容器中运行.但是,为了团队合作,应用程序所需的每个工具都应该是容器化的.

源代码管理

我从不直接将源代码放在容器中.我更喜欢按体积(docker run -v选项)将其安装到容器中.

当我想运行一个会改变我的源代码的命令时,比如构建,运行测试或npm更新,我可以从主机或容器中执行,具体取决于此工具运行所需的配置数量.
它越复杂或特定于应用程序,我就会考虑在容器中执行它.

运行容器

按照上面的例子中,我会运行myappmysql容器.

$ cd myapp
$ docker run -d \    # run as daemon (detached)
 -p 82:80 \          # bind container's port 80 to host's 82
 -p 22001:22 \       # bind container's port 22 to host's 22001
 --expose 3306       # exposed to other container linked with it
 --name mysql
 author/mysqlimage  
$ docker run -d \    # run as daemon (detached)
 -p 81:80 \          # bind container's port 80 to host's 81
 -p 22001:22 \       # bind container's port 22 to host's 22001
 -v $(pwd):/var/www  # mount current host's directory to container's /var/www
 --link mysql:db     # give access to mysql container (ports) as db alias
 --name myapp
 author/apacheimage
Run Code Online (Sandbox Code Playgroud)

myapp容器可以与mysql容器交谈.测试它:$ telnet db 3306会工作.

使用图.运行容器

就像我说的,Docker的cmd对我来说是噩梦,所以我找到了另一个很棒的工具,Fig让我最终得到了这个清晰的yaml文件,位于我项目的根目录:

web:
    image: lighta971/laravel-apache
    links:
        - db
    ports: 
        - "81:80"
        - "22001:22"
    volumes:
        - .:/app
db:
    image: lighta971/phpmyadmin-apache
    ports:
        - "82:80"
        - "22002:22"
    expose:
        - "3306"
Run Code Online (Sandbox Code Playgroud)

然后$ cd myapp && fig up给出与下面命令相同的结果:)

2.容纳复杂的环境

我也在使用Docker进行Android开发.一个基本的Android/Cordova设置很大,比如Gigs of downloads,这需要时间来设置环境.
这就是为什么我将所有组件放入一个"瑞士军刀"容器中:

  • Android SDK
  • Android NDK
  • Apache Ant
  • Android工具
  • Java的
  • ...

它会产生一个图像,其中包含我设置Cordova环境所需的一切:

$ docker run -i 
 --privileged                  # special permission for usb
 -v /dev/bus/usb:/dev/bus/usb  # mount usb volume
 -v $(pwd):/app                # mount current folder
 -p 8001:8000
 lighta971/cordova-env
Run Code Online (Sandbox Code Playgroud)

其中我别名cvd:

$ alias cdv='docker run -i --privileged -v /dev/bus/usb:/dev/bus/usb -v $(pwd):/app -p 8001:8000 lighta971/cordova-env'
Run Code Online (Sandbox Code Playgroud)

现在我可以透明地使用容器内的所有程序,就像它安装在我的系统上一样.例如:

$ cdv adb devices            # List usb devices
$ cdv cordova build android  # Build an app
$ cdv cordova run android    # Run an app on a device
$ cdv npm update             # Update an app dependencies
Run Code Online (Sandbox Code Playgroud)

由于卷装选项,所有这些命令都可以在当前目录中使用$(pwd):/app.

Dockerfile

总而言之,还有其他事情要知道,比如:

  • 了解构建过程以制作有效的图像
  • 处理持久数据的需求
  • 保持图像包更新
  • 等等

希望你明白:)


rch*_*euk 8

我在docker中尝试了很多不同的开发环境设置.

我的团队坚持使用的是一个预定义的目录,代码可以放在该目录中,然后作为目录映射到docker容器中.必要的环境变量放在Dockerfile中,并编写了一堆bash脚本来启动容器,并在其中映射必要的路径.我们将Dockerfile存储在Git中,每次添加新的依赖项时,我们都必须更新Dockerfile并可能重建映像(这主要是由于我们如何处理依赖关系管理,它并不理想,我不认为这是必要的,但将取决于技术堆栈)

由于我们使用了多种不同的技术,我们的脚本是按技术进行的.我们所有的容器都将映射到存储所有配置的技术特定文件夹.例如,/ opt /目录成为我们的代码所在的主目录.当运行docker run命令时,它将在本地/ opt /目录中映射到docker容器中的/ opt /目录.

这通常有效.

然而,建立本地开发环境是其自身的挑战.我开始使用Windows机器,它将从git中获取.我把它映射到运行docker的Ubuntu VM.

在ubuntu VM中,我有bash脚本可以启动所有需要的docker容器.

./start-apache.sh
./start-mysql.sh
./start-mongodb.sh ... and so on
Run Code Online (Sandbox Code Playgroud)

当我发现由于使用Windows作为主机时,这最终停止了工作,我在创建项目所依赖的符号链接时遇到了问题.所以我切换到在Ubuntu VM中使用git,然后使用相同的bash脚本启动Ubuntu中的所有内容.

这方面的缺点是我基本上是在VM中编码,并且无法在Windows中使用我的首选IDE.这并不可怕,但在虚拟机中工作并不理想,imo.

这种设置还有很多不足之处.对于我们的小型开发团队来说,需要数周时间才能使其处于可维护的状态.工作流程可以改进,但既没有时间也不知道如何......

我有兴趣听听他们为使用docker而开发的其他人的工作流程.


iam*_*nat 5

这最终是我解决的工作流程.

设置开发环境的关键点:

  • 编写代码必须在docker之外进行
  • VCS必须在docker之外
  • 所有编译和执行都应该在docker中
  • Docker容器应该是无状态的,因此修改和创建新的docker容器只涉及重新编译,执行

正如lighta所建议,有两种选择:

  1. 每项服务都有一个码头
  2. 一个码头工人内的所有服务

我更喜欢后一种方法,因为我正在研究多个项目,并且让mxn码头工人感觉比拥有码头工人更糟糕.

设置环境:

  • phusion_baseimage开始
  • 安装了mysql,phpmyadmin,nodejs,grunt及其伙伴,apache,django
  • 设置初始化服务和日志记录(有微风runit,并svlogd与底座图像来一起)启动Apache,在启动mysql的等.所以docker start会重启这些服务
  • 公开所需的端口(80,通常为8000,用于运行测试服务器)
  • 现在,我按以下方式定义我的挂载点
    • ~/host/projectDocker/src > /root/project
    • ~/host/projectDocker/dbData/mysql_data > /var/lib/mysql
    • ~/host/projectDocker/apache_conf > /etc/apache/sites-enabled/

到目前为止,这已经非常顺利.每当我们安装一些特定的库或依赖项时(特别是Haskell说),我们只需设置一个新映像,并要求所有开发人员提取最新映像并重建其容器.瞧!

所有冰雹码头工人.