Skip to content

Commit 1462de2

Browse files
committed
Security upgrades
- Use Alpine versions of flask, gunicorn - Upgrade Alpine from 3.18 to 3.19 - Upgrade numpy to 1.25 - Upgrade pandas to 2.0 - Upgrade pillow to 10.3 - Upgrade psycopg2 to 2.9.9 - Upgrade biopython to 1.81 - Use a virtual environment to hold the portal - Install wheels into the virt environment - Invoke gunicorn from venv but use system path - Add worker pool to gunicorn
1 parent 2bbd01e commit 1462de2

File tree

7 files changed

+39
-41
lines changed

7 files changed

+39
-41
lines changed

docker/Dockerfile

+28-30
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# `numpy-gitpod` and `numpy-dev`—and I'm not going to use a `-dev` image in production.) See the `py_deps`
1616
# below.
1717

18-
FROM alpine:3.18
18+
FROM alpine:3.19
1919

2020

2121
# Configurable Arguments
@@ -58,8 +58,8 @@ RUN \
5858
:
5959

6060
RUN \
61-
build_deps="automake bzip2-dev cyrus-sasl-dev git g++ gcc libffi-dev libjpeg-turbo-dev libwebp-dev libxml2-dev libxslt-dev make musl-dev openjpeg-dev openldap-dev openssl-dev pcre-dev python3-dev postgresql-dev su-exec tiff-dev zlib-dev " &&\
62-
run_deps="curl krb5-libs libgcc libjpeg-turbo libldap libpq libsasl libstdc++ libwebp libxml2 libxslt netcat-openbsd openjpeg python3 rsync tiff tidyhtml" &&\
61+
build_deps="automake bzip2-dev cyrus-sasl-dev git g++ gcc libffi-dev libjpeg-turbo-dev libwebp-dev libxml2-dev libxslt-dev make musl-dev openjpeg-dev openldap-dev openssl-dev pcre-dev python3-dev postgresql-dev su-exec tiff-dev zlib-dev py3-pip" &&\
62+
run_deps="curl krb5-libs libgcc libjpeg-turbo libldap libpq libsasl libstdc++ libwebp libxml2 libxslt netcat-openbsd openjpeg python3 rsync tiff tidyhtml py3-gunicorn py3-flask" &&\
6363
py_deps="py3-numpy py3-pandas py3-pillow py3-psycopg2 py3-biopython" &&\
6464
/sbin/apk update --quiet &&\
6565
/sbin/apk add --no-progress --quiet --virtual /edrn-build $build_deps &&\
@@ -69,20 +69,19 @@ RUN \
6969

7070
# Over on GitHub Actions, we need to fail fast and not hit the six hour run limit, so make sure we got it right
7171

72-
RUN [ "`/usr/bin/python3 --version`" = "Python 3.11.10" ]
73-
RUN [ "`/usr/bin/python3 -c 'import numpy; print(numpy.__version__)'`" = "1.24.4" ]
74-
RUN [ "`/usr/bin/python3 -c 'import pandas; print(pandas.__version__)'`" = "1.5.3" ]
75-
RUN [ "`/usr/bin/python3 -c 'import PIL; print(PIL.__version__)'`" = "9.5.0" ]
76-
RUN [ "`/usr/bin/python3 -c 'import psycopg2; print(psycopg2.__version__)'`" = "2.9.6 (dt dec pq3 ext lo64)" ]
77-
RUN [ "`/usr/bin/python3 -c 'import Bio; print(Bio.__version__)'`" = "1.81" ]
72+
RUN echo `/usr/bin/python3 --version` | grep -q '^Python 3\.11\.'
73+
RUN echo `/usr/bin/python3 -c 'import numpy; print(numpy.__version__)'` | grep -q '^1\.25\.'
74+
RUN echo `/usr/bin/python3 -c 'import pandas; print(pandas.__version__)'` | grep -q '^2\.0\.'
75+
RUN echo `/usr/bin/python3 -c 'import PIL; print(PIL.__version__)'` | grep -q '^10\.3\.'
76+
RUN echo `/usr/bin/python3 -c 'import psycopg2; print(psycopg2.__version__)'` | grep -q '^2\.9\.'
77+
# Note that Biopython does not use MAJOR.MINOR.MICRO versions so there's no trailing dot here
78+
RUN echo `/usr/bin/python3 -c 'import Bio; print(Bio.__version__)'` | grep -q '^1\.81'
7879

