From b21ec215162fb9792f12753ae4ad584c97c67e4c Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 18 Sep 2025 11:44:01 +0000 Subject: [PATCH] supervisor --- Dockerfile | 6 +++++- main.py | 8 +++++++- requirements.txt | 1 + run.sh | 16 ++++++++++------ static/favicon.ico | Bin 0 -> 1150 bytes static/favicon.png | Bin 0 -> 5106 bytes supervisor.conf | 23 +++++++++++++++++++++++ 7 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 static/favicon.ico create mode 100644 static/favicon.png create mode 100644 supervisor.conf diff --git a/Dockerfile b/Dockerfile index 3cdb743..646b6f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,6 +36,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ texlive-xetex \ texlive-science \ libxml2-dev \ + supervisor \ && rm -rf /var/lib/apt/lists/* @@ -46,12 +47,15 @@ WORKDIR /app # Copy requirements and install dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt +COPY supervisor.conf /etc/supervisor/conf.d/supervisor.conf # Copy the rest of the app COPY . . + # Expose the app port EXPOSE 8000 RUN chmod +x run.sh # Command to run when container starts -CMD ["./run.sh", "&"] +#CMD ["./run.sh"] +CMD ["/usr/bin/supervisord", "-n"] diff --git a/main.py b/main.py index 27b76de..6f678fd 100644 --- a/main.py +++ b/main.py @@ -750,4 +750,10 @@ async def health(): except Exception: logger.exception("Health check failed") return JSONResponse({"ok": False}, status_code=500) - return {"ok": True} \ No newline at end of file + return {"ok": True} + +favicon_path = PATHS.BASE_DIR / 'static' / 'favicon.png' + +@app.get('/favicon.ico', include_in_schema=False) +async def favicon(): + return FileResponse(favicon_path) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 09482a0..ec42d85 100644 --- a/requirements.txt +++ b/requirements.txt @@ -122,3 +122,4 @@ Werkzeug==3.1.3 wrapt==1.17.3 xlrd==2.0.2 xlsxwriter==3.2.9 +supervisor diff --git a/run.sh b/run.sh index 1476f1a..15d2a67 100755 --- a/run.sh +++ b/run.sh @@ -1,10 +1,14 @@ #!/bin/bash -# This script starts the FastAPI application using Gunicorn. -echo "Starting DocProcessor with Gunicorn on port 0.0.0.0:8000..." +# Exit immediately if a command exits with a non-zero status. +set -e -exec gunicorn -w 4 --threads 2 -k uvicorn.workers.UvicornWorker --forwarded-allow-ips='*' main:app -b 0.0.0.0:8000 & -echo "Done" -echo "Starting huey..." +# Start Gunicorn in the background +gunicorn -w 4 --threads 2 -k uvicorn.workers.UvicornWorker --forwarded-allow-ips='*' main:app -b 0.0.0.0:8000 & +echo "Started Gunicorn..." +# Store the Gunicorn process ID +GUNICORN_PID=$! +echo "Gunicorn PID: $GUNICORN_PID" +# Start the Huey consumer in the foreground exec huey_consumer.py main.huey -w 4 -echo "Done" +echo "Started Huey consumer..." \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..dd5347d48901ab9822ebd288dc56646dea1f73a5 GIT binary patch literal 1150 zcmd6myGjF55Qb+ZX*7_4XeDT=jhNcPN(2!bg=lFZSO^xDiYSQIf{2AS)`EzamxwQ* zAQFotOAvy&>@~Z76B7u@rcc73nVmD=%$ajGA_m`7O8A|UotVhDh)g3wME>I#5!MFz z(`Yor^Srq4`w9FJ$90pcAP5o~vu!(ul`sq=$57sN-9>7gpfk_+Z?QM7=N%J2#4agc ztJNZTAKr1D40S%}S;Ly}&+K6v{sMnp`AVe{$&)9RZD+_Sz=z7i?U|+0kmER;#MjtU zB&)#|zXJE&;y>y6gwA2_k*-DZ^pG$Jgg$fRU7-hh@1q0wN1m^#KZBKYI^9#FXquvH z@MGj};A_7Z^os7-_cFDTx_`qkdiZugXF$U+m+Uo<-tmv#vRUE&+G%~QRj)Vi7iJgs z3svz~v69Q>`f{BMdXF%(+M9DM<8N7(HKFfKp;+upjr48DX~vm#o?1HpDX~$VJ)h4< pGTp&n=J=^rn`gn9#yPw0l!18Gzmlq)>@Ry##9u&aQGnm({s3o_ezpJr literal 0 HcmV?d00001 diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..6613b783c8d5d9bb906b92e6ceebd3675691e674 GIT binary patch literal 5106 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 YEEIY1sYsX-c`E?M1{Ub5^RBo41vr1CDgXcg literal 0 HcmV?d00001 diff --git a/supervisor.conf b/supervisor.conf new file mode 100644 index 0000000..6f3b2d4 --- /dev/null +++ b/supervisor.conf @@ -0,0 +1,23 @@ +[supervisord] +nodaemon=true +user=root + +[program:gunicorn] +command=gunicorn -w 4 --threads 2 -k uvicorn.workers.UvicornWorker --forwarded-allow-ips='*' main:app -b 0.0.0.0:8000 +directory=/app +autostart=true +autorestart=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:huey] +command=huey_consumer.py main.huey -w 4 +directory=/app +autostart=true +autorestart=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 \ No newline at end of file