docker-为开发和生产编写相同的配置,但仅在开发中启用主机和容器之间的代码共享
docker-compose same config for dev and production but enable code sharing between host and container only in development
因为使用 docker 的最重要的好处是保持 dev 和 prod env 相同所以让我们排除使用两个不同 docker-compose.yml
的选项
假设我们有一个 Django 应用程序,我们使用 gunicorn
来为生产服务,我们有一个专用的 apache2 作为反向代理(这个 apache2 在设计上不在 docker 之外)。所以这个应用程序(docker-compose)只有两部分,web
(Django)和db
(mysql)。 db部分没有问题。
对于 Django 部分,没有 docker 的开发例程将使用 venv 和 python3 manage.py runserver
或 IDE 提供的任何快捷方式。我们可以愉快地更改我们的代码,开发服务器很聪明,可以立即进行更改和反映。
当 docker 出现时事情变得棘手,因为所有源代码都应该打包到图像中,这给我们的开发人员一次又一次地重新创建图像和容器带来了很大的开销。一个人可能有以下解决方案(我发现它并不优雅):
在docker-compose.yml
使用volume将源代码文件夹挂载到容器中,这样宿主机源代码文件夹中的所有更改都会自动反映到容器中,然后gunicorn
将拿起零钱反映。 --- 这确实消除了大部分重新创建容器的开销,但我们不能在生产中使用相同的 docker-compose.yml
,因为这会引入对主机服务器上源代码的依赖性。
我知道有一个命令行选项可以将主机文件夹挂载到容器,但据我所知,这个选项只存在于 docker run
中,而不存在于 docker-compose
中。因此,使用不同的命令在不同的环境中启动服务是另一个死胡同。 (我不是 100% 确定这一点,因为我对 docker 还是很陌生,如果我错了请纠正我)
TLDR;
我如何设置我的环境以便
- 我只使用一个
docker-compose.yml
用于开发和生产
- 我无需重新创建 docker 容器就可以轻松地进行实时更改开发
非常感谢!
我也喜欢将尽可能多的功能塞进一个 docker-compose.yml 文件中。我会考虑的一些策略:
为生产和开发定义不同的服务。所以你会 运行 docker-compose up dev
或 docker-compose up prod
或 docker-compose run dev
。这里有一些复制,但通常不会很多。
使用多个docker-compose.yml文件并合并它们。例如:docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
。此处有更多详细信息:https://docs.docker.com/compose/extends/
我通常只是注释掉我的卷部分,但这可能不是最好的解决方案。
将 docker-compose.yml
中的 django 服务定义为
services:
backend:
image: backend
然后为dev添加一个文件:docker-compose.dev.yml
services:
backend:
extends:
file: docker-compose.yml
service: backend
volume: local_path:path
要发布产品,只需 docker-compose up
为开发启动
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
要热重载 dev django 应用程序,只需重载 gunicorn ps aux | grep gunicorn | grep greencar_proj | awk '{ print }' | xargs kill -HUP
因为使用 docker 的最重要的好处是保持 dev 和 prod env 相同所以让我们排除使用两个不同 docker-compose.yml
假设我们有一个 Django 应用程序,我们使用 gunicorn
来为生产服务,我们有一个专用的 apache2 作为反向代理(这个 apache2 在设计上不在 docker 之外)。所以这个应用程序(docker-compose)只有两部分,web
(Django)和db
(mysql)。 db部分没有问题。
对于 Django 部分,没有 docker 的开发例程将使用 venv 和 python3 manage.py runserver
或 IDE 提供的任何快捷方式。我们可以愉快地更改我们的代码,开发服务器很聪明,可以立即进行更改和反映。
当 docker 出现时事情变得棘手,因为所有源代码都应该打包到图像中,这给我们的开发人员一次又一次地重新创建图像和容器带来了很大的开销。一个人可能有以下解决方案(我发现它并不优雅):
在
docker-compose.yml
使用volume将源代码文件夹挂载到容器中,这样宿主机源代码文件夹中的所有更改都会自动反映到容器中,然后gunicorn
将拿起零钱反映。 --- 这确实消除了大部分重新创建容器的开销,但我们不能在生产中使用相同的docker-compose.yml
,因为这会引入对主机服务器上源代码的依赖性。我知道有一个命令行选项可以将主机文件夹挂载到容器,但据我所知,这个选项只存在于
docker run
中,而不存在于docker-compose
中。因此,使用不同的命令在不同的环境中启动服务是另一个死胡同。 (我不是 100% 确定这一点,因为我对 docker 还是很陌生,如果我错了请纠正我)
TLDR; 我如何设置我的环境以便
- 我只使用一个
docker-compose.yml
用于开发和生产 - 我无需重新创建 docker 容器就可以轻松地进行实时更改开发
非常感谢!
我也喜欢将尽可能多的功能塞进一个 docker-compose.yml 文件中。我会考虑的一些策略:
为生产和开发定义不同的服务。所以你会 运行
docker-compose up dev
或docker-compose up prod
或docker-compose run dev
。这里有一些复制,但通常不会很多。使用多个docker-compose.yml文件并合并它们。例如:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
。此处有更多详细信息:https://docs.docker.com/compose/extends/
我通常只是注释掉我的卷部分,但这可能不是最好的解决方案。
将 docker-compose.yml
中的 django 服务定义为
services:
backend:
image: backend
然后为dev添加一个文件:docker-compose.dev.yml
services:
backend:
extends:
file: docker-compose.yml
service: backend
volume: local_path:path
要发布产品,只需 docker-compose up
为开发启动
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
要热重载 dev django 应用程序,只需重载 gunicorn ps aux | grep gunicorn | grep greencar_proj | awk '{ print }' | xargs kill -HUP