7980
RUN \
8081
: See https://github.com/python-ldap/python-ldap/issues/432 for workaround to Python LDAP vs OpenLDAP 2.5 issue &&\
8182
echo 'INPUT ( libldap.so )' > /usr/lib/libldap_r.so &&\
82-
/usr/bin/python3 -m ensurepip --upgrade &&\
83-
/usr/bin/pip3 install --quiet --progress-bar off --upgrade pip setuptools wheel &&\
84-
/usr/bin/pip3 install gunicorn==20.1.0 &&\
85-
/usr/bin/install -o edrn -g edrn -d /app /app/media /app/static /app/wheels &&\
83+
/usr/bin/python3 -m venv --system-site-packages --upgrade-deps /app &&\
84+
/usr/bin/install -o edrn -g edrn -d /app/media /app/static /app/wheels &&\
8685
:
8786

8887
COPY --chown=edrn:edrn ./dist/*.whl /app/wheels/
@@ -104,32 +103,30 @@ COPY --chown=edrn:edrn ./dist/*.whl /app/wheels/
104103
# Except the Docker plugin for Jenkins at CBIIT chokes with an HTTP 400 error because apparently
105104
# the single layer made above is too big. So, we have to do these in separate RUNs:
106105

107-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.controls-*.whl
108-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.streams-*.whl
109-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.content-*.whl
110-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrn.collabgroups-*.whl
111-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrn.theme-*.whl
112-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.ploneimport-*.whl
113-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/eke.geocoding-*.whl
114-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/eke.knowledge-*.whl
115-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/eke.biomarkers-*.whl
116-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.search-*.whl
117-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrn.metrics-*.whl
118-
RUN /usr/bin/pip3 install --progress-bar off /app/wheels/edrnsite.policy-*.whl
106+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.controls-*.whl
107+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.streams-*.whl
108+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.content-*.whl
109+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrn.collabgroups-*.whl
110+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrn.theme-*.whl
111+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.ploneimport-*.whl
112+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/eke.geocoding-*.whl
113+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/eke.knowledge-*.whl
114+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/eke.biomarkers-*.whl
115+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.search-*.whl
116+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrn.metrics-*.whl
117+
RUN /app/bin/pip3 install --progress-bar off /app/wheels/edrnsite.policy-*.whl
119118

120119
# And this too:
121120

122121
RUN \
123122
cd /app &&\
124123
: Get the static files ready &&\
125-
/sbin/su-exec edrn /usr/bin/env LDAP_BIND_PASSWORD=unused SIGNING_KEY=unused /usr/bin/django-admin collectstatic --settings edrnsite.policy.settings.ops --no-input --clear --link &&\
124+
/sbin/su-exec edrn /usr/bin/env LDAP_BIND_PASSWORD=unused SIGNING_KEY=unused /app/bin/django-admin collectstatic --settings edrnsite.policy.settings.ops --no-input --clear --link &&\
126125
: Clean up clean up everybody everywhere &&\
127-
: PrismaCloud does not like pip to be in the image &&\
128-
/usr/bin/pip3 uninstall --yes --quiet pip &&\
129126
/sbin/apk del --quiet /edrn-build &&\
130127
/bin/rm -rf /app/wheels &&\
131128
/bin/rm -rf /var/cache/apk/* &&\
132-
/bin/chown -R edrn:edrn /usr/lib/python3.*/site-packages &&\
129+
/bin/chown -R edrn:edrn /app/lib/python3.*/site-packages &&\
133130
:
134131

