【发布时间】:2022-01-16 04:19:26
【问题描述】:
init container 是 Kubernetes 的一个很棒的功能,我想知道 docker-compose 是否支持它?它允许我在启动主应用程序之前运行一些命令。
我遇到了这个 PR https://github.com/docker/compose-cli/issues/1499,它提到支持初始化容器。但我在他们的参考资料中找不到相关文档。
【问题讨论】:
标签: docker docker-compose
init container 是 Kubernetes 的一个很棒的功能,我想知道 docker-compose 是否支持它?它允许我在启动主应用程序之前运行一些命令。
我遇到了这个 PR https://github.com/docker/compose-cli/issues/1499,它提到支持初始化容器。但我在他们的参考资料中找不到相关文档。
【问题讨论】:
标签: docker docker-compose
这对我来说是一个发现,但是是的,现在可以使用带有 docker-compose 的 init 容器,因为版本 1.29 可以在您在问题中链接的 PR 中看到。
同时,当我写这些行时,似乎this feature has not yet found its way to the documentation
您可以定义对另一个容器的依赖,条件基本上是“当另一个容器成功完成其工作时”。这为定义运行任何类型脚本的容器留下了空间,并在启动其他依赖容器之前完成它们并退出。
为了说明,我用一个非常常见的场景制作了一个示例:启动 db 容器,确保 db 已启动并在启动应用程序容器之前初始化其数据。
注意:初始化 db(至少就官方 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 个服务:
db-init 容器运行的initproject.sh 脚本对于这个演示来说是非常基本的,它只是每 2 秒重试一次连接到数据库,直到它成功或达到 50 次尝试的限制,然后创建一个数据库/表和插入一些数据:
#! /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 中找到,以及通过在浏览器中调用 http://localhost:9999 来测试初始化是否成功的 php 脚本。
有趣的部分是观察使用docker-compose up -d启动服务时发生了什么。
使用此类功能可以完成的唯一限制可能是您的想象力;)感谢您让我发现这一点。
【讨论】: