From 14c1c0120917cbe9ea306e43ae9e92f48da85600 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Tue, 29 Aug 2023 15:00:16 +0200 Subject: [PATCH] Make backend image rootless --- backend/.dockerignore | 34 +++++++++++++ backend/Dockerfile | 48 +++++++++++++------ backend/docker-compose.yml | 25 ++++++++++ .../common.txt => requirements.txt} | 0 backend/requirements/dev.txt | 3 -- backend/requirements/prod.txt | 3 -- docker-compose-dev.yml | 4 +- 7 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 backend/docker-compose.yml rename backend/{requirements/common.txt => requirements.txt} (100%) delete mode 100644 backend/requirements/dev.txt delete mode 100644 backend/requirements/prod.txt diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 000000000..3edb0b5ee --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/backend/Dockerfile b/backend/Dockerfile index 07b58d526..d5d55c22e 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,6 +1,19 @@ -FROM python:3.9-slim-buster as base +FROM python:3.9-slim as base + WORKDIR /app +# Create a non-privileged user that the app will run under. +# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user +ARG UID=10001 +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + appuser + # certificates config ARG CACERT_LOCATION COPY ./cert/. /etc/ssl/certs/ @@ -13,32 +26,37 @@ RUN apt update && apt install -y \ gcc \ && rm -rf /var/lib/apt/lists/* -# install python libraries (except torch) -COPY requirements/ requirements/ ENV PIP_CERT=$CACERT_LOCATION -RUN pip --default-timeout=300 install --upgrade pip \ - && pip --default-timeout=300 install --no-cache-dir -r requirements/common.txt \ - && rm -r /root/.cache + +# Download dependencies as a separate step to take advantage of Docker's caching. +# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. +# Leverage a bind mount to requirements.txt to avoid having to copy them into +# into this layer. +RUN --mount=type=cache,target=/root/.cache/pip \ + --mount=type=bind,source=requirements.txt,target=requirements.txt \ + python -m pip install -r requirements.txt ARG VERSION ARG MODEL="EffB7_2023-03-06_08" ENV SSL_CERT_FILE=$CACERT_LOCATION RUN curl -o model.pth https://storage.gra.cloud.ovh.net/v1/AUTH_df731a99a3264215b973b3dee70a57af/basegun-public/models/${MODEL}/${MODEL}.pth -COPY src/ src/ +COPY . . RUN mkdir -p src/weights \ && mv model.pth src/weights/model.pth \ && echo '{"app": "'${VERSION}'", "model": "'${MODEL}'"}' > versions.json -# launch website +# Copy the source code into the container. +COPY . . + +# Expose the port that the application listens on. +EXPOSE 8000 + +# Install pytorch FROM base as dev -RUN pip --default-timeout=300 install --no-cache-dir -r requirements/dev.txt -CMD ["uvicorn", "src.main:app", "--reload", "--host", "0.0.0.0", "--port", "5000"] +RUN pip install torch==1.13.0 torchvision==0.14.0 --extra-index-url https://download.pytorch.org/whl/cpu FROM base as test -RUN pip install -r requirements/dev.txt && pip install requests && rm -r /root/.cache -COPY tests/ tests/ -CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"] +RUN pip install requests torch==1.13.0 torchvision==0.14.0 --extra-index-url https://download.pytorch.org/whl/cpu FROM base as prod -RUN pip install --no-cache-dir -r requirements/prod.txt -CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"] +RUN pip install torch==1.13.0+cpu torchvision==0.14.0+cpu --extra-index-url https://download.pytorch.org/whl/cpu diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml new file mode 100644 index 000000000..13cff8e5a --- /dev/null +++ b/backend/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3.8' +services: + backend: + build: + context: . + target: dev + user: appuser + command: uvicorn src.main:app --reload --host 0.0.0.0 --port 8000 + environment: + - PATH_LOGS=/tmp/logs + - OS_USERNAME + - OS_PASSWORD + - OS_PROJECT_NAME + - http_proxy + - https_proxy + - UVICORN_LOG_LEVEL=${UVICORN_LOG_LEVEL} + - LOG_LEVEL=${UVICORN_LOG_LEVEL} + - no_proxy + - WORKSPACE=dev + - REQUESTS_CA_BUNDLE=$CACERT_LOCATION + ports: + - 8000:8000 + volumes: + - .:/code + - /code/src/weights diff --git a/backend/requirements/common.txt b/backend/requirements.txt similarity index 100% rename from backend/requirements/common.txt rename to backend/requirements.txt diff --git a/backend/requirements/dev.txt b/backend/requirements/dev.txt deleted file mode 100644 index 3ab327fcf..000000000 --- a/backend/requirements/dev.txt +++ /dev/null @@ -1,3 +0,0 @@ ---extra-index-url https://download.pytorch.org/whl/cpu -torch==1.13.0 -torchvision==0.14.0 \ No newline at end of file diff --git a/backend/requirements/prod.txt b/backend/requirements/prod.txt deleted file mode 100644 index 8f4ca7caf..000000000 --- a/backend/requirements/prod.txt +++ /dev/null @@ -1,3 +0,0 @@ ---extra-index-url https://download.pytorch.org/whl/cpu -torch==1.13.0+cpu -torchvision==0.14.0+cpu \ No newline at end of file diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 914a5ba8e..c263f1a28 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -11,6 +11,8 @@ services: context: ./backend target: ${BUILD_TARGET:-dev} container_name: basegun-backend + command: uvicorn src.main:app --reload --host 0.0.0.0 --port 8000 + user: appuser environment: - PATH_LOGS=/app/logs - OS_USERNAME @@ -25,7 +27,7 @@ services: - REQUESTS_CA_BUNDLE=$CACERT_LOCATION image: basegun-backend:${TAG:-2.0}-dev ports: - - 5000:5000 + - 8000:8000 volumes: - $PWD/backend/src:/app/src - $PWD/backend/tests:/app/tests