135132
COPY --chown=edrn:edrn docker/*.py /app/
@@ -144,7 +141,8 @@ EXPOSE 8000
144141
VOLUME ["/app/media"]
145142
USER edrn
146143
WORKDIR /app
147-
ENTRYPOINT ["/usr/bin/gunicorn"]
144+
ENTRYPOINT ["/app/bin/python3"]
145+
CMD ["/usr/bin/gunicorn", "-c", "/app/gunicorn.conf.py"]
148146
HEALTHCHECK --interval=5m --timeout=2m --start-period=10m CMD /usr/bin/curl --fail --retry 6 --max-time 5 --retry-delay 10 --retry-max-time 60 http://127.0.0.1:8000/ || /bin/sh -c 'killall5 -TERM && (/bin/sleep 10; killall5 -KILL)'
149147

150148

docker/docker-compose.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ services:
174174
# Worker processes run Django functions so it needs all the same env vars as `portal`.
175175
worker:
176176
image: ${EDRN_IMAGE_OWNER-edrndocker/}edrn-portal:${EDRN_VERSION:-6.3.0-uid26013}
177-
entrypoint: ['/usr/bin/django-admin', 'worker', '--verbosity', '2']
177+
entrypoint: ['/app/bin/django-admin', 'worker', '--verbosity', '2']
178178
volumes:
179179
-
180180
type: bind

docker/gunicorn.conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
errorlog = '-'
1212
loglevel = 'debug'
1313

14-
# workers = multiprocessing.cpu_count() * 2 + 1
14+
workers = multiprocessing.cpu_count() * 2 + 1
1515
# threads =
1616
# worker_class = 'gevent' # TODO: test this out
1717

src/edrnsite.content/setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ install_requires =
2424
wagtail-django-recaptcha ~= 1.0
2525
django-recaptcha ~= 3.0.0
2626
gdown ~= 4.7.1
27-
pandas == 1.5.3 # Must match py3-pandas package in Dockerfile
27+
pandas ~= 2.0.3 # Must match py3-pandas package in Dockerfile
2828

2929

3030
# A couple of the forms in this package actually depend on eke.knowledge, but eke.knowledge depends on

src/edrnsite.policy/setup.cfg

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ install_requires =
3434
django-auth-ldap ~= 4.1.0
3535
django-celery-results ~= 2.5.1
3636
django-redis ~= 5.4.0
37-
pillow == 9.5.0 # Must match py3-pillow package installed in Dockerfile
38-
psycopg2 == 2.9.6 # Must match py3-pyscopg2 package installed in Dockerfile
37+
pillow ~= 10.3.0 # Must match py3-pillow package installed in Dockerfile
38+
psycopg2 ~= 2.9.9 # Must match py3-pyscopg2 package installed in Dockerfile
3939
pymemcache ~= 3.5.2
4040
wagtail == 5.2.3
4141
wagtail-favicon ~= 0.3.0

src/eke.biomarkers/setup.cfg

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ install_requires =
2121
eke.knowledge
2222
edrnsite.content
2323
edrn.auth
24-
biopython == 1.81 # Must mathc py3-biopython package in Dockerfile
24+
biopython ~= 1.81 # Must mathc py3-biopython package in Dockerfile
2525
django < 5
2626
django_plotly_dash == 1.7.1
27-
numpy == 1.24.4 # Must match py3-numpy package in Dockerfile
28-
pandas == 1.5.3 # Must match py3-pandas package in Dockerfile
27+
numpy ~= 1.25.2 # Must match py3-numpy package in Dockerfile
28+
pandas ~= 2.0.3 # Must match py3-pandas package in Dockerfile
2929
rdflib ~= 6.1.1 # Regression in 6.2.0, see https://github.com/RDFLib/rdflib/issues/2120
3030
sortedcontainers ~= 2.4.0
3131
wagtail < 6

src/eke.knowledge/setup.cfg

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ install_requires =
2222
edrnsite.controls
2323
edrn.collabgroups
2424
eke.geocoding
25-
biopython == 1.81 # Must match py3-biopython package in Dockerfile
25+
biopython ~= 1.81 # Must match py3-biopython package in Dockerfile
2626
boto3 ~= 1.24.75
2727
celery ~= 5.2.7
2828
dash-dangerously-set-inner-html ~= 0.0.2
2929
django < 5
3030
django_plotly_dash == 1.7.1
3131
humanize ~= 4.3.0
3232
libgravatar ~= 1.0.4
33-
numpy == 1.24.4 # Must match py3-numpy package in Dockerfile
34-
pandas == 1.5.3 # Must match py3-pandas package in Dockerfile
33+
numpy ~= 1.25.2 # Must match py3-numpy package in Dockerfile
34+
pandas ~= 2.0.3 # Must match py3-pandas package in Dockerfile
3535
rdflib == 6.1.1 # Regression in 6.2.0, see https://github.com/RDFLib/rdflib/issues/2120
3636
sortedcontainers ~= 2.4.0
3737
wagtail < 6

0 commit comments

Comments
 (0)