From 93e99d5b89bca273a65a5ed923400cb75827f911 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 14:42:51 +0100 Subject: [PATCH 1/9] Make packages easier to read --- docker/hasher-api/Dockerfile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docker/hasher-api/Dockerfile b/docker/hasher-api/Dockerfile index 1a32e1d9b..bbc638c94 100644 --- a/docker/hasher-api/Dockerfile +++ b/docker/hasher-api/Dockerfile @@ -19,8 +19,17 @@ ARG TEST="false" # OS setup RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install --yes --no-install-recommends procps ca-certificates \ - iproute2 git curl libpq-dev curl gnupg g++ locales + apt-get install --yes --no-install-recommends \ + procps \ + ca-certificates \ + iproute2 \ + git \ + curl \ + libpq-dev \ + curl \ + gnupg \ + g++ \ + locales RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen # clean up From 4b1f8fa5bfbd696d588acf9e2c90d704ae011e25 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 14:44:51 +0100 Subject: [PATCH 2/9] Remove unneeded packages --- docker/hasher-api/Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/docker/hasher-api/Dockerfile b/docker/hasher-api/Dockerfile index bbc638c94..a04efba49 100644 --- a/docker/hasher-api/Dockerfile +++ b/docker/hasher-api/Dockerfile @@ -23,12 +23,9 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ procps \ ca-certificates \ iproute2 \ - git \ - curl \ libpq-dev \ curl \ gnupg \ - g++ \ locales RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen From d087520ed62fe05bf25f18d5a03ffe0fcc62db58 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 15:03:28 +0100 Subject: [PATCH 3/9] Merge three pixl python docker images into one multi-stage dockerfile to avoid repetition. --- docker-compose.yml | 9 ++-- docker/export-api/Dockerfile | 48 ----------------- docker/hasher-api/Dockerfile | 52 ------------------- .../{imaging-api => pixl-python}/Dockerfile | 42 ++++++++++++++- 4 files changed, 47 insertions(+), 104 deletions(-) delete mode 100644 docker/export-api/Dockerfile delete mode 100644 docker/hasher-api/Dockerfile rename docker/{imaging-api => pixl-python}/Dockerfile (53%) diff --git a/docker-compose.yml b/docker-compose.yml index 6953ea9dd..71c05b72f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -81,7 +81,8 @@ services: hasher-api: build: context: . - dockerfile: ./docker/hasher-api/Dockerfile + dockerfile: ./docker/pixl-python/Dockerfile + target: hasher_api args: <<: *build-args-common environment: @@ -253,7 +254,8 @@ services: export-api: build: context: . - dockerfile: ./docker/export-api/Dockerfile + dockerfile: ./docker/pixl-python/Dockerfile + target: export_api args: <<: *build-args-common environment: @@ -299,7 +301,8 @@ services: imaging-api: build: context: . - dockerfile: ./docker/imaging-api/Dockerfile + dockerfile: ./docker/pixl-python/Dockerfile + target: imaging_api args: <<: *build-args-common depends_on: diff --git a/docker/export-api/Dockerfile b/docker/export-api/Dockerfile deleted file mode 100644 index dfbd0324b..000000000 --- a/docker/export-api/Dockerfile +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) University College London Hospitals NHS Foundation Trust -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -FROM python:3.11.7-slim-bullseye -SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] - -ARG TEST="false" - -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install --yes --no-install-recommends \ - procps \ - ca-certificates \ - iproute2 \ - libpq-dev \ - curl \ - gnupg \ - locales -RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen -RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -# Install requirements before copying modules -COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml -COPY ./pixl_export/pyproject.toml ./pixl_export/pyproject.toml -RUN pip3 install --no-cache-dir pixl_core/ \ - && pip3 install --no-cache-dir pixl_export/ - -COPY ./pixl_core/ pixl_core/ -COPY ./pixl_export/ . -RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \ - --no-cache-dir --force-reinstall --no-deps . && \ - if [ "$TEST" = "true" ]; then pip install --no-cache-dir pixl_core/[test] .[test]; fi - -HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 - -ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker/hasher-api/Dockerfile b/docker/hasher-api/Dockerfile deleted file mode 100644 index a04efba49..000000000 --- a/docker/hasher-api/Dockerfile +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) University College London Hospitals NHS Foundation Trust -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -FROM python:3.11.7-slim-bullseye -SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] - -ARG TEST="false" - -# OS setup -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install --yes --no-install-recommends \ - procps \ - ca-certificates \ - iproute2 \ - libpq-dev \ - curl \ - gnupg \ - locales -RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen - -# clean up -RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -# Install requirements before copying modules -COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml -COPY ./hasher/pyproject.toml . -RUN --mount=type=cache,target=/root/.cache \ - pip3 install --no-cache-dir pixl_core/ \ - && pip3 install --no-cache-dir /app/ - -COPY ./pixl_core/ pixl_core/ -COPY ./hasher/ . -RUN --mount=type=cache,target=/root/.cache \ - pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ . && \ - if [ "$TEST" = "true" ]; \ - then pip install --no-cache-dir --force-reinstall --no-deps pixl_core/[test] \ - --no-cache-dir --force-reinstall --no-deps .[test]; fi - -ENTRYPOINT ["uvicorn", "hasher.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker/imaging-api/Dockerfile b/docker/pixl-python/Dockerfile similarity index 53% rename from docker/imaging-api/Dockerfile rename to docker/pixl-python/Dockerfile index 647771236..4a19ff331 100644 --- a/docker/imaging-api/Dockerfile +++ b/docker/pixl-python/Dockerfile @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM python:3.11.7-slim-bullseye +FROM python:3.11.7-slim-bullseye AS pixl_python_base SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] ARG TEST="false" @@ -30,6 +30,46 @@ RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* WORKDIR /app +# --- END COMMMON --- + +FROM pixl_python_base AS export_api + +# Install requirements before copying modules +COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml +COPY ./pixl_export/pyproject.toml ./pixl_export/pyproject.toml +RUN pip3 install --no-cache-dir pixl_core/ \ + && pip3 install --no-cache-dir pixl_export/ + +COPY ./pixl_core/ pixl_core/ +COPY ./pixl_export/ . +RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \ + --no-cache-dir --force-reinstall --no-deps . && \ + if [ "$TEST" = "true" ]; then pip install --no-cache-dir pixl_core/[test] .[test]; fi + +HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 + +ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] + +FROM pixl_python_base AS hasher_api + +# Install requirements before copying modules +COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml +COPY ./hasher/pyproject.toml . +RUN --mount=type=cache,target=/root/.cache \ + pip3 install --no-cache-dir pixl_core/ \ + && pip3 install --no-cache-dir /app/ + +COPY ./pixl_core/ pixl_core/ +COPY ./hasher/ . +RUN --mount=type=cache,target=/root/.cache \ + pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ . && \ + if [ "$TEST" = "true" ]; \ + then pip install --no-cache-dir --force-reinstall --no-deps pixl_core/[test] \ + --no-cache-dir --force-reinstall --no-deps .[test]; fi + +ENTRYPOINT ["uvicorn", "hasher.main:app", "--host", "0.0.0.0", "--port", "8000"] + +FROM pixl_python_base AS imaging_api # Install requirements before copying modules COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml From 1e1c18ecc61c94c6dc40ce9ff9e284f24572a704 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 15:18:05 +0100 Subject: [PATCH 4/9] Specify healthcheck command in only one place --- docker-compose.yml | 2 -- docker/pixl-python/Dockerfile | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 71c05b72f..40fcce784 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -101,7 +101,6 @@ services: networks: - pixl-net healthcheck: - test: ["CMD", "curl", "-f", "http://hasher-api:8000/heart-beat"] interval: 10s timeout: 30s retries: 5 @@ -311,7 +310,6 @@ services: orthanc-raw: condition: service_healthy healthcheck: - test: curl -f http://0.0.0.0:8000/heart-beat interval: 10s timeout: 30s retries: 5 diff --git a/docker/pixl-python/Dockerfile b/docker/pixl-python/Dockerfile index 4a19ff331..07bb72aa2 100644 --- a/docker/pixl-python/Dockerfile +++ b/docker/pixl-python/Dockerfile @@ -29,8 +29,9 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && locale-gen RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* +HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 + WORKDIR /app -# --- END COMMMON --- FROM pixl_python_base AS export_api @@ -46,8 +47,6 @@ RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \ --no-cache-dir --force-reinstall --no-deps . && \ if [ "$TEST" = "true" ]; then pip install --no-cache-dir pixl_core/[test] .[test]; fi -HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 - ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] FROM pixl_python_base AS hasher_api From 63d6edb3dd39ab080c7472ee945da67923d531c5 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 16:10:44 +0100 Subject: [PATCH 5/9] De-dupe the pre-reqs installation code using a build arg --- docker-compose.yml | 3 +++ docker/pixl-python/Dockerfile | 28 +++++++++------------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 40fcce784..508223d27 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -84,6 +84,7 @@ services: dockerfile: ./docker/pixl-python/Dockerfile target: hasher_api args: + PIXL_PACKAGE_DIR: hasher <<: *build-args-common environment: <<: [*proxy-common, *pixl-common-env] @@ -256,6 +257,7 @@ services: dockerfile: ./docker/pixl-python/Dockerfile target: export_api args: + PIXL_PACKAGE_DIR: pixl_export <<: *build-args-common environment: <<: @@ -303,6 +305,7 @@ services: dockerfile: ./docker/pixl-python/Dockerfile target: imaging_api args: + PIXL_PACKAGE_DIR: pixl_imaging <<: *build-args-common depends_on: queue: diff --git a/docker/pixl-python/Dockerfile b/docker/pixl-python/Dockerfile index 07bb72aa2..f6b8a4603 100644 --- a/docker/pixl-python/Dockerfile +++ b/docker/pixl-python/Dockerfile @@ -32,14 +32,17 @@ RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 WORKDIR /app - -FROM pixl_python_base AS export_api +ARG PIXL_PACKAGE_DIR # Install requirements before copying modules COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml -COPY ./pixl_export/pyproject.toml ./pixl_export/pyproject.toml +COPY ./$PIXL_PACKAGE_DIR/pyproject.toml ./$PIXL_PACKAGE_DIR/pyproject.toml RUN pip3 install --no-cache-dir pixl_core/ \ - && pip3 install --no-cache-dir pixl_export/ + && pip3 install --no-cache-dir $PIXL_PACKAGE_DIR/ + + + +FROM pixl_python_base AS export_api COPY ./pixl_core/ pixl_core/ COPY ./pixl_export/ . @@ -49,14 +52,8 @@ RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \ ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] -FROM pixl_python_base AS hasher_api -# Install requirements before copying modules -COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml -COPY ./hasher/pyproject.toml . -RUN --mount=type=cache,target=/root/.cache \ - pip3 install --no-cache-dir pixl_core/ \ - && pip3 install --no-cache-dir /app/ +FROM pixl_python_base AS hasher_api COPY ./pixl_core/ pixl_core/ COPY ./hasher/ . @@ -65,17 +62,10 @@ RUN --mount=type=cache,target=/root/.cache \ if [ "$TEST" = "true" ]; \ then pip install --no-cache-dir --force-reinstall --no-deps pixl_core/[test] \ --no-cache-dir --force-reinstall --no-deps .[test]; fi - ENTRYPOINT ["uvicorn", "hasher.main:app", "--host", "0.0.0.0", "--port", "8000"] -FROM pixl_python_base AS imaging_api -# Install requirements before copying modules -COPY ./pixl_core/pyproject.toml ./pixl_core/pyproject.toml -COPY ./pixl_imaging/pyproject.toml ./pixl_imaging/pyproject.toml -RUN --mount=type=cache,target=/root/.cache \ - pip3 install --no-cache-dir pixl_core/ \ - && pip3 install --no-cache-dir pixl_imaging/ +FROM pixl_python_base AS imaging_api COPY ./pixl_core/ pixl_core/ COPY ./pixl_imaging/ . From 46a08e07e768ed53b3a77ce30cc3f8eaba5591d8 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 8 May 2024 16:16:04 +0100 Subject: [PATCH 6/9] De-dupe the actual install as well --- docker/pixl-python/Dockerfile | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/docker/pixl-python/Dockerfile b/docker/pixl-python/Dockerfile index f6b8a4603..f730168c3 100644 --- a/docker/pixl-python/Dockerfile +++ b/docker/pixl-python/Dockerfile @@ -32,6 +32,7 @@ RUN apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* HEALTHCHECK CMD /usr/bin/curl -f http://0.0.0.0:8000/heart-beat || exit 1 WORKDIR /app +# specify what we're installing using build time arg ARG PIXL_PACKAGE_DIR # Install requirements before copying modules @@ -40,39 +41,20 @@ COPY ./$PIXL_PACKAGE_DIR/pyproject.toml ./$PIXL_PACKAGE_DIR/pyproject.toml RUN pip3 install --no-cache-dir pixl_core/ \ && pip3 install --no-cache-dir $PIXL_PACKAGE_DIR/ - - -FROM pixl_python_base AS export_api - +# Install our code COPY ./pixl_core/ pixl_core/ -COPY ./pixl_export/ . +COPY ./$PIXL_PACKAGE_DIR/ . RUN pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ \ --no-cache-dir --force-reinstall --no-deps . && \ if [ "$TEST" = "true" ]; then pip install --no-cache-dir pixl_core/[test] .[test]; fi -ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] +# Each container should be run with a different entry point +FROM pixl_python_base AS export_api +ENTRYPOINT ["uvicorn", "pixl_export.main:app", "--host", "0.0.0.0", "--port", "8000"] FROM pixl_python_base AS hasher_api - -COPY ./pixl_core/ pixl_core/ -COPY ./hasher/ . -RUN --mount=type=cache,target=/root/.cache \ - pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ . && \ - if [ "$TEST" = "true" ]; \ - then pip install --no-cache-dir --force-reinstall --no-deps pixl_core/[test] \ - --no-cache-dir --force-reinstall --no-deps .[test]; fi ENTRYPOINT ["uvicorn", "hasher.main:app", "--host", "0.0.0.0", "--port", "8000"] - FROM pixl_python_base AS imaging_api - -COPY ./pixl_core/ pixl_core/ -COPY ./pixl_imaging/ . -RUN --mount=type=cache,target=/root/.cache \ - pip install --no-cache-dir --force-reinstall --no-deps pixl_core/ . && \ - if [ "$TEST" = "true" ]; \ - then pip install --no-cache-dir --force-reinstall --no-deps pixl_core/[test] \ - --no-cache-dir --force-reinstall --no-deps .[test]; fi - ENTRYPOINT ["/app/scripts/migrate_and_run.sh"] From 3b0bac0b9c757059d2b093ba6ded9f89df80b65c Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Tue, 21 May 2024 17:01:37 +0100 Subject: [PATCH 7/9] Unite orthanc Dockerfiles --- docker-compose.yml | 6 ++- docker/orthanc-anon/Dockerfile | 46 ---------------------- docker/{orthanc-raw => orthanc}/Dockerfile | 12 +++++- pixl_imaging/tests/docker-compose.yml | 3 +- 4 files changed, 17 insertions(+), 50 deletions(-) delete mode 100644 docker/orthanc-anon/Dockerfile rename docker/{orthanc-raw => orthanc}/Dockerfile (86%) diff --git a/docker-compose.yml b/docker-compose.yml index 508223d27..21770d113 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -110,7 +110,8 @@ services: orthanc-anon: build: context: . - dockerfile: ./docker/orthanc-anon/Dockerfile + dockerfile: ./docker/orthanc/Dockerfile + target: pixl_orthanc_anon args: <<: *build-args-common platform: linux/amd64 @@ -180,7 +181,8 @@ services: orthanc-raw: build: context: . - dockerfile: ./docker/orthanc-raw/Dockerfile + dockerfile: ./docker/orthanc/Dockerfile + target: pixl_orthanc_raw args: <<: *build-args-common ORTHANC_RAW_MAXIMUM_STORAGE_SIZE: ${ORTHANC_RAW_MAXIMUM_STORAGE_SIZE} diff --git a/docker/orthanc-anon/Dockerfile b/docker/orthanc-anon/Dockerfile deleted file mode 100644 index fc5fe000e..000000000 --- a/docker/orthanc-anon/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) University College London Hospitals NHS Foundation Trust -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -FROM orthancteam/orthanc:24.3.3 -SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] - -# Create a virtual environment, recommended since python 3.11 and Debian bookworm based images -# where you get a warning when installing system-wide packages. -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install --yes --no-install-recommends python3-venv -RUN python3 -m venv /.venv - -# Install curl, used in system tests -RUN apt-get --assume-yes install curl - -# Install requirements before copying modules -COPY ./pixl_core/pyproject.toml /pixl_core/pyproject.toml -COPY ./pixl_dcmd/pyproject.toml /pixl_dcmd/pyproject.toml - -RUN --mount=type=cache,target=/root/.cache \ - /.venv/bin/pip install pixl_core/ \ - && /.venv/bin/pip install pixl_dcmd/ - -COPY ./orthanc/orthanc-anon/plugin/pixl.py /etc/orthanc/pixl.py - -COPY ./pixl_core/ /pixl_core -RUN --mount=type=cache,target=/root/.cache \ - /.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_core - -COPY ./pixl_dcmd/ /pixl_dcmd -RUN --mount=type=cache,target=/root/.cache \ - /.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_dcmd - -ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ - diff --git a/docker/orthanc-raw/Dockerfile b/docker/orthanc/Dockerfile similarity index 86% rename from docker/orthanc-raw/Dockerfile rename to docker/orthanc/Dockerfile index b558520d8..1d85f8e1b 100644 --- a/docker/orthanc-raw/Dockerfile +++ b/docker/orthanc/Dockerfile @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM orthancteam/orthanc:24.3.3 +FROM orthancteam/orthanc:24.3.3 AS pixl_orthanc_base SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] @@ -22,6 +22,9 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install --yes --no-install-recommends python3-venv RUN python3 -m venv /.venv +# Install curl for now, but try to remove this dependency +RUN apt-get --assume-yes install curl + # Install requirements before copying modules COPY ./pixl_core/pyproject.toml /pixl_core/pyproject.toml COPY ./pixl_dcmd/pyproject.toml /pixl_dcmd/pyproject.toml @@ -38,6 +41,8 @@ COPY ./pixl_dcmd/ /pixl_dcmd RUN --mount=type=cache,target=/root/.cache \ /.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_dcmd +FROM pixl_orthanc_base AS pixl_orthanc_raw + COPY ./orthanc/orthanc-raw/plugin/pixl.py /etc/orthanc/pixl.py # Orthanc can't substitute environment veriables as integers so copy and replace before running @@ -50,3 +55,8 @@ RUN sed -i "s/\${ORTHANC_RAW_JOB_HISTORY_SIZE}/${ORTHANC_RAW_JOB_HISTORY_SIZE:-1 RUN sed -i "s/\${ORTHANC_RAW_CONCURRENT_JOBS}/${ORTHANC_RAW_CONCURRENT_JOBS:-5}/g" /run/secrets/orthanc.json ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ + +FROM pixl_orthanc_base AS pixl_orthanc_anon +COPY ./orthanc/orthanc-anon/plugin/pixl.py /etc/orthanc/pixl.py + +ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ diff --git a/pixl_imaging/tests/docker-compose.yml b/pixl_imaging/tests/docker-compose.yml index 56c8a776d..bf318b794 100644 --- a/pixl_imaging/tests/docker-compose.yml +++ b/pixl_imaging/tests/docker-compose.yml @@ -50,7 +50,8 @@ services: orthanc-raw: build: context: ../../ - dockerfile: ./docker/orthanc-raw/Dockerfile + dockerfile: ./docker/orthanc/Dockerfile + target: pixl_orthanc_raw environment: ORTHANC_NAME: "PIXL: Raw" ORTHANC_USERNAME: "orthanc" From 98fa6896fb33bf6090fb5b9c2309dbe64ce331bd Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Wed, 18 Dec 2024 17:59:54 +0000 Subject: [PATCH 8/9] Further de-duping of code in Dockerfile to tidy up the merge --- docker-compose.yml | 2 ++ docker/orthanc/Dockerfile | 23 +++++++++-------------- pixl_imaging/tests/docker-compose.yml | 1 + 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 996853e28..49607200b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,6 +107,7 @@ services: target: pixl_orthanc_anon args: <<: *build-args-common + ORTHANC_DIR: orthanc-anon ORTHANC_CONCURRENT_JOBS: ${ORTHANC_CONCURRENT_JOBS} platform: linux/amd64 command: /run/secrets @@ -177,6 +178,7 @@ services: target: pixl_orthanc_raw args: <<: *build-args-common + ORTHANC_DIR: orthanc-raw ORTHANC_RAW_MAXIMUM_STORAGE_SIZE: ${ORTHANC_RAW_MAXIMUM_STORAGE_SIZE} ORTHANC_RAW_JOB_HISTORY_SIZE: ${ORTHANC_RAW_JOB_HISTORY_SIZE} ORTHANC_CONCURRENT_JOBS: ${ORTHANC_CONCURRENT_JOBS} diff --git a/docker/orthanc/Dockerfile b/docker/orthanc/Dockerfile index a78503428..81602a90a 100644 --- a/docker/orthanc/Dockerfile +++ b/docker/orthanc/Dockerfile @@ -40,33 +40,28 @@ COPY ./pixl_dcmd/ /pixl_dcmd RUN --mount=type=cache,target=/root/.cache \ /.venv/bin/pip install --no-cache-dir --force-reinstall --no-deps ./pixl_dcmd -FROM pixl_orthanc_base AS pixl_orthanc_raw +ARG ORTHANC_DIR +COPY ./orthanc/${ORTHANC_DIR}/plugin/pixl.py /etc/orthanc/pixl.py +COPY ./orthanc/${ORTHANC_DIR}/config /run/secrets -COPY ./orthanc/orthanc-raw/plugin/pixl.py /etc/orthanc/pixl.py +ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ # Orthanc can't substitute environment veriables as integers so copy and replace before running +ARG ORTHANC_CONCURRENT_JOBS +RUN sed -i "s/\${ORTHANC_CONCURRENT_JOBS}/${ORTHANC_CONCURRENT_JOBS:-5}/g" /run/secrets/orthanc.json + +FROM pixl_orthanc_base AS pixl_orthanc_raw + ARG ORTHANC_RAW_MAXIMUM_STORAGE_SIZE ARG ORTHANC_RAW_JOB_HISTORY_SIZE -ARG ORTHANC_CONCURRENT_JOBS ARG PIXL_DICOM_TRANSFER_TIMEOUT -COPY ./orthanc/orthanc-raw/config /run/secrets RUN sed -i "s/\${ORTHANC_RAW_MAXIMUM_STORAGE_SIZE}/${ORTHANC_RAW_MAXIMUM_STORAGE_SIZE:-0}/g" /run/secrets/orthanc.json RUN sed -i "s/\${ORTHANC_RAW_JOB_HISTORY_SIZE}/${ORTHANC_RAW_JOB_HISTORY_SIZE:-100}/g" /run/secrets/orthanc.json -RUN sed -i "s/\${ORTHANC_CONCURRENT_JOBS}/${ORTHANC_CONCURRENT_JOBS:-5}/g" /run/secrets/orthanc.json RUN sed -i "s/\${ORTHANC_RAW_STABLE_SECONDS}/${PIXL_DICOM_TRANSFER_TIMEOUT:-600}/g" /run/secrets/orthanc.json -ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ - FROM pixl_orthanc_base AS pixl_orthanc_anon -COPY ./orthanc/orthanc-anon/plugin/pixl.py /etc/orthanc/pixl.py -ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ COPY ./orthanc/orthanc-anon/plugin/download_dicom_spec.py /etc/orthanc/download_dicom_spec.py RUN --mount=type=cache,target=/root/.cache \ python3 /etc/orthanc/download_dicom_spec.py -ARG ORTHANC_CONCURRENT_JOBS -COPY ./orthanc/orthanc-anon/config /run/secrets - -RUN sed -i "s/\${ORTHANC_CONCURRENT_JOBS}/${ORTHANC_CONCURRENT_JOBS:-5}/g" /run/secrets/orthanc.json - diff --git a/pixl_imaging/tests/docker-compose.yml b/pixl_imaging/tests/docker-compose.yml index 3aded6e04..a72c8b865 100644 --- a/pixl_imaging/tests/docker-compose.yml +++ b/pixl_imaging/tests/docker-compose.yml @@ -72,6 +72,7 @@ services: target: pixl_orthanc_raw args: PIXL_DICOM_TRANSFER_TIMEOUT: 30 + ORTHANC_DIR: orthanc-raw environment: ORTHANC_NAME: "PIXL: Raw" ORTHANC_USERNAME: "orthanc" From dc59b208f679a708a3af2a1fcf71edaae554a7c3 Mon Sep 17 00:00:00 2001 From: Jeremy Stein Date: Mon, 6 Jan 2025 17:09:11 +0000 Subject: [PATCH 9/9] Add more build stages to avoid re-downloading spec (which is only needed in orthanc-anon anyway) --- docker/orthanc/Dockerfile | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/docker/orthanc/Dockerfile b/docker/orthanc/Dockerfile index 81602a90a..e1d3b2482 100644 --- a/docker/orthanc/Dockerfile +++ b/docker/orthanc/Dockerfile @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM orthancteam/orthanc:24.7.3@sha256:57a3d037729897331027ddc00c12695b50f1effbbf805f855396f3d0248d2d5f AS pixl_orthanc_base +FROM orthancteam/orthanc:24.7.3@sha256:57a3d037729897331027ddc00c12695b50f1effbbf805f855396f3d0248d2d5f AS pixl_orthanc_apt SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] # Create a virtual environment, recommended since python 3.11 and Debian bookworm based images @@ -20,10 +20,25 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ apt-get install --yes --no-install-recommends python3-venv tzdata RUN python3 -m venv /.venv +ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ # Install curl for now, but try to remove this dependency RUN apt-get --assume-yes install curl +FROM pixl_orthanc_apt AS pixl_orthanc_with_spec +# This part changes rarely, so do it nice and early to avoid redoing it every time we change our code. +# It does have a dependency though, which would normally be fulfilled by our project files, so install that +# manually. +# Do it in dead end build stage to discard this environment afterwards, +# and because the spec is only needed in orthanc-anon. +RUN /.venv/bin/pip install dicom-validator +COPY ./orthanc/orthanc-anon/plugin/download_dicom_spec.py /etc/orthanc/download_dicom_spec.py +RUN --mount=type=cache,target=/root/.cache \ + python3 /etc/orthanc/download_dicom_spec.py + + +FROM pixl_orthanc_apt AS pixl_orthanc_base + # Install requirements before copying modules COPY ./pixl_core/pyproject.toml /pixl_core/pyproject.toml COPY ./pixl_dcmd/pyproject.toml /pixl_dcmd/pyproject.toml @@ -44,8 +59,6 @@ ARG ORTHANC_DIR COPY ./orthanc/${ORTHANC_DIR}/plugin/pixl.py /etc/orthanc/pixl.py COPY ./orthanc/${ORTHANC_DIR}/config /run/secrets -ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ - # Orthanc can't substitute environment veriables as integers so copy and replace before running ARG ORTHANC_CONCURRENT_JOBS RUN sed -i "s/\${ORTHANC_CONCURRENT_JOBS}/${ORTHANC_CONCURRENT_JOBS:-5}/g" /run/secrets/orthanc.json @@ -60,8 +73,4 @@ RUN sed -i "s/\${ORTHANC_RAW_JOB_HISTORY_SIZE}/${ORTHANC_RAW_JOB_HISTORY_SIZE:-1 RUN sed -i "s/\${ORTHANC_RAW_STABLE_SECONDS}/${PIXL_DICOM_TRANSFER_TIMEOUT:-600}/g" /run/secrets/orthanc.json FROM pixl_orthanc_base AS pixl_orthanc_anon - -COPY ./orthanc/orthanc-anon/plugin/download_dicom_spec.py /etc/orthanc/download_dicom_spec.py -RUN --mount=type=cache,target=/root/.cache \ - python3 /etc/orthanc/download_dicom_spec.py - +COPY --from=pixl_orthanc_with_spec /root/dicom-validator /root/dicom-validator