diff --git a/Dockerfile.django-alpine b/Dockerfile.django-alpine index 828a15b786f..a92f95fc46a 100644 --- a/Dockerfile.django-alpine +++ b/Dockerfile.django-alpine @@ -11,26 +11,17 @@ WORKDIR /app RUN \ apk update && \ apk add --no-cache \ - gcc \ - build-base \ bind-tools \ postgresql16-client \ xmlsec \ git \ util-linux \ - curl-dev \ openssl \ - libffi-dev \ - python3-dev \ - libpq-dev \ && \ rm -rf /var/cache/apk/* && \ true COPY requirements.txt ./ -# CPUCOUNT=1 is needed, otherwise the wheel for uwsgi won't always be build succesfully -# https://github.com/unbit/uwsgi/issues/1318#issuecomment-542238096 -RUN export PYCURL_SSL_LIBRARY=openssl && \ - CPUCOUNT=1 pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt +RUN pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt FROM base AS release WORKDIR /app @@ -49,8 +40,9 @@ RUN \ git \ util-linux \ postgresql16-client \ - curl-dev \ openssl \ + # py3-curl for Celery SQS broker support (avoids compilation) + py3-curl \ # needed for integration-tests bash \ && \ @@ -65,6 +57,16 @@ RUN \ --find-links=/tmp/wheels \ -r ./requirements.txt +# Install uwsgi via pip for Alpine (system package is compiled for Python 3.12, but we use Python 3.13) +# uwsgi needs build dependencies to compile +RUN apk add --no-cache --virtual .uwsgi-build-deps \ + gcc \ + musl-dev \ + linux-headers \ + python3-dev \ + && pip3 install --no-cache-dir uwsgi==2.0.28 \ + && apk del .uwsgi-build-deps + COPY \ docker/entrypoint-celery-beat.sh \ docker/entrypoint-celery-worker.sh \ diff --git a/Dockerfile.django-debian b/Dockerfile.django-debian index 779dbcba13d..12d3602d163 100644 --- a/Dockerfile.django-debian +++ b/Dockerfile.django-debian @@ -11,25 +11,17 @@ WORKDIR /app RUN \ apt-get -y update && \ apt-get -y install --no-install-recommends \ - gcc \ - build-essential \ dnsutils \ - libpq-dev \ postgresql-client \ xmlsec1 \ git \ uuid-runtime \ - # libcurl4-openssl-dev is required for installing pycurl python package - libcurl4-openssl-dev \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists && \ true COPY requirements.txt ./ -# CPUCOUNT=1 is needed, otherwise the wheel for uwsgi won't always be build succesfully -# https://github.com/unbit/uwsgi/issues/1318#issuecomment-542238096 -RUN export PYCURL_SSL_LIBRARY=openssl && \ - CPUCOUNT=1 pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt +RUN pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt FROM base AS release WORKDIR /app @@ -50,11 +42,13 @@ RUN \ xmlsec1 \ git \ uuid-runtime \ - libpq-dev \ # only required for the dbshell (used by the initializer job) postgresql-client \ - # libcurl4-openssl-dev is required for installing pycurl python package - libcurl4-openssl-dev \ + # python3-pycurl for Celery SQS broker support (avoids compilation) + python3-pycurl \ + # uwsgi from system packages (avoids compilation) + uwsgi \ + uwsgi-plugin-python3 \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists && \ diff --git a/Dockerfile.nginx-alpine b/Dockerfile.nginx-alpine index bfdf4a4114a..8be00a5814d 100644 --- a/Dockerfile.nginx-alpine +++ b/Dockerfile.nginx-alpine @@ -11,31 +11,24 @@ WORKDIR /app RUN \ apk update && \ apk add --no-cache \ - gcc \ - build-base \ bind-tools \ postgresql16-client \ xmlsec \ git \ util-linux \ - curl-dev \ openssl \ - libffi-dev \ - python3-dev \ - libpq-dev \ && \ rm -rf /var/cache/apk/* && \ true COPY requirements.txt requirements-dev.txt ./ -# CPUCOUNT=1 is needed, otherwise the wheel for uwsgi won't always be build succesfully -# https://github.com/unbit/uwsgi/issues/1318#issuecomment-542238096 -RUN CPUCOUNT=1 pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt +RUN pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements.txt # needed for static files debug toolbar -RUN CPUCOUNT=1 pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements-dev.txt +RUN pip3 wheel --wheel-dir=/tmp/wheels -r ./requirements-dev.txt FROM build AS collectstatic -RUN apk add nodejs npm +# py3-curl for Celery SQS broker support (avoids compilation) +RUN apk add nodejs npm py3-curl RUN npm install -g yarn --force diff --git a/docker-compose.override.dev.yml b/docker-compose.override.dev.yml index bc31139a352..d3d3a3cd4c1 100644 --- a/docker-compose.override.dev.yml +++ b/docker-compose.override.dev.yml @@ -3,7 +3,7 @@ services: uwsgi: build: context: . - dockerfile: Dockerfile.django-debian + dockerfile: Dockerfile.django-${DEFECT_DOJO_OS:-debian} target: development entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST:-postgres}:${DD_DATABASE_PORT:-5432}', '-t', '30', '--', '/entrypoint-uwsgi-dev.sh'] volumes: diff --git a/docker/entrypoint-uwsgi-dev.sh b/docker/entrypoint-uwsgi-dev.sh index 7051ccadc00..b54ace14453 100755 --- a/docker/entrypoint-uwsgi-dev.sh +++ b/docker/entrypoint-uwsgi-dev.sh @@ -31,10 +31,21 @@ watchmedo shell-command \ /app/dojo & -exec uwsgi \ +echo -n "Starting uwsgi" + +# Only use --home on Debian; pip-installed uwsgi on Alpine doesn't need it +if [ ! -f /etc/alpine-release ]; then + UWSGI_HOME_OPT="--home /usr/local" +else + UWSGI_HOME_OPT="" +fi + +uwsgi \ "--${DD_UWSGI_MODE}" "${DD_UWSGI_ENDPOINT}" \ --protocol uwsgi \ - --wsgi dojo.wsgi:application \ + --plugin python3 \ + ${UWSGI_HOME_OPT} \ + --module dojo.wsgi:application \ --enable-threads \ --processes "${DD_UWSGI_NUM_OF_PROCESSES:-4}" \ --threads "${DD_UWSGI_NUM_OF_THREADS:-4}" \ diff --git a/docker/entrypoint-uwsgi.sh b/docker/entrypoint-uwsgi.sh index a9ca7bf49e6..b5cb82ece7f 100755 --- a/docker/entrypoint-uwsgi.sh +++ b/docker/entrypoint-uwsgi.sh @@ -34,13 +34,24 @@ if [ -n "${DD_UWSGI_MAX_FD}" ]; then DD_UWSGI_EXTRA_ARGS="${DD_UWSGI_EXTRA_ARGS} --max-fd ${DD_UWSGI_MAX_FD}" fi -exec uwsgi \ +echo -n "Starting uwsgi" + +# Only use --home on Debian; pip-installed uwsgi on Alpine doesn't need it +if [ ! -f /etc/alpine-release ]; then + UWSGI_HOME_OPT="--home /usr/local" +else + UWSGI_HOME_OPT="" +fi + +uwsgi \ "--${DD_UWSGI_MODE}" "${DD_UWSGI_ENDPOINT}" \ --protocol uwsgi \ + --plugin python3 \ + ${UWSGI_HOME_OPT} \ + --module dojo.wsgi:application \ --enable-threads \ --processes "${DD_UWSGI_NUM_OF_PROCESSES:-4}" \ --threads "${DD_UWSGI_NUM_OF_THREADS:-4}" \ - --wsgi dojo.wsgi:application \ --buffer-size="${DD_UWSGI_BUFFER_SIZE:-8192}" \ --http 0.0.0.0:8081 --http-to "${DD_UWSGI_ENDPOINT}" \ --logformat "${DD_UWSGI_LOGFORMAT:-$DD_UWSGI_LOGFORMAT_DEFAULT}" \ diff --git a/requirements.txt b/requirements.txt index 4b57e450d82..10f624011f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,14 +29,17 @@ lxml==6.0.2 Markdown==3.10 openpyxl==3.1.5 Pillow==12.0.0 # required by django-imagekit -psycopg[c]==3.3.2 +psycopg[binary]==3.3.2 cryptography==46.0.3 python-dateutil==2.9.0.post0 redis==7.1.0 requests==2.32.5 sqlalchemy==2.0.45 # Required by Celery broker transport urllib3==2.6.2 -uWSGI==2.0.31 +# uWSGI is installed via system packages on Debian (uwsgi + uwsgi-plugin-python3) to avoid compilation. +# On Alpine, uwsgi is installed via pip because the system package (uwsgi-python3) is compiled for Python 3.12 +# but the container uses Python 3.13.7 from the official Python Docker image. +# uwsgi==2.0.28 vobject==0.9.9 whitenoise==5.2.0 titlecase==2.4.1 @@ -62,7 +65,8 @@ drf-spectacular-sidecar==2025.12.1 django-ratelimit==4.1.0 argon2-cffi==25.1.0 blackduck==1.1.3 -pycurl==7.45.7 # Required for Celery Broker AWS (SQS) support +# pycurl is required for Celery SQS broker support but is installed via system +# packages (python3-pycurl on Debian, py3-curl on Alpine) to avoid compilation boto3==1.41.5 # Required for Celery Broker AWS (SQS) support netaddr==1.3.0 vulners==3.1.3