-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Dockerfile
156 lines (134 loc) · 6.02 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
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# Ubuntu 24.04 (noble)
# https://hub.docker.com/_/ubuntu/tags?page=1&name=noble
ARG ROOT_IMAGE=ubuntu:24.04
FROM $ROOT_IMAGE
LABEL maintainer="Jupyter Project <jupyter@googlegroups.com>"
ARG NB_USER="jovyan"
ARG NB_UID="1000"
ARG NB_GID="100"
# Fix: https://github.com/hadolint/hadolint/wiki/DL4006
# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
USER root
# Install all OS dependencies for the Server that starts
# but lacks all features (e.g., download as all possible file formats)
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update --yes && \
# - `apt-get upgrade` is run to patch known vulnerabilities in system packages
# as the Ubuntu base image is rebuilt too seldom sometimes (less than once a month)
apt-get upgrade --yes && \
apt-get install --yes --no-install-recommends \
# - bzip2 is necessary to extract the micromamba executable.
bzip2 \
ca-certificates \
locales \
# - `netbase` provides /etc/{protocols,rpc,services}, part of POSIX
# and required by various C functions like getservbyname and getprotobyname
# https://github.com/jupyter/docker-stacks/pull/2129
netbase \
sudo \
# - `tini` is installed as a helpful container entrypoint,
# that reaps zombie processes and such of the actual executable we want to start
# See https://github.com/krallin/tini#why-tini for details
tini \
wget && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
echo "C.UTF-8 UTF-8" >> /etc/locale.gen && \
locale-gen
# Configure environment
ENV CONDA_DIR=/opt/conda \
SHELL=/bin/bash \
NB_USER="${NB_USER}" \
NB_UID=${NB_UID} \
NB_GID=${NB_GID} \
LC_ALL=C.UTF-8 \
LANG=C.UTF-8 \
LANGUAGE=C.UTF-8
ENV PATH="${CONDA_DIR}/bin:${PATH}" \
HOME="/home/${NB_USER}"
# Copy a script that we will use to correct permissions after running certain commands
COPY fix-permissions /usr/local/bin/fix-permissions
RUN chmod a+rx /usr/local/bin/fix-permissions
# Enable prompt color in the skeleton .bashrc before creating the default NB_USER
# hadolint ignore=SC2016
RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc && \
# More information in: https://github.com/jupyter/docker-stacks/pull/2047
# and docs: https://docs.conda.io/projects/conda/en/latest/dev-guide/deep-dives/activation.html
echo 'eval "$(conda shell.bash hook)"' >> /etc/skel/.bashrc
# Delete existing user with UID="${NB_UID}" if it exists
# hadolint ignore=SC2046
RUN if grep -q "${NB_UID}" /etc/passwd; then \
userdel --remove $(id -un "${NB_UID}"); \
fi
# Create "${NB_USER}" user (`jovyan` by default) with UID="${NB_UID}" (`1000` by default) and in the 'users' group
# and make sure these dirs are writable by the `users` group.
RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \
sed -i.bak -e 's/^%admin/#%admin/' /etc/sudoers && \
sed -i.bak -e 's/^%sudo/#%sudo/' /etc/sudoers && \
useradd --no-log-init --create-home --shell /bin/bash --uid "${NB_UID}" --no-user-group "${NB_USER}" && \
mkdir -p "${CONDA_DIR}" && \
chown "${NB_USER}:${NB_GID}" "${CONDA_DIR}" && \
chmod g+w /etc/passwd && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}"
USER ${NB_UID}
# Pin the Python version here, or set it to "default"
ARG PYTHON_VERSION=3.12
# Setup work directory for backward-compatibility
RUN mkdir "/home/${NB_USER}/work" && \
fix-permissions "/home/${NB_USER}"
# Download and install Micromamba, and initialize the Conda prefix.
# <https://github.com/mamba-org/mamba#micromamba>
# Similar projects using Micromamba:
# - Micromamba-Docker: <https://github.com/mamba-org/micromamba-docker>
# - repo2docker: <https://github.com/jupyterhub/repo2docker>
# Install Python, Mamba, and jupyter_core
# Cleanup temporary files and remove Micromamba
# Correct permissions
# Do all this in a single RUN command to avoid duplicating all of the
# files across image layers when the permissions change
COPY --chown="${NB_UID}:${NB_GID}" initial-condarc "${CONDA_DIR}/.condarc"
WORKDIR /tmp
RUN set -x && \
arch=$(uname -m) && \
if [ "${arch}" = "x86_64" ]; then \
# Should be simpler, see <https://github.com/mamba-org/mamba/issues/1437>
arch="64"; \
fi && \
# https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html#linux-and-macos
wget --progress=dot:giga -O - \
"https://micro.mamba.pm/api/micromamba/linux-${arch}/latest" | tar -xvj bin/micromamba && \
PYTHON_SPECIFIER="python=${PYTHON_VERSION}" && \
if [[ "${PYTHON_VERSION}" == "default" ]]; then PYTHON_SPECIFIER="python"; fi && \
# Install the packages
./bin/micromamba install \
--root-prefix="${CONDA_DIR}" \
--prefix="${CONDA_DIR}" \
--yes \
'jupyter_core' \
# excluding mamba 2.X due to several breaking changes
# https://github.com/jupyter/docker-stacks/pull/2147
'mamba<2.0.0' \
"${PYTHON_SPECIFIER}" && \
rm -rf /tmp/bin/ && \
# Pin major.minor version of python
# https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-pkgs.html#preventing-packages-from-updating-pinning
mamba list --full-name 'python' | awk 'END{sub("[^.]*$", "*", $2); print $1 " " $2}' >> "${CONDA_DIR}/conda-meta/pinned" && \
mamba clean --all -f -y && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}"
# Copy local files as late as possible to avoid cache busting
COPY run-hooks.sh start.sh /usr/local/bin/
# Configure container entrypoint
ENTRYPOINT ["tini", "-g", "--", "start.sh"]
USER root
# Create dirs for startup hooks
RUN mkdir /usr/local/bin/start-notebook.d && \
mkdir /usr/local/bin/before-notebook.d
COPY 10activate-conda-env.sh /usr/local/bin/before-notebook.d/
# Switch back to jovyan to avoid accidental container runs as root
USER ${NB_UID}
WORKDIR "${HOME}"