我在为我的团队设置开发环境的docker时面临一些问题。到目前为止:
我使用基本图像启动容器
docker run -t -i ubuntu:latest "/bin/bash"
我在其中安装了所有编译和构建工具
我提交了该图片并将其推送到我们当地的泊坞服务器
docker commit e239ab... 192.168.10.100:5000/team-dev:beta
到目前为止一切顺利。现在,作为团队成员:
我在计算机上提取开发环境图像
docker pull 192.168.10.100:5000/team-dev:beta
我开始一个容器:
docker run -t -i 5cca4... "/bin/bash"
此时,我将我的容器视为一种可以通过SSH连接并工作的远程计算机。
我尝试从容器内部执行git clone
,但由于公钥问题而失败。我手动将id_rsa *文件复制到docker中,克隆工作正常。然后我尝试编辑一些源文件,但我的vim配置,bash配置,一切都被抛弃了,因为这是一个全新的OS环境。什么工作真的很好我的整个依赖版本的构建环境。
这些是我想要帮助我解决这个问题的可能解决方案。
拉动基本图像后,使用dockerfile将所有环境变量从主机添加到docker。
缺点:每次我的主机环境更改bash / vim / git我都需要更新dockerfile
使用主机到容器的卷。 Git克隆并编辑主机中的文件。从docker内部运行构建脚本和编译。
缺点:如果需要,数据卷中的内容无法用于更新图像。我不知道这是否是我应该关心的事情。
或者我是以错误的方式接近这个?
答案 0 :(得分:36)
作为一名年轻的码头用户,我将尝试解释我对它的使用。我主要将它用于两件事:隔离服务和容纳复杂的环境。
赞Separation Of Concern Principle
为什么?对于可重用性和可伸缩性(顺便进行调试和维护)。
例如,为了拥有PHP Laravel网站的开发环境,我会运行几个容器:
这些容器(服务)中的每一个都将链接,以便它们可以一起工作。例如:
Apache <== Mysql (3306 port).
Apache容器现在可以通过公开的 3306端口打开与Mysql容器的TCP连接。
类似的项目将依赖于单个Docker镜像,但将在不同的容器中运行。但是,为了团队合作,应用程序所需的每个工具都应该是容器化的。
我从不直接将源代码放在容器中。我更喜欢将音量(docker run -v
option)安装到容器中。
如果我想运行一个会改变我的源代码的命令,比如构建,运行测试或npm更新,我可以从主机或容器中执行此操作,具体取决于此配置的数量工具需要运行。
它越复杂或特定于应用程序,我就越会考虑在容器中执行它。
按照上面的示例,我将运行myapp
和mysql
容器。
$ 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
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"
然后$ cd myapp && fig up
给出与下面命令相同的结果:)
我也使用Docker进行Android开发。一个基本的Android / Cordova设置很大,比如Gigs of downloads,并且需要时间来设置环境 这就是为什么我将所有组件放入一个瑞士军刀中的原因#34;容器:
它会生成一张图像,其中包含我设置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
我在cvd
中出现了别名:
$ alias cdv='docker run -i --privileged -v /dev/bus/usb:/dev/bus/usb -v $(pwd):/app -p 8001:8000 lighta971/cordova-env'
现在我可以透明地使用容器内的所有程序,就像它安装在我的系统上一样。例如:
$ 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
由于卷装选项$(pwd):/app
,所有这些命令都可以在当前目录中使用。
所有这一切,还有其他事情要知道,比如:
希望你明白:)
答案 1 :(得分:8)
我已尝试过很多不同的开发环境设置,可以在docker中工作。
我的团队坚持使用的是一个预定义的目录,代码可以放在该目录中,然后作为目录映射到docker容器中。必要的环境变量放在Dockerfile中,并编写了一堆bash脚本来启动容器,并在其中映射必要的路径。我们将Dockerfile存储在Git中,每次添加新的依赖项时,我们都必须更新Dockerfile并可能重建映像(这主要是由于我们处理依赖关系管理的方式,它不是理想的,我不认为它是必要的,但将取决于技术堆栈)< / p>
由于我们使用了多种不同的技术,我们的脚本是按技术进行的。我们所有的容器都将映射到存储所有配置的特定于技术的文件夹。例如,/ 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
当我发现由于使用Windows作为主机时,这最终停止了工作,我在创建项目所依赖的符号链接时遇到了问题。所以我转而在Ubuntu VM中使用git,然后使用相同的bash脚本启动Ubuntu中的所有内容。
这样做的缺点是我基本上是在VM中编码,并且无法在Windows中使用我的首选IDE。这并不可怕,但在虚拟机中工作并不理想,imo。
这种设置还有很多不足之处。对于我们的小型开发团队来说,需要数周时间才能使其处于可维护的状态。工作流程可以改进,但既没有时间也没有知道......
我有兴趣听听他们为使用码头工作人员而开发的其他人的工作流程。
答案 2 :(得分:5)
这最终是我解决的工作流程。
设置开发环境的关键点:
正如lighta所建议,有两种选择:
我更喜欢后一种方法,因为我正在开展多个项目,并且有m x n码头工人感觉比拥有码头工人更糟糕。
设置环境:
runit
和svlogd
轻而易举),以便在启动时启动apache,mysql等。所以docker start会重启这些服务~/host/projectDocker/src
&gt; /root/project
~/host/projectDocker/dbData/mysql_data
&gt; /var/lib/mysql
~/host/projectDocker/apache_conf
&gt; /etc/apache/sites-enabled/
到目前为止,这已经非常顺利。每当我们安装一些特定的库或依赖项时(特别是Haskell说),我们只需设置一个新映像,并要求所有开发人员提取最新映像并重建其容器。瞧!
所有冰雹码头。
答案 3 :(得分:1)
这就是我为我的nodejs app做的。
首先将Dockerfile作为源代码的一部分,看起来像这个
FROM node:0.10-onbuild
EXPOSE 8080
COPY . /src
这用于构建图像:
sudo docker build -t myapp .
构建完成后,我会开发代码并使用以下内容查看容器中的更改:
sudo docker run --rm -it -p 8080:8080 --name="myapp" -v '/path/to/app/src:/usr/src/app' myapp:latest
注意-v在这里我将我的本地目录挂载到容器中,所以每次进行代码更改时我都不需要重建。
代码由github管理,因此开发流程是相同的。创建分支,在本地工作,一旦准备合并回主人。
如果我的应用程序依赖于另一项服务,比如rabbitmq,我添加这是一个单独的docker容器,并为我的应用程序使用配置文件。
希望这是有帮助的
答案 4 :(得分:0)
我使用Java,JDK,SDK管理器,gradle和maven,角度CLI,android接受的许可证等创建了在docker容器中使用cordova的图像... https://hub.docker.com/r/walterwhites/docker-cordova/builds/
构建图像
sudo docker build . -t walterwhites/cordova
运行容器:
docker run -ti --rm --name=cordova -v /Users/username/workspace/gusto-coffee-mobile-app:/workspace walterwhites/cordova
选项-t是使用终端运行容器 选项-i是以交互模式运行 选项-rm是在退出时停止容器 选项-v是创建要在主机(本地计算机)和容器之间共享的卷
注意在cordova上使用tun app:
添加android平台:
cordova platform add android
构建
cordova build android