docker-compose 是否支持初始化容器?
Does docker-compose support init container?
init container
是 Kubernetes 中的一个很棒的特性,我想知道 docker-compose 是否支持它?它允许我在启动主应用程序之前 运行 一些命令。
我看到这个 PR https://github.com/docker/compose-cli/issues/1499,其中提到支持 init 容器。但是我在他们的参考资料中找不到相关文档。
这对我来说是一个发现,但是是的,从 1.29 版开始,现在可以将初始化容器与 docker-compose
一起使用,如您在问题中链接的 PR 中所示。
与此同时,当我写下这些行时,似乎 this feature has not yet found its way to the documentation
您可以定义对其他容器的依赖,条件基本上是“当其他容器成功完成其工作时”。这留下了空间来定义容器 运行 任何类型的脚本并在启动其他依赖容器之前完成它们时退出。
为了说明,我制作了一个非常常见的示例:启动数据库容器,确保数据库已启动并在启动应用程序容器之前初始化其数据。
注意:初始化数据库(至少就官方 mysql 图像而言)不需要 init 容器,所以这个例子更像是一个说明,而不是一个坚如磐石的典型工作流程。
complete example is available in a public github repo所以我只会在这个答案中展示重点。
让我们从撰写文件开始
---
x-common-env: &cenv
MYSQL_ROOT_PASSWORD: totopipobingo
services:
db:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
<<: *cenv
init-db:
image: mysql:8.0
command: /initproject.sh
environment:
<<: *cenv
volumes:
- ./initproject.sh:/initproject.sh
depends_on:
db:
condition: service_started
my_app:
build:
context: ./php
environment:
<<: *cenv
volumes:
- ./index.php:/var/www/html/index.php
ports:
- 9999:80
depends_on:
init-db:
condition: service_completed_successfully
你可以看到我定义了3个服务:
- 最先启动的数据库
- 仅在数据库启动后启动的初始化容器。这只是 运行 一个脚本(见下文),一旦一切都被初始化就会退出
- 只有在 init 容器成功完成其工作后才会启动的应用程序容器。
db-init
容器的 initproject.sh
脚本 运行 对于这个演示来说是非常基础的,它只是每 2 秒重试一次连接到数据库,直到它成功或达到限制尝试 50 次,然后创建一个 db/table 并插入一些数据:
#! /usr/bin/env bash
# Test we can access the db container allowing for start
for i in {1..50}; do mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "show databases" && s=0 && break || s=$? && sleep 2; done
if [ ! $s -eq 0 ]; then exit $s; fi
# Init some stuff in db before leaving the floor to the application
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "create database my_app"
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "create table my_app.test (id int unsigned not null auto_increment primary key, myval varchar(255) not null)"
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "insert into my_app.test (myval) values ('toto'), ('pipo'), ('bingo')"
应用程序容器的 Dockerfile 很简单(为 php 添加 mysqli 驱动程序)并且可以在 example repo 和 php 中找到通过在浏览器中调用 http://localhost:9999
来测试 init 的脚本是否成功。
有趣的部分是观察使用 docker-compose up -d
启动服务时发生的情况。
这种功能所能做的唯一限制可能是您的想象力 ;) 感谢您让我发现了这一点。
init container
是 Kubernetes 中的一个很棒的特性,我想知道 docker-compose 是否支持它?它允许我在启动主应用程序之前 运行 一些命令。
我看到这个 PR https://github.com/docker/compose-cli/issues/1499,其中提到支持 init 容器。但是我在他们的参考资料中找不到相关文档。
这对我来说是一个发现,但是是的,从 1.29 版开始,现在可以将初始化容器与 docker-compose
一起使用,如您在问题中链接的 PR 中所示。
与此同时,当我写下这些行时,似乎 this feature has not yet found its way to the documentation
您可以定义对其他容器的依赖,条件基本上是“当其他容器成功完成其工作时”。这留下了空间来定义容器 运行 任何类型的脚本并在启动其他依赖容器之前完成它们时退出。
为了说明,我制作了一个非常常见的示例:启动数据库容器,确保数据库已启动并在启动应用程序容器之前初始化其数据。
注意:初始化数据库(至少就官方 mysql 图像而言)不需要 init 容器,所以这个例子更像是一个说明,而不是一个坚如磐石的典型工作流程。
complete example is available in a public github repo所以我只会在这个答案中展示重点。
让我们从撰写文件开始
---
x-common-env: &cenv
MYSQL_ROOT_PASSWORD: totopipobingo
services:
db:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
<<: *cenv
init-db:
image: mysql:8.0
command: /initproject.sh
environment:
<<: *cenv
volumes:
- ./initproject.sh:/initproject.sh
depends_on:
db:
condition: service_started
my_app:
build:
context: ./php
environment:
<<: *cenv
volumes:
- ./index.php:/var/www/html/index.php
ports:
- 9999:80
depends_on:
init-db:
condition: service_completed_successfully
你可以看到我定义了3个服务:
- 最先启动的数据库
- 仅在数据库启动后启动的初始化容器。这只是 运行 一个脚本(见下文),一旦一切都被初始化就会退出
- 只有在 init 容器成功完成其工作后才会启动的应用程序容器。
db-init
容器的 initproject.sh
脚本 运行 对于这个演示来说是非常基础的,它只是每 2 秒重试一次连接到数据库,直到它成功或达到限制尝试 50 次,然后创建一个 db/table 并插入一些数据:
#! /usr/bin/env bash
# Test we can access the db container allowing for start
for i in {1..50}; do mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "show databases" && s=0 && break || s=$? && sleep 2; done
if [ ! $s -eq 0 ]; then exit $s; fi
# Init some stuff in db before leaving the floor to the application
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "create database my_app"
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "create table my_app.test (id int unsigned not null auto_increment primary key, myval varchar(255) not null)"
mysql -u root -p${MYSQL_ROOT_PASSWORD} -h db -e "insert into my_app.test (myval) values ('toto'), ('pipo'), ('bingo')"
应用程序容器的 Dockerfile 很简单(为 php 添加 mysqli 驱动程序)并且可以在 example repo 和 php 中找到通过在浏览器中调用 http://localhost:9999
来测试 init 的脚本是否成功。
有趣的部分是观察使用 docker-compose up -d
启动服务时发生的情况。
这种功能所能做的唯一限制可能是您的想象力 ;) 感谢您让我发现了这一点。