|
| 1 | +# syntax=docker/dockerfile:1 |
| 2 | + |
| 3 | +# Define arguments in the global scope |
| 4 | +ARG PYTHON_VERSION="3.11.9" |
| 5 | +ARG UV_VERSION="0.5" |
| 6 | + |
| 7 | +FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv_build |
| 8 | +# we docker image is built based on debian |
| 9 | +FROM python:${PYTHON_VERSION}-slim-bookworm AS base |
| 10 | + |
| 11 | + |
| 12 | +# |
| 13 | +# USAGE: |
| 14 | +# cd sercices/notifications |
| 15 | +# docker build -f Dockerfile -t notifications:prod --target production ../../ |
| 16 | +# docker run notifications:prod |
| 17 | +# |
| 18 | +# REQUIRED: context expected at ``osparc-simcore/`` folder because we need access to osparc-simcore/packages |
| 19 | + |
| 20 | +LABEL maintainer=GitHK |
| 21 | + |
| 22 | +# for docker apt caching to work this needs to be added: [https://vsupalov.com/buildkit-cache-mount-dockerfile/] |
| 23 | +RUN rm -f /etc/apt/apt.conf.d/docker-clean && \ |
| 24 | + echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache |
| 25 | +RUN --mount=type=cache,target=/var/cache/apt,sharing=private \ |
| 26 | + set -eux && \ |
| 27 | + apt-get update && \ |
| 28 | + apt-get install -y --no-install-recommends \ |
| 29 | + gosu \ |
| 30 | + curl \ |
| 31 | + && apt-get clean -y \ |
| 32 | + # verify that the binary works |
| 33 | + && gosu nobody true |
| 34 | + |
| 35 | +# simcore-user uid=8004(scu) gid=8004(scu) groups=8004(scu) |
| 36 | +ENV SC_USER_ID=8004 \ |
| 37 | + SC_USER_NAME=scu \ |
| 38 | + SC_BUILD_TARGET=base \ |
| 39 | + SC_BOOT_MODE=default |
| 40 | + |
| 41 | +RUN adduser \ |
| 42 | + --uid ${SC_USER_ID} \ |
| 43 | + --disabled-password \ |
| 44 | + --gecos "" \ |
| 45 | + --shell /bin/sh \ |
| 46 | + --home /home/${SC_USER_NAME} \ |
| 47 | + ${SC_USER_NAME} |
| 48 | + |
| 49 | + |
| 50 | +# Sets utf-8 encoding for Python et al |
| 51 | +ENV LANG=C.UTF-8 |
| 52 | + |
| 53 | +# Turns off writing .pyc files; superfluous on an ephemeral container. |
| 54 | +ENV PYTHONDONTWRITEBYTECODE=1 \ |
| 55 | + VIRTUAL_ENV=/home/scu/.venv |
| 56 | + |
| 57 | +# Ensures that the python and pip executables used in the image will be |
| 58 | +# those from our virtualenv. |
| 59 | +ENV PATH="${VIRTUAL_ENV}/bin:$PATH" |
| 60 | + |
| 61 | +# rclone installation |
| 62 | +ARG TARGETARCH |
| 63 | +ENV TARGETARCH=${TARGETARCH} |
| 64 | +RUN \ |
| 65 | + --mount=type=bind,source=scripts/install_rclone.bash,target=/tmp/install_rclone.bash \ |
| 66 | + ./tmp/install_rclone.bash |
| 67 | + |
| 68 | +# -------------------------- Build stage ------------------- |
| 69 | +# Installs build/package management tools and third party dependencies |
| 70 | +# |
| 71 | +# + /build WORKDIR |
| 72 | +# |
| 73 | +FROM base AS build |
| 74 | + |
| 75 | +ENV SC_BUILD_TARGET=build |
| 76 | + |
| 77 | +RUN --mount=type=cache,target=/var/cache/apt,sharing=private \ |
| 78 | + set -eux \ |
| 79 | + && apt-get update \ |
| 80 | + && apt-get install -y --no-install-recommends \ |
| 81 | + build-essential |
| 82 | + |
| 83 | +# install UV https://docs.astral.sh/uv/guides/integration/docker/#installing-uv |
| 84 | +COPY --from=uv_build /uv /uvx /bin/ |
| 85 | + |
| 86 | +# NOTE: python virtualenv is used here such that installed |
| 87 | +# packages may be moved to production image easily by copying the venv |
| 88 | +RUN uv venv "${VIRTUAL_ENV}" |
| 89 | + |
| 90 | +RUN --mount=type=cache,target=/root/.cache/uv \ |
| 91 | + uv pip install --upgrade \ |
| 92 | + wheel \ |
| 93 | + setuptools |
| 94 | + |
| 95 | +WORKDIR /build |
| 96 | + |
| 97 | +# install base 3rd party dependencies |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +# --------------------------Prod-depends-only stage ------------------- |
| 102 | +# This stage is for production only dependencies that get partially wiped out afterwards (final docker image concerns) |
| 103 | +# |
| 104 | +# + /build |
| 105 | +# + services/notifications [scu:scu] WORKDIR |
| 106 | +# |
| 107 | +FROM build AS prod-only-deps |
| 108 | + |
| 109 | +ENV SC_BUILD_TARGET prod-only-deps |
| 110 | + |
| 111 | +WORKDIR /build/services/notifications |
| 112 | + |
| 113 | +RUN \ |
| 114 | + --mount=type=bind,source=packages,target=/build/packages,rw \ |
| 115 | + --mount=type=bind,source=services/notifications,target=/build/services/notifications,rw \ |
| 116 | + --mount=type=cache,target=/root/.cache/uv \ |
| 117 | + uv pip sync \ |
| 118 | + requirements/prod.txt \ |
| 119 | + && uv pip list |
| 120 | + |
| 121 | + |
| 122 | +# --------------------------Production stage ------------------- |
| 123 | +# Final cleanup up to reduce image size and startup setup |
| 124 | +# Runs as scu (non-root user) |
| 125 | +# |
| 126 | +# + /home/scu $HOME = WORKDIR |
| 127 | +# + services/notifications [scu:scu] |
| 128 | +# |
| 129 | +FROM base AS production |
| 130 | + |
| 131 | +ENV SC_BUILD_TARGET=production \ |
| 132 | + SC_BOOT_MODE=production |
| 133 | + |
| 134 | +ENV PYTHONOPTIMIZE=TRUE |
| 135 | +# https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode |
| 136 | +ENV UV_COMPILE_BYTECODE=1 |
| 137 | + |
| 138 | +WORKDIR /home/scu |
| 139 | + |
| 140 | +# ensure home folder is read/writable for user scu |
| 141 | +RUN chown -R scu /home/scu |
| 142 | + |
| 143 | +# Starting from clean base image, copies pre-installed virtualenv from prod-only-deps |
| 144 | +COPY --chown=scu:scu --from=prod-only-deps ${VIRTUAL_ENV} ${VIRTUAL_ENV} |
| 145 | + |
| 146 | +# Copies booting scripts |
| 147 | +COPY --chown=scu:scu services/notifications/docker services/notifications/docker |
| 148 | +RUN chmod +x services/notifications/docker/*.sh |
| 149 | + |
| 150 | + |
| 151 | +HEALTHCHECK --interval=30s \ |
| 152 | + --timeout=20s \ |
| 153 | + --start-period=30s \ |
| 154 | + --retries=3 \ |
| 155 | + CMD ["python3", "services/notifications/docker/healthcheck.py", "http://localhost:8000/health"] |
| 156 | + |
| 157 | +EXPOSE 8000 |
| 158 | + |
| 159 | +ENTRYPOINT [ "/bin/sh", "services/notifications/docker/entrypoint.sh" ] |
| 160 | +CMD ["/bin/sh", "services/notifications/docker/boot.sh"] |
| 161 | + |
| 162 | + |
| 163 | +# --------------------------Development stage ------------------- |
| 164 | +# Source code accessible in host but runs in container |
| 165 | +# Runs as myu with same gid/uid as host |
| 166 | +# Placed at the end to speed-up the build if images targeting production |
| 167 | +# |
| 168 | +# + /devel WORKDIR |
| 169 | +# + services (mounted volume) |
| 170 | +# |
| 171 | +FROM build AS development |
| 172 | + |
| 173 | +ENV SC_BUILD_TARGET=development \ |
| 174 | + SC_DEVEL_MOUNT=/devel/services/notifications |
| 175 | + |
| 176 | +WORKDIR /devel |
| 177 | + |
| 178 | +RUN chown -R scu:scu "${VIRTUAL_ENV}" |
| 179 | + |
| 180 | +EXPOSE 8000 |
| 181 | +EXPOSE 3000 |
| 182 | + |
| 183 | +ENTRYPOINT ["/bin/sh", "services/notifications/docker/entrypoint.sh"] |
| 184 | +CMD ["/bin/sh", "services/notifications/docker/boot.sh"] |
0 commit comments