|
| 1 | +FROM nvidia/cuda:12.4.1-devel-ubuntu22.04 |
| 2 | + |
| 3 | +# Optional ARG for username (only set if secret is provided) |
| 4 | +ARG USERNAME="" |
| 5 | +ENV username="${USERNAME}" |
| 6 | + |
| 7 | +# Optional ARG for SSH port |
| 8 | +ARG PORT="2222" |
| 9 | +ENV SSH_PORT="${PORT}" |
| 10 | + |
| 11 | +# Dependencies installation |
| 12 | +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ |
| 13 | + build-essential=12.9ubuntu3 \ |
| 14 | + micro=2.0.9-1ubuntu0.22.04.3 \ |
| 15 | + nano=6.2-1ubuntu0.1 \ |
| 16 | + git=1:2.34.1-1ubuntu1.15 \ |
| 17 | + openssh-server=1:8.9p1-3ubuntu0.13 \ |
| 18 | + wget=1.21.2-2ubuntu1.1 \ |
| 19 | + && rm -rf /var/lib/apt/lists/* \ |
| 20 | + && mkdir -p /var/run/sshd \ |
| 21 | + && ssh-keygen -A |
| 22 | + |
| 23 | +# Set shell to bash with pipefail for safer pipe operations |
| 24 | +SHELL ["/bin/bash", "-o", "pipefail", "-c"] |
| 25 | + |
| 26 | +# Create user using Docker secrets for sensitive data |
| 27 | +RUN --mount=type=secret,id=username \ |
| 28 | + --mount=type=secret,id=password \ |
| 29 | + --mount=type=secret,id=ssh_key \ |
| 30 | + if [ -f "/run/secrets/username" ] && [ -s "/run/secrets/username" ] && [ -f "/run/secrets/password" ] && [ -s "/run/secrets/password" ]; then \ |
| 31 | + export NAME && \ |
| 32 | + NAME="$(cat /run/secrets/username)" && \ |
| 33 | + export PASSWORD && \ |
| 34 | + PASSWORD="$(cat /run/secrets/password)" && \ |
| 35 | + useradd -m -u 1000 -s /bin/bash "${NAME}" && \ |
| 36 | + echo "${NAME}:${PASSWORD}" | chpasswd && \ |
| 37 | + echo "root:${PASSWORD}" | chpasswd && \ |
| 38 | + usermod -aG sudo "${NAME}" && \ |
| 39 | + chown -R "${NAME}":"${NAME}" "/home/${NAME}" && \ |
| 40 | + echo "${NAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ |
| 41 | + echo "${NAME}" > /tmp/username; \ |
| 42 | + else \ |
| 43 | + echo "root" > /tmp/username; \ |
| 44 | + fi |
| 45 | + |
| 46 | +# Configure SSH permissions for devcontainer (only if custom user was created) |
| 47 | +RUN export USERNAME && \ |
| 48 | + USERNAME="$(cat /tmp/username)" && \ |
| 49 | + if [ "${USERNAME}" != "root" ]; then \ |
| 50 | + mkdir -p /var/run/sshd && \ |
| 51 | + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \ |
| 52 | + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config; \ |
| 53 | + fi |
| 54 | + |
| 55 | +# Conditionally add SSH public key if provided |
| 56 | +RUN --mount=type=secret,id=ssh_key \ |
| 57 | + export USERNAME && \ |
| 58 | + USERNAME="$(cat /tmp/username)" && \ |
| 59 | + if [ -f /run/secrets/ssh_key ] && [ -s /run/secrets/ssh_key ] && [ "${USERNAME}" != "root" ]; then \ |
| 60 | + export SSH_PUB_KEY && \ |
| 61 | + SSH_PUB_KEY="$(cat /run/secrets/ssh_key)" && \ |
| 62 | + mkdir -p "/home/${USERNAME}/.ssh/" && \ |
| 63 | + echo "${SSH_PUB_KEY}" >> "/home/${USERNAME}/.ssh/authorized_keys" && \ |
| 64 | + chmod 700 "/home/${USERNAME}/.ssh/" && \ |
| 65 | + chown -R "${USERNAME}":"${USERNAME}" "/home/${USERNAME}/.ssh/" && \ |
| 66 | + chmod 600 "/home/${USERNAME}/.ssh/authorized_keys"; \ |
| 67 | + fi |
| 68 | + |
| 69 | +# Set up custom entrypoint and init scripts |
| 70 | +COPY dev-container/scripts/custom-entrypoint.sh /opt/custom-entrypoint.sh |
| 71 | +COPY dev-container/scripts/init-pykokkos.sh /opt/init-pykokkos.sh |
| 72 | +RUN chmod +x /opt/custom-entrypoint.sh /opt/init-pykokkos.sh |
| 73 | + |
| 74 | +# Set working directory based on USERNAME ARG |
| 75 | +# WORKDIR_PATH will be passed as build arg from build script |
| 76 | +ARG WORKDIR_PATH="/root" |
| 77 | + |
| 78 | +# Set WORKDIR - use WORKDIR_PATH from build arg |
| 79 | +WORKDIR ${WORKDIR_PATH} |
| 80 | + |
| 81 | +# Temporarily switch to user for conda and git operations |
| 82 | +USER ${USERNAME:-root} |
| 83 | + |
| 84 | +# Set up and initialize conda environment |
| 85 | +# Install conda in the user's home directory |
| 86 | +RUN export USERNAME && \ |
| 87 | + USERNAME="$(cat /tmp/username)" && \ |
| 88 | + if [ "${USERNAME}" != "root" ]; then \ |
| 89 | + export HOME_DIR="/home/${USERNAME}" && \ |
| 90 | + wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \ |
| 91 | + bash miniconda.sh -b -p "${HOME_DIR}/miniconda3" && \ |
| 92 | + rm -f miniconda.sh && \ |
| 93 | + echo "${HOME_DIR}/miniconda3/bin" > /tmp/conda_path; \ |
| 94 | + else \ |
| 95 | + export HOME_DIR="/root" && \ |
| 96 | + wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \ |
| 97 | + bash miniconda.sh -b -p "${HOME_DIR}/miniconda3" && \ |
| 98 | + rm -f miniconda.sh && \ |
| 99 | + echo "${HOME_DIR}/miniconda3/bin" > /tmp/conda_path; \ |
| 100 | + fi |
| 101 | + |
| 102 | +# Initialize user's conda environment, TOS agreements and ensure it's loaded in every shell |
| 103 | +RUN export CONDA_PATH && \ |
| 104 | + CONDA_PATH="$(cat /tmp/conda_path)" && \ |
| 105 | + "${CONDA_PATH}"/conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \ |
| 106 | + "${CONDA_PATH}"/conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r && \ |
| 107 | + "${CONDA_PATH}"/conda init |
| 108 | + |
| 109 | +# Clone pykokkos repository (installation will happen at runtime) |
| 110 | +RUN git clone https://github.com/kokkos/pykokkos.git |
| 111 | + |
| 112 | +# Add conda to PATH in .bashrc |
| 113 | +RUN export CONDA_PATH && \ |
| 114 | + CONDA_PATH="$(cat /tmp/conda_path)" && \ |
| 115 | + export HOME_DIR && \ |
| 116 | + HOME_DIR="$(dirname "$(dirname "${CONDA_PATH}")")" && \ |
| 117 | + if [ "${HOME_DIR}" != "/root" ]; then \ |
| 118 | + echo "export PATH=\"${CONDA_PATH}:${HOME_DIR}/miniconda3/condabin:${HOME_DIR}/.local/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> "${HOME_DIR}/.bashrc" && \ |
| 119 | + echo "export condaPath=${CONDA_PATH}" >> "${HOME_DIR}/.bashrc"; \ |
| 120 | + else \ |
| 121 | + echo "export PATH=\"${CONDA_PATH}:${HOME_DIR}/miniconda3/condabin:${HOME_DIR}/.local/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> "${HOME_DIR}/.bashrc" && \ |
| 122 | + echo "export condaPath=${CONDA_PATH}" >> "${HOME_DIR}/.bashrc"; \ |
| 123 | + fi |
| 124 | + |
| 125 | +# Switch back to root for entrypoint execution (required for sshd and init scripts) |
| 126 | +USER root |
| 127 | + |
| 128 | +# Expose port in order to be able to connect from IDEs |
| 129 | +EXPOSE ${SSH_PORT} |
| 130 | + |
| 131 | +ENTRYPOINT ["/opt/custom-entrypoint.sh"] |
0 commit comments