我有真正的问题,试图得到一个docker-comment脚本来启动一个mysql数据库和一个Django项目,但是让Django项目等到mysql数据库准备好。
我有两个文件,一个Dockerfile和一个docker-compose.yml,我在下面复制了它们。
当我运行docker-compose.yml并检查web容器的日志时,它说它无法连接到数据库mydb。然而,我第二次运行它(没有清除容器和图像)时,它正确连接,Django应用程序正常工作。
我花了一整天的时间尝试了很多事情,比如脚本、健康检查等等,但是我无法让它工作。
Dockerfile
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY ./ /code/
RUN pip install -r requirements.txt
RUN python manage.py collectstatic --noinput
docker-compose.yml
version: '3'
services:
mydb:
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=django
- MYSQL_PASSWORD=secret
- MYSQL_DATABASE=dbMarksWebsite
image: mysql:5.7
ports:
# Map default mysql port 3306 to 3308 on outside so that I can connect
# to mysql using workbench localhost with port 3308
- "3308:3306"
web:
environment:
- DJANGO_DEBUG=1
- DOCKER_PASSWORD=secret
- DOCKER_USER=django
- DOCKER_DB=dbMarksWebsite
- DOCKER_HOST=mydb
- DOCKER_PORT=3306
build: .
command: >
sh -c "sleep 10 &&
python manage.py migrate &&
python manage.py loaddata myprojects_testdata.json &&
python manage.py runserver 0.0.0.0:8080"
ports:
- "8080:8080"
depends_on:
- mydb
第一次运行(没有现有图像或容器):
...
File "/usr/local/lib/python3.6/site-packages/MySQLdb/__init__.py", line 84, in Connect
return Connection(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 179, in __init__
super(Connection, self).__init__(*args, **kwargs2)
django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'mydb' (115)")
第二轮:
System check identified no issues (0 silenced).
March 27, 2020 - 16:44:57
Django version 2.2.11, using settings 'ebdjango.settings'
Starting development server at http://0.0.0.0:8080/
Quit the server with CONTROL-C.
我在entrypoint.sh中使用以下函数解决了它:
function wait_for_db()
{
while ! ./manage.py sqlflush > /dev/null 2>&1 ;do
echo "Waiting for the db to be ready."
sleep 1
done
}
出于测试/开发目的,您可以使用具有运行状况检查的MySQL映像版本(我相信有一个healthcheck/MySQL
image),或者配置您自己的映像版本(参见这里的示例:Docker compose check if MySQL connection is ready)。
对于生产使用,您不想在启动时升级数据库模式,也不想假设数据库已启动。升级模式会自动鼓励您不要考虑部署错误并需要回滚时会发生什么,并行模式升级也不会起作用。较长版本:https://pythonspeed.com/articles/schema-migrations-server-startup/
对于任何感兴趣的人,我找到了一个解决方案:
1-我编写了一个python脚本,每秒连接一次数据库,但有一个超时。我将此超时设置为60秒,但在我的计算机上似乎可以正常工作。
2-我在我的撰写文件中添加了等待命令。
这应该意味着我可以为我的网站调出一组测试容器,在那里我可以指定所使用的Python和MySQL的确切版本。
相关文件如下所示:
Dockerfile:
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY ./ /code/
RUN pip install -r requirements.txt
RUN python manage.py collectstatic --noinput
docker-compose.yml
version: '3'
services:
mydb:
container_name: mydb
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=django
- MYSQL_PASSWORD=secret
- MYSQL_DATABASE=dbMarksWebsite
image: mysql:5.7
ports:
# Map default mysql port 3306 to 3308 on outside so that I can connect
# to mysql using workbench localhost with port 3308
- "3308:3306"
web:
container_name: web
environment:
- DJANGO_DEBUG=1
- DOCKER_PASSWORD=secret
- DOCKER_USER=django
- DOCKER_DB=dbMarksWebsite
- DOCKER_HOST=mydb
- DOCKER_PORT=3306
build: .
command: >
sh -c "python ./bin/wait-for.py mydb 3306 django secret dbMarksWebsite 60 &&
python manage.py migrate &&
python manage.py loaddata myprojects_testdata.json &&
python manage.py runserver 0.0.0.0:8080"
ports:
- "8080:8080"
depends_on:
- mydb
等待
'''
I don't like adding this in here, but I cannot get the typical wait-for scripts
to work with MySQL database in docker, so I hve written a python script that
either times out after ? seconds or successfully connects to the database
The input arguments for the script need to be:
HOST, PORT, USERNAME, PASSWORD, DATABASE, TIMEOUT
'''
import sys, os
import time
import pymysql
def readCommandLineArgument():
'''
Validate the number of command line input arguments and return the
input filename
'''
# Get arguments
if len(sys.argv)!=7:
raise ValueError("You must pass in 6 arguments, HOST, PORT, USERNAME, PASSWORD, DATABASE, TIMEOUT")
# return the arguments as a tuple
return (sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
def connectToDB(HOST, PORT, USERNAME, PASSWORD, DATABASE):
'''
for now, just try to connect to the database.
'''
con = pymysql.connect(host=HOST, port=PORT, user=USERNAME, password=PASSWORD, database=DATABASE)
with con:
cur = con.cursor()
cur.execute("SELECT VERSION()")
def runDelay():
'''
I don't like passing passwords in, but this is only used for a test docker
delay script
'''
# Get the database connection characteristics.
(HOST, PORT, USERNAME, PASSWORD, DATABASE, TIMEOUT) = readCommandLineArgument()
# Ensure timeout is an integer greater than zero, otherwise use 15 secs a default
try:
TIMEOUT = int(TIMEOUT)
if TIMEOUT <= 0:
raise("Timeout needs to be > 0")
except:
TIMEOUT = 60
# Ensure port is an integer greater than zero, otherwise use 3306 as default
try:
PORT = int(PORT)
if PORT <= 0:
raise("Port needs to be > 0")
except:
PORT = 3306
# Try to connect to the database TIMEOUT times
for i in range(0, TIMEOUT):
try:
# Try to connect to db
connectToDB(HOST, PORT, USERNAME, PASSWORD, DATABASE)
# If an error hasn't been raised, then exit
return True
except Exception as Ex:
strErr=Ex.args[0]
print(Ex.args)
# Sleep for 1 second
time.sleep(1)
# If I get here, assume a timeout has occurred
raise("Timeout")
if __name__ == "__main__":
runDelay()
我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似
问题内容: 我在项目中将Django与PostgreSQL一起使用。我把它们放在不同的容器中,问题是我需要在运行django之前等待postgres。这时我正在用django容器的command.sh文件执行此操作。我还发现netcat可以解决问题,但是我更喜欢没有附加软件包的方法。curl和wget无法执行此操作,因为它们不支持postgres协议。有办法吗? 问题答案: 您的解决方案tizia
问题内容: 情况如下: 我有一个泊坞窗容器(jenkins)。我已经将套接字安装到容器中,以便可以在jenkins容器中执行docker命令。 手动操作,一切都在容器中进行。但是,当詹金斯执行作业时,它不会“等待” 命令运行完成。 下面是Jenkinsfile的摘录。短期命令可以正确运行,并输出环境变量。仅运行下一个命令(python),然后Jenkins立即继续前进,而无需等待完成。Jenkin
我正试图将图像上传到firebase存储,但调用该函数时,未执行wait以获取url。我错过了什么? 看看这个其他主题,我发现问题可能是“然后”,但我如何设置代码以等待url? 异步/等待/然后飞镖/颤振 谢谢
我想在docker容器中安排一个作业。首先,在环顾四周之后,我可以正确地建立集装箱时区。当我在终端中使用“date”命令时,它会显示我所在城市和国家的小时数,但cronjob会使用默认情况下在容器中指定的时区。我读到有必要告诉克朗,时区已经改变了。我尝试了使用环境变量TZ_CRON,但它不起作用。我还重新启动了容器内的cron服务,但它仍以相同的方式工作。 我的代码基于此回购协议https://g
在Windows上使用Workbase客户端(v6.3.5 x64)的最新副本,我试图从我的MySQL数据库创建一个转储文件,但总是只得到一个0~1Ko的转储文件。我在具有相同版本的两台服务器上尝试过,我得到了相同的结果: < li >执行任务时出错:“ascii”编解码器无法对位置7中的字符u'\xa3 '进行编码:序号不在范围(128)内 < li >执行任务时出错[错误32]该进程无法访问该