我目前正在使用 git 在我的不同主机中部署我的应用程序。我的代码库被安装到运行 Docker镜像:
中搬运工-compose.yml
services:
app:
image: my.registry.net:5000/my/app
volumes:
- .:/app
# [...]
所以我的部署是这样的:
$ git pull
$ docker-compose build && docker-compose up -d
$ docker-compose exec app some_dependencies_installation_command
$ docker-compose exec app some_cache_clearing_command
对我来说似乎错误的原因很多,你可以想象。虽然如果出现问题我仍然可以恢复到我以前的git发布标签。
我想通过将代码库添加到映像中来简化部署,因此我不再使用git 进行部署,而是依赖图像提取。如果你不建议这样做以及为什么,请不要犹豫告诉我。
我很想简单地将我的代码库添加到我的图像的末尾,并在主机中只安装所需的东西:
Dockerfile
# [...]
ADD . /app
搬运工-compose.prod.yml
services:
app:
image: my.registry.net:5000/my/app
volumes:
- ./config.yml:/app/config.yml
- ./logs:/app/logs
- ./cache:/app/cache
- ./sessions:/app/sessions
# [...]
因此,一旦构建,我只需要使用以下部署我的图像:
$ docker-compose pull && docker-compose up -d
这是一个好的方式吗?如何修改我的图片,以便在出现问题时还原(因为Dockerfile
实际上从不更改)?另外,是不是每次都依赖于一层Dockerfile来拉动整个代码库而不仅仅是差异(就像使用git一样)?
答案 0 :(得分:2)
将源代码绑定到容器上通常是为了在开发时具有快速反馈循环。这是通过避免在代码更改完成后重建映像来实现的。该技术主要用于本地开发目的。对于生产环境,不应使用此技术。
Docker镜像设计为独立的。图像所需的所有依赖项都应该打包在图像中。依赖于绑定挂载来提供源代码或依赖关系不是 建议因为生成的Docker镜像不可移植。无论何时切换到新计算机,都需要将该源代码和依赖项传输到该新计算机。
因此,建议的方法是将源代码添加到图像中。您还应该从标准的Docker工作流程中受益,您可以在其中构建图像,为其提供特定标记(通常是版本)和推送 它进入Docker存储库。从那时起,您只需拉动图像并在您拥有的任何计算机上启动它。
关于版本控制:构建图像时,使用源代码版本(或git标记或提交ID)标记它。
docker build -t <image-name>:<version> .
您还可以使用docker pull <image-name>:<version>
提取特定版本。使用此技术,您始终可以恢复为任何版本的图像。
答案 1 :(得分:1)
docker-compose是docker的一个编排工具,但还有其他像kubernetes或docker swarm。你应该自己检查一下,考虑一下你可以使用这些工具的地方。
要对图像进行版本控制,您可以标记它们(使用-t)。因此,您将能够推出特定版本my.registry.net:5000/my/app:1.1.0
等。
构建可以在您的计算机上本地完成,也可以在CI / CD管道中自动完成。
Docker不会提取代码库,只提取带文件的图层。如果编译程序,则只应添加二进制文件和一些资产。图层会被缓存,只在需要时才会启用。
如果要最小化注册表中的图像,可以在docker中使用多阶段构建。这使用多个阶段来构建最后一个容器,该容器仅为您的应用程序提供服务,因此需要的文件更少。例如。您可以使用javac在一个阶段编译二进制文件,使用nodejs和webpack在另一个阶段编译资产,并将生成的文件复制到最后一个只包含java运行时和静态生成资产的容器中。官方文档在这里:https://docs.docker.com/develop/develop-images/multistage-build/
答案 2 :(得分:1)
你是对的,你的方法有很多问题,包括:
不是在容器内烘焙应用程序的源代码并在每次部署时重建应用程序,而是可以构建应用程序(可能在另一个&#34; build&#34;容器中,如果您想构建构建环境也是可移植的,即用于构建的容器),并将构建产生的工件添加到将在生产环境中部署的另一个图像中(在测试和QA之后,因为你确实有多个环境,对吧?:)。 p>
Docker图像标记可以这样工作:在每次提交(可能在最新的图像标记下)和每个git标记(在相应的图像标记下)构建图像。示例:对于主分支上的每个提交,您需要更新&#34; your-image:latest
当您标记1.0.0版本时,您会生成your-image:1.0.0
。
如果您有各种CI服务,您也可以自动执行此过程。
请注意,在生产中使用最新标记可能会导致环境不稳定,因为您不知道要部署的版本。使用另一个更具体的标签。
更新:正如其他人一直指出的那样,将您的资源放在容器中是一种可以应用于开发阶段的策略。但这不是你的情况,因为我假设你在谈论(预)生产过程。