Docker compose getting mysql db fully started before flask app starts
I just started to dockerize my app. I've built my Dockerfile
and docker-compose.yml
and everything seems to work fine except one thing. There are times my flask app will start too quick and throw a connection refused error (because the MySQL db is not fully up). I am using healthcheck
to check if the db is up but this seems to not be reliable (I'm even making sure I can see show databases
, but mysql apparently initializes more things after the healthcheck passes? not sure what the healthcheck is for then). In my output, I see that the db does get created first but it is still initializing when the flask app starts up. Ideally, when I run docker-compose up I want to be able to see this line first,
db_1_eae741771281 | 2018-11-10T00:50:21.473098Z 0 [Note] mysqld: ready for connections.
and then start my flask app entry point. Currently, it doesn't do this.
Is there a more reliable way to ensure the MySQL is fully up before starting my start.sh
?
Dockerfile:
FROM python:3.5-alpine
RUN apk update && apk upgrade
RUN apk add --no-cache curl python build-base openldap-dev python2-dev python3-dev pkgconfig python-dev libffi-dev musl-dev make gcc
RUN pip install --upgrade pip
RUN adduser -D user
WORKDIR /home/user
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
COPY app app
COPY start.sh ./
RUN chmod +x start.sh
RUN chown -R user:user ./
USER user
EXPOSE 5000
ENTRYPOINT ["./start.sh"]
docker-compose.yml:
version: "2.1"
services:
db:
image: mysql:5.7
ports:
- "32000:3306"
environment:
- MYSQL_DATABASE=mydb
- MYSQL_USER=user
- MYSQL_PASSWORD=user123
- MYSQL_ROOT_PASSWORD=user123
volumes:
- ./db:/docker-entrypoint-initdb.d/:ro
healthcheck:
test: "mysql --user=user --password=user123 --execute "SHOW DATABASES;""
timeout: 20s
retries: 20
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
condition: service_healthy
start.sh
#!/bin/sh
source venv/bin/activate
# Start Gunicorn processes
echo Starting Gunicorn.
exec gunicorn -b 0.0.0.0:5000 wsgi --chdir my_app --timeout 9999 --workers 3 --access-logfile - --error-logfile - --capture-output --log-level debug
docker docker-compose
add a comment |
I just started to dockerize my app. I've built my Dockerfile
and docker-compose.yml
and everything seems to work fine except one thing. There are times my flask app will start too quick and throw a connection refused error (because the MySQL db is not fully up). I am using healthcheck
to check if the db is up but this seems to not be reliable (I'm even making sure I can see show databases
, but mysql apparently initializes more things after the healthcheck passes? not sure what the healthcheck is for then). In my output, I see that the db does get created first but it is still initializing when the flask app starts up. Ideally, when I run docker-compose up I want to be able to see this line first,
db_1_eae741771281 | 2018-11-10T00:50:21.473098Z 0 [Note] mysqld: ready for connections.
and then start my flask app entry point. Currently, it doesn't do this.
Is there a more reliable way to ensure the MySQL is fully up before starting my start.sh
?
Dockerfile:
FROM python:3.5-alpine
RUN apk update && apk upgrade
RUN apk add --no-cache curl python build-base openldap-dev python2-dev python3-dev pkgconfig python-dev libffi-dev musl-dev make gcc
RUN pip install --upgrade pip
RUN adduser -D user
WORKDIR /home/user
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
COPY app app
COPY start.sh ./
RUN chmod +x start.sh
RUN chown -R user:user ./
USER user
EXPOSE 5000
ENTRYPOINT ["./start.sh"]
docker-compose.yml:
version: "2.1"
services:
db:
image: mysql:5.7
ports:
- "32000:3306"
environment:
- MYSQL_DATABASE=mydb
- MYSQL_USER=user
- MYSQL_PASSWORD=user123
- MYSQL_ROOT_PASSWORD=user123
volumes:
- ./db:/docker-entrypoint-initdb.d/:ro
healthcheck:
test: "mysql --user=user --password=user123 --execute "SHOW DATABASES;""
timeout: 20s
retries: 20
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
condition: service_healthy
start.sh
#!/bin/sh
source venv/bin/activate
# Start Gunicorn processes
echo Starting Gunicorn.
exec gunicorn -b 0.0.0.0:5000 wsgi --chdir my_app --timeout 9999 --workers 3 --access-logfile - --error-logfile - --capture-output --log-level debug
docker docker-compose
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have thehealth_check
in place, but still getting the issue.
– honeybadger_execute
Nov 11 at 3:23
add a comment |
I just started to dockerize my app. I've built my Dockerfile
and docker-compose.yml
and everything seems to work fine except one thing. There are times my flask app will start too quick and throw a connection refused error (because the MySQL db is not fully up). I am using healthcheck
to check if the db is up but this seems to not be reliable (I'm even making sure I can see show databases
, but mysql apparently initializes more things after the healthcheck passes? not sure what the healthcheck is for then). In my output, I see that the db does get created first but it is still initializing when the flask app starts up. Ideally, when I run docker-compose up I want to be able to see this line first,
db_1_eae741771281 | 2018-11-10T00:50:21.473098Z 0 [Note] mysqld: ready for connections.
and then start my flask app entry point. Currently, it doesn't do this.
Is there a more reliable way to ensure the MySQL is fully up before starting my start.sh
?
Dockerfile:
FROM python:3.5-alpine
RUN apk update && apk upgrade
RUN apk add --no-cache curl python build-base openldap-dev python2-dev python3-dev pkgconfig python-dev libffi-dev musl-dev make gcc
RUN pip install --upgrade pip
RUN adduser -D user
WORKDIR /home/user
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
COPY app app
COPY start.sh ./
RUN chmod +x start.sh
RUN chown -R user:user ./
USER user
EXPOSE 5000
ENTRYPOINT ["./start.sh"]
docker-compose.yml:
version: "2.1"
services:
db:
image: mysql:5.7
ports:
- "32000:3306"
environment:
- MYSQL_DATABASE=mydb
- MYSQL_USER=user
- MYSQL_PASSWORD=user123
- MYSQL_ROOT_PASSWORD=user123
volumes:
- ./db:/docker-entrypoint-initdb.d/:ro
healthcheck:
test: "mysql --user=user --password=user123 --execute "SHOW DATABASES;""
timeout: 20s
retries: 20
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
condition: service_healthy
start.sh
#!/bin/sh
source venv/bin/activate
# Start Gunicorn processes
echo Starting Gunicorn.
exec gunicorn -b 0.0.0.0:5000 wsgi --chdir my_app --timeout 9999 --workers 3 --access-logfile - --error-logfile - --capture-output --log-level debug
docker docker-compose
I just started to dockerize my app. I've built my Dockerfile
and docker-compose.yml
and everything seems to work fine except one thing. There are times my flask app will start too quick and throw a connection refused error (because the MySQL db is not fully up). I am using healthcheck
to check if the db is up but this seems to not be reliable (I'm even making sure I can see show databases
, but mysql apparently initializes more things after the healthcheck passes? not sure what the healthcheck is for then). In my output, I see that the db does get created first but it is still initializing when the flask app starts up. Ideally, when I run docker-compose up I want to be able to see this line first,
db_1_eae741771281 | 2018-11-10T00:50:21.473098Z 0 [Note] mysqld: ready for connections.
and then start my flask app entry point. Currently, it doesn't do this.
Is there a more reliable way to ensure the MySQL is fully up before starting my start.sh
?
Dockerfile:
FROM python:3.5-alpine
RUN apk update && apk upgrade
RUN apk add --no-cache curl python build-base openldap-dev python2-dev python3-dev pkgconfig python-dev libffi-dev musl-dev make gcc
RUN pip install --upgrade pip
RUN adduser -D user
WORKDIR /home/user
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
COPY app app
COPY start.sh ./
RUN chmod +x start.sh
RUN chown -R user:user ./
USER user
EXPOSE 5000
ENTRYPOINT ["./start.sh"]
docker-compose.yml:
version: "2.1"
services:
db:
image: mysql:5.7
ports:
- "32000:3306"
environment:
- MYSQL_DATABASE=mydb
- MYSQL_USER=user
- MYSQL_PASSWORD=user123
- MYSQL_ROOT_PASSWORD=user123
volumes:
- ./db:/docker-entrypoint-initdb.d/:ro
healthcheck:
test: "mysql --user=user --password=user123 --execute "SHOW DATABASES;""
timeout: 20s
retries: 20
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
condition: service_healthy
start.sh
#!/bin/sh
source venv/bin/activate
# Start Gunicorn processes
echo Starting Gunicorn.
exec gunicorn -b 0.0.0.0:5000 wsgi --chdir my_app --timeout 9999 --workers 3 --access-logfile - --error-logfile - --capture-output --log-level debug
docker docker-compose
docker docker-compose
edited Nov 10 at 11:27
asked Nov 10 at 1:41
honeybadger_execute
1078
1078
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have thehealth_check
in place, but still getting the issue.
– honeybadger_execute
Nov 11 at 3:23
add a comment |
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have thehealth_check
in place, but still getting the issue.
– honeybadger_execute
Nov 11 at 3:23
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have the
health_check
in place, but still getting the issue.– honeybadger_execute
Nov 11 at 3:23
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have the
health_check
in place, but still getting the issue.– honeybadger_execute
Nov 11 at 3:23
add a comment |
3 Answers
3
active
oldest
votes
OK I also had problems with health_check
...
Maybe not the most optimal, but the most reliable solution is to use a MySQL client (mysqladmin
) to ping your MySQL server before starting your application.
1 - Create a wait.sh
script (db
is your MySQL service name here) :
#!/bin/sh
# Wait until MySQL is ready
while ! mysqladmin ping -h"db" -P"3306" --silent; do
echo "Waiting for MySQL to be up..."
sleep 1
done
2 - Get a MySQL client from your app
Dockerfile :
# install mysql client, will be used to ping mysql
apt-get -y install mysql-client
3 - In your docker-compose.yml
file, just add scripts to your container (I used volumes but you can keep using COPY
) and run wait.sh
before start.sh
:
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
command: bash -c "/usr/local/bin/wait.sh && /usr/local/bin/start.sh"
volumes:
- ./start.sh:/usr/local/bin/start.sh
- ./wait.sh:/usr/local/bin/wait.sh
This should work.
If you really don't want having to download a MySQL client, try this (again db
is your MySQL service name here). It has worked in most of my project but not in all (may depend of the distribution?) :
#!/bin/sh
# Wait until MySQL is ready
while ! exec 6<>/dev/tcp/db/3306; do
echo "Trying to connect to MySQL at 3306..."
sleep 5
done
PS : avoid naming your services "app" or "db", you may have problems later if you have other containers with those same service names (even in different networks).
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not usehealthcheck
butcommand
instead which override the default command. Although both solutions usemysqladmin
to ping server every interval seconds.
– Yann39
Nov 11 at 19:07
Okay, and why do we need to installmysql-client
? Willmysqladmin ping
not work without it?
– honeybadger_execute
Nov 12 at 9:30
1
Yes just chain your commands in the docker-composecommand
instruction :command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mixwait.sh
andstart.sh
in a single script if you prefer.
– Yann39
Nov 12 at 20:56
1
Indeedpython3.5-alpine
is based onalpine:3.8
Linux image which usesh
(bash
is not included). So you can just usesh
if you don't want to installbash
, then the docker-compose command would be :command: sh -c "..."
. Also use the#!/bin/sh
shebang instead of#!/bin/bash
in your scripts. For the differences see this answer.
– Yann39
Nov 13 at 7:34
|
show 5 more comments
While using a health check is easier, it totally depends on how reliable the check is.
Another approach would be to rely on projects like wait-for-it
or wait-for
, in your app container.
Since you are getting a connection refused, these scripts could return only once the connection is possible and your app can start only after.
Also, in case that doesn't work too, you could have a separate script (python in your case) to check until the DB is ready and you can call this script in your start.sh
before starting the flask app.
yeah, thewait-for-it
script didn't work either. I ended up having to put asleep 30
in mystart.sh
before starting the app and that seems to solve the problem.
– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
add a comment |
This is a common problem with multi containers. It is difficult to control the speed at which different containers start. Container orchestration solution like Kubernetes might be able to help you in such cases.
Kubernetes has the concept of init containers which run to completion before your dependent container can start. You can find sample of init container here
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
This youtube vide might be helpful for you as well
https://www.youtube.com/watch?v=n2FPsunhuFc
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53235312%2fdocker-compose-getting-mysql-db-fully-started-before-flask-app-starts%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
OK I also had problems with health_check
...
Maybe not the most optimal, but the most reliable solution is to use a MySQL client (mysqladmin
) to ping your MySQL server before starting your application.
1 - Create a wait.sh
script (db
is your MySQL service name here) :
#!/bin/sh
# Wait until MySQL is ready
while ! mysqladmin ping -h"db" -P"3306" --silent; do
echo "Waiting for MySQL to be up..."
sleep 1
done
2 - Get a MySQL client from your app
Dockerfile :
# install mysql client, will be used to ping mysql
apt-get -y install mysql-client
3 - In your docker-compose.yml
file, just add scripts to your container (I used volumes but you can keep using COPY
) and run wait.sh
before start.sh
:
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
command: bash -c "/usr/local/bin/wait.sh && /usr/local/bin/start.sh"
volumes:
- ./start.sh:/usr/local/bin/start.sh
- ./wait.sh:/usr/local/bin/wait.sh
This should work.
If you really don't want having to download a MySQL client, try this (again db
is your MySQL service name here). It has worked in most of my project but not in all (may depend of the distribution?) :
#!/bin/sh
# Wait until MySQL is ready
while ! exec 6<>/dev/tcp/db/3306; do
echo "Trying to connect to MySQL at 3306..."
sleep 5
done
PS : avoid naming your services "app" or "db", you may have problems later if you have other containers with those same service names (even in different networks).
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not usehealthcheck
butcommand
instead which override the default command. Although both solutions usemysqladmin
to ping server every interval seconds.
– Yann39
Nov 11 at 19:07
Okay, and why do we need to installmysql-client
? Willmysqladmin ping
not work without it?
– honeybadger_execute
Nov 12 at 9:30
1
Yes just chain your commands in the docker-composecommand
instruction :command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mixwait.sh
andstart.sh
in a single script if you prefer.
– Yann39
Nov 12 at 20:56
1
Indeedpython3.5-alpine
is based onalpine:3.8
Linux image which usesh
(bash
is not included). So you can just usesh
if you don't want to installbash
, then the docker-compose command would be :command: sh -c "..."
. Also use the#!/bin/sh
shebang instead of#!/bin/bash
in your scripts. For the differences see this answer.
– Yann39
Nov 13 at 7:34
|
show 5 more comments
OK I also had problems with health_check
...
Maybe not the most optimal, but the most reliable solution is to use a MySQL client (mysqladmin
) to ping your MySQL server before starting your application.
1 - Create a wait.sh
script (db
is your MySQL service name here) :
#!/bin/sh
# Wait until MySQL is ready
while ! mysqladmin ping -h"db" -P"3306" --silent; do
echo "Waiting for MySQL to be up..."
sleep 1
done
2 - Get a MySQL client from your app
Dockerfile :
# install mysql client, will be used to ping mysql
apt-get -y install mysql-client
3 - In your docker-compose.yml
file, just add scripts to your container (I used volumes but you can keep using COPY
) and run wait.sh
before start.sh
:
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
command: bash -c "/usr/local/bin/wait.sh && /usr/local/bin/start.sh"
volumes:
- ./start.sh:/usr/local/bin/start.sh
- ./wait.sh:/usr/local/bin/wait.sh
This should work.
If you really don't want having to download a MySQL client, try this (again db
is your MySQL service name here). It has worked in most of my project but not in all (may depend of the distribution?) :
#!/bin/sh
# Wait until MySQL is ready
while ! exec 6<>/dev/tcp/db/3306; do
echo "Trying to connect to MySQL at 3306..."
sleep 5
done
PS : avoid naming your services "app" or "db", you may have problems later if you have other containers with those same service names (even in different networks).
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not usehealthcheck
butcommand
instead which override the default command. Although both solutions usemysqladmin
to ping server every interval seconds.
– Yann39
Nov 11 at 19:07
Okay, and why do we need to installmysql-client
? Willmysqladmin ping
not work without it?
– honeybadger_execute
Nov 12 at 9:30
1
Yes just chain your commands in the docker-composecommand
instruction :command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mixwait.sh
andstart.sh
in a single script if you prefer.
– Yann39
Nov 12 at 20:56
1
Indeedpython3.5-alpine
is based onalpine:3.8
Linux image which usesh
(bash
is not included). So you can just usesh
if you don't want to installbash
, then the docker-compose command would be :command: sh -c "..."
. Also use the#!/bin/sh
shebang instead of#!/bin/bash
in your scripts. For the differences see this answer.
– Yann39
Nov 13 at 7:34
|
show 5 more comments
OK I also had problems with health_check
...
Maybe not the most optimal, but the most reliable solution is to use a MySQL client (mysqladmin
) to ping your MySQL server before starting your application.
1 - Create a wait.sh
script (db
is your MySQL service name here) :
#!/bin/sh
# Wait until MySQL is ready
while ! mysqladmin ping -h"db" -P"3306" --silent; do
echo "Waiting for MySQL to be up..."
sleep 1
done
2 - Get a MySQL client from your app
Dockerfile :
# install mysql client, will be used to ping mysql
apt-get -y install mysql-client
3 - In your docker-compose.yml
file, just add scripts to your container (I used volumes but you can keep using COPY
) and run wait.sh
before start.sh
:
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
command: bash -c "/usr/local/bin/wait.sh && /usr/local/bin/start.sh"
volumes:
- ./start.sh:/usr/local/bin/start.sh
- ./wait.sh:/usr/local/bin/wait.sh
This should work.
If you really don't want having to download a MySQL client, try this (again db
is your MySQL service name here). It has worked in most of my project but not in all (may depend of the distribution?) :
#!/bin/sh
# Wait until MySQL is ready
while ! exec 6<>/dev/tcp/db/3306; do
echo "Trying to connect to MySQL at 3306..."
sleep 5
done
PS : avoid naming your services "app" or "db", you may have problems later if you have other containers with those same service names (even in different networks).
OK I also had problems with health_check
...
Maybe not the most optimal, but the most reliable solution is to use a MySQL client (mysqladmin
) to ping your MySQL server before starting your application.
1 - Create a wait.sh
script (db
is your MySQL service name here) :
#!/bin/sh
# Wait until MySQL is ready
while ! mysqladmin ping -h"db" -P"3306" --silent; do
echo "Waiting for MySQL to be up..."
sleep 1
done
2 - Get a MySQL client from your app
Dockerfile :
# install mysql client, will be used to ping mysql
apt-get -y install mysql-client
3 - In your docker-compose.yml
file, just add scripts to your container (I used volumes but you can keep using COPY
) and run wait.sh
before start.sh
:
app:
build: ./
ports:
- "5000:5000"
depends_on:
db:
command: bash -c "/usr/local/bin/wait.sh && /usr/local/bin/start.sh"
volumes:
- ./start.sh:/usr/local/bin/start.sh
- ./wait.sh:/usr/local/bin/wait.sh
This should work.
If you really don't want having to download a MySQL client, try this (again db
is your MySQL service name here). It has worked in most of my project but not in all (may depend of the distribution?) :
#!/bin/sh
# Wait until MySQL is ready
while ! exec 6<>/dev/tcp/db/3306; do
echo "Trying to connect to MySQL at 3306..."
sleep 5
done
PS : avoid naming your services "app" or "db", you may have problems later if you have other containers with those same service names (even in different networks).
answered Nov 11 at 10:33
Yann39
2,08632232
2,08632232
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not usehealthcheck
butcommand
instead which override the default command. Although both solutions usemysqladmin
to ping server every interval seconds.
– Yann39
Nov 11 at 19:07
Okay, and why do we need to installmysql-client
? Willmysqladmin ping
not work without it?
– honeybadger_execute
Nov 12 at 9:30
1
Yes just chain your commands in the docker-composecommand
instruction :command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mixwait.sh
andstart.sh
in a single script if you prefer.
– Yann39
Nov 12 at 20:56
1
Indeedpython3.5-alpine
is based onalpine:3.8
Linux image which usesh
(bash
is not included). So you can just usesh
if you don't want to installbash
, then the docker-compose command would be :command: sh -c "..."
. Also use the#!/bin/sh
shebang instead of#!/bin/bash
in your scripts. For the differences see this answer.
– Yann39
Nov 13 at 7:34
|
show 5 more comments
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not usehealthcheck
butcommand
instead which override the default command. Although both solutions usemysqladmin
to ping server every interval seconds.
– Yann39
Nov 11 at 19:07
Okay, and why do we need to installmysql-client
? Willmysqladmin ping
not work without it?
– honeybadger_execute
Nov 12 at 9:30
1
Yes just chain your commands in the docker-composecommand
instruction :command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mixwait.sh
andstart.sh
in a single script if you prefer.
– Yann39
Nov 12 at 20:56
1
Indeedpython3.5-alpine
is based onalpine:3.8
Linux image which usesh
(bash
is not included). So you can just usesh
if you don't want to installbash
, then the docker-compose command would be :command: sh -c "..."
. Also use the#!/bin/sh
shebang instead of#!/bin/bash
in your scripts. For the differences see this answer.
– Yann39
Nov 13 at 7:34
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Is that different than this solution here?stackoverflow.com/a/42757250/10067412
– honeybadger_execute
Nov 11 at 11:17
Yes it does not use
healthcheck
but command
instead which override the default command. Although both solutions use mysqladmin
to ping server every interval seconds.– Yann39
Nov 11 at 19:07
Yes it does not use
healthcheck
but command
instead which override the default command. Although both solutions use mysqladmin
to ping server every interval seconds.– Yann39
Nov 11 at 19:07
Okay, and why do we need to install
mysql-client
? Will mysqladmin ping
not work without it?– honeybadger_execute
Nov 12 at 9:30
Okay, and why do we need to install
mysql-client
? Will mysqladmin ping
not work without it?– honeybadger_execute
Nov 12 at 9:30
1
1
Yes just chain your commands in the docker-compose
command
instruction : command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mix wait.sh
and start.sh
in a single script if you prefer.– Yann39
Nov 12 at 20:56
Yes just chain your commands in the docker-compose
command
instruction : command: bash -c "chmod +x /usr/local/bin/wait.sh /usr/local/bin/start.sh && /usr/local/bin/wait.sh && /usr/local/bin/start.sh"
. You can also mix wait.sh
and start.sh
in a single script if you prefer.– Yann39
Nov 12 at 20:56
1
1
Indeed
python3.5-alpine
is based on alpine:3.8
Linux image which use sh
(bash
is not included). So you can just use sh
if you don't want to install bash
, then the docker-compose command would be : command: sh -c "..."
. Also use the #!/bin/sh
shebang instead of #!/bin/bash
in your scripts. For the differences see this answer.– Yann39
Nov 13 at 7:34
Indeed
python3.5-alpine
is based on alpine:3.8
Linux image which use sh
(bash
is not included). So you can just use sh
if you don't want to install bash
, then the docker-compose command would be : command: sh -c "..."
. Also use the #!/bin/sh
shebang instead of #!/bin/bash
in your scripts. For the differences see this answer.– Yann39
Nov 13 at 7:34
|
show 5 more comments
While using a health check is easier, it totally depends on how reliable the check is.
Another approach would be to rely on projects like wait-for-it
or wait-for
, in your app container.
Since you are getting a connection refused, these scripts could return only once the connection is possible and your app can start only after.
Also, in case that doesn't work too, you could have a separate script (python in your case) to check until the DB is ready and you can call this script in your start.sh
before starting the flask app.
yeah, thewait-for-it
script didn't work either. I ended up having to put asleep 30
in mystart.sh
before starting the app and that seems to solve the problem.
– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
add a comment |
While using a health check is easier, it totally depends on how reliable the check is.
Another approach would be to rely on projects like wait-for-it
or wait-for
, in your app container.
Since you are getting a connection refused, these scripts could return only once the connection is possible and your app can start only after.
Also, in case that doesn't work too, you could have a separate script (python in your case) to check until the DB is ready and you can call this script in your start.sh
before starting the flask app.
yeah, thewait-for-it
script didn't work either. I ended up having to put asleep 30
in mystart.sh
before starting the app and that seems to solve the problem.
– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
add a comment |
While using a health check is easier, it totally depends on how reliable the check is.
Another approach would be to rely on projects like wait-for-it
or wait-for
, in your app container.
Since you are getting a connection refused, these scripts could return only once the connection is possible and your app can start only after.
Also, in case that doesn't work too, you could have a separate script (python in your case) to check until the DB is ready and you can call this script in your start.sh
before starting the flask app.
While using a health check is easier, it totally depends on how reliable the check is.
Another approach would be to rely on projects like wait-for-it
or wait-for
, in your app container.
Since you are getting a connection refused, these scripts could return only once the connection is possible and your app can start only after.
Also, in case that doesn't work too, you could have a separate script (python in your case) to check until the DB is ready and you can call this script in your start.sh
before starting the flask app.
answered Nov 10 at 16:49
Pramodh Valavala
47127
47127
yeah, thewait-for-it
script didn't work either. I ended up having to put asleep 30
in mystart.sh
before starting the app and that seems to solve the problem.
– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
add a comment |
yeah, thewait-for-it
script didn't work either. I ended up having to put asleep 30
in mystart.sh
before starting the app and that seems to solve the problem.
– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
yeah, the
wait-for-it
script didn't work either. I ended up having to put a sleep 30
in my start.sh
before starting the app and that seems to solve the problem.– honeybadger_execute
Nov 11 at 3:21
yeah, the
wait-for-it
script didn't work either. I ended up having to put a sleep 30
in my start.sh
before starting the app and that seems to solve the problem.– honeybadger_execute
Nov 11 at 3:21
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
The best practice would be to have a simple script (python would be ideal for you since the container already has everything you need) which tries to connect and validate the DB on a loop until successful. Sort of like the health check but in your app container instead.
– Pramodh Valavala
Nov 11 at 5:28
add a comment |
This is a common problem with multi containers. It is difficult to control the speed at which different containers start. Container orchestration solution like Kubernetes might be able to help you in such cases.
Kubernetes has the concept of init containers which run to completion before your dependent container can start. You can find sample of init container here
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
This youtube vide might be helpful for you as well
https://www.youtube.com/watch?v=n2FPsunhuFc
add a comment |
This is a common problem with multi containers. It is difficult to control the speed at which different containers start. Container orchestration solution like Kubernetes might be able to help you in such cases.
Kubernetes has the concept of init containers which run to completion before your dependent container can start. You can find sample of init container here
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
This youtube vide might be helpful for you as well
https://www.youtube.com/watch?v=n2FPsunhuFc
add a comment |
This is a common problem with multi containers. It is difficult to control the speed at which different containers start. Container orchestration solution like Kubernetes might be able to help you in such cases.
Kubernetes has the concept of init containers which run to completion before your dependent container can start. You can find sample of init container here
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
This youtube vide might be helpful for you as well
https://www.youtube.com/watch?v=n2FPsunhuFc
This is a common problem with multi containers. It is difficult to control the speed at which different containers start. Container orchestration solution like Kubernetes might be able to help you in such cases.
Kubernetes has the concept of init containers which run to completion before your dependent container can start. You can find sample of init container here
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
This youtube vide might be helpful for you as well
https://www.youtube.com/watch?v=n2FPsunhuFc
answered Nov 10 at 3:30
Nilesh Gule
1,224911
1,224911
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53235312%2fdocker-compose-getting-mysql-db-fully-started-before-flask-app-starts%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Possible duplicate of Docker-compose check if mysql connection is ready
– Yann39
Nov 10 at 17:14
@Yann39 I already saw that post and tried all the solutions recommended in the post, however, none of those works. As you can see in my code I have the
health_check
in place, but still getting the issue.– honeybadger_execute
Nov 11 at 3:23