unit: nginx unit fails when web application load time is longer than 60 seconds
I have a python web application, that has a very long loading time due to some heavy database calculations that need to be run one on start time of the application. When running the application in a docker container with nginx unit, the setup of the application fails. The curl request in the docker entrypoint that configures the web app (https://github.com/nginx/unit/blob/master/pkg/docker/docker-entrypoint.sh#L43) fails with the following error when the application takes longer than 60 seconds to start:
curl: (52) Empty reply from server
Here is my sample application code:
Directory Structure:
- app.py
- config.json
- Dockerfile
- requirements.txt
Dockerfile:
FROM nginx/unit:1.26.1-python3.9
COPY requirements.txt /config/requirements.txt
RUN pip install -r /config/requirements.txt
COPY config.json /docker-entrypoint.d/config.json
COPY app.py /www/app.py
app.py:
from flask import Flask
import time
app = Flask(__name__)
application = app
# Artificially ensure a high load time
time.sleep(70)
@app.route('/')
def hello_world():
return 'Hello, World!'
config.json:
{
"settings": {
"http":{
"header_read_timeout": 300,
"body_read_timeout":300,
"idle_timeout":300,
"send_timeout":300
}
},
"listeners": {
"*:8080": {
"pass": "applications/python_app"
}
},
"applications": {
"python_app": {
"type": "python",
"path": "/www/",
"module": "app",
"callable": "app",
"limits":{
"timeout": 300,
"requests": 500
}
}
}
}
requirements.txt:
Flask==2.0.2
I tried to configure all timeouts in a way that the should not produce problems, but this did not help. Is there anything that I am doing wrong?
Thanks for any support in advance already!
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 16 (9 by maintainers)
Commits related to this issue
- Increased readtimeout for configuration endpoint. Closes: <https://github.com/nginx/unit/issues/676> — committed to nginx/unit by tippexs 2 years ago
Hi @Phylu we have scheduled the next release for end of May (Thu. May 26th). So it will be around the corner.
Hi @Phylu
sorry for the really long delay with this issue. I was finally able to reproduce it constantly and found the timeout in the unit source code. We are closing the connection to the config http endpoint after 60 seconds.
We will check if it makes sense to make this timeout configurable. For now and your issue it is faster to quickly change the sources. file:
nxt_controller.c-nxt_controller_conn_read_stateYou can change the timeout from 60 seconds to 90 or even 120 seconds. To make the new
unitdbinary work with the docker container you have to use the version1.26.1of the unit source and configure unit from source using the following configure command.hg clone http://hg.nginx.org/unit -r 1.26.1type
maketo build unit. Copy the newunitdbinary into the container: Copy theunitdin the build context of docker by issuingcp unit/src/build/unitd .and add this to your DockerfileCOPY unitd /usr/sbin/unitdLet me know if you need anything else or in case you have more questions.
@Phylu I have something to test. The issue may not be in the Unit source. We were not able to reproduce the issue on other OSes like Ubuntu, Mac or CentOS.
Will share some idea how to fix this later today.
Update - Still working on it.
libcurldoes not have a read timeout. That said, curl would technically wait forever for a response from the server.@hongzhidao Here is the debug log from running it in docker via
CMD ["unitd-debug","--no-daemon","--control","unix:/var/run/control.unit.sock"]and setting thetime.sleepto120seconds. I am currently on another machine and the timing here seems a little bit different and this ensures that it fails.debug.log
You won’t see the curl error message though as the
curlstatement in the entrypoint contains the silent flag. If you overwrite the entrypoint and remove the-sthere, you will see the following curl error at the end of the logs:Perfect. That is the exact same approach I am following right now. Let me quickly test this with and without docker and share the result here.