如果等待mysql容器的docker容器基于python映像(例如Django应用程序),则可以使用以下代码。
优点是:
- 它不是基于wait-for-it.sh,它确实等待mysql的IP和端口准备就绪,但这并不自动意味着mysql初始化已完成。
- 它不是必须存在于容器中的基于mysql或mysqladmin可执行文件的shell脚本:由于您的容器基于python映像,因此需要在该映像之上安装mysql。通过以下解决方案,您可以使用容器中已经存在的技术:纯python。
码:
import time
import pymysql
def database_not_ready_yet(error, checking_interval_seconds):
print('Database initialization has not yet finished. Retrying over {0} second(s). The encountered error was: {1}.'
.format(checking_interval_seconds,
repr(error)))
time.sleep(checking_interval_seconds)
def wait_for_database(host, port, db, user, password, checking_interval_seconds):
"""
Wait until the database is ready to handle connections.
This is necessary to ensure that the application docker container
only starts working after the MySQL database container has finished initializing.
More info: https://docs.docker.com/compose/startup-order/ and https://docs.docker.com/compose/compose-file/#depends_on .
"""
print('Waiting until the database is ready to handle connections....')
database_ready = False
while not database_ready:
db_connection = None
try:
db_connection = pymysql.connect(host=host,
port=port,
db=db,
user=user,
password=password,
charset='utf8mb4',
connect_timeout=5)
print('Database connection made.')
db_connection.ping()
print('Database ping successful.')
database_ready = True
print('The database is ready for handling incoming connections.')
except pymysql.err.OperationalError as err:
database_not_ready_yet(err, checking_interval_seconds)
except pymysql.err.MySQLError as err:
database_not_ready_yet(err, checking_interval_seconds)
except Exception as err:
database_not_ready_yet(err, checking_interval_seconds)
finally:
if db_connection is not None and db_connection.open:
db_connection.close()
用法:
- 将此代码添加到
wait-for-mysql-db.py
应用程序源代码中的python文件中(例如)。
- 编写另一个python脚本(
startup.py
例如),该首先执行上述代码,然后启动您的应用程序。
- 确保应用程序容器的Dockerfile将这两个python脚本以及应用程序的源代码打包到Docker映像中。
- 在您的码头工人,撰写文件,用配置的应用程序容器:
command: ["python3", "startup.py"]
。
请注意,此解决方案是针对MySQL数据库制作的。您需要对其稍作调整以适合另一个数据库。