-
Notifications
You must be signed in to change notification settings - Fork 26
/
Dockerfile
220 lines (182 loc) · 7.58 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# syntax=docker/dockerfile:1
ARG PYTHON_VERSION="3.10.10"
FROM python:${PYTHON_VERSION}-slim-buster as base
#
# USAGE:
# cd sercices/dynamic-sidecar
# docker build -f Dockerfile -t dynamic-sidecar:prod --target production ../../
# docker run dynamic-sidecar:prod
#
# REQUIRED: context expected at ``osparc-simcore/`` folder because we need access to osparc-simcore/packages
LABEL maintainer="Andrei Neagu <neagu@itis.swiss>"
# NOTE: to list the latest version run `make` inside `scripts/apt-packages-versions`
ENV DOCKER_APT_VERSION="5:24.0.5-1~debian.10~buster"
ENV DOCKER_COMPOSE_APT_VERSION="2.20.2-1~debian.10~buster"
# for docker apt caching to work this needs to be added: [https://vsupalov.com/buildkit-cache-mount-dockerfile/]
RUN rm -f /etc/apt/apt.conf.d/docker-clean && \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN \
--mount=type=cache,target=/var/cache/apt,mode=0755,sharing=private \
--mount=type=cache,target=/var/lib/apt,mode=0755,sharing=private \
set -eux && \
apt-get update && \
apt-get install -y --no-install-recommends\
curl \
gnupg \
lsb-release \
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
docker-ce-cli=${DOCKER_APT_VERSION} \
docker-compose-plugin=${DOCKER_COMPOSE_APT_VERSION} \
gosu \
libcap2-bin \
ca-certificates \
# required by python-magic
libmagic1 \
&& apt-get remove -y\
gnupg \
lsb-release \
&& apt-get clean -y\
# verify that the binary works
&& gosu nobody true
# install RClone, we do it in a separate layer such that the cache is not locked forever, as this seems to take a long time
RUN \
--mount=type=bind,source=scripts/install_rclone.bash,target=install_rclone.bash \
./install_rclone.bash
# simcore-user uid=8004(scu) gid=8004(scu) groups=8004(scu)
ENV SC_USER_ID=8004 \
SC_USER_NAME=scu \
SC_BUILD_TARGET=base \
SC_BOOT_MODE=default
RUN adduser \
--uid ${SC_USER_ID} \
--disabled-password \
--gecos "" \
--shell /bin/sh \
--home /home/${SC_USER_NAME} \
${SC_USER_NAME}
# Sets utf-8 encoding for Python et al
ENV LANG=C.UTF-8
# Turns off writing .pyc files; superfluous on an ephemeral container.
ENV PYTHONDONTWRITEBYTECODE=1 \
VIRTUAL_ENV=/home/scu/.venv
# Ensures that the python and pip executables used
# in the image will be those from our virtualenv.
ENV PATH="${VIRTUAL_ENV}/bin:$PATH"
# directory where dynamic-sidecar stores creates and shares
# volumes between itself and the spawned containers
ENV DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR="/dy-volumes"
# create direcotry to persist SharedStore data accessiable
# between dynamic-sidecar reboots
ENV DYNAMIC_SIDECAR_SHARED_STORE_DIR="${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}/shared-store"
RUN mkdir -p "${DYNAMIC_SIDECAR_SHARED_STORE_DIR}" && \
chown -R scu:scu "${DYNAMIC_SIDECAR_SHARED_STORE_DIR}"
# -------------------------- Build stage -------------------
# Installs build/package management tools and third party dependencies
#
# + /build WORKDIR
#
FROM base as build
ENV SC_BUILD_TARGET=build
RUN --mount=type=cache,target=/var/cache/apt,mode=0755,sharing=private \
--mount=type=cache,target=/var/lib/apt,mode=0755,sharing=private \
set -eux \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential
# NOTE: install https://github.com/astral-sh/uv ultra-fast rust-based pip replacement
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
pip install uv~=0.1
# NOTE: python virtualenv is used here such that installed
# packages may be moved to production image easily by copying the venv
RUN uv venv "${VIRTUAL_ENV}" \
&& mkdir -p "${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}"
RUN --mount=type=cache,mode=0755,target=/root/.cache/uv \
uv pip install --upgrade \
pip~=24.0 \
wheel \
setuptools
WORKDIR /build
# install base 3rd party dependencies
# NOTE: copies to /build to avoid overwriting later which would invalidate this layer
RUN \
--mount=type=bind,source=services/dynamic-sidecar/requirements/_base.txt,target=_base.txt \
--mount=type=cache,mode=0755,target=/root/.cache/pip \
uv pip install \
--requirement _base.txt
# copy utility devops scripts
COPY --chown=scu:scu services/dynamic-sidecar/scripts/Makefile /home/scu
COPY --chown=root:root services/dynamic-sidecar/scripts/Makefile /root
# --------------------------Prod-depends-only stage -------------------
# This stage is for production only dependencies that get partially wiped out afterwards (final docker image concerns)
#
# + /build
# + services/dynamic-sidecar [scu:scu] WORKDIR
#
FROM build as prod-only-deps
ENV SC_BUILD_TARGET prod-only-deps
WORKDIR /build/services/dynamic-sidecar
RUN \
--mount=type=bind,source=packages,target=/build/packages,rw \
--mount=type=bind,source=services/dynamic-sidecar,target=/build/services/dynamic-sidecar,rw \
--mount=type=cache,mode=0755,target=/root/.cache/uv \
uv pip install \
--requirement requirements/prod.txt \
&& uv pip list
# --------------------------Production stage -------------------
# Final cleanup up to reduce image size and startup setup
# Runs as scu (non-root user)
#
# + /home/scu $HOME = WORKDIR
# + services/dynamic-sidecar [scu:scu]
#
FROM base as production
ENV SC_BUILD_TARGET=production \
SC_BOOT_MODE=production
ENV PYTHONOPTIMIZE=TRUE
WORKDIR /home/scu
# ensure home folder is read/writable for user scu
RUN chown -R scu /home/scu
# Starting from clean base image, copies pre-installed virtualenv from prod-only-deps
COPY --chown=scu:scu --from=prod-only-deps ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY --chown=scu:scu --from=prod-only-deps ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR} ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}
# Copies booting scripts
COPY --chown=scu:scu services/dynamic-sidecar/docker services/dynamic-sidecar/docker
RUN chmod +x services/dynamic-sidecar/docker/*.sh
# disabled healthcheck as director-v2 is already taking care of it
# in oder to have similar performance a more aggressive healethcek
# would be required.
# removing the healthchek would not cause any issues at this point
# NOTE: When adding a healthcheck
# - remove UpdateHealth - no longer required
# - remove WaitForSidecarAPI - no longer required
# - After `get_dynamic_sidecar_placement` inside CreateSidecars call
# (the sidecar's API will be up and running; guaranteed by the docker engine healthck).
# Add the following line `scheduler_data.dynamic_sidecar.is_ready = True`
# The healthcheck guarantees that the API is available
HEALTHCHECK NONE
EXPOSE 8000
ENTRYPOINT [ "/bin/sh", "services/dynamic-sidecar/docker/entrypoint.sh" ]
CMD ["/bin/sh", "services/dynamic-sidecar/docker/boot.sh"]
# --------------------------Development stage -------------------
# Source code accessible in host but runs in container
# Runs as myu with same gid/uid as host
# Placed at the end to speed-up the build if images targeting production
#
# + /devel WORKDIR
# + services (mounted volume)
#
FROM build as development
ENV SC_BUILD_TARGET=development \
SC_BOOT_MODE=development
WORKDIR /devel
RUN chown -R scu:scu "${VIRTUAL_ENV}" \
&& chown -R scu:scu "${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}"
EXPOSE 8000
EXPOSE 3000
ENTRYPOINT ["/bin/sh", "services/dynamic-sidecar/docker/entrypoint.sh"]
CMD ["/bin/sh", "services/dynamic-sidecar/docker/boot.sh"]