From 3b08ed73e7862a7989bbb73243fd687d4fec0157 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Mon, 19 May 2025 23:55:24 +0200 Subject: [PATCH 01/11] remove binary files, wsgi rename --- .gitignore | 2 ++ src/locale/de/LC_MESSAGES/django.mo | Bin 3853 -> 0 bytes src/locale/en/LC_MESSAGES/django.mo | Bin 46184 -> 0 bytes src/{django.wsgi => wsgi.py} | 0 4 files changed, 2 insertions(+) delete mode 100644 src/locale/de/LC_MESSAGES/django.mo delete mode 100644 src/locale/en/LC_MESSAGES/django.mo rename src/{django.wsgi => wsgi.py} (100%) diff --git a/.gitignore b/.gitignore index 8e614510..573b7551 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ venv/ .python-version node_modules/ + +*.mo \ No newline at end of file diff --git a/src/locale/de/LC_MESSAGES/django.mo b/src/locale/de/LC_MESSAGES/django.mo deleted file mode 100644 index 21fa752fae783f54f039080262e8554fe5467ea5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3853 zcmcImO^hSO6|V4)*$^NkKuF;2DhoSe+6zcX;N4m9u04yj_RKJz-4$F=xw~vvrd?%K zSC4l_iWDhQj!`Z_B8e0!N-iiDqzEa}o|qiCamy`8+~9@;ms}9vt8S0&9d8hav^4X% z-Bqu@_r34E@+Xhn^?QNqB>sMizn_0kh_k@eJMa(JXTU4K&w*ROm+lnehrr(ep8);= z*aH3ocmnt}@CU#L?h@ir;FG}nfX@T@`&WSX16$?uF7O`Q4}rYS0`CRh06q@&x1La>(r| zAYTs`5d6a*S$Fm->n-Z!huS64SUSH?GLCI-JoTL&(djc|XZLiX+)746nNd$EL$NhR z#a<=kE$!RfO*d7)d#prfvvA>^w*)NdTq@qFt;s|^Nl4O8AiWhx*Nau6Zb&(29oaa} zodd(kP^XHd_i8lu+6GWnxX4%BLM3iI}|*vtzqw$;e)DbdBMkX=^~47H3Xk*x7h zo4GGOTpb6@$6{xw<^xZQvZQX+Z(loKm)kGb8OhWsnd~o`LQdp8FwQs$=OPrg+olBpnp*+1zvK~zwO9Tt$89QpBoYQoV_s^0zY=&U>S$*F&a-`5~(>6S^tGAWYXENUBYg5~21R|Frgp+K`__$WA(vPhnx=3|2TxNn`(*pK z1X$81@H9&tdd>KBA70y2Wb86!v#I#S+(5LWEDLE86=Twbp#p|z9&S{0>VTyNPaZTZ zK*`Y>#TW0ojcbBqdRcbMPykdf>C254`a#tN`gs~Q@;$7z@4V~(*ojQFc42HLJ zm#$=|E|dzLKPxX(#g?$p$)! zF6M(Q+OajNY;8u{YESc?s3E~W^%sWel68i>jtwm zV9;rGnlsujRG+W#tU{YaJNsks@#=;@J5HrG=O`XZmnpw?b!R<#dA5#ep`W9siEV25SSzcM8Hd|!?ZtEOB0pI>W9Z}>y|8kwBATdT!)foO>1o*0?Sh1* zJ!=-m8%=VTC=|?73w0UMm13E4z1$?qRKH^&jz1r0pghKs@l_E5vo1Ytk{r|C+%EJ` zn}fW6c$1f0RC+}0fjl0r!jJKg4sZ69Iqc2LDIDKccVkHyT6&k|f+~Zdu2TZzw>cQNYf?`9)LkEJ0kFy7H zX-~O{Vil>Y6;r{dP!p_fAAXR9ZC&jT3OS0fcs7e)j0= zorqa9)2OHPVzx%SHBlO8)GiuZnP_@S_4NV7g4Q^~6})5;N+fo#2A3F>tEI9XYng+b zE6X-!C;dNT1;5XFbLNBcREi3fS%HPqs)901`v50bnh{Q@0~nLK>`{;3n};{?YpF0M zMhnJ#0@L95g1DFmJYw=xa?{|@;S_fdKfupWKFQF6OsOb0+kCof$-uz|CO1D3WN04l z5e_><0SqC^0enQe95h%5U$X9Hx2)m^PBEl_+3_hAidmGR2pCvm)AHuo><43NEpyyq16Z58_rn1j#!keNugN_~j{^V)Lg U+Z}vOZTR3-hL1k}*??L34gM*MP5=M^ diff --git a/src/locale/en/LC_MESSAGES/django.mo b/src/locale/en/LC_MESSAGES/django.mo deleted file mode 100644 index fbe24ad2e7ab3081b74e3d8aaeaaa7aa9188eafd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46184 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

