diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..434917b
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,12 @@
+# Ignore documentation
+book/
+docs/
+
+# Ignore version control folder
+.git/
+.gitignore
+
+# Ignore R stuff
+.Rhistory
+.Rproj.user
+py-rocket-base.Rproj
diff --git a/Dockerfile b/Dockerfile
index c0d9122..ff8f2fa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -81,7 +81,10 @@ RUN echo "Installing Miniforge..." \
EXPOSE 8888
ENTRYPOINT ["/srv/start"]
-# appendix
+### END OF BASE IMAGE
+
+### APPENDIX
+
USER root
# Define environment variables
@@ -90,7 +93,11 @@ ENV REPO_DIR="/srv/repo" \
DISPLAY=":1.0" \
R_VERSION="4.4.1"
-COPY . ${REPO_DIR}
+# Add NB_USER to staff group (required for rocker script)
+# Ensure the staff group exists first
+RUN groupadd -f staff && usermod -a -G staff "${NB_USER}"
+
+COPY --chown=${NB_USER}:${NB_USER} . ${REPO_DIR}
RUN chgrp -R staff ${REPO_DIR} && \
chmod -R g+rwx ${REPO_DIR} && \
rm -rf ${REPO_DIR}/book ${REPO_DIR}/docs
@@ -101,18 +108,15 @@ RUN mkdir -p /pyrocket_scripts && \
chown -R root:staff /pyrocket_scripts && \
chmod -R 775 /pyrocket_scripts
-# Add NB_USER to staff group (required for rocker script)
-RUN usermod -a -G staff "${NB_USER}"
-
-# Install R, RStudio via Rocker scripts
-# ENV R_DOCKERFILE="verse_${R_VERSION}"
-# RUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \
-# chmod +x ${REPO_DIR}/rocker.sh && \
-# ${REPO_DIR}/rocker.sh
-
# Install extra conda packages
RUN /pyrocket_scripts/install-conda-packages.sh ${REPO_DIR}/environment.yml
+# Install R, RStudio via Rocker scripts
+ENV R_DOCKERFILE="verse_${R_VERSION}"
+RUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \
+ chmod +x ${REPO_DIR}/rocker.sh && \
+ ${REPO_DIR}/rocker.sh
+
# Install extra apt packages
# Install linux packages after R installation since the R install scripts get rid of packages
RUN /pyrocket_scripts/install-apt-packages.sh ${REPO_DIR}/apt.txt
@@ -133,6 +137,8 @@ RUN mkdir -p ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_server_config.d/ && \
cp ${REPO_DIR}/custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_server_config.d/ && \
cp ${REPO_DIR}/custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_notebook_config.d/
+# Set up the start command
+USER ${NB_USER}
RUN chmod +x ${REPO_DIR}/start \
&& cp ${REPO_DIR}/start /srv/start
diff --git a/book/_quarto.yml b/book/_quarto.yml
index 579e537..89ebd88 100644
--- a/book/_quarto.yml
+++ b/book/_quarto.yml
@@ -24,6 +24,7 @@ book:
- publishing.qmd
- jupyter-config.qmd
- developers.qmd
+ - related.qmd
sidebar:
background: "#D9E3E4"
@@ -47,3 +48,9 @@ format:
code-copy: true
code-overflow: wrap
toc: true
+
+crossref:
+ chapters: true
+ labels: roman
+ subref-labels: roman i
+
diff --git a/book/configuration_files.qmd b/book/configuration_files.qmd
index e27d6e3..bcb5d3c 100644
--- a/book/configuration_files.qmd
+++ b/book/configuration_files.qmd
@@ -19,8 +19,7 @@ Here is the code for your Docker file. You can name the conda package file to so
```
COPY environment.yml environment.yml
-RUN /pyrocket_scripts/install-conda-packages.sh environment.yml
-RUN rm environment.yml
+RUN /pyrocket_scripts/install-conda-packages.sh environment.yml && rm environment.yml
```
This is a standard format. You can add version pinning.
@@ -41,8 +40,7 @@ Here is the code for your Docker file. You can name your conda lock file somethi
```
COPY conda-lock.yml conda-lock.yml
-RUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml
-RUN rm conda-lock.yml
+RUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml && rm conda-lock.yml
```
## install-pip-packages.sh
@@ -51,8 +49,7 @@ The `install-pip-packages.sh` script will install packages using `pip`. Here is
```
COPY requirements.txt requirements.txt
-RUN /pyrocket_scripts/install-pip-packages.sh requirements.txt
-RUN rm requirements.txt
+RUN /pyrocket_scripts/install-pip-packages.sh requirements.txt && rm requirements.txt
```
requirements.txt
@@ -70,8 +67,7 @@ Here is the code for your Docker file. You can name the R script file to somethi
```
COPY install.R install.R
-RUN /pyrocket_scripts/install-r-packages.sh install.R
-RUN rm install.R
+RUN /pyrocket_scripts/install-r-packages.sh install.R && rm install.R
```
install.R example
@@ -104,8 +100,7 @@ The `install-apt-packages.sh` script will install packages with `apt-get`. Here
```
USER root
COPY apt.txt apt.txt
-RUN /pyrocket_scripts/install-apt-packages.sh apt.txt
-RUN rm apt.txt
+RUN /pyrocket_scripts/install-apt-packages.sh apt.txt && rm apt.txt
USER ${NB_USER}
```
@@ -124,8 +119,7 @@ The `run-postbuild.sh` script can be run as root or jovyan (`${NB_USER}`). The s
```
COPY postBuild postBuild
-RUN /pyrocket_scripts/run-postbuild.sh postBuild
-RUN rm postBuild
+RUN /pyrocket_scripts/run-postbuild.sh postBuild && rm postBuild
```
postBuild
@@ -144,8 +138,7 @@ The `setup-start.sh` script will move the file you provide into `${REPO_DIR}/chi
```
COPY start start
-RUN /pyrocket_scripts/setup-start.sh start
-RUN rm start
+RUN /pyrocket_scripts/setup-start.sh start && rm start
```
## install-vscode-extensions.sh
@@ -154,8 +147,8 @@ The `install-vscode-extensions.sh` script will add VSCode extensions.
```
COPY vscode-extensions.txt vscode-extensions.txt
-RUN /pyrocket_scripts/install-vscode-extensions.sh vscode-extensions.txt
-RUN rm vscode-extensions.txt
+RUN /pyrocket_scripts/install-vscode-extensions.sh vscode-extensions.txt && \
+ rm vscode-extensions.txt
```
vscode-extensions.txt
diff --git a/book/customizing.qmd b/book/customizing.qmd
index f9bf782..8c62d61 100644
--- a/book/customizing.qmd
+++ b/book/customizing.qmd
@@ -28,8 +28,8 @@ The format for calling the pyrocket and rocker scripts is the following.
pyrocket scripts take files (or a path to a directory with Desktop files) as arguments. The `COPY` command is needed to copy the file into the Docker build context where it can be used in `RUN` commands. Without this you will get a "file not found" error. Removing the file after you are done with it will clean up your image files.
```
COPY environment.yml environment.yml
-RUN /pyrocket_scripts/install-conda-packages.sh environment.yml
-RUN rm environment.yml
+RUN /pyrocket_scripts/install-conda-packages.sh environment.yml && \
+ rm environment.yml
```
Rocker scripts do not take arguments. Note that PATH must be given since rocker installation scripts will fail with conda on the path. The path specification is only within the specific RUN context.
@@ -78,8 +78,8 @@ Dockerfile
FROM ghcr.io/nmfs-opensci/py-rocket-base:latest
COPY environment.yml environment.yml
-RUN /pyrocket_scripts/install-conda-packages.sh environment.yml
-RUN rm environment.yml
+RUN /pyrocket_scripts/install-conda-packages.sh environment.yml && \
+ rm environment.yml
```
environment.yml
@@ -107,8 +107,7 @@ Dockerfile
FROM ghcr.io/nmfs-opensci/py-rocket-base:latest
COPY install.R install.R
-RUN /pyrocket_scripts/install-r-packages.sh install.R
-RUN rm install.R
+RUN /pyrocket_scripts/install-r-packages.sh install.R && rm install.R
```
install.R
@@ -136,8 +135,7 @@ FROM ghcr.io/nmfs-opensci/py-rocket-base:latest
USER root
COPY apt.txt apt.txt
-RUN /pyrocket_scripts/install-apt-packages.sh apt.txt
-RUN rm apt.txt
+RUN /pyrocket_scripts/install-apt-packages.sh apt.txt && rm apt.txt
USER ${NB_USER}
```
diff --git a/book/developers.qmd b/book/developers.qmd
index 116f7cc..d9ce8f0 100644
--- a/book/developers.qmd
+++ b/book/developers.qmd
@@ -186,7 +186,7 @@ WORKDIR ${HOME} # <10>
This script will copy in the rocker scripts from [rocker-versioned2](https://github.com/rocker-org/rocker-versioned2) into `${REPO_DIR}` to install things. It will read in one of the rocker docker files using `R_DOCKERFILE` defined in the `appendix` file (which is inserted into the main docker file).
Variables defined here will only be available in this script. Click on the numbers in the script to learn what each section is doing.
-```
+```r
#!/bin/bash
set -e
@@ -248,7 +248,7 @@ fi # <13>
Within a JupyterHub, the user home directory `$HOME` is typically re-mapped to the user persistent home directory. That means that the image build process cannot put things into `$HOME`, they would just be lost when `$HOME` is re-mapped. If a process needs to have something in the home directory, e.g. in some local user configuration, this must be done in the `start` script. The repo2docker docker image specifies that the start script is `${REPO_DIR}/start`. In py-rocket-base, the start scripts in a child docker file is souces in a subshell from the py-rocket-base start script.
-```
+```r
#!/bin/bash
set -euo pipefail
@@ -280,7 +280,7 @@ exec "$@"
The default for XDG and xfce4 is for Desktop files to be in ~/Desktop but this leads to a variety of problems. First we are altering the user directiory which seems rude, second orphan desktop files might be in ~/Desktop so who knows what the user Desktop experience with be, here the Desktop dir is set to /usr/share/Desktop so is part of the image. Users that really want to customize Desktop can change `~/.config/user-dirs.dirs`. Though py-rocket-base might not respect that. Not sure why you'd do that instead of just using a different image that doesn't have the py-rocket-base behavior.
-```
+```r
#!/bin/bash
set -e
diff --git a/book/related.qmd b/book/related.qmd
new file mode 100644
index 0000000..b980196
--- /dev/null
+++ b/book/related.qmd
@@ -0,0 +1,8 @@
+# Related Docker Stacks
+
+- [NASA Openscapes corn](https://github.com/NASA-Openscapes/corn) and [NASA Openscapes py-rocket](https://github.com/NASA-Openscapes/py-rocket)
+- [Rocker](https://rocker-project.org/images/devcontainer/images.html) R docker stack
+- [Pangeo](https://github.com/pangeo-data/pangeo-docker-images) geosciences docker stack
+- [Jupyter](https://jupyter-docker-stacks.readthedocs.io/en/latest/) data science docker stack
+- [geocompx](https://github.com/geocompx/docker)
+- [b-data](https://github.com/b-data) GPU accelerated docker images and devcontainers
diff --git a/docs/configuration_files.html b/docs/configuration_files.html
index be3946d..4d8b80b 100644
--- a/docs/configuration_files.html
+++ b/docs/configuration_files.html
@@ -163,6 +163,12 @@
7Developer notes
+
+
The install-pip-packages.sh script will install packages using pip. Here is the code for your Docker file. You can name your pip package file something other than requirements.txt.
# to match rocker/verse:4.4 used in py-rocker-base
# look up the date that the Rocker image was created and put that
@@ -283,8 +285,7 @@
The install-apt-packages.sh script will install packages with apt-get. Here is the code for your Docker file. You can name the apt file of packages names to something other than apt.txt. Comments and newlines are allowed. Installation requires root.
USER root
COPY apt.txt apt.txt
-RUN /pyrocket_scripts/install-apt-packages.sh apt.txt
-RUN rm apt.txt
+RUN /pyrocket_scripts/install-apt-packages.sh apt.txt && rm apt.txt
USER ${NB_USER}
apt.txt example
# Some useful stuff
@@ -297,8 +298,7 @@
2.5 run-postbuild.sh
The run-postbuild.sh script can be run as root or jovyan (${NB_USER}). The script has some extra code to remove leftover files after installing Python extensions.
The start bash code is run when the image starts. py-rocker-base has a start script at ${REPO_DIR}/start which loads the Desktop applications. If you change that start file (by copying your start file onto that location), then the Desktop apps will not be loaded properly. Instead, the setup-start.sh will add your start file to a directory ${REPO_DIR}/childstarts and will run all those scripts after ${REPO_DIR}/start.
The setup-start.sh script will move the file you provide into ${REPO_DIR}/childstarts. As usual you can name your script something other than start.
The format for calling the pyrocket and rocker scripts is the following.
pyrocket scripts take files (or a path to a directory with Desktop files) as arguments. The COPY command is needed to copy the file into the Docker build context where it can be used in RUN commands. Without this you will get a “file not found” error. Removing the file after you are done with it will clean up your image files.
Rocker scripts do not take arguments. Note that PATH must be given since rocker installation scripts will fail with conda on the path. The path specification is only within the specific RUN context.
USER root
RUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \
@@ -277,8 +283,8 @@
This script will copy in the rocker scripts from rocker-versioned2 into ${REPO_DIR} to install things. It will read in one of the rocker docker files using R_DOCKERFILE defined in the appendix file (which is inserted into the main docker file). Variables defined here will only be available in this script. Click on the numbers in the script to learn what each section is doing.
-
#!/bin/bash
-set -e
-
-# Copy in the rocker files. Work in ${REPO_DIR} to make sure I don't clobber anything
-cd ${REPO_DIR}
-wget https://github.com/rocker-org/rocker-versioned2/archive/refs/tags/R${R_VERSION}.tar.gz
-tar zxvf R${R_VERSION}.tar.gz && \
-mv rocker-versioned2-R${R_VERSION}/scripts /rocker_scripts && \
-ROCKER_DOCKERFILE_NAME="${R_DOCKERFILE}.Dockerfile"
-mv rocker-versioned2-R${R_VERSION}/dockerfiles/${ROCKER_DOCKERFILE_NAME} /rocker_scripts/original.Dockerfile && \
-rm R${R_VERSION}.tar.gz && \
-rm -rf rocker-versioned2-R${R_VERSION}
-
-cd /
-# Read the Dockerfile and process each line
-while IFS= read -r line; do
- # Check if the line starts with ENV or RUN
- if [[ "$line" == ENV* ]]; then
- # Assign variable
- var_assignment=$(echo "$line" | sed 's/^ENV //g')
- # Replace ENV DEFAULT_USER="jovyan"
- if [[ "$var_assignment" == DEFAULT_USER* ]]; then
- var_assignment="DEFAULT_USER=${NB_USER}"
- fi
- # Run this way eval "export ..." otherwise the " will get turned to %22
- eval "export $var_assignment"
- # Write the exported variable to env.txt
- echo "export $var_assignment" >> ${REPO_DIR}/env.txt
- elif [[ "$line" == RUN* ]]; then
- # Run the command from the RUN line
- cmd=$(echo "$line" | sed 's/^RUN //g')
- echo "Executing: $cmd"
- eval "$cmd" # || echo ${cmd}" encountered an error, but continuing..."
- fi
-done < /rocker_scripts/original.Dockerfile
-
-# Install extra tex packages that are not installed by default
-if command -v tlmgr &> /dev/null; then
- echo "Installing texlive collection-latexrecommended..."
- tlmgr install collection-latexrecommended
- tlmgr install pdfcol tcolorbox eurosym upquote adjustbox titling enumitem ulem soul rsfs
-fi
-
+
#!/bin/bash
+set -e
+
+# Copy in the rocker files. Work in ${REPO_DIR} to make sure I don't clobber anything
+cd ${REPO_DIR}
+wget https://github.com/rocker-org/rocker-versioned2/archive/refs/tags/R${R_VERSION}.tar.gz
+tar zxvf R${R_VERSION}.tar.gz && \
+mv rocker-versioned2-R${R_VERSION}/scripts /rocker_scripts && \
+ROCKER_DOCKERFILE_NAME="${R_DOCKERFILE}.Dockerfile"
+mv rocker-versioned2-R${R_VERSION}/dockerfiles/${ROCKER_DOCKERFILE_NAME} /rocker_scripts/original.Dockerfile && \
+rm R${R_VERSION}.tar.gz && \
+rm -rf rocker-versioned2-R${R_VERSION}
+
+cd /
+# Read the Dockerfile and process each line
+while IFS= read -r line; do
+# Check if the line starts with ENV or RUN
+if [[ "$line"== ENV* ]]; then
+# Assign variable
+ var_assignment=$(echo "$line"| sed 's/^ENV //g')
+# Replace ENV DEFAULT_USER="jovyan"
+if [[ "$var_assignment"== DEFAULT_USER* ]]; then
+ var_assignment="DEFAULT_USER=${NB_USER}"
+ fi
+# Run this way eval "export ..." otherwise the " will get turned to %22
+ eval "export $var_assignment"
+# Write the exported variable to env.txt
+ echo "export $var_assignment">>${REPO_DIR}/env.txt
+ elif [[ "$line"== RUN* ]]; then
+# Run the command from the RUN line
+ cmd=$(echo "$line"| sed 's/^RUN //g')
+ echo "Executing: $cmd"
+ eval "$cmd"# || echo ${cmd}" encountered an error, but continuing..."
+ fi
+done </rocker_scripts/original.Dockerfile
+
+# Install extra tex packages that are not installed by default
+if command -v tlmgr &>/dev/null; then
+ echo "Installing texlive collection-latexrecommended..."
+ tlmgr install collection-latexrecommended
+ tlmgr install pdfcol tcolorbox eurosym upquote adjustbox titling enumitem ulem soul rsfs
+fi
+
1
The rocker-versioned2 repository for a particular R version is copied into {REPO_DIR} and unzipped. R_VERSION is defined in appendix.
@@ -542,30 +549,30 @@
7.11 start
Within a JupyterHub, the user home directory $HOME is typically re-mapped to the user persistent home directory. That means that the image build process cannot put things into $HOME, they would just be lost when $HOME is re-mapped. If a process needs to have something in the home directory, e.g. in some local user configuration, this must be done in the start script. The repo2docker docker image specifies that the start script is ${REPO_DIR}/start. In py-rocket-base, the start scripts in a child docker file is souces in a subshell from the py-rocket-base start script.
-
#!/bin/bash
-set -euo pipefail
-
-# Start - Set any environment variables here
-# These are inherited by all processes, *except* RStudio
-# USE export <parname>=value
-# source this file to get the variables defined in the rocker Dockerfile
-source ${REPO_DIR}/env.txt
-# End - Set any environment variables here
-
-# Run child start scripts in a subshell to contain its environment
-# ${REPO_DIR}/childstart/ is created by setup-start.sh
-if [ -d "${REPO_DIR}/childstart/" ]; then
- for script in ${REPO_DIR}/childstart/*; do
- if [ -f "$script" ]; then
- echo "Sourcing script: $script"
- source "$script" || {
- echo "Error: Failed to source $script. Moving on to the next script."
- }
- fi
- done
-fi
-exec "$@"
-
+
#!/bin/bash
+set -euo pipefail
+
+# Start - Set any environment variables here
+# These are inherited by all processes, *except* RStudio
+# USE export <parname>=value
+# source this file to get the variables defined in the rocker Dockerfile
+source ${REPO_DIR}/env.txt
+# End - Set any environment variables here
+
+# Run child start scripts in a subshell to contain its environment
+# ${REPO_DIR}/childstart/ is created by setup-start.sh
+if [ -d "${REPO_DIR}/childstart/" ]; then
+for script in${REPO_DIR}/childstart/*; do
+if [ -f "$script" ]; then
+ echo "Sourcing script: $script"
+ source "$script"|| {
+ echo "Error: Failed to source $script. Moving on to the next script."
+ }
+ fi
+ done
+fi
+exec "$@"
+
1
In a Docker file so no way to dynamically set environmental variables, so the env.txt file with the export <var>=<value> are source at start up.
@@ -579,52 +586,52 @@
7.12 desktop.sh
The default for XDG and xfce4 is for Desktop files to be in ~/Desktop but this leads to a variety of problems. First we are altering the user directiory which seems rude, second orphan desktop files might be in ~/Desktop so who knows what the user Desktop experience with be, here the Desktop dir is set to /usr/share/Desktop so is part of the image. Users that really want to customize Desktop can change ~/.config/user-dirs.dirs. Though py-rocket-base might not respect that. Not sure why you’d do that instead of just using a different image that doesn’t have the py-rocket-base behavior.
-
#!/bin/bash
-set -e
-
-# Copy in the Desktop files
-APPLICATIONS_DIR=/usr/share/applications
-DESKTOP_DIR=/usr/share/Desktop
-mkdir -p "${DESKTOP_DIR}"
-chown :staff /usr/share/Desktop
-chmod 775 /usr/share/Desktop
-# set the Desktop dir default for XDG
-echo 'XDG_DESKTOP_DIR="${DESKTOP_DIR}"' > /etc/xdg/user-dirs.defaults
-
-# The for loops will fail if they return null (no files). Set shell option nullglob
-shopt -s nullglob
-
-for desktop_file_path in ${REPO_DIR}/Desktop/*.desktop; do
- cp "${desktop_file_path}" "${APPLICATIONS_DIR}/."
- # Symlink application to desktop and set execute permission so xfce (desktop) doesn't complain
- desktop_file_name="$(basename ${desktop_file_path})"
- # Set execute permissions on the copied .desktop file
- chmod +x "${APPLICATIONS_DIR}/${desktop_file_name}"
- ln -sf "${APPLICATIONS_DIR}/${desktop_file_name}" "${DESKTOP_DIR}/${desktop_file_name}"
-done
-update-desktop-database "${APPLICATIONS_DIR}"
-
-# Add MIME Type data from XML files to the MIME database.
-MIME_DIR="/usr/share/mime"
-MIME_PACKAGES_DIR="${MIME_DIR}/packages"
-mkdir -p "${MIME_PACKAGES_DIR}"
-for mime_file_path in ${REPO_DIR}/Desktop/*.xml; do
- cp "${mime_file_path}" "${MIME_PACKAGES_DIR}/."
-done
-update-mime-database "${MIME_DIR}"
-
-# Add icons
-ICON_DIR="/usr/share/icons"
-ICON_PACKAGES_DIR="${ICON_DIR}/packages"
-mkdir -p "${ICON_PACKAGES_DIR}"
-for icon_file_path in "${REPO_DIR}"/Desktop/*.png; do
- cp "${icon_file_path}" "${ICON_PACKAGES_DIR}/" || echo "Failed to copy ${icon_file_path}"
-done
-for icon_file_path in "${REPO_DIR}"/Desktop/*.svg; do
- cp "${icon_file_path}" "${ICON_PACKAGES_DIR}/" || echo "Failed to copy ${icon_file_path}"
-done
-gtk-update-icon-cache "${ICON_DIR}"
-
+
#!/bin/bash
+set -e
+
+# Copy in the Desktop files
+APPLICATIONS_DIR=/usr/share/applications
+DESKTOP_DIR=/usr/share/Desktop
+mkdir -p "${DESKTOP_DIR}"
+chown :staff /usr/share/Desktop
+chmod 775/usr/share/Desktop
+# set the Desktop dir default for XDG
+echo 'XDG_DESKTOP_DIR="${DESKTOP_DIR}"'>/etc/xdg/user-dirs.defaults
+
+# The for loops will fail if they return null (no files). Set shell option nullglob
+shopt -s nullglob
+
+for desktop_file_path in${REPO_DIR}/Desktop/*.desktop; do
+ cp "${desktop_file_path}""${APPLICATIONS_DIR}/."
+# Symlink application to desktop and set execute permission so xfce (desktop) doesn't complain
+ desktop_file_name="$(basename ${desktop_file_path})"
+# Set execute permissions on the copied .desktop file
+ chmod +x "${APPLICATIONS_DIR}/${desktop_file_name}"
+ ln -sf "${APPLICATIONS_DIR}/${desktop_file_name}""${DESKTOP_DIR}/${desktop_file_name}"
+done
+update-desktop-database "${APPLICATIONS_DIR}"
+
+# Add MIME Type data from XML files to the MIME database.
+MIME_DIR="/usr/share/mime"
+MIME_PACKAGES_DIR="${MIME_DIR}/packages"
+mkdir -p "${MIME_PACKAGES_DIR}"
+for mime_file_path in${REPO_DIR}/Desktop/*.xml; do
+ cp "${mime_file_path}""${MIME_PACKAGES_DIR}/."
+done
+update-mime-database "${MIME_DIR}"
+
+# Add icons
+ICON_DIR="/usr/share/icons"
+ICON_PACKAGES_DIR="${ICON_DIR}/packages"
+mkdir -p "${ICON_PACKAGES_DIR}"
+for icon_file_path in"${REPO_DIR}"/Desktop/*.png; do
+ cp "${icon_file_path}""${ICON_PACKAGES_DIR}/"|| echo "Failed to copy ${icon_file_path}"
+done
+for icon_file_path in"${REPO_DIR}"/Desktop/*.svg; do
+ cp "${icon_file_path}""${ICON_PACKAGES_DIR}/"|| echo "Failed to copy ${icon_file_path}"
+done
+gtk-update-icon-cache "${ICON_DIR}"
+
1
This is the default local for system applications.
@@ -1267,6 +1274,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/search.json b/docs/search.json
index 632feaf..0868406 100644
--- a/docs/search.json
+++ b/docs/search.json
@@ -44,7 +44,7 @@
"href": "customizing.html#helper-scripts",
"title": "1 Using py-rocket-base",
"section": "",
- "text": "1.1.1 pyrocket scripts\nHow to use the helper scripts is shown in configuration files. The helper scripts provide code to do common tasks. Users can write their own Docker file code to do these tasks but the helper scripts provide standardized code. The scripts are\n\ninstall-conda-packages.sh\ninstall-pip-packages.sh\ninstall-r-packages.sh\ninstall-apt-packages.sh\ninstall-vscode-extensions.sh\ninstall-desktop.sh\nsetup-start.sh\nrun-postbuild.sh\n\n\n\n1.1.2 rocker scripts\nThe rocker docker stack also includes a set of scripts for extending rocker packages. These are included py-rocket-base.\n\n\n1.1.3 Calling the scripts\nThe format for calling the pyrocket and rocker scripts is the following.\npyrocket scripts take files (or a path to a directory with Desktop files) as arguments. The COPY command is needed to copy the file into the Docker build context where it can be used in RUN commands. Without this you will get a “file not found” error. Removing the file after you are done with it will clean up your image files.\nCOPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml\nRUN rm environment.yml\nRocker scripts do not take arguments. Note that PATH must be given since rocker installation scripts will fail with conda on the path. The path specification is only within the specific RUN context.\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}",
+ "text": "1.1.1 pyrocket scripts\nHow to use the helper scripts is shown in configuration files. The helper scripts provide code to do common tasks. Users can write their own Docker file code to do these tasks but the helper scripts provide standardized code. The scripts are\n\ninstall-conda-packages.sh\ninstall-pip-packages.sh\ninstall-r-packages.sh\ninstall-apt-packages.sh\ninstall-vscode-extensions.sh\ninstall-desktop.sh\nsetup-start.sh\nrun-postbuild.sh\n\n\n\n1.1.2 rocker scripts\nThe rocker docker stack also includes a set of scripts for extending rocker packages. These are included py-rocket-base.\n\n\n1.1.3 Calling the scripts\nThe format for calling the pyrocket and rocker scripts is the following.\npyrocket scripts take files (or a path to a directory with Desktop files) as arguments. The COPY command is needed to copy the file into the Docker build context where it can be used in RUN commands. Without this you will get a “file not found” error. Removing the file after you are done with it will clean up your image files.\nCOPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml && \\\n rm environment.yml\nRocker scripts do not take arguments. Note that PATH must be given since rocker installation scripts will fail with conda on the path. The path specification is only within the specific RUN context.\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}",
"crumbs": [
"1Using py-rocket-base"
]
@@ -64,7 +64,7 @@
"href": "customizing.html#examples",
"title": "1 Using py-rocket-base",
"section": "1.3 Examples",
- "text": "1.3 Examples\n\n1.3.1 Add some Python packages\nYou want to add some Python packages to the conda notebook environment.\nyour-repo/\n├── Dockerfile\n├── environment.yml\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nCOPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml\nRUN rm environment.yml\nenvironment.yml\nname: required\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\n1.3.2 Add R packages\nAdd an R script to install packages. Important: packages that have linux dependencies (e.g. all the spatial packages depend on GDAL) will not work if you use install.packages(). GDAL will not be installed.\nyour-repo/\n├── Dockerfile\n├── install.R\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nCOPY install.R install.R\nRUN /pyrocket_scripts/install-r-packages.sh install.R\nRUN rm install.R\ninstall.R\n# to match rocker/verse:4.4 used in py-rocker-base\n# look up the date that the Rocker image was created and put that\nrepo <- \"https://p3m.dev/cran/__linux__/jammy/2024-05-13\"\nlist.of.packages <- c(\"ncdf4\", \"httr\", \"plyr\", \"lubridate\")\ninstall.packages(list.of.packages, repos=repo)\n\n\n1.3.3 Add some linux packages\nYou want to add some linux packages with apt-get. apt-get requires root so you will need to switch to root and switch back to ${NB_USER}.\nyour-repo/\n├── Dockerfile\n├── apt.txt\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nCOPY apt.txt apt.txt\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt\nRUN rm apt.txt\nUSER ${NB_USER}\napt.txt\n# a package\nlibgl1-mesa-glx\n\n# Another\nvim\n\n\n1.3.4 Add R geospatial packages\nGeospatial packages require some linux packages. To get this working in your Docker image add this to your Docker file:\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}\nYou have access to all the rocker scripts and you can run these similar to the line above.",
+ "text": "1.3 Examples\n\n1.3.1 Add some Python packages\nYou want to add some Python packages to the conda notebook environment.\nyour-repo/\n├── Dockerfile\n├── environment.yml\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nCOPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml && \\\n rm environment.yml\nenvironment.yml\nname: required\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\n1.3.2 Add R packages\nAdd an R script to install packages. Important: packages that have linux dependencies (e.g. all the spatial packages depend on GDAL) will not work if you use install.packages(). GDAL will not be installed.\nyour-repo/\n├── Dockerfile\n├── install.R\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nCOPY install.R install.R\nRUN /pyrocket_scripts/install-r-packages.sh install.R && rm install.R\ninstall.R\n# to match rocker/verse:4.4 used in py-rocker-base\n# look up the date that the Rocker image was created and put that\nrepo <- \"https://p3m.dev/cran/__linux__/jammy/2024-05-13\"\nlist.of.packages <- c(\"ncdf4\", \"httr\", \"plyr\", \"lubridate\")\ninstall.packages(list.of.packages, repos=repo)\n\n\n1.3.3 Add some linux packages\nYou want to add some linux packages with apt-get. apt-get requires root so you will need to switch to root and switch back to ${NB_USER}.\nyour-repo/\n├── Dockerfile\n├── apt.txt\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nCOPY apt.txt apt.txt\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt && rm apt.txt\nUSER ${NB_USER}\napt.txt\n# a package\nlibgl1-mesa-glx\n\n# Another\nvim\n\n\n1.3.4 Add R geospatial packages\nGeospatial packages require some linux packages. To get this working in your Docker image add this to your Docker file:\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}\nYou have access to all the rocker scripts and you can run these similar to the line above.",
"crumbs": [
"1Using py-rocket-base"
]
@@ -84,7 +84,7 @@
"href": "configuration_files.html#install-conda-packages.sh",
"title": "2 Customization scripts",
"section": "",
- "text": "COPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml\nRUN rm environment.yml\n\n\nname: required\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\nCOPY conda-lock.yml conda-lock.yml\nRUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml\nRUN rm conda-lock.yml",
+ "text": "COPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml && rm environment.yml\n\n\nname: required\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\nCOPY conda-lock.yml conda-lock.yml\nRUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml && rm conda-lock.yml",
"crumbs": [
"2Customization scripts"
]
@@ -94,7 +94,7 @@
"href": "configuration_files.html#install-pip-packages.sh",
"title": "2 Customization scripts",
"section": "2.2 install-pip-packages.sh",
- "text": "2.2 install-pip-packages.sh\nThe install-pip-packages.sh script will install packages using pip. Here is the code for your Docker file. You can name your pip package file something other than requirements.txt.\nCOPY requirements.txt requirements.txt\nRUN /pyrocket_scripts/install-pip-packages.sh requirements.txt\nRUN rm requirements.txt\nrequirements.txt\n#a package\nharmony-py",
+ "text": "2.2 install-pip-packages.sh\nThe install-pip-packages.sh script will install packages using pip. Here is the code for your Docker file. You can name your pip package file something other than requirements.txt.\nCOPY requirements.txt requirements.txt\nRUN /pyrocket_scripts/install-pip-packages.sh requirements.txt && rm requirements.txt\nrequirements.txt\n#a package\nharmony-py",
"crumbs": [
"2Customization scripts"
]
@@ -104,7 +104,7 @@
"href": "configuration_files.html#install-r-packages.sh",
"title": "2 Customization scripts",
"section": "2.3 install-r-packages.sh",
- "text": "2.3 install-r-packages.sh\nThe install-r-packages.sh script will run the supplied R script which you can use to install R packages to the system library.\nHere is the code for your Docker file. You can name the R script file to something other than install.R. Make sure your file is an R script.\nCOPY install.R install.R\nRUN /pyrocket_scripts/install-r-packages.sh install.R\nRUN rm install.R\ninstall.R example\n# to match rocker/verse:4.4 used in py-rocker-base\n# look up the date that the Rocker image was created and put that\nrepo <- \"https://p3m.dev/cran/__linux__/jammy/2024-05-13\"\nlist.of.packages <- c(\"ncdf4\", \"httr\", \"plyr\", \"lubridate\")\ninstall.packages(list.of.packages, repos=repo)\n\n2.3.1 Add R geospatial packages\nGeospatial packages require some linux packages. To get this working in your Docker image add this to your Docker file:\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}",
+ "text": "2.3 install-r-packages.sh\nThe install-r-packages.sh script will run the supplied R script which you can use to install R packages to the system library.\nHere is the code for your Docker file. You can name the R script file to something other than install.R. Make sure your file is an R script.\nCOPY install.R install.R\nRUN /pyrocket_scripts/install-r-packages.sh install.R && rm install.R\ninstall.R example\n# to match rocker/verse:4.4 used in py-rocker-base\n# look up the date that the Rocker image was created and put that\nrepo <- \"https://p3m.dev/cran/__linux__/jammy/2024-05-13\"\nlist.of.packages <- c(\"ncdf4\", \"httr\", \"plyr\", \"lubridate\")\ninstall.packages(list.of.packages, repos=repo)\n\n2.3.1 Add R geospatial packages\nGeospatial packages require some linux packages. To get this working in your Docker image add this to your Docker file:\nDockerfile\nFROM ghcr.io/nmfs-opensci/py-rocket-base:latest\n\nUSER root\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n /rocker_scripts/install_geospatial.sh\nUSER ${NB_USER}",
"crumbs": [
"2Customization scripts"
]
@@ -114,7 +114,7 @@
"href": "configuration_files.html#install-apt-packages.sh",
"title": "2 Customization scripts",
"section": "2.4 install-apt-packages.sh",
- "text": "2.4 install-apt-packages.sh\nThe install-apt-packages.sh script will install packages with apt-get. Here is the code for your Docker file. You can name the apt file of packages names to something other than apt.txt. Comments and newlines are allowed. Installation requires root.\nUSER root\nCOPY apt.txt apt.txt\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt\nRUN rm apt.txt\nUSER ${NB_USER}\napt.txt example\n# Some useful stuff\ntk-dev\n\n# Add some more\ncmocean",
+ "text": "2.4 install-apt-packages.sh\nThe install-apt-packages.sh script will install packages with apt-get. Here is the code for your Docker file. You can name the apt file of packages names to something other than apt.txt. Comments and newlines are allowed. Installation requires root.\nUSER root\nCOPY apt.txt apt.txt\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt && rm apt.txt\nUSER ${NB_USER}\napt.txt example\n# Some useful stuff\ntk-dev\n\n# Add some more\ncmocean",
"crumbs": [
"2Customization scripts"
]
@@ -124,7 +124,7 @@
"href": "configuration_files.html#run-postbuild.sh",
"title": "2 Customization scripts",
"section": "2.5 run-postbuild.sh",
- "text": "2.5 run-postbuild.sh\nThe run-postbuild.sh script can be run as root or jovyan (${NB_USER}). The script has some extra code to remove leftover files after installing Python extensions.\nCOPY postBuild postBuild\nRUN /pyrocket_scripts/run-postbuild.sh postBuild\nRUN rm postBuild\npostBuild\n#!/bin/bash -l\nset -e\n\n<bash commands>",
+ "text": "2.5 run-postbuild.sh\nThe run-postbuild.sh script can be run as root or jovyan (${NB_USER}). The script has some extra code to remove leftover files after installing Python extensions.\nCOPY postBuild postBuild\nRUN /pyrocket_scripts/run-postbuild.sh postBuild && rm postBuild\npostBuild\n#!/bin/bash -l\nset -e\n\n<bash commands>",
"crumbs": [
"2Customization scripts"
]
@@ -134,7 +134,7 @@
"href": "configuration_files.html#setup-start.sh",
"title": "2 Customization scripts",
"section": "2.6 setup-start.sh",
- "text": "2.6 setup-start.sh\nThe start bash code is run when the image starts. py-rocker-base has a start script at ${REPO_DIR}/start which loads the Desktop applications. If you change that start file (by copying your start file onto that location), then the Desktop apps will not be loaded properly. Instead, the setup-start.sh will add your start file to a directory ${REPO_DIR}/childstarts and will run all those scripts after ${REPO_DIR}/start.\nThe setup-start.sh script will move the file you provide into ${REPO_DIR}/childstarts. As usual you can name your script something other than start.\nCOPY start start\nRUN /pyrocket_scripts/setup-start.sh start\nRUN rm start",
+ "text": "2.6 setup-start.sh\nThe start bash code is run when the image starts. py-rocker-base has a start script at ${REPO_DIR}/start which loads the Desktop applications. If you change that start file (by copying your start file onto that location), then the Desktop apps will not be loaded properly. Instead, the setup-start.sh will add your start file to a directory ${REPO_DIR}/childstarts and will run all those scripts after ${REPO_DIR}/start.\nThe setup-start.sh script will move the file you provide into ${REPO_DIR}/childstarts. As usual you can name your script something other than start.\nCOPY start start\nRUN /pyrocket_scripts/setup-start.sh start && rm start",
"crumbs": [
"2Customization scripts"
]
@@ -144,7 +144,7 @@
"href": "configuration_files.html#install-vscode-extensions.sh",
"title": "2 Customization scripts",
"section": "2.7 install-vscode-extensions.sh",
- "text": "2.7 install-vscode-extensions.sh\nThe install-vscode-extensions.sh script will add VSCode extensions.\nCOPY vscode-extensions.txt vscode-extensions.txt\nRUN /pyrocket_scripts/install-vscode-extensions.sh vscode-extensions.txt\nRUN rm vscode-extensions.txt\nvscode-extensions.txt\ngitlens\nindent-rainbow\ncode-spell-checker\nprettier",
+ "text": "2.7 install-vscode-extensions.sh\nThe install-vscode-extensions.sh script will add VSCode extensions.\nCOPY vscode-extensions.txt vscode-extensions.txt\nRUN /pyrocket_scripts/install-vscode-extensions.sh vscode-extensions.txt && \\\n rm vscode-extensions.txt\nvscode-extensions.txt\ngitlens\nindent-rainbow\ncode-spell-checker\nprettier",
"crumbs": [
"2Customization scripts"
]
@@ -364,7 +364,7 @@
"href": "developers.html#rocker.sh",
"title": "7 Developer notes",
"section": "7.10 rocker.sh",
- "text": "7.10 rocker.sh\nThis script will copy in the rocker scripts from rocker-versioned2 into ${REPO_DIR} to install things. It will read in one of the rocker docker files using R_DOCKERFILE defined in the appendix file (which is inserted into the main docker file). Variables defined here will only be available in this script. Click on the numbers in the script to learn what each section is doing.\n#!/bin/bash\nset -e\n\n# Copy in the rocker files. Work in ${REPO_DIR} to make sure I don't clobber anything\ncd ${REPO_DIR}\nwget https://github.com/rocker-org/rocker-versioned2/archive/refs/tags/R${R_VERSION}.tar.gz\ntar zxvf R${R_VERSION}.tar.gz && \\\nmv rocker-versioned2-R${R_VERSION}/scripts /rocker_scripts && \\\nROCKER_DOCKERFILE_NAME=\"${R_DOCKERFILE}.Dockerfile\"\nmv rocker-versioned2-R${R_VERSION}/dockerfiles/${ROCKER_DOCKERFILE_NAME} /rocker_scripts/original.Dockerfile && \\\nrm R${R_VERSION}.tar.gz && \\\nrm -rf rocker-versioned2-R${R_VERSION}\n\ncd /\n# Read the Dockerfile and process each line\nwhile IFS= read -r line; do\n # Check if the line starts with ENV or RUN\n if [[ \"$line\" == ENV* ]]; then\n # Assign variable\n var_assignment=$(echo \"$line\" | sed 's/^ENV //g')\n # Replace ENV DEFAULT_USER=\"jovyan\"\n if [[ \"$var_assignment\" == DEFAULT_USER* ]]; then\n var_assignment=\"DEFAULT_USER=${NB_USER}\"\n fi\n # Run this way eval \"export ...\" otherwise the \" will get turned to %22\n eval \"export $var_assignment\"\n # Write the exported variable to env.txt\n echo \"export $var_assignment\" >> ${REPO_DIR}/env.txt\n elif [[ \"$line\" == RUN* ]]; then\n # Run the command from the RUN line\n cmd=$(echo \"$line\" | sed 's/^RUN //g')\n echo \"Executing: $cmd\"\n eval \"$cmd\" # || echo ${cmd}\" encountered an error, but continuing...\"\n fi\ndone < /rocker_scripts/original.Dockerfile\n\n# Install extra tex packages that are not installed by default\nif command -v tlmgr &> /dev/null; then\n echo \"Installing texlive collection-latexrecommended...\"\n tlmgr install collection-latexrecommended\n tlmgr install pdfcol tcolorbox eurosym upquote adjustbox titling enumitem ulem soul rsfs\nfi\n\n1\n\nThe rocker-versioned2 repository for a particular R version is copied into {REPO_DIR} and unzipped. R_VERSION is defined in appendix.\n\n2\n\nThe unzipped directory will be named rocker-versioned2-R${R_VERSION}. We move the scripts directory to /rocker_scripts (base level) because the rocker scripts expect the scripts to be there.\n\n3\n\nR_DOCKERFILE is defined as verse_${R_VERSION}. The docker file we will process (find ENV and RUN lines) is called ROCKER_DOCKERFILE_NAME in the rocker files. We move this to /rocker_scripts/original.Dockerfile so we can refer to it later.\n\n4\n\nClean up the rocker directories that we no longer need.\n\n5\n\ncd to the base level where /rocker_scripts is.\n\n6\n\nThe big while loop is processing /rocker_scripts/original.Dockerfile. The code is using piping > and the input file and pipe is specified at the end of the while loop code.\n\n7\n\nThis looks if the line starts with ENV and if it does, it strips off ENV and stores the variable assigment statement to $var_assignment.\n\n8\n\nThe rocker docker files do not use the NB_USER environmental variable (defined in appendix). If the ENV line is defining the default user, we need to change that assignment to the variable NB_USER. This part is specific to the rocker docker files.\n\n9\n\nWe need to export any variables (ENV) found in the docker file so it is available to the scripts that will run in the RUN statements. We need to export the variables as done here (with eval and export) otherwise they don’t make it to the child scripts about to be run. Getting variables to be exported to child scripts being called by a parent script is tricky and this line required a lot of testing and debugging to get variables exported properly.\n\n10\n\nThe export line will only make the variable available to the child scripts. We also want them available in the final image. To do that, we write them to a file that we will source from the docker file. Scripts are run in an ephemeral subshell during docker builds so we cannot define the variable here.\n\n11\n\nIf the docker file line starts with RUN then run the command. This command should be a rocker script because that is how rocker docker files are organized. See an example rocker docker file.\n\n12\n\nHere the input file for the while loop is specified.\n\n13\n\nThe rocker install_texlive.sh script (which is part of verse) will provide a basic texlive installation. Here a few more packages are added so that the user is able to run vanilla Quarto to PDF and Myst to PDF. See the chapter on texlive.",
+ "text": "7.10 rocker.sh\nThis script will copy in the rocker scripts from rocker-versioned2 into ${REPO_DIR} to install things. It will read in one of the rocker docker files using R_DOCKERFILE defined in the appendix file (which is inserted into the main docker file). Variables defined here will only be available in this script. Click on the numbers in the script to learn what each section is doing.\n#!/bin/bash\nset -e\n\n# Copy in the rocker files. Work in ${REPO_DIR} to make sure I don't clobber anything\n1cd ${REPO_DIR}\nwget https://github.com/rocker-org/rocker-versioned2/archive/refs/tags/R${R_VERSION}.tar.gz\ntar zxvf R${R_VERSION}.tar.gz && \\\n2mv rocker-versioned2-R${R_VERSION}/scripts /rocker_scripts && \\\n3ROCKER_DOCKERFILE_NAME=\"${R_DOCKERFILE}.Dockerfile\"\nmv rocker-versioned2-R${R_VERSION}/dockerfiles/${ROCKER_DOCKERFILE_NAME} /rocker_scripts/original.Dockerfile && \\\n4rm R${R_VERSION}.tar.gz && \\\nrm -rf rocker-versioned2-R${R_VERSION}\n\n5cd /\n6# Read the Dockerfile and process each line\nwhile IFS= read -r line; do\n7 # Check if the line starts with ENV or RUN\n if [[ \"$line\" == ENV* ]]; then\n # Assign variable\n var_assignment=$(echo \"$line\" | sed 's/^ENV //g')\n8 # Replace ENV DEFAULT_USER=\"jovyan\"\n if [[ \"$var_assignment\" == DEFAULT_USER* ]]; then\n var_assignment=\"DEFAULT_USER=${NB_USER}\"\n fi\n # Run this way eval \"export ...\" otherwise the \" will get turned to %22\n9 eval \"export $var_assignment\"\n # Write the exported variable to env.txt\n10 echo \"export $var_assignment\" >> ${REPO_DIR}/env.txt\n11 elif [[ \"$line\" == RUN* ]]; then\n # Run the command from the RUN line\n cmd=$(echo \"$line\" | sed 's/^RUN //g')\n echo \"Executing: $cmd\"\n eval \"$cmd\" # || echo ${cmd}\" encountered an error, but continuing...\"\n fi\n12done < /rocker_scripts/original.Dockerfile\n\n13# Install extra tex packages that are not installed by default\nif command -v tlmgr &> /dev/null; then\n echo \"Installing texlive collection-latexrecommended...\"\n tlmgr install collection-latexrecommended\n tlmgr install pdfcol tcolorbox eurosym upquote adjustbox titling enumitem ulem soul rsfs\nfi\n\n1\n\nThe rocker-versioned2 repository for a particular R version is copied into {REPO_DIR} and unzipped. R_VERSION is defined in appendix.\n\n2\n\nThe unzipped directory will be named rocker-versioned2-R${R_VERSION}. We move the scripts directory to /rocker_scripts (base level) because the rocker scripts expect the scripts to be there.\n\n3\n\nR_DOCKERFILE is defined as verse_${R_VERSION}. The docker file we will process (find ENV and RUN lines) is called ROCKER_DOCKERFILE_NAME in the rocker files. We move this to /rocker_scripts/original.Dockerfile so we can refer to it later.\n\n4\n\nClean up the rocker directories that we no longer need.\n\n5\n\ncd to the base level where /rocker_scripts is.\n\n6\n\nThe big while loop is processing /rocker_scripts/original.Dockerfile. The code is using piping > and the input file and pipe is specified at the end of the while loop code.\n\n7\n\nThis looks if the line starts with ENV and if it does, it strips off ENV and stores the variable assigment statement to $var_assignment.\n\n8\n\nThe rocker docker files do not use the NB_USER environmental variable (defined in appendix). If the ENV line is defining the default user, we need to change that assignment to the variable NB_USER. This part is specific to the rocker docker files.\n\n9\n\nWe need to export any variables (ENV) found in the docker file so it is available to the scripts that will run in the RUN statements. We need to export the variables as done here (with eval and export) otherwise they don’t make it to the child scripts about to be run. Getting variables to be exported to child scripts being called by a parent script is tricky and this line required a lot of testing and debugging to get variables exported properly.\n\n10\n\nThe export line will only make the variable available to the child scripts. We also want them available in the final image. To do that, we write them to a file that we will source from the docker file. Scripts are run in an ephemeral subshell during docker builds so we cannot define the variable here.\n\n11\n\nIf the docker file line starts with RUN then run the command. This command should be a rocker script because that is how rocker docker files are organized. See an example rocker docker file.\n\n12\n\nHere the input file for the while loop is specified.\n\n13\n\nThe rocker install_texlive.sh script (which is part of verse) will provide a basic texlive installation. Here a few more packages are added so that the user is able to run vanilla Quarto to PDF and Myst to PDF. See the chapter on texlive.",
"crumbs": [
"7Developer notes"
]
@@ -374,7 +374,7 @@
"href": "developers.html#start",
"title": "7 Developer notes",
"section": "7.11 start",
- "text": "7.11 start\nWithin a JupyterHub, the user home directory $HOME is typically re-mapped to the user persistent home directory. That means that the image build process cannot put things into $HOME, they would just be lost when $HOME is re-mapped. If a process needs to have something in the home directory, e.g. in some local user configuration, this must be done in the start script. The repo2docker docker image specifies that the start script is ${REPO_DIR}/start. In py-rocket-base, the start scripts in a child docker file is souces in a subshell from the py-rocket-base start script.\n#!/bin/bash\nset -euo pipefail\n\n# Start - Set any environment variables here\n# These are inherited by all processes, *except* RStudio\n# USE export <parname>=value\n# source this file to get the variables defined in the rocker Dockerfile\nsource ${REPO_DIR}/env.txt\n# End - Set any environment variables here\n\n# Run child start scripts in a subshell to contain its environment\n# ${REPO_DIR}/childstart/ is created by setup-start.sh\nif [ -d \"${REPO_DIR}/childstart/\" ]; then\n for script in ${REPO_DIR}/childstart/*; do\n if [ -f \"$script\" ]; then\n echo \"Sourcing script: $script\"\n source \"$script\" || {\n echo \"Error: Failed to source $script. Moving on to the next script.\"\n }\n fi\n done\nfi\nexec \"$@\"\n\n1\n\nIn a Docker file so no way to dynamically set environmental variables, so the env.txt file with the export <var>=<value> are source at start up.\n\n2\n\nRun any child start script in a subshell. Run in a subshell to contain any set statements or similar. start scripts are moved into childstarts by the setup-start.sh pyrocket script.",
+ "text": "7.11 start\nWithin a JupyterHub, the user home directory $HOME is typically re-mapped to the user persistent home directory. That means that the image build process cannot put things into $HOME, they would just be lost when $HOME is re-mapped. If a process needs to have something in the home directory, e.g. in some local user configuration, this must be done in the start script. The repo2docker docker image specifies that the start script is ${REPO_DIR}/start. In py-rocket-base, the start scripts in a child docker file is souces in a subshell from the py-rocket-base start script.\n#!/bin/bash\nset -euo pipefail\n\n1# Start - Set any environment variables here\n# These are inherited by all processes, *except* RStudio\n# USE export <parname>=value\n# source this file to get the variables defined in the rocker Dockerfile\nsource ${REPO_DIR}/env.txt\n# End - Set any environment variables here\n\n# Run child start scripts in a subshell to contain its environment\n# ${REPO_DIR}/childstart/ is created by setup-start.sh\n2if [ -d \"${REPO_DIR}/childstart/\" ]; then\n for script in ${REPO_DIR}/childstart/*; do\n if [ -f \"$script\" ]; then\n echo \"Sourcing script: $script\"\n source \"$script\" || {\n echo \"Error: Failed to source $script. Moving on to the next script.\"\n }\n fi\n done\nfi\nexec \"$@\"\n\n1\n\nIn a Docker file so no way to dynamically set environmental variables, so the env.txt file with the export <var>=<value> are source at start up.\n\n2\n\nRun any child start script in a subshell. Run in a subshell to contain any set statements or similar. start scripts are moved into childstarts by the setup-start.sh pyrocket script.",
"crumbs": [
"7Developer notes"
]
@@ -384,9 +384,19 @@
"href": "developers.html#desktop.sh",
"title": "7 Developer notes",
"section": "7.12 desktop.sh",
- "text": "7.12 desktop.sh\nThe default for XDG and xfce4 is for Desktop files to be in ~/Desktop but this leads to a variety of problems. First we are altering the user directiory which seems rude, second orphan desktop files might be in ~/Desktop so who knows what the user Desktop experience with be, here the Desktop dir is set to /usr/share/Desktop so is part of the image. Users that really want to customize Desktop can change ~/.config/user-dirs.dirs. Though py-rocket-base might not respect that. Not sure why you’d do that instead of just using a different image that doesn’t have the py-rocket-base behavior.\n#!/bin/bash\nset -e\n\n# Copy in the Desktop files\nAPPLICATIONS_DIR=/usr/share/applications\nDESKTOP_DIR=/usr/share/Desktop\nmkdir -p \"${DESKTOP_DIR}\"\nchown :staff /usr/share/Desktop\nchmod 775 /usr/share/Desktop\n# set the Desktop dir default for XDG\necho 'XDG_DESKTOP_DIR=\"${DESKTOP_DIR}\"' > /etc/xdg/user-dirs.defaults\n\n# The for loops will fail if they return null (no files). Set shell option nullglob\nshopt -s nullglob\n\nfor desktop_file_path in ${REPO_DIR}/Desktop/*.desktop; do\n cp \"${desktop_file_path}\" \"${APPLICATIONS_DIR}/.\"\n # Symlink application to desktop and set execute permission so xfce (desktop) doesn't complain\n desktop_file_name=\"$(basename ${desktop_file_path})\"\n # Set execute permissions on the copied .desktop file\n chmod +x \"${APPLICATIONS_DIR}/${desktop_file_name}\"\n ln -sf \"${APPLICATIONS_DIR}/${desktop_file_name}\" \"${DESKTOP_DIR}/${desktop_file_name}\"\ndone\nupdate-desktop-database \"${APPLICATIONS_DIR}\"\n\n# Add MIME Type data from XML files to the MIME database.\nMIME_DIR=\"/usr/share/mime\"\nMIME_PACKAGES_DIR=\"${MIME_DIR}/packages\"\nmkdir -p \"${MIME_PACKAGES_DIR}\"\nfor mime_file_path in ${REPO_DIR}/Desktop/*.xml; do\n cp \"${mime_file_path}\" \"${MIME_PACKAGES_DIR}/.\"\ndone\nupdate-mime-database \"${MIME_DIR}\"\n\n# Add icons\nICON_DIR=\"/usr/share/icons\"\nICON_PACKAGES_DIR=\"${ICON_DIR}/packages\"\nmkdir -p \"${ICON_PACKAGES_DIR}\"\nfor icon_file_path in \"${REPO_DIR}\"/Desktop/*.png; do\n cp \"${icon_file_path}\" \"${ICON_PACKAGES_DIR}/\" || echo \"Failed to copy ${icon_file_path}\"\ndone\nfor icon_file_path in \"${REPO_DIR}\"/Desktop/*.svg; do\n cp \"${icon_file_path}\" \"${ICON_PACKAGES_DIR}/\" || echo \"Failed to copy ${icon_file_path}\"\ndone\ngtk-update-icon-cache \"${ICON_DIR}\"\n\n1\n\nThis is the default local for system applications.\n\n2\n\nCreate the Desktop directory and make sure jovyan can put files there. This is mainly for debugging.\n\n3\n\nSet up the default XDG_DESKTOP_DIR value. This will be copied to the ~.config (by xinitrc).\n\n4\n\nCopy the .desktop file in the Desktop directory into the applications directory and make a symlink to the Desktop directory. The former means that the applications will appear in the menu in xfce4 desktop and the latter means there will be a desktop icon.\n\n5\n\nAdd any mime xml files to the mime folder and update the mime database.\n\n6\n\nAdd any png or svg icon files to the icon folder and update the icon database.",
+ "text": "7.12 desktop.sh\nThe default for XDG and xfce4 is for Desktop files to be in ~/Desktop but this leads to a variety of problems. First we are altering the user directiory which seems rude, second orphan desktop files might be in ~/Desktop so who knows what the user Desktop experience with be, here the Desktop dir is set to /usr/share/Desktop so is part of the image. Users that really want to customize Desktop can change ~/.config/user-dirs.dirs. Though py-rocket-base might not respect that. Not sure why you’d do that instead of just using a different image that doesn’t have the py-rocket-base behavior.\n#!/bin/bash\nset -e\n\n# Copy in the Desktop files\n1APPLICATIONS_DIR=/usr/share/applications\n2DESKTOP_DIR=/usr/share/Desktop\nmkdir -p \"${DESKTOP_DIR}\"\nchown :staff /usr/share/Desktop\nchmod 775 /usr/share/Desktop\n# set the Desktop dir default for XDG\n3echo 'XDG_DESKTOP_DIR=\"${DESKTOP_DIR}\"' > /etc/xdg/user-dirs.defaults\n\n# The for loops will fail if they return null (no files). Set shell option nullglob\nshopt -s nullglob\n\n4for desktop_file_path in ${REPO_DIR}/Desktop/*.desktop; do\n cp \"${desktop_file_path}\" \"${APPLICATIONS_DIR}/.\"\n # Symlink application to desktop and set execute permission so xfce (desktop) doesn't complain\n desktop_file_name=\"$(basename ${desktop_file_path})\"\n # Set execute permissions on the copied .desktop file\n chmod +x \"${APPLICATIONS_DIR}/${desktop_file_name}\"\n ln -sf \"${APPLICATIONS_DIR}/${desktop_file_name}\" \"${DESKTOP_DIR}/${desktop_file_name}\"\ndone\nupdate-desktop-database \"${APPLICATIONS_DIR}\"\n\n5# Add MIME Type data from XML files to the MIME database.\nMIME_DIR=\"/usr/share/mime\"\nMIME_PACKAGES_DIR=\"${MIME_DIR}/packages\"\nmkdir -p \"${MIME_PACKAGES_DIR}\"\nfor mime_file_path in ${REPO_DIR}/Desktop/*.xml; do\n cp \"${mime_file_path}\" \"${MIME_PACKAGES_DIR}/.\"\ndone\nupdate-mime-database \"${MIME_DIR}\"\n\n6# Add icons\nICON_DIR=\"/usr/share/icons\"\nICON_PACKAGES_DIR=\"${ICON_DIR}/packages\"\nmkdir -p \"${ICON_PACKAGES_DIR}\"\nfor icon_file_path in \"${REPO_DIR}\"/Desktop/*.png; do\n cp \"${icon_file_path}\" \"${ICON_PACKAGES_DIR}/\" || echo \"Failed to copy ${icon_file_path}\"\ndone\nfor icon_file_path in \"${REPO_DIR}\"/Desktop/*.svg; do\n cp \"${icon_file_path}\" \"${ICON_PACKAGES_DIR}/\" || echo \"Failed to copy ${icon_file_path}\"\ndone\ngtk-update-icon-cache \"${ICON_DIR}\"\n\n1\n\nThis is the default local for system applications.\n\n2\n\nCreate the Desktop directory and make sure jovyan can put files there. This is mainly for debugging.\n\n3\n\nSet up the default XDG_DESKTOP_DIR value. This will be copied to the ~.config (by xinitrc).\n\n4\n\nCopy the .desktop file in the Desktop directory into the applications directory and make a symlink to the Desktop directory. The former means that the applications will appear in the menu in xfce4 desktop and the latter means there will be a desktop icon.\n\n5\n\nAdd any mime xml files to the mime folder and update the mime database.\n\n6\n\nAdd any png or svg icon files to the icon folder and update the icon database.",
"crumbs": [
"7Developer notes"
]
+ },
+ {
+ "objectID": "related.html",
+ "href": "related.html",
+ "title": "8 Related Docker Stacks",
+ "section": "",
+ "text": "NASA Openscapes corn and NASA Openscapes py-rocket\nRocker R docker stack\nPangeo geosciences docker stack\nJupyter data science docker stack\ngeocompx\nb-data GPU accelerated docker images and devcontainers",
+ "crumbs": [
+ "8Related Docker Stacks"
+ ]
}
]
\ No newline at end of file
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 6676d66..80abc1b 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -6,15 +6,15 @@
https://nmfs-opensci.github.io/py-rocket-base/customizing.html
- 2024-11-07T20:02:38.909Z
+ 2024-11-13T19:52:16.722Zhttps://nmfs-opensci.github.io/py-rocket-base/configuration_files.html
- 2024-11-07T20:08:18.221Z
+ 2024-11-13T17:17:45.029Zhttps://nmfs-opensci.github.io/py-rocket-base/r-packages.html
- 2024-11-05T16:40:51.958Z
+ 2024-11-13T15:33:31.967Zhttps://nmfs-opensci.github.io/py-rocket-base/desktop.html
@@ -30,6 +30,10 @@
https://nmfs-opensci.github.io/py-rocket-base/developers.html
- 2024-11-06T03:27:24.051Z
+ 2024-11-13T15:31:34.479Z
+
+
+ https://nmfs-opensci.github.io/py-rocket-base/related.html
+ 2024-11-13T15:30:18.666Z
diff --git a/environment.yml b/environment.yml
index e1452f0..5ea7958 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,12 +1,15 @@
-name: py-rocket-base-extras
+name: py-rocket-base
channels:
- conda-forge
- nodefaults
dependencies:
+ # Core JupyterHub packages
+ - python=3.12
+ - pangeo-notebook=2024.11.11
+ - pip
- jupyter-resource-usage
- - jupyterlab-git
- gh-scoped-creds==4.1
# R/RStudio Support
@@ -22,6 +25,7 @@ dependencies:
#- syncthing~=1.22.1
# Extra Jupyter tools
+ - jupyterlab-git
- jupyter-ai
- jupyter-book
- jupyter-offlinenotebook