diff --git a/.github/workflows/cuda-image.yml b/.github/workflows/cuda-image.yml index dc9e60e..7b8a2ec 100644 --- a/.github/workflows/cuda-image.yml +++ b/.github/workflows/cuda-image.yml @@ -11,22 +11,41 @@ jobs: # For biggish images, github actions runs out of disk space. - name: cleanup disk space run: sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc - - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v3 - - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + - name: Login to Docker Hub + uses: docker/login-action@v2 with: - registry: ghcr.io - username: ${{github.actor}} - password: ${{secrets.GITHUB_TOKEN}} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build the Docker image (torch) - run: docker build cuda --build-arg BASE=quay.io/jupyter/pytorch-notebook:cuda12-ubuntu-24.04 --tag ghcr.io/schmidtdse/cuda:latest - - name: Publish cuda (torch) - run: docker push ghcr.io/schmidtdse/cuda:latest - - - name: Build the Docker image (tensorflow) - run: docker build cuda --build-arg BASE=quay.io/jupyter/tensorflow-notebook:cuda-latest --tag ghcr.io/schmidtdse/tensorflow:latest - - name: Publish tensorflow - run: docker push ghcr.io/schmidtdse/tensorflow:latest + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: cuda + push: true + tags: ${{ github.ref }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + type=ref,event=branch + type=semver,pattern=v{{version}} + type=sha,format=short + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: cuda + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/R/Dockerfile b/R/Dockerfile new file mode 100644 index 0000000..0910174 --- /dev/null +++ b/R/Dockerfile @@ -0,0 +1,14 @@ +FROM ghcr.io/schmidtdse/base + +# Install R, RStudio +USER root + +RUN curl -s https://raw.githubusercontent.com/rocker-org/ml/refs/heads/master/install_r.sh | bash +RUN curl -s https://raw.githubusercontent.com/rocker-org/ml/refs/heads/master/install_rstudio.sh | bash + +USER ${NB_USER} + +# We either must modify the official /workdir/pixi.toml, or we can use pixi add +# We don't need to activate pixi env, just be in the correct workdir +RUN cd ${DOCKER_WORKDIR} && pixi add jupyter-rsession-proxy + diff --git a/base/Dockerfile b/base/Dockerfile index a25a611..e2b681a 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -41,22 +41,18 @@ RUN apt-get update -q && apt-get -y install curl && apt-get clean && rm -rf /var RUN mkdir -p ${CODE_EXTENSIONSDIR} && chown -R ${NB_USER}:users ${CODE_EXTENSIONSDIR} RUN curl -fsSL https://code-server.dev/install.sh | sh && rm -rf /home/${NB_USER}/.cache -# Install R, RStudio -RUN curl -s https://raw.githubusercontent.com/rocker-org/ml/refs/heads/master/install_r.sh | bash -RUN curl -s https://raw.githubusercontent.com/rocker-org/ml/refs/heads/master/install_rstudio.sh | bash - # Build the environment USER ${NB_USER} COPY vscode-extensions.txt /tmp/vscode-extensions.txt RUN xargs -n 1 code-server --extensions-dir ${CODE_EXTENSIONSDIR} --install-extension < /tmp/vscode-extensions.txt -COPY pixi.toml . +COPY --chown=${NB_UID}:${NB_UID} pixi.toml . RUN pixi install \ && rm -rf ~/.cache/rattler # Set up shell activation script - RUN pixi shell-hook -s bash > ./shell-hook +RUN pixi shell-hook -s bash > ./shell-hook USER root ENV ENTRYPOINT_SCRIPT="/entrypoint.sh" RUN echo "#!/bin/bash" > ${ENTRYPOINT_SCRIPT} @@ -65,7 +61,6 @@ RUN echo 'exec "$@"' >> ${ENTRYPOINT_SCRIPT} RUN chmod +x ${ENTRYPOINT_SCRIPT} USER ${NB_USER} -WORKDIR "/home/${NB_USER}" EXPOSE 8888 ENTRYPOINT ["/entrypoint.sh"] CMD ["jupyter", "lab", "--no-browser", "--ip=0.0.0.0"] diff --git a/base/config.ts b/base/config.ts deleted file mode 100644 index 92e18c6..0000000 --- a/base/config.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Configuration helper for continue.dev -// From: https://github.com/continuedev/continue/issues/4323#issuecomment-2688947097 -// replace ${VAR_NAME} placeholders with their process.env values -const replaceEnvVars = (obj: T): T => { - if (Array.isArray(obj)) { - return obj.map(replaceEnvVars) as T; - } - - if (!obj || typeof obj !== 'object') { - return obj; - } - - const result = { ...obj } as Record; - for (const key in result) { - if (Object.prototype.hasOwnProperty.call(result, key)) { - if (typeof result[key] === 'string') { - result[key] = result[key].replace(/\$\{(.+?)\}/g, (_, varName) => - process.env[varName] ?? ''); - } else if (result[key] && typeof result[key] === 'object') { - result[key] = replaceEnvVars(result[key]); - } - } - } - return result as T; -}; diff --git a/base/environment.yml b/base/environment.yml deleted file mode 100644 index c4024fa..0000000 --- a/base/environment.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: base -channels: - - conda-forge -dependencies: - - glances - - git-filter-repo - - jupyter-resource-usage - - jupyter-vscode-proxy - - minio - - pypdf - - pip - - pip: - - jupyter-keepalive - diff --git a/base/pixi.toml b/base/pixi.toml index ab9c482..ff4ee7e 100644 --- a/base/pixi.toml +++ b/base/pixi.toml @@ -1,7 +1,7 @@ [workspace] authors = ["Matt Fisher "] channels = ["conda-forge", "nodefaults"] -name = "geojupyter-pixi-docker-image" +name = "schmidtdse" platforms = ["linux-64"] version = "0.1.0" @@ -15,7 +15,6 @@ jupyterlab-favorites = "*" jupyter-collaboration = "*" jupyter-server-proxy = "*" jupyter-vscode-proxy = "*" -jupyter-rsession-proxy = "*" jupyterlab-myst = "*" typst = "*" ruff = "*" diff --git a/cuda/Dockerfile b/cuda/Dockerfile index df19f52..e2b681a 100644 --- a/cuda/Dockerfile +++ b/cuda/Dockerfile @@ -1,38 +1,66 @@ -ARG BASE=quay.io/jupyter/minimal-notebook:ubuntu-24.04 +FROM ghcr.io/prefix-dev/pixi:noble AS build +LABEL "org.opencontainers.image.description"="A pixi-based Docker image for a robust GeoJupyter environment" -# cuda image uses: -# ARG BASE=quay.io/jupyter/pytorch-notebook:cuda12-ubuntu-24.04 -FROM $BASE +# Use bash as default shell instead of sh +ENV SHELL=/bin/bash +# Don't buffer Python stdout/stderr output +ENV PYTHONBUFFERED=1 +# Don't prompt in apt commands +ENV DEBIAN_FRONTEND=noninteractive -# Make code-server extensions etc persist to container, not hub -ENV XDG_DATA_HOME=/opt/share -ENV PATH=/opt/share/pixi/bin:$PATH - -## Grant user sudoer privileges -USER root -RUN adduser "$NB_USER" sudo && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers -RUN mkdir /opt/share && chown -R ${NB_USER}:users /opt/share - -USER ${NB_USER} +# Set up JupyterLab user +ENV NB_USER=jovyan +ENV NB_UID=1000 +ENV USER="${NB_USER}" +ENV HOME="/home/${NB_USER}" +RUN userdel ubuntu \ + && groupadd \ + --gid ${NB_UID} \ + ${NB_USER} \ + && useradd \ + --comment "Default Jupyter user" \ + --create-home \ + --no-log-init \ + --uid ${NB_UID} \ + --gid ${NB_UID} \ + --shell ${SHELL} \ + ${NB_USER} +ENV DOCKER_WORKDIR=/workdir +WORKDIR ${DOCKER_WORKDIR} +RUN chown ${NB_UID}:${NB_UID} ${DOCKER_WORKDIR} -## Create user-owned workspace -RUN sudo mkdir /workspace && sudo chown -R ${NB_USER}:users /workspace +# this env var is recognized by jupyter-vscode-proxy: +ENV CODE_EXTENSIONSDIR=/opt/share/code-server +# put quarto on the path too +ENV PATH=$PATH:/usr/lib/rstudio-server/bin/quarto/bin +USER root # code-server (VSCode) -RUN sudo curl -fsSL https://code-server.dev/install.sh | sh && rm -rf .cache +RUN apt-get update -q && apt-get -y install curl && apt-get clean && rm -rf /var/lib/apt/lists/* +RUN mkdir -p ${CODE_EXTENSIONSDIR} && chown -R ${NB_USER}:users ${CODE_EXTENSIONSDIR} +RUN curl -fsSL https://code-server.dev/install.sh | sh && rm -rf /home/${NB_USER}/.cache -# apt utilities, code-server setup -COPY install_utilities.sh /tmp/install_utilities.sh -RUN sudo bash /tmp/install_utilities.sh +# Build the environment +USER ${NB_USER} -# install pixi -RUN curl -fsSL https://pixi.sh/install.sh | PIXI_HOME=/opt/share/pixi bash +COPY vscode-extensions.txt /tmp/vscode-extensions.txt +RUN xargs -n 1 code-server --extensions-dir ${CODE_EXTENSIONSDIR} --install-extension < /tmp/vscode-extensions.txt -COPY vscode-extensions.txt vscode-extensions.txt -RUN xargs -n 1 code-server --install-extension < vscode-extensions.txt +COPY --chown=${NB_UID}:${NB_UID} pixi.toml . +RUN pixi install \ + && rm -rf ~/.cache/rattler -COPY environment.yml environment.yml -RUN conda update --all --solver=classic -n base -c conda-forge conda && \ - conda env update --file environment.yml +# Set up shell activation script +RUN pixi shell-hook -s bash > ./shell-hook +USER root +ENV ENTRYPOINT_SCRIPT="/entrypoint.sh" +RUN echo "#!/bin/bash" > ${ENTRYPOINT_SCRIPT} + RUN cat ${PWD}/shell-hook >> ${ENTRYPOINT_SCRIPT} +RUN echo 'exec "$@"' >> ${ENTRYPOINT_SCRIPT} +RUN chmod +x ${ENTRYPOINT_SCRIPT} +USER ${NB_USER} +EXPOSE 8888 +ENTRYPOINT ["/entrypoint.sh"] +CMD ["jupyter", "lab", "--no-browser", "--ip=0.0.0.0"] diff --git a/cuda/environment.yml b/cuda/environment.yml deleted file mode 100644 index c4024fa..0000000 --- a/cuda/environment.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: base -channels: - - conda-forge -dependencies: - - glances - - git-filter-repo - - jupyter-resource-usage - - jupyter-vscode-proxy - - minio - - pypdf - - pip - - pip: - - jupyter-keepalive - diff --git a/cuda/pixi.toml b/cuda/pixi.toml new file mode 100644 index 0000000..396e3c9 --- /dev/null +++ b/cuda/pixi.toml @@ -0,0 +1,29 @@ +[workspace] +authors = ["Matt Fisher "] +channels = ["conda-forge", "nodefaults"] +name = "schmidtdse-cuda" +platforms = ["linux-64"] +version = "0.1.0" + +[tasks] + +[dependencies] +python = ">=3.12" +jupyterhub-singleuser = "*" +jupyterlab = ">=4.4.2" +jupyterlab-favorites = "*" +jupyter-collaboration = "*" +jupyter-server-proxy = "*" +jupyter-vscode-proxy = "*" +jupyterlab-myst = "*" +typst = "*" +ruff = "*" +pre-commit = "*" +gh = "*" +gh-scoped-creds = "*" + +[system-requirements] +cuda = "12.6" + +[dependencies] +pytorch-gpu = "*" diff --git a/cuda/vscode-extensions.txt b/cuda/vscode-extensions.txt index c2478f1..8cf04f1 100644 --- a/cuda/vscode-extensions.txt +++ b/cuda/vscode-extensions.txt @@ -1,5 +1,10 @@ ms-python.python ms-toolsai.jupyter ms-vscode.live-server +quarto.quarto +posit.shiny +reditorsupport.r continue.continue +alefragnani.project-manager +saoudrizwan.claude-dev