5=NlV};>FbUz(IOe!N%C@-C|ufGo{UAuJc8y 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 Date: Mon, 19 May 2025 23:55:40 +0200 Subject: [PATCH 02/11] add Dockerfile --- .dockerignore | 27 +++++++++++++++++++++ Dockerfile | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 3 files changed, 90 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..573b7551 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,27 @@ +latex/anschreiben/veranstalter.adr +# Ignore all files in db folder +db/* +# But keep the folder +!db/.gitkeep + +*.pyc +htmlcov +pyenv +*.aux +*.log +.idea +*.pdf +*.adr +.project +.pydevproject +.settings/* +.coverage +settings_secret.py +static/* +venv/ +.vscode/* +.python-version + +node_modules/ + +*.mo \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e9d8850f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,62 @@ +# Stage 1 +FROM python:3.13-slim AS builder + +RUN mkdir /app + +WORKDIR /app + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +RUN pip install --upgrade pip + +RUN apt-get update && apt-get install -y \ + curl \ + gnupg \ + ca-certificates \ + && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt /app/ + +RUN pip install --no-cache-dir -r requirements.txt + +COPY package*.json ./ + +RUN npm i + +# Stage 2 +FROM python:3.13-slim + +RUN useradd -m -r appuser && \ + mkdir /app && \ + chown -R appuser /app + +COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/ +COPY --from=builder /usr/local/bin/ /usr/local/bin/ + +RUN apt-get update && apt-get install -y gettext \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + + +WORKDIR /app + +COPY --chown=appuser:appuser . . + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app/src + +RUN python manage.py migrate --no-input +RUN python manage.py compilemessages + +USER appuser + +EXPOSE 8000 + + +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "wsgi:application"] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 7cd115d3..eb640240 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ django-debug-toolbar==6.3.0 freezegun==1.5.5 django-formtools==2.5.1 django-allauth[socialaccount,keycloak]==65.16.1 +gunicorn==26.0.0 \ No newline at end of file From 427b09bf0858b8ec37ccbddcbe7f3b99eec011be Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Tue, 20 May 2025 23:59:35 +0200 Subject: [PATCH 03/11] add docker compose and .env --- .env | 11 +++++++++++ docker-compose.yml | 25 +++++++++++++++++++++++++ src/settings_production.py | 22 +++++++++++----------- src/wsgi.py | 4 +++- 4 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 .env create mode 100644 docker-compose.yml diff --git a/.env b/.env new file mode 100644 index 00000000..31fa3b69 --- /dev/null +++ b/.env @@ -0,0 +1,11 @@ +SETTINGS_FILE=settings +DEBUG=False +ALLOWED_HOSTS=.fachschaft.informatik.tu-darmstadt.de,.d120.de +SECRET_KEY= +KEYCLOAK_CLIENT_ID= +KEYCLOAK_SECRET= +KEYCLOAK_SERVER_URL= +EMAIL_HOST=mail.d120.de +EMAIL_PORT=587 +EMAIL_HOST_USER=pyfeedback +EMAIL_HOST_PASSWORD= \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..b85d87b1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +services: + django-web: + build: . + container_name: pyfeedback-docker + ports: + - "8000:8000" + environment: + - SETTINGS_FILE=${SETTINGS_FILE} + - DEBUG=${DEBUG} + - ALLOWED_HOSTS=${ALLOWED_HOSTS} + - SECRET_KEY=${SECRET_KEY} + - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID} + - KEYCLOAK_SECRET=${KEYCLOAK_SECRET} + - KEYCLOAK_SERVER_URL=${KEYCLOAK_SERVER_URL} + - EMAIL_HOST=${EMAIL_HOST} + - EMAIL_PORT=${EMAIL_PORT} + - EMAIL_HOST_USER=${EMAIL_HOST_USER} + - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} + env_file: + - .env + volumes: + - db_data:/app/db/ + +volumes: + db_data: \ No newline at end of file diff --git a/src/settings_production.py b/src/settings_production.py index ba6f04ea..e5096749 100644 --- a/src/settings_production.py +++ b/src/settings_production.py @@ -1,11 +1,11 @@ from settings import * -import settings_secret as secrets +import os -DEBUG = False +DEBUG = os.getenv("DEBUG") -ALLOWED_HOSTS = ['.fachschaft.informatik.tu-darmstadt.de', '.d120.de'] +ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(",") -SECRET_KEY = secrets.SECRET_KEY +SECRET_KEY = os.getenv("SECRET_KEY") URL_PREFIX = 'feedback/' @@ -20,10 +20,10 @@ { "provider_id": "keycloak", "name": "Keycloak", - "client_id": secrets.KEYCLOAK_CLIENT_ID, - "secret": secrets.KEYCLOAK_SECRET, + "client_id": os.getenv("KEYCLOAK_CLIENT_ID"), + "secret": os.getenv("KEYCLOAK_SECRET"), "settings": { - "server_url": secrets.KEYCLOAK_SERVER_URL, + "server_url": os.getenv("KEYCLOAK_SERVER_URL"), }, } ] @@ -33,11 +33,11 @@ # @see https://docs.djangoproject.com/es/1.9/topics/email/ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = 'mail.d120.de' -EMAIL_PORT = 587 +EMAIL_HOST = os.getenv("EMAIL_HOST") +EMAIL_PORT = int(os.getenv("EMAIL_PORT")) EMAIL_USE_TLS = True -EMAIL_HOST_USER = 'pyfeedback' -EMAIL_HOST_PASSWORD = secrets.EMAIL_HOST_PASSWORD +EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER") +EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD") SESSION_COOKIE_PATH = '/feedback' SESSION_COOKIE_SECURE = True diff --git a/src/wsgi.py b/src/wsgi.py index ac4b0cc0..872c4101 100644 --- a/src/wsgi.py +++ b/src/wsgi.py @@ -2,7 +2,9 @@ from django.core.wsgi import get_wsgi_application +# select in .env which settings to use +settings_file = os.getenv("SETTINGS_FILE", "settings") -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_file) application = get_wsgi_application() From 26ac563dfc419f0515ff4b2e402be8d67ef12dd3 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 21 May 2025 00:29:26 +0200 Subject: [PATCH 04/11] update Dockerfile --- Dockerfile | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index e9d8850f..64d73022 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Stage 1 +## Stage 1: build stage FROM python:3.13-slim AS builder RUN mkdir /app @@ -8,6 +8,7 @@ WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 +# install packages and node RUN pip install --upgrade pip RUN apt-get update && apt-get install -y \ @@ -19,31 +20,36 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# install pip requirements COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt +# install node_modules COPY package*.json ./ RUN npm i -# Stage 2 +## Stage 2: production stage FROM python:3.13-slim RUN useradd -m -r appuser && \ mkdir /app && \ chown -R appuser /app +# Copy the python dependencies and node_modules from the builder stage COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/ COPY --from=builder /usr/local/bin/ /usr/local/bin/ +COPY --from=builder /app/node_modules/ /app/node_modules/ +# install gettext for translations (compiling) RUN apt-get update && apt-get install -y gettext \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* - WORKDIR /app +# copy the code COPY --chown=appuser:appuser . . ENV PYTHONDONTWRITEBYTECODE=1 @@ -51,12 +57,16 @@ ENV PYTHONUNBUFFERED=1 WORKDIR /app/src -RUN python manage.py migrate --no-input +# compile translations RUN python manage.py compilemessages +# migrate db changes +RUN python manage.py migrate --no-input + +# switch to non-root user USER appuser EXPOSE 8000 - +# start applicaiton with gunicorn CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "wsgi:application"] \ No newline at end of file From f0408054ad6d0816957f65e21d3cec9a83b44050 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Thu, 22 May 2025 21:34:42 +0200 Subject: [PATCH 05/11] dockerfile fix --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 64d73022..e9a86cd0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,15 +57,15 @@ ENV PYTHONUNBUFFERED=1 WORKDIR /app/src +# switch to non-root user +USER appuser + # compile translations -RUN python manage.py compilemessages +RUN django-admin compilemessages # migrate db changes RUN python manage.py migrate --no-input -# switch to non-root user -USER appuser - EXPOSE 8000 # start applicaiton with gunicorn From 61495e8972f523695e11335015671150ca09da8f Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Thu, 22 May 2025 23:41:45 +0200 Subject: [PATCH 06/11] bug fix --- src/settings_production.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings_production.py b/src/settings_production.py index e5096749..939eb06e 100644 --- a/src/settings_production.py +++ b/src/settings_production.py @@ -1,7 +1,7 @@ from settings import * import os -DEBUG = os.getenv("DEBUG") +DEBUG = (os.getenv("DEBUG", "False") == "True") # os.getenv only returns a string ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(",") From 0a2c05e8e980d55535a5d372328bb105f373be43 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Mon, 1 Dec 2025 23:05:31 +0100 Subject: [PATCH 07/11] minor change --- .env | 3 +-- docker-compose.yml | 3 +-- src/settings_production.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.env b/.env index 31fa3b69..ec31d8b5 100644 --- a/.env +++ b/.env @@ -1,5 +1,4 @@ SETTINGS_FILE=settings -DEBUG=False ALLOWED_HOSTS=.fachschaft.informatik.tu-darmstadt.de,.d120.de SECRET_KEY= KEYCLOAK_CLIENT_ID= @@ -8,4 +7,4 @@ KEYCLOAK_SERVER_URL= EMAIL_HOST=mail.d120.de EMAIL_PORT=587 EMAIL_HOST_USER=pyfeedback -EMAIL_HOST_PASSWORD= \ No newline at end of file +EMAIL_HOST_PASSWORD= diff --git a/docker-compose.yml b/docker-compose.yml index b85d87b1..343f1356 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,6 @@ services: - "8000:8000" environment: - SETTINGS_FILE=${SETTINGS_FILE} - - DEBUG=${DEBUG} - ALLOWED_HOSTS=${ALLOWED_HOSTS} - SECRET_KEY=${SECRET_KEY} - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID} @@ -22,4 +21,4 @@ services: - db_data:/app/db/ volumes: - db_data: \ No newline at end of file + db_data: diff --git a/src/settings_production.py b/src/settings_production.py index 939eb06e..ccc1db5c 100644 --- a/src/settings_production.py +++ b/src/settings_production.py @@ -1,7 +1,7 @@ from settings import * import os -DEBUG = (os.getenv("DEBUG", "False") == "True") # os.getenv only returns a string +DEBUG = False ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(",") From c706cfee6d5c923e6a2bf8ec61640536b9ca2566 Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Tue, 2 Dec 2025 00:05:53 +0100 Subject: [PATCH 08/11] minor fix --- .env | 7 ++++--- docker-compose.yml | 15 ++------------- src/settings_production.py | 2 +- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/.env b/.env index ec31d8b5..3fe5de79 100644 --- a/.env +++ b/.env @@ -1,10 +1,11 @@ SETTINGS_FILE=settings +DEBUG=False ALLOWED_HOSTS=.fachschaft.informatik.tu-darmstadt.de,.d120.de SECRET_KEY= KEYCLOAK_CLIENT_ID= KEYCLOAK_SECRET= KEYCLOAK_SERVER_URL= -EMAIL_HOST=mail.d120.de -EMAIL_PORT=587 -EMAIL_HOST_USER=pyfeedback +EMAIL_HOST= +EMAIL_PORT= +EMAIL_HOST_USER= EMAIL_HOST_PASSWORD= diff --git a/docker-compose.yml b/docker-compose.yml index 343f1356..b889e065 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,21 +4,10 @@ services: container_name: pyfeedback-docker ports: - "8000:8000" - environment: - - SETTINGS_FILE=${SETTINGS_FILE} - - ALLOWED_HOSTS=${ALLOWED_HOSTS} - - SECRET_KEY=${SECRET_KEY} - - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID} - - KEYCLOAK_SECRET=${KEYCLOAK_SECRET} - - KEYCLOAK_SERVER_URL=${KEYCLOAK_SERVER_URL} - - EMAIL_HOST=${EMAIL_HOST} - - EMAIL_PORT=${EMAIL_PORT} - - EMAIL_HOST_USER=${EMAIL_HOST_USER} - - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} env_file: - .env volumes: - - db_data:/app/db/ + - pyfeedback-db-vol:/app/db/ volumes: - db_data: + pyfeedback-db-vol: diff --git a/src/settings_production.py b/src/settings_production.py index ccc1db5c..939eb06e 100644 --- a/src/settings_production.py +++ b/src/settings_production.py @@ -1,7 +1,7 @@ from settings import * import os -DEBUG = False +DEBUG = (os.getenv("DEBUG", "False") == "True") # os.getenv only returns a string ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(",") From 33fcaf3f8bffe5c1cb2b2befaed9d3c5649ce07f Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 6 May 2026 21:04:43 +0200 Subject: [PATCH 09/11] rename env --- .env => .env.example | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .env => .env.example (100%) diff --git a/.env b/.env.example similarity index 100% rename from .env rename to .env.example From c6eb85f32e0bc04e75549660090e8677c627412e Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 6 May 2026 21:17:53 +0200 Subject: [PATCH 10/11] minor changes --- .dockerignore | 5 ++++- .env.example | 1 + .gitignore | 5 ++++- Dockerfile | 2 +- docker-compose.yml | 6 +++--- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.dockerignore b/.dockerignore index 573b7551..e18fae4c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,9 +19,12 @@ pyenv settings_secret.py static/* venv/ +.venv .vscode/* .python-version node_modules/ -*.mo \ No newline at end of file +*.mo + +.env \ No newline at end of file diff --git a/.env.example b/.env.example index 3fe5de79..d0a33ace 100644 --- a/.env.example +++ b/.env.example @@ -9,3 +9,4 @@ EMAIL_HOST= EMAIL_PORT= EMAIL_HOST_USER= EMAIL_HOST_PASSWORD= +GUNICORN_WORKERS= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 573b7551..25255289 100644 --- a/.gitignore +++ b/.gitignore @@ -19,9 +19,12 @@ pyenv settings_secret.py static/* venv/ +.venv/ .vscode/* .python-version node_modules/ -*.mo \ No newline at end of file +*.mo + +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e9a86cd0..30caeea7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -69,4 +69,4 @@ RUN python manage.py migrate --no-input EXPOSE 8000 # start applicaiton with gunicorn -CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "wsgi:application"] \ No newline at end of file +CMD ["sh", "-c", "gunicorn --bind 0.0.0.0:8000 --workers ${GUNICORN_WORKERS:-3} wsgi:application"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b889e065..8320c1b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,5 @@ services: - django-web: + pyfeedback: build: . container_name: pyfeedback-docker ports: @@ -7,7 +7,7 @@ services: env_file: - .env volumes: - - pyfeedback-db-vol:/app/db/ + - pyfeedback-db:/app/db/ volumes: - pyfeedback-db-vol: + pyfeedback-db: From e87233c33da9bcc99dd54781a540eaad54ebb8ec Mon Sep 17 00:00:00 2001 From: 4-dash <120916864+4-dash@users.noreply.github.com> Date: Wed, 6 May 2026 22:25:02 +0200 Subject: [PATCH 11/11] improve dockerfile --- Dockerfile | 40 +++++++++++++++++++++------------------- entrypoint.sh | 11 +++++++++++ 2 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 30caeea7..b96f6326 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,13 @@ ## Stage 1: build stage FROM python:3.13-slim AS builder -RUN mkdir /app - -WORKDIR /app - +ARG DEBIAN_FRONTEND=noninteractive ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 -# install packages and node -RUN pip install --upgrade pip +WORKDIR /app +# install packages and node RUN apt-get update && apt-get install -y \ curl \ gnupg \ @@ -21,28 +18,31 @@ RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* # install pip requirements -COPY requirements.txt /app/ - -RUN pip install --no-cache-dir -r requirements.txt +COPY requirements.txt . +RUN pip install --upgrade pip && \ + pip install --no-cache-dir -r requirements.txt # install node_modules COPY package*.json ./ - RUN npm i ## Stage 2: production stage FROM python:3.13-slim +ARG DEBIAN_FRONTEND=noninteractive +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + RUN useradd -m -r appuser && \ mkdir /app && \ chown -R appuser /app -# Copy the python dependencies and node_modules from the builder stage +# Copy dependencies from builder COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/ COPY --from=builder /usr/local/bin/ /usr/local/bin/ -COPY --from=builder /app/node_modules/ /app/node_modules/ +COPY --from=builder /app/node_modules/ /app/node_modules/ -# install gettext for translations (compiling) +# install gettext for translations RUN apt-get update && apt-get install -y gettext \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -52,19 +52,21 @@ WORKDIR /app # copy the code COPY --chown=appuser:appuser . . -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 - WORKDIR /app/src -# switch to non-root user USER appuser # compile translations RUN django-admin compilemessages -# migrate db changes -RUN python manage.py migrate --no-input +# --- Runtime Setup --- +USER root +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +USER appuser + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] EXPOSE 8000 diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..5573e743 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Exit on error +set -e + +echo "Applying database migrations..." +python manage.py migrate --no-input + +# Start the application +echo "Starting Gunicorn..." +exec "$@" \ No newline at end of file