如何编译开发中的Docker容器中的代码?

时间:2014-04-03 15:56:54

标签: deployment web-deployment docker

我的所有网站代码都在我的容器中的/srv下。

我的Dockerfile使用git下载代码,并使其成为图像的一部分,以便更轻松地部署到生产环境。

但是,如何在开发中编辑代码?我认为使用卷是解决方案,例如:-v /docker/mycontainer/srv:/srv。但它会覆盖容器中的目录。如果这是我第一次运行它,它会清空它,因为主机中没有任何东西。所以无论我在Dockerfile中做了什么都会丢失。

我希望在我的应用的不同版本中共享/srv/myapp内的目录和文件,例如:/srv/myapp/user-uploads。这是专业网站开发中的common practice

那么我能做些什么来做这些事情呢?:

  • 在开发中的/ srv中编辑代码
  • 不同版本的share / srv / myapp / user-uploads
  • 让Dockerfile下载代码。在我看来,在Docker之外做“git clone”或“git pull”会破坏Docker的目的。此外,我无法在主机中运行,例如数据库迁移或其他特定于应用程序的脚本。

有没有办法进行反向音量安装?我的意思是让容器覆盖主机,而不是相反。

我认为一个解决方案可能是在运行容器的守护进程之前将/ srv复制到/srv.deployment-copy。然后当我运行守护进程时检查/srv.deployment-copy是否存在并将所有内容复制回/ srv。这样我可以使用/ srv作为卷,并且仍然可以使用Dockerfile将代码部署到它。我已经在所有docker命令中使用别名,因此自动执行此操作不会有问题。你觉得怎么样?

5 个答案:

答案 0 :(得分:13)

我发现在开发中编辑代码的最佳方法是像往常一样安装所有内容(包括克隆应用程序的存储库),但是将容器中的所有代码移动到/srv/myapp.deploy.dev。然后启动容器rw/srv/myapp,以及一个init.d脚本清理该卷并复制新内容,如下所示:

rm -r /srv/myapp/*
rm -r /srv/myapp/.[!.]*
cp -r /srv/myapp.deploy.dev/. /srv/myapp
rm -r /srv/myapp.deploy.dev

答案 1 :(得分:12)

还有另一种方法可以从另一个容器启动容器中的容器:

看看 https://docs.docker.com/userguide/dockervolumes/
创建和安装数据卷容器

如果您希望在容器之间共享某些持久性数据,或者想要从非持久性容器中使用,则最好创建一个命名的数据卷容器,然后从中装入数据。

让我们创建一个新的命名容器,其中包含要共享的卷。

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

然后,您可以使用--volumes-from标志将/ dbdata卷挂载到另一个容器中。

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres

另一个:

$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres

我们可以使用卷执行的另一项有用功能是将它们用于备份,还原或迁移。我们通过使用--volumes-from标志来创建一个安装该卷的新容器,如下所示:

$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

=============

我认为你不应该使用主机目录挂载到容器。 但是你可以使用具有所有权力的卷。 您可以使用具有完善编辑器和工具集的其他容器来编辑卷中的文件。并且容器这个你的应用程序将是干净的,没有开销。

结构是:
- )应用数据的容器
docker run -d -v /data --name data
- )app二进制文件的容器
docker run -d --volumes-from data --name app1
- )用于开发的编辑和实用程序的容器
docker run -d --volumes-from data --name editor

答案 2 :(得分:6)

注意:您不能容器目录挂载到-v的主机目录。

我认为你不需要修改/ srv和/srv.deployment-copy。如果你

我认为:

  • 您应该将卷用于持久性/共享数据:-v /hostdir/user-uploads:/srv/myapp/user-uploads,或者您可以使用data volume container概念。您可以考虑存储在主机(仅限数据容器)的文件系统支持的数据库,并允许容器在-v之前使用它。

  • 您是对的:对于生产部署 - 您可以使用源代码(git clone)构建映像,为每个版本构建映像。不需要在生产中编辑源代码。

  • 对于开发环境
  • - 您应该在没有源代码的情况下构建映像,或者如果使用相同的映像进行部署/开发,您可以使用卷隐藏源代码目录。然后在本地git克隆源代码并使用卷-v /hostdir/project/src:/srv/project与容器共享源代码。您最好共享源代码只读(最后是:ro),任何临时或中间文件都应该存储在容器中的其他位置。我在服务启动之前在容器启动时执行了设置脚本(数据迁移,重建一些索引/缓存数据文件等)。因此,每当我觉得我需要新的re-init时,我就会杀死开发容器并再次运行它。或者,我不会停止旧容器 - 我只是运行另一个容器。

答案 3 :(得分:5)

我使用git找到了一个很好的方法:

CONTAINER=my_container
SYNC_REPO=/tmp/my.git
CODE=/var/www

#create bare repo in container
docker exec $CONTAINER git init --bare $SYNC_REPO

#add executable syncing hook that checks out into code dir in container
printf "#!/bin/sh\nGIT_WORK_TREE=$CODE git checkout -f\n" | \
docker exec -i $CONTAINER bash -c "tee $SYNC_REPO/hooks/post-receive;chmod +x \$_"

#use git-remote-helper to use docker exec instead of ssh for git
git remote add docker "ext::docker exec -i $CONTAINER sh -c %S% $SYNC_REPO"

#push updated local code into docker
git push docker master

假设你有一个代码的本地git。 Git需要安装在容器中。或者,您可以使用docker run和一个安装了git的共享卷的数据容器。

答案 4 :(得分:1)

假设git不是容器的入口点,如果你的docker容器中安装了git,你可以ssh到容器中并运行git clone / git pull。由于卷与主机共享的方式,从容器到文件的更改也将发送给主机(实际上它是相同的文件)。

Here是如何快速ssh到容器的一些解释。