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

Cho*_*per 62 deployment web-deployment docker

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

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

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

里面/srv/myapp还有我希望在我的应用程序的不同版本之间共享的目录和文件,例如:/srv/myapp/user-uploads.这是专业Web开发中的常见做法.

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

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

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

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

Cho*_*per 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
Run Code Online (Sandbox Code Playgroud)

  • 我绊倒了同样的问题,看起来你已经解决了,但我不清楚你在做什么.你能否详细说明你在Dockerfile中做了什么(在图像创建时)和在一些启动脚本中做的事情(在容器创建时)? (4认同)
  • @ user779159对不起,我已离开网站好几个月了.我在这里做的是在创建卷之前将代码移动到其他地方,然后我创建卷(如果是第一次将为空,或者如果不是则为旧代码),然后删除卷中的所有内容(以防万一)它包含旧代码),然后我将新代码移入其中.所以现在我将新代码放在一个卷中,所以我可以从外面编辑它. (3认同)

Mik*_*ikl 13

还有另一种方法从另一个容器启动容器卷:

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

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

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

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用--volumes-from标志将/ dbdata卷装入另一个容器中.

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
Run Code Online (Sandbox Code Playgroud)

而另一个:

$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
Run Code Online (Sandbox Code Playgroud)

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

$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
Run Code Online (Sandbox Code Playgroud)

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

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

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


Jir*_*iri 6

注意:您无法容器目录装载到主机目录中-v.

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

我觉得:

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

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

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


til*_*ill 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
Run Code Online (Sandbox Code Playgroud)

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