From 7d762750a9e685b437362d7b5a5a3c08ca4e57db Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:21:19 -0800 Subject: [PATCH 1/8] Update install-desktop.sh --- scripts/install-desktop.sh | 66 ++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/scripts/install-desktop.sh b/scripts/install-desktop.sh index 5652ff6..0fa1882 100644 --- a/scripts/install-desktop.sh +++ b/scripts/install-desktop.sh @@ -10,36 +10,46 @@ if [[ $(id -u) -ne 0 ]]; then exit 1 fi -# Check if a filename argument is provided -if [ -n "$1" ]; then - echo " Warning: Passed-in file '$1' is ignored. Looking for Desktop files in the 'Desktop' directory in your repository." >&2 +# Check if a directory argument is provided +if [ -z "$1" ]; then + echo " Error: No directory provided. Please provide a directory path where the script can find .desktop, .png, and .xml files." + echo " Usage: RUN /pyrocket_scripts/setup-desktop.sh " + exit 1 +fi + +# Set TARGET_DIR to the user-provided argument +TARGET_DIR="$1" + +# Verify that TARGET_DIR exists and is a directory +if [ ! -d "${TARGET_DIR}" ]; then + echo " Error: Provided directory '${TARGET_DIR}' does not exist." + echo " Did you run COPY first to copy the directory into the Docker build context?" + exit 1 +fi + +# Proceed to copy .desktop, .png, and .xml files from the specified directory +echo " Looking for Desktop-related files in '${TARGET_DIR}'..." + +mkdir -p "${REPO_DIR}/Desktop" + +# Find and copy .desktop, .png, and .xml files from TARGET_DIR to ${REPO_DIR}/Desktop +find "${TARGET_DIR}" -type f \( -name "*.desktop" -o -name "*.png" -o -name "*.xml" \) -exec cp {} "${REPO_DIR}/Desktop/" \; + +# Check if any files were copied and provide feedback +if [ "$(ls -A "${REPO_DIR}/Desktop" 2>/dev/null)" ]; then + echo " Successfully copied Desktop-related files to '${REPO_DIR}/Desktop'." +else + echo " Warning: No .desktop, .png, or .xml files found in '${TARGET_DIR}'. Nothing was copied." fi -echo " Checking for ${REPO_DIR}/childimage/..." -if [ -d "${REPO_DIR}/childimage/" ]; then - cd "${REPO_DIR}/childimage/" || exit 1 - - echo " Checking for Desktop directory..." - if test -d "${REPO_DIR}/childimage/Desktop"; then - - echo " ${REPO_DIR}/childimage/Desktop directory found. Proceeding with installation..." - - mkdir -p "${REPO_DIR}/Desktop" - cp -r ${REPO_DIR}/childimage/Desktop/* "${REPO_DIR}/Desktop/" 2>/dev/null - - # Check if desktop.sh exists before executing - if test -f "${REPO_DIR}/desktop.sh"; then - echo " Running ${REPO_DIR}/desktop.sh." - chmod +x "${REPO_DIR}/desktop.sh" - "${REPO_DIR}/desktop.sh" - else - echo " Warning: desktop.sh not found. Skipping execution." - fi - else - echo " No Desktop directory found in ${REPO_DIR}/childimage/. Skipping setup." - fi +# Check if desktop.sh exists before executing +if [ -f "${REPO_DIR}/desktop.sh" ]; then + echo " Running ${REPO_DIR}/desktop.sh to move Desktop files to appropriate directories and register as applications." + chmod +x "${REPO_DIR}/desktop.sh" + "${REPO_DIR}/desktop.sh" else - echo " Directory ${REPO_DIR}/childimage/ does not exist. Skipping script." + echo " Warning: desktop.sh not found. Skipping execution." fi -echo " Success! install-desktop.sh" +echo " Success! setup-desktop.sh" + From 1039d5db278848f69f30764e2f0aa055c81c2cc2 Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:26:44 -0800 Subject: [PATCH 2/8] Update run-postbuild.sh --- scripts/run-postbuild.sh | 57 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/scripts/run-postbuild.sh b/scripts/run-postbuild.sh index dbd63f2..9d93a87 100644 --- a/scripts/run-postbuild.sh +++ b/scripts/run-postbuild.sh @@ -3,33 +3,38 @@ echo "Running run-postbuild.sh" # Check if a filename argument is provided -if [ -n "$1" ]; then - echo " Warning: Passed-in file '$1' to run-postbuild.sh is ignored. Looking for a file named 'postBuild' in your repository." >&2 +if [ -z "$1" ]; then + echo " Error: No script file provided. Please specify a script file to execute." + echo " Usage: RUN /pyrocket_scripts/run-postbuild.sh " + exit 1 fi -echo " Checking for ${REPO_DIR}/childimage/..." -if [ -d "${REPO_DIR}/childimage/" ]; then - cd "${REPO_DIR}/childimage/" || exit 1 - - echo " Checking for postBuild..." - if test -f "postBuild"; then - # Check the user and output which user the script is running as - if [[ $(id -u) -eq 0 ]]; then - echo " Running run-postbuild.sh as root." - else - echo " Running run-postbuild.sh as ${NB_USER}." - fi - - chmod +x postBuild - ./postBuild - rm -rf /tmp/* - rm -rf ${HOME}/.cache ${HOME}/.npm ${HOME}/.yarn - rm -rf ${NB_PYTHON_PREFIX}/share/jupyter/lab/staging - find ${CONDA_DIR} -follow -type f -name '*.a' -delete - find ${CONDA_DIR} -follow -type f -name '*.js.map' -delete - else - echo " No postBuild file found. Skipping execution." - fi +# Set SCRIPT_FILE to the provided argument +SCRIPT_FILE="$1" + +# Verify that SCRIPT_FILE exists and is a file +if [ ! -f "${SCRIPT_FILE}" ]; then + echo " Error: Specified script file '${SCRIPT_FILE}' does not exist." + exit 1 +fi + +# Check the user and output which user the script is running as +if [[ $(id -u) -eq 0 ]]; then + echo " Running run-postbuild.sh as root." else - echo " Directory ${REPO_DIR}/childimage/ does not exist. Skipping script." + echo " Running run-postbuild.sh as ${NB_USER}." fi + +# Make the script executable and run it +chmod +x "${SCRIPT_FILE}" +"${SCRIPT_FILE}" + +# Clean up temporary and cached files +rm -rf /tmp/* +rm -rf ${HOME}/.cache ${HOME}/.npm ${HOME}/.yarn +rm -rf ${NB_PYTHON_PREFIX}/share/jupyter/lab/staging +find ${CONDA_DIR} -follow -type f -name '*.a' -delete +find ${CONDA_DIR} -follow -type f -name '*.js.map' -delete + +echo " Success! run-postbuild.sh" + From 9686400c43b5eac4a86a4123ced4025e62306973 Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:34:28 -0800 Subject: [PATCH 3/8] Update start --- start | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/start b/start index cafc24b..ff8ccad 100644 --- a/start +++ b/start @@ -9,7 +9,16 @@ set -euo pipefail source ${REPO_DIR}/env.txt # End - Set any environment variables here -# Run child start in a subshell to contain its environment -[ -f ${REPO_DIR}/childimage/start ] && ( source ${REPO_DIR}/childimage/start ) - +# 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 "$@" From 56ef79b81dcd761f03861fa11032c8f0966c0b2e Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:41:39 -0800 Subject: [PATCH 4/8] Update setup-start.sh --- scripts/setup-start.sh | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/scripts/setup-start.sh b/scripts/setup-start.sh index 15d1ec5..641679a 100644 --- a/scripts/setup-start.sh +++ b/scripts/setup-start.sh @@ -2,31 +2,37 @@ # Required User: NB_USER # Check if a filename argument is provided -if [ -n "$1" ]; then - echo "Warning: Passed-in file '$1' to setup-start.sh is ignored. Looking for a file named 'start' in your repository." >&2 +if [ -z "$1" ]; then + echo "Error: setup-start.sh requires a script file to be provided as an argument." >&2 + echo "Usage: setup-start.sh " >&2 + exit 1 +fi + +SCRIPT_FILE="$1" + +# Check if the specified file exists +if [ ! -f "$SCRIPT_FILE" ]; then + echo "Error: The file '$SCRIPT_FILE' does not exist." >&2 + echo "Did you use COPY to copy the file into the Docker build context?" + exit 1 fi # Check if running as root and switch to NB_USER if needed if [[ $(id -u) -eq 0 ]]; then - echo "Switching to ${NB_USER} to run start.sh" - exec su "${NB_USER}" -c "/bin/bash $0" # Switches to NB_USER and reruns the script + echo "Switching to ${NB_USER} to run setup-start.sh" + exec su "${NB_USER}" -c "/bin/bash $0 $SCRIPT_FILE" # Pass the script file as an argument fi echo "Running setup-start.sh as ${NB_USER}" -echo " Checking for ${REPO_DIR}/childimage/..." -if [ -d "${REPO_DIR}/childimage/" ]; then - cd "${REPO_DIR}/childimage/" || exit 1 - - echo " Checking for start in ${REPO_DIR}/childimage/..." - if test -f "start"; then - echo " start found in ${REPO_DIR}/childimage/." - chmod +x start - else - echo " No start file found in ${REPO_DIR}/childimage/. Skipping." - fi -else - echo " Directory ${REPO_DIR}/childimage/ does not exist. Skipping." -fi +# Ensure ${REPO_DIR}/childstarts exists +mkdir -p "${REPO_DIR}/childstarts" + +# Copy the passed script to the childstarts directory +echo " Copying '$SCRIPT_FILE' to ${REPO_DIR}/childstarts/" +cp "$SCRIPT_FILE" "${REPO_DIR}/childstarts/" + +# Make the copied script executable +chmod +x "${REPO_DIR}/childstarts/$(basename "$SCRIPT_FILE")" echo " Success! setup-start.sh" From 78f49da6b3b4f76972074b1c3c15ffcbf9bedfaa Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:42:24 -0800 Subject: [PATCH 5/8] Update setup-start.sh --- scripts/setup-start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-start.sh b/scripts/setup-start.sh index 641679a..bc07fad 100644 --- a/scripts/setup-start.sh +++ b/scripts/setup-start.sh @@ -4,7 +4,7 @@ # Check if a filename argument is provided if [ -z "$1" ]; then echo "Error: setup-start.sh requires a script file to be provided as an argument." >&2 - echo "Usage: setup-start.sh " >&2 + echo "Usage: /pyrocket_scripts/setup-start.sh " >&2 exit 1 fi From bbe034564220132de7d564cfb2ab1ac22af46ca2 Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:44:55 -0800 Subject: [PATCH 6/8] Update setup-start.sh --- scripts/setup-start.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/setup-start.sh b/scripts/setup-start.sh index bc07fad..d8e9a2d 100644 --- a/scripts/setup-start.sh +++ b/scripts/setup-start.sh @@ -8,23 +8,23 @@ if [ -z "$1" ]; then exit 1 fi -SCRIPT_FILE="$1" - -# Check if the specified file exists -if [ ! -f "$SCRIPT_FILE" ]; then - echo "Error: The file '$SCRIPT_FILE' does not exist." >&2 - echo "Did you use COPY to copy the file into the Docker build context?" - exit 1 -fi - # Check if running as root and switch to NB_USER if needed if [[ $(id -u) -eq 0 ]]; then echo "Switching to ${NB_USER} to run setup-start.sh" - exec su "${NB_USER}" -c "/bin/bash $0 $SCRIPT_FILE" # Pass the script file as an argument + exec su "${NB_USER}" -c "/bin/bash $0 $1" # Pass the script file as an argument fi echo "Running setup-start.sh as ${NB_USER}" +SCRIPT_FILE="$1" + +# Check if the specified file exists +if [ ! -f "$SCRIPT_FILE" ]; then + echo " Error: The file '$SCRIPT_FILE' does not exist." >&2 + echo " Did you use COPY to copy the file into the Docker build context?" + exit 1 +fi + # Ensure ${REPO_DIR}/childstarts exists mkdir -p "${REPO_DIR}/childstarts" From 114989f679826c97c0629298504f8b7d0101f526 Mon Sep 17 00:00:00 2001 From: Eli Holmes - NOAA Date: Tue, 5 Nov 2024 15:45:59 -0800 Subject: [PATCH 7/8] get rid of childimage --- appendix | 3 --- 1 file changed, 3 deletions(-) diff --git a/appendix b/appendix index 3ea0ac1..7fc349d 100644 --- a/appendix +++ b/appendix @@ -51,9 +51,6 @@ RUN chown -R root:staff /pyrocket_scripts && \ # Convert NB_USER to ENV (from ARG) so that it passes to the child dockerfile ENV NB_USER=${NB_USER} -# Copy the child repo files into childimage so they are available to scripts -ONBUILD COPY --chown=${NB_USER}:${NB_USER} . ${REPO_DIR}/childimage - # Revert to default user and home as pwd USER ${NB_USER} WORKDIR ${HOME} From f0044578a720e5b0be689d2453f7bd296aa49942 Mon Sep 17 00:00:00 2001 From: Eli Holmes Date: Tue, 5 Nov 2024 16:03:44 -0800 Subject: [PATCH 8/8] update and remove refs to childimage and make sure to copy in files --- book/configuration_files.qmd | 27 +++++++++++++++++++------ book/customizing.qmd | 14 +++++++++++-- book/desktop.qmd | 6 ++++-- book/developers.qmd | 25 ++++++++++++++--------- docs/configuration_files.html | 38 ++++++++++++++++++++++++----------- docs/customizing.html | 17 ++++++++++++---- docs/desktop.html | 6 ++++-- docs/developers.html | 32 +++++++++++++++-------------- docs/search.json | 30 +++++++++++++-------------- docs/sitemap.xml | 8 ++++---- 10 files changed, 131 insertions(+), 72 deletions(-) diff --git a/book/configuration_files.qmd b/book/configuration_files.qmd index d63bdc2..619008b 100644 --- a/book/configuration_files.qmd +++ b/book/configuration_files.qmd @@ -7,7 +7,9 @@ The `install-conda-packages.sh` script will install conda packages to the conda Here is the code for your Docker file. You can name the conda package file to something other than `environment.yml`. Make sure your file has `name:`. The name is arbitrary. It is ignored but required for the script. ``` +COPY environment.yml environment.yml RUN /pyrocket_scripts/install-conda-packages.sh environment.yml +RUN rm environment.yml ``` This is a standard format. You can add version pinning. @@ -27,16 +29,21 @@ dependencies: Instead of a list of conda packages (typically called environment.yml), you can use a conda lock file instead. Here is the code for your Docker file. You can name your conda lock file something other than `conda-lock.yml`. + ``` +COPY conda-lock.yml conda-lock.yml RUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml +RUN rm conda-lock.yml ``` -## requirments.txt +## requirements.txt 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`. ``` +COPY requirements.txt requirements.txt RUN /pyrocket_scripts/install-pip-packages.sh requirements.txt +RUN rm requirements.txt ``` requirements.txt @@ -53,7 +60,9 @@ The `install-r-packages.sh` script will run the supplied R script which you can Here 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. ``` +COPY install.R install.R RUN /pyrocket_scripts/install-r-packages.sh install.R +RUN rm install.R ``` install.R example @@ -85,7 +94,9 @@ 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 USER ${NB_USER} ``` @@ -100,10 +111,12 @@ cmocean ## postBuild -The `run-postbuild.sh` script can be run as root or jovyan (`${NB_USER}`). This script does not accept a file name. You need to name your postBuild script `postBuild` and put at the base level with your Docker file. +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. ``` -RUN /pyrocket_scripts/run-postbuild.sh +COPY postBuild postBuild +RUN /pyrocket_scripts/run-postbuild.sh postBuild +RUN rm postBuild ``` postBuild @@ -116,12 +129,14 @@ set -e ## start -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 the end of `${REPO_DIR}/start` so that the Desktop is still setup properly. +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 does not accept a file name. You need to name your start script `start` and put at the base level with your Docker file. +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`. ``` -RUN /pyrocket_scripts/setup-start.sh +COPY start start +RUN /pyrocket_scripts/setup-start.sh start +RUN rm start ``` ## Desktop applications diff --git a/book/customizing.qmd b/book/customizing.qmd index ba05a4b..d4a5e6d 100644 --- a/book/customizing.qmd +++ b/book/customizing.qmd @@ -4,12 +4,16 @@ py-rocket-base is designed to be used in the FROM line of a Dockerfile similar t **Calling the scripts** -The format for calling the pyrocket and rocker scripts is the following. +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 ``` -Note that PATH must be given for the subshell since rocker installation scripts will fail with conda on the path. +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 && \ @@ -54,7 +58,9 @@ 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 ``` environment.yml @@ -81,7 +87,9 @@ 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 ``` install.R @@ -108,7 +116,9 @@ Dockerfile 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 USER ${NB_USER} ``` diff --git a/book/desktop.qmd b/book/desktop.qmd index 1e9e215..607a6bc 100644 --- a/book/desktop.qmd +++ b/book/desktop.qmd @@ -8,11 +8,13 @@ py-rocket-base puts these `.desktop` files in `/usr/share/Desktop`. Typically th ## Adding an application in your child docker image -Use the pyrocket script, `install-desktop.sh` to set up the desktop and move your files to the proper location. Here is the code for your Docker file. This script must be run as root. It does not take any arguments. Instead you include your desktop files in a directory called `Desktop` at the base level with your Docker file. +Use the pyrocket script `install-desktop.sh` to set up the desktop and move your files to the proper location. Provide a path to a directory with your Desktop files as the argument to the script. Here is the code for your Docker file. This script must be run as root. ``` USER root -RUN /pyrocket_scripts/install-desktop.sh +COPY ./Desktop /tmp/Desktop +RUN /pyrocket_scripts/install-desktop.sh /tmp/Desktop +RUN rm -rf /tmp/Desktop USER ${NB_USER} ``` diff --git a/book/developers.qmd b/book/developers.qmd index cb7e7d8..e6e0274 100644 --- a/book/developers.qmd +++ b/book/developers.qmd @@ -166,12 +166,9 @@ RUN chown -R root:staff /pyrocket_scripts && \ # <8> # Convert NB_USER to ENV (from ARG) so that it passes to the child dockerfile ENV NB_USER=${NB_USER} # <9> -# Copy the child repo files into childimage so they are available to scripts -ONBUILD COPY --chown=${NB_USER}:${NB_USER} . ${REPO_DIR}/childimage # <10> - # Revert to default user and home as pwd -USER ${NB_USER} # <11> -WORKDIR ${HOME} # <11> +USER ${NB_USER} # <10> +WORKDIR ${HOME} # <10> ``` 1. Some commands need to be run as root, such as installing linux packages with `apt-get` 2. Set variables. CONDA_ENV is useful for child builds @@ -182,7 +179,6 @@ WORKDIR ${HOME} # <11> 7. `book` and `docs` are the documentation files and are not needed in the image. 8. Copy the pyrocket helper scripts to the `/pyrocket_scripts` directory and set to executable. 9. The `NB_USER` environmental variable is not exported by repo2docker (it is an argument confined to the parent build) but is very useful for child builds. So it is converted to an environmental variable. -10. Copy the child build context (files with the Docker file) into `${REPO_DIR}`. Make sure that jovyan owns the directory. Note, jovyan owns `${REPO_DIR}` (this is set by repo2docker). 11. The parent docker build completes by setting the user to jovyan and the working directory to `${HOME}`. Within a JupyterHub deployment, `${HOME}` will often be re-mapped to the user persistent memory so it is important not to write anything that needs to be persistent to `${HOME}`, for example configuration. You can do this in the `start` script since that runs after the user directory is mapped or you can put configuration files in some place other than `${HOME}`. ## rocker.sh @@ -263,13 +259,22 @@ set -euo pipefail source ${REPO_DIR}/env.txt # <1> # End - Set any environment variables here # <1> -# Run child start in a subshell to contain its environment -[ -f ${REPO_DIR}/childimage/start ] && ( source ${REPO_DIR}/childimage/start ) # <2> - +# 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 # <2> + for script in ${REPO_DIR}/childstart/*; do # <2> + if [ -f "$script" ]; then # <2> + echo "Sourcing script: $script" # <2> + source "$script" || { # <2> + echo "Error: Failed to source $script. Moving on to the next script." # <2> + } # <2> + fi # <2> + done # <2> +fi # <2> exec "$@" ``` 1. In a Docker file so no way to dynamically set environmental variables, so the `env.txt` file with the `export =` are source at start up. -2. Run any child start script in a subshell. Run in a subshell to contain any `set` statements or similar. +2. Run 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. ## desktop.sh diff --git a/docs/configuration_files.html b/docs/configuration_files.html index b40d173..96448d1 100644 --- a/docs/configuration_files.html +++ b/docs/configuration_files.html @@ -176,7 +176,7 @@

Table of contents

  • 2.1 environment.yml
  • 2.2 conda-lock.yml
  • -
  • 2.3 requirments.txt
  • +
  • 2.3 requirements.txt
  • 2.4 install.R
    • 2.4.1 Add R geospatial packages
    • @@ -214,7 +214,9 @@

      2  2.1 environment.yml

      The install-conda-packages.sh script will install conda packages to the conda notebook environment, the user environment in the py-rocket-base image (same as for pangeo and repo2docker images).

      Here is the code for your Docker file. You can name the conda package file to something other than environment.yml. Make sure your file has name:. The name is arbitrary. It is ignored but required for the script.

      -
      RUN /pyrocket_scripts/install-conda-packages.sh environment.yml
      +
      COPY environment.yml environment.yml
      +RUN /pyrocket_scripts/install-conda-packages.sh environment.yml
      +RUN rm environment.yml

      This is a standard format. You can add version pinning.

      environment.yml

      name: optional
      @@ -228,12 +230,16 @@ 

      2.2 conda-lock.yml

      Instead of a list of conda packages (typically called environment.yml), you can use a conda lock file instead.

      Here is the code for your Docker file. You can name your conda lock file something other than conda-lock.yml.

      -
      RUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml
      +
      COPY conda-lock.yml conda-lock.yml
      +RUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml
      +RUN rm conda-lock.yml
      -
      -

      2.3 requirments.txt

      +
      +

      2.3 requirements.txt

      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.

      -
      RUN /pyrocket_scripts/install-pip-packages.sh requirements.txt
      +
      COPY requirements.txt requirements.txt
      +RUN /pyrocket_scripts/install-pip-packages.sh requirements.txt
      +RUN rm requirements.txt

      requirements.txt

      #a package
       harmony-py
      @@ -243,7 +249,9 @@ 

      2.4 install.R

      The install-r-packages.sh script will run the supplied R script which you can use to install R packages to the system library.

      Here 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.

      -
      RUN /pyrocket_scripts/install-r-packages.sh install.R
      +
      COPY install.R install.R
      +RUN /pyrocket_scripts/install-r-packages.sh install.R
      +RUN rm install.R

      install.R example

      # to match rocker/verse:4.4 used in py-rocker-base
       # look up the date that the Rocker image was created and put that
      @@ -266,7 +274,9 @@ 

      2.5 apt.txt

      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
       USER ${NB_USER}

      apt.txt example

      # Some useful stuff
      @@ -277,8 +287,10 @@ 

      2.6 postBuild

      -

      The run-postbuild.sh script can be run as root or jovyan (${NB_USER}). This script does not accept a file name. You need to name your postBuild script postBuild and put at the base level with your Docker file.

      -
      RUN /pyrocket_scripts/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.

      +
      COPY postBuild postBuild
      +RUN /pyrocket_scripts/run-postbuild.sh postBuild
      +RUN rm postBuild

      postBuild

      #!/bin/bash -l
       set -e
      @@ -287,9 +299,11 @@ 

      2.7 start

      -

      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 the end of ${REPO_DIR}/start so that the Desktop is still setup properly.

      -

      The setup-start.sh script does not accept a file name. You need to name your start script start and put at the base level with your Docker file.

      -
      RUN /pyrocket_scripts/setup-start.sh
      +

      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.

      +
      COPY start start
      +RUN /pyrocket_scripts/setup-start.sh start
      +RUN rm start

      2.8 Desktop applications

      diff --git a/docs/customizing.html b/docs/customizing.html index 771b854..dd8d162 100644 --- a/docs/customizing.html +++ b/docs/customizing.html @@ -210,8 +210,11 @@

      1  Dockerfile

      FROM ghcr.io/nmfs-opensci/py-rocket-base:latest
       
      -RUN /pyrocket_scripts/install-r-packages.sh install.R
      +COPY install.R install.R +RUN /pyrocket_scripts/install-r-packages.sh install.R +RUN rm install.R

      install.R

      # to match rocker/verse:4.4 used in py-rocker-base
       # look up the date that the Rocker image was created and put that
      @@ -280,7 +287,9 @@ 

      4 

      4.1 Adding an application in your child docker image

      -

      Use the pyrocket script, install-desktop.sh to set up the desktop and move your files to the proper location. Here is the code for your Docker file. This script must be run as root. It does not take any arguments. Instead you include your desktop files in a directory called Desktop at the base level with your Docker file.

      +

      Use the pyrocket script install-desktop.sh to set up the desktop and move your files to the proper location. Provide a path to a directory with your Desktop files as the argument to the script. Here is the code for your Docker file. This script must be run as root.

      USER root
      -RUN /pyrocket_scripts/install-desktop.sh
      +COPY ./Desktop /tmp/Desktop
      +RUN /pyrocket_scripts/install-desktop.sh  /tmp/Desktop
      +RUN rm -rf /tmp/Desktop
       USER ${NB_USER}

      4.1.1 Create the Desktop directory

      diff --git a/docs/developers.html b/docs/developers.html index cc50a9a..8016a12 100644 --- a/docs/developers.html +++ b/docs/developers.html @@ -393,12 +393,9 @@

      # Convert NB_USER to ENV (from ARG) so that it passes to the child dockerfile ENV NB_USER=${NB_USER} -# Copy the child repo files into childimage so they are available to scripts -ONBUILD COPY --chown=${NB_USER}:${NB_USER} . ${REPO_DIR}/childimage - -# Revert to default user and home as pwd -USER ${NB_USER} -WORKDIR ${HOME}

      +# Revert to default user and home as pwd +USER ${NB_USER} +WORKDIR ${HOME}
      1
      @@ -438,11 +435,7 @@

      10
      -Copy the child build context (files with the Docker file) into ${REPO_DIR}. Make sure that jovyan owns the directory. Note, jovyan owns ${REPO_DIR} (this is set by repo2docker). -
      -
      11
      -
      -The parent docker build completes by setting the user to jovyan and the working directory to ${HOME}. Within a JupyterHub deployment, ${HOME} will often be re-mapped to the user persistent memory so it is important not to write anything that needs to be persistent to ${HOME}, for example configuration. You can do this in the start script since that runs after the user directory is mapped or you can put configuration files in some place other than ${HOME}. +The parent docker build completes by setting the user to jovyan and the working directory to ${HOME}. Within a JupyterHub deployment, ${HOME} will often be re-mapped to the user persistent memory so it is important not to write anything that needs to be persistent to ${HOME}, for example configuration. You can do this in the start script since that runs after the user directory is mapped or you can put configuration files in some place other than ${HOME}.

      @@ -559,9 +552,18 @@

      1
      @@ -570,7 +572,7 @@

      2
      -Run any child start script in a subshell. Run in a subshell to contain any set statements or similar. +Run 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.

      diff --git a/docs/search.json b/docs/search.json index c8041b4..1d3937b 100644 --- a/docs/search.json +++ b/docs/search.json @@ -54,7 +54,7 @@ "href": "customizing.html#examples", "title": "1  Using py-rocket-base", "section": "1.2 Examples", - "text": "1.2 Examples\n\n1.2.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\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml\nenvironment.yml\nname: optional\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\n1.2.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\nRUN /pyrocket_scripts/install-r-packages.sh 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.2.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\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt\nUSER ${NB_USER}\napt.txt\n# a package\nlibgl1-mesa-glx\n\n# Another\nvim\n\n\n1.2.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.2 Examples\n\n1.2.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: optional\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy\n\n\n1.2.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.2.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.2.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": [ "1  Using py-rocket-base" ] @@ -74,7 +74,7 @@ "href": "configuration_files.html#environment.yml", "title": "2  Configuration files", "section": "", - "text": "RUN /pyrocket_scripts/install-conda-packages.sh environment.yml\n\n\nname: optional\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy", + "text": "COPY environment.yml environment.yml\nRUN /pyrocket_scripts/install-conda-packages.sh environment.yml\nRUN rm environment.yml\n\n\nname: optional\nchannels:\n - conda-forge\ndependencies:\n - cmocean\n - numpy", "crumbs": [ "2  Configuration files" ] @@ -84,17 +84,17 @@ "href": "configuration_files.html#conda-lock.yml", "title": "2  Configuration files", "section": "2.2 conda-lock.yml", - "text": "2.2 conda-lock.yml\nInstead of a list of conda packages (typically called environment.yml), you can use a conda lock file instead.\nHere is the code for your Docker file. You can name your conda lock file something other than conda-lock.yml.\nRUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml", + "text": "2.2 conda-lock.yml\nInstead of a list of conda packages (typically called environment.yml), you can use a conda lock file instead.\nHere is the code for your Docker file. You can name your conda lock file something other than conda-lock.yml.\nCOPY conda-lock.yml conda-lock.yml\nRUN /pyrocket_scripts/install-conda-packages.sh conda-lock.yml\nRUN rm conda-lock.yml", "crumbs": [ "2  Configuration files" ] }, { - "objectID": "configuration_files.html#requirments.txt", - "href": "configuration_files.html#requirments.txt", + "objectID": "configuration_files.html#requirements.txt", + "href": "configuration_files.html#requirements.txt", "title": "2  Configuration files", - "section": "2.3 requirments.txt", - "text": "2.3 requirments.txt\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.\nRUN /pyrocket_scripts/install-pip-packages.sh requirements.txt\nrequirements.txt\n#a package\nharmony-py", + "section": "2.3 requirements.txt", + "text": "2.3 requirements.txt\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", "crumbs": [ "2  Configuration files" ] @@ -104,7 +104,7 @@ "href": "configuration_files.html#install.r", "title": "2  Configuration files", "section": "2.4 install.R", - "text": "2.4 install.R\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.\nRUN /pyrocket_scripts/install-r-packages.sh 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.4.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.4 install.R\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.4.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": [ "2  Configuration files" ] @@ -114,7 +114,7 @@ "href": "configuration_files.html#apt.txt", "title": "2  Configuration files", "section": "2.5 apt.txt", - "text": "2.5 apt.txt\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\nRUN /pyrocket_scripts/install-apt-packages.sh apt.txt\nUSER ${NB_USER}\napt.txt example\n# Some useful stuff\ntk-dev\n\n# Add some more\ncmocean", + "text": "2.5 apt.txt\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", "crumbs": [ "2  Configuration files" ] @@ -124,7 +124,7 @@ "href": "configuration_files.html#postbuild", "title": "2  Configuration files", "section": "2.6 postBuild", - "text": "2.6 postBuild\nThe run-postbuild.sh script can be run as root or jovyan (${NB_USER}). This script does not accept a file name. You need to name your postBuild script postBuild and put at the base level with your Docker file.\nRUN /pyrocket_scripts/run-postbuild.sh\npostBuild\n#!/bin/bash -l\nset -e\n\n<bash commands>", + "text": "2.6 postBuild\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>", "crumbs": [ "2  Configuration files" ] @@ -134,7 +134,7 @@ "href": "configuration_files.html#start", "title": "2  Configuration files", "section": "2.7 start", - "text": "2.7 start\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 the end of ${REPO_DIR}/start so that the Desktop is still setup properly.\nThe setup-start.sh script does not accept a file name. You need to name your start script start and put at the base level with your Docker file.\nRUN /pyrocket_scripts/setup-start.sh", + "text": "2.7 start\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", "crumbs": [ "2  Configuration files" ] @@ -164,7 +164,7 @@ "href": "desktop.html", "title": "4  Desktop", "section": "", - "text": "4.1 Adding an application in your child docker image\nUse the pyrocket script, install-desktop.sh to set up the desktop and move your files to the proper location. Here is the code for your Docker file. This script must be run as root. It does not take any arguments. Instead you include your desktop files in a directory called Desktop at the base level with your Docker file.", + "text": "4.1 Adding an application in your child docker image\nUse the pyrocket script install-desktop.sh to set up the desktop and move your files to the proper location. Provide a path to a directory with your Desktop files as the argument to the script. Here is the code for your Docker file. This script must be run as root.", "crumbs": [ "4  Desktop" ] @@ -174,7 +174,7 @@ "href": "desktop.html#adding-an-application-in-your-child-docker-image", "title": "4  Desktop", "section": "", - "text": "USER root\nRUN /pyrocket_scripts/install-desktop.sh\nUSER ${NB_USER}\n\n4.1.1 Create the Desktop directory\nCreate the directory and add the .desktop and optional .png and .xml files. py-rocket-base will move them to the correct places (/usr/share/applications and /usr/share/Desktop, /usr/share/mime/packages and icon locations).\nyour-repo/\n├── Dockerfile\n├── optional extra files\n├── Desktop/\n│ ├── qgis.desktop\n│ ├── qgis.xml\n│ └── qgis.png\n\n4.1.1.1 .desktop file\nThe .desktop file is a configuration file that describes how an application is launched. The required parts are Name, Exec and Type. MimeType specifies what types of files the application can use (optional).\ncdat.desktop\n[Desktop Entry]\nType=Application\nName=CWUtils\nGenericName=CoastWatch Data Analysis Tool\nIcon=/srv/repo/Desktop/cdat.png\nTryExec=cdat\nExec=cdat %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nKeywords=map;globe;\n\n\n4.1.1.2 .xml\nYou can specify the mime types via xml.\n\n\n4.1.1.3 icons\nYou can include a png or svg for the icon. py-rocket-base will place this in /usr/share/icons/hicolor. If you put your icon file in the Desktop directory in your repo, then in your desktop file, use the file name without the extension. If for some reason, your icon is not showing up, use the direct url /srv/repo/Desktop/your-icon-name.png. If the icon cache does not update properly, you have the use the full url.\nIcon=cdat\nYou can also use an absolute file path.\nIf an icon is installed with your application, it will be in the installation files.\nIcon=/srv/conda/envs/notebook/share/qgis/images/icons/qgis-icon-512x512.png\nor if you include an icon in your Desktop directory, it will be in /srv/repo/Desktop.\nIcon=/srv/repo/Desktop/cdat.png\n\n\n\n4.1.2 Install the application\nHow you install the application really varies. Here are 2 examples.\nQGIS\n\nadd qgis to environment.yml\nadd libgl1-mesa-glx to apt.txt\nadd the .desktop file to Desktop directory\n\nqgis.desktop\n# From: https://github.com/qgis/QGIS/blob/ltr-3_28/linux/org.qgis.qgis.desktop.in\n[Desktop Entry]\nType=Application\nName=QGIS Desktop\nGenericName=Geographic Information System\nIcon=/srv/conda/envs/notebook/share/qgis/images/icons/qgis-icon-512x512.png\nTryExec=qgis\nExec=qgis %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nMimeType=application/x-qgis-project;application/x-qgis-project-container;application/x-qgis-layer-settings;application/x-qgis-layer-definition;application/x-qgis-composer-template;image/tiff;image/jpeg;image/jp2;application/x-raster-aig;application/x-raster-ecw;application/x-raster-mrsid;application/x-mapinfo-mif;application/x-esri-shape;application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/geopackage+sqlite3;\nKeywords=map;globe;postgis;wms;wfs;ogc;osgeo;\nStartupWMClass=QGIS3\nCoastWatch Utilities\nAdd this to the docker file to install\nUSER root\n# Install cwutils\nRUN cd /tmp && \\\n wget https://www.star.nesdis.noaa.gov/socd/coastwatch/cwf/cwutils-4_0_0_198-linux-x86_64.tar.gz && \\\n tar -zxf cwutils-4_0_0_198-linux-x86_64.tar.gz && \\\n rm -rf cwutils-4_0_0_198-linux-x86_64.tar.gz\nENV PATH=${PATH}:/tmp/cwutils_4.0.0.198/bin\nENV MANPATH=${MANPATH}:/tmp/cwutils_4.0.0.198/doc/man\nENV INSTALL4J ADD VM PARAMS=-Dsun.java2d.uiScale=2.0\nUSER ${NB_USER}\nAdd this cdat.desktop file to Desktop directory\n[Desktop Entry]\nType=Application\nName=CWUtils\nGenericName=CoastWatch Data Analysis Tool\nIcon=/srv/repo/Desktop/cdat.png\nTryExec=cdat\nExec=cdat %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nKeywords=map;globe;\nAdd cdat.png icon to Desktop directory.", + "text": "USER root\nCOPY ./Desktop /tmp/Desktop\nRUN /pyrocket_scripts/install-desktop.sh /tmp/Desktop\nRUN rm -rf /tmp/Desktop\nUSER ${NB_USER}\n\n4.1.1 Create the Desktop directory\nCreate the directory and add the .desktop and optional .png and .xml files. py-rocket-base will move them to the correct places (/usr/share/applications and /usr/share/Desktop, /usr/share/mime/packages and icon locations).\nyour-repo/\n├── Dockerfile\n├── optional extra files\n├── Desktop/\n│ ├── qgis.desktop\n│ ├── qgis.xml\n│ └── qgis.png\n\n4.1.1.1 .desktop file\nThe .desktop file is a configuration file that describes how an application is launched. The required parts are Name, Exec and Type. MimeType specifies what types of files the application can use (optional).\ncdat.desktop\n[Desktop Entry]\nType=Application\nName=CWUtils\nGenericName=CoastWatch Data Analysis Tool\nIcon=/srv/repo/Desktop/cdat.png\nTryExec=cdat\nExec=cdat %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nKeywords=map;globe;\n\n\n4.1.1.2 .xml\nYou can specify the mime types via xml.\n\n\n4.1.1.3 icons\nYou can include a png or svg for the icon. py-rocket-base will place this in /usr/share/icons/hicolor. If you put your icon file in the Desktop directory in your repo, then in your desktop file, use the file name without the extension. If for some reason, your icon is not showing up, use the direct url /srv/repo/Desktop/your-icon-name.png. If the icon cache does not update properly, you have the use the full url.\nIcon=cdat\nYou can also use an absolute file path.\nIf an icon is installed with your application, it will be in the installation files.\nIcon=/srv/conda/envs/notebook/share/qgis/images/icons/qgis-icon-512x512.png\nor if you include an icon in your Desktop directory, it will be in /srv/repo/Desktop.\nIcon=/srv/repo/Desktop/cdat.png\n\n\n\n4.1.2 Install the application\nHow you install the application really varies. Here are 2 examples.\nQGIS\n\nadd qgis to environment.yml\nadd libgl1-mesa-glx to apt.txt\nadd the .desktop file to Desktop directory\n\nqgis.desktop\n# From: https://github.com/qgis/QGIS/blob/ltr-3_28/linux/org.qgis.qgis.desktop.in\n[Desktop Entry]\nType=Application\nName=QGIS Desktop\nGenericName=Geographic Information System\nIcon=/srv/conda/envs/notebook/share/qgis/images/icons/qgis-icon-512x512.png\nTryExec=qgis\nExec=qgis %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nMimeType=application/x-qgis-project;application/x-qgis-project-container;application/x-qgis-layer-settings;application/x-qgis-layer-definition;application/x-qgis-composer-template;image/tiff;image/jpeg;image/jp2;application/x-raster-aig;application/x-raster-ecw;application/x-raster-mrsid;application/x-mapinfo-mif;application/x-esri-shape;application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/geopackage+sqlite3;\nKeywords=map;globe;postgis;wms;wfs;ogc;osgeo;\nStartupWMClass=QGIS3\nCoastWatch Utilities\nAdd this to the docker file to install\nUSER root\n# Install cwutils\nRUN cd /tmp && \\\n wget https://www.star.nesdis.noaa.gov/socd/coastwatch/cwf/cwutils-4_0_0_198-linux-x86_64.tar.gz && \\\n tar -zxf cwutils-4_0_0_198-linux-x86_64.tar.gz && \\\n rm -rf cwutils-4_0_0_198-linux-x86_64.tar.gz\nENV PATH=${PATH}:/tmp/cwutils_4.0.0.198/bin\nENV MANPATH=${MANPATH}:/tmp/cwutils_4.0.0.198/doc/man\nENV INSTALL4J ADD VM PARAMS=-Dsun.java2d.uiScale=2.0\nUSER ${NB_USER}\nAdd this cdat.desktop file to Desktop directory\n[Desktop Entry]\nType=Application\nName=CWUtils\nGenericName=CoastWatch Data Analysis Tool\nIcon=/srv/repo/Desktop/cdat.png\nTryExec=cdat\nExec=cdat %F\nTerminal=false\nStartupNotify=false\nCategories=Qt;Education;Science;Geography;\nKeywords=map;globe;\nAdd cdat.png icon to Desktop directory.", "crumbs": [ "4  Desktop" ] @@ -344,7 +344,7 @@ "href": "developers.html#appendix", "title": "7  Developer notes", "section": "7.9 appendix", - "text": "7.9 appendix\nThis a long file with many pieces. The pieces are explained below. Click on the number next to code to read about what that code block does.\n1USER root\n\n2# Set env variables\n# This is the default env in repo2docker type images\nENV CONDA_ENV=notebook\n# Tell applications where to open desktop apps\nDISPLAY=\":1.0\"\n\n# Install R, RStudio via Rocker scripts\n3ENV R_VERSION=\"4.4.1\"\nENV R_DOCKERFILE=\"verse_${R_VERSION}\"\n# This is in the rocker script but will not run since ${NB_USER} already exists\n# Needed because rocker scripts set permissions based on the staff group\nRUN usermod -a -G staff \"${NB_USER}\"\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n chmod +x ${REPO_DIR}/rocker.sh && \\\n ${REPO_DIR}/rocker.sh\n\n4# Install linux packages after R installation since the R install scripts get rid of packages\n# The package_list part is reading the file and doing clean-up to just have the list of packages\nRUN package_list=$(grep -v '^\\s*#' ${REPO_DIR}/apt2.txt | grep -v '^\\s*$' | sed 's/\\r//g; s/#.*//; s/^[[:space:]]*//; s/[[:space:]]*$//' | awk '{$1=$1};1') && \\\n apt-get update && \\\n apt-get install --yes --no-install-recommends $package_list && \\\n apt-get autoremove --purge && \\\n apt-get clean && \\\n rm -rf /var/lib/apt/lists/*\n \n# Re-enable man pages disabled in Ubuntu 18 minimal image\n# https://wiki.ubuntu.com/Minimal\n5RUN yes | unminimize\n# NOTE: $NB_PYTHON_PREFIX is the same as $CONDA_PREFIX at run-time.\n# $CONDA_PREFIX isn't available in this context.\n# NOTE: Prepending ensures a working path; if $MANPATH was previously empty,\n# the trailing colon ensures that system paths are searched.\nENV MANPATH=\"${NB_PYTHON_PREFIX}/share/man:${MANPATH}\"\nRUN mandb\n\n# Add custom jupyter config. You can also put config.py files in the same place\n6COPY custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_server_config.d/\nCOPY custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_notebook_config.d/\n\n# Clean up extra files in ${REPO_DIR}\n7RUN rm -rf ${REPO_DIR}/book ${REPO_DIR}/docs\n\n# Copy scripts into /pyrocket_scripts directory in the image\n8RUN mkdir -p /pyrocket_scripts && cp -r ${REPO_DIR}/scripts/* /pyrocket_scripts/\n\n# Set ownership to root and permissions to 755\nRUN chown -R root:staff /pyrocket_scripts && \\\n chmod -R 775 /pyrocket_scripts\n\n# Convert NB_USER to ENV (from ARG) so that it passes to the child dockerfile\n9ENV NB_USER=${NB_USER}\n\n# Copy the child repo files into childimage so they are available to scripts\n10ONBUILD COPY --chown=${NB_USER}:${NB_USER} . ${REPO_DIR}/childimage\n\n# Revert to default user and home as pwd\n11USER ${NB_USER}\nWORKDIR ${HOME}\n\n1\n\nSome commands need to be run as root, such as installing linux packages with apt-get\n\n2\n\nSet variables. CONDA_ENV is useful for child builds\n\n3\n\nThis section runs the script rocker.sh which installs R and RStudio using rocker scripts.\n\n4\n\nThe rocker scripts build R from source and as part of clean up in the script, linux packages are removed that are not needed. repo2docker installs the packages in apt.txt automatically before the code in appendix thus the needed linux packages (which include packages for the Xfce Desktop Environment in \\desktop) are put in apt2.txt. repo2docker will not detect this file and we can install the packages here after R is built. The grep -v etc code is processing apt2.txt and removing comments and blank lines.\n\n5\n\nUbuntu does not have man pages installed by default. These lines activate man so users have the common help files.\n\n6\n\nThis is some custom jupyter config to allow hidden files to be listed in the folder browser.\n\n7\n\nbook and docs are the documentation files and are not needed in the image.\n\n8\n\nCopy the pyrocket helper scripts to the /pyrocket_scripts directory and set to executable.\n\n9\n\nThe NB_USER environmental variable is not exported by repo2docker (it is an argument confined to the parent build) but is very useful for child builds. So it is converted to an environmental variable.\n\n10\n\nCopy the child build context (files with the Docker file) into ${REPO_DIR}. Make sure that jovyan owns the directory. Note, jovyan owns ${REPO_DIR} (this is set by repo2docker).\n\n11\n\nThe parent docker build completes by setting the user to jovyan and the working directory to ${HOME}. Within a JupyterHub deployment, ${HOME} will often be re-mapped to the user persistent memory so it is important not to write anything that needs to be persistent to ${HOME}, for example configuration. You can do this in the start script since that runs after the user directory is mapped or you can put configuration files in some place other than ${HOME}.", + "text": "7.9 appendix\nThis a long file with many pieces. The pieces are explained below. Click on the number next to code to read about what that code block does.\n1USER root\n\n2# Set env variables\n# This is the default env in repo2docker type images\nENV CONDA_ENV=notebook\n# Tell applications where to open desktop apps\nDISPLAY=\":1.0\"\n\n# Install R, RStudio via Rocker scripts\n3ENV R_VERSION=\"4.4.1\"\nENV R_DOCKERFILE=\"verse_${R_VERSION}\"\n# This is in the rocker script but will not run since ${NB_USER} already exists\n# Needed because rocker scripts set permissions based on the staff group\nRUN usermod -a -G staff \"${NB_USER}\"\nRUN PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && \\\n chmod +x ${REPO_DIR}/rocker.sh && \\\n ${REPO_DIR}/rocker.sh\n\n4# Install linux packages after R installation since the R install scripts get rid of packages\n# The package_list part is reading the file and doing clean-up to just have the list of packages\nRUN package_list=$(grep -v '^\\s*#' ${REPO_DIR}/apt2.txt | grep -v '^\\s*$' | sed 's/\\r//g; s/#.*//; s/^[[:space:]]*//; s/[[:space:]]*$//' | awk '{$1=$1};1') && \\\n apt-get update && \\\n apt-get install --yes --no-install-recommends $package_list && \\\n apt-get autoremove --purge && \\\n apt-get clean && \\\n rm -rf /var/lib/apt/lists/*\n \n# Re-enable man pages disabled in Ubuntu 18 minimal image\n# https://wiki.ubuntu.com/Minimal\n5RUN yes | unminimize\n# NOTE: $NB_PYTHON_PREFIX is the same as $CONDA_PREFIX at run-time.\n# $CONDA_PREFIX isn't available in this context.\n# NOTE: Prepending ensures a working path; if $MANPATH was previously empty,\n# the trailing colon ensures that system paths are searched.\nENV MANPATH=\"${NB_PYTHON_PREFIX}/share/man:${MANPATH}\"\nRUN mandb\n\n# Add custom jupyter config. You can also put config.py files in the same place\n6COPY custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_server_config.d/\nCOPY custom_jupyter_server_config.json ${NB_PYTHON_PREFIX}/etc/jupyter/jupyter_notebook_config.d/\n\n# Clean up extra files in ${REPO_DIR}\n7RUN rm -rf ${REPO_DIR}/book ${REPO_DIR}/docs\n\n# Copy scripts into /pyrocket_scripts directory in the image\n8RUN mkdir -p /pyrocket_scripts && cp -r ${REPO_DIR}/scripts/* /pyrocket_scripts/\n\n# Set ownership to root and permissions to 755\nRUN chown -R root:staff /pyrocket_scripts && \\\n chmod -R 775 /pyrocket_scripts\n\n# Convert NB_USER to ENV (from ARG) so that it passes to the child dockerfile\n9ENV NB_USER=${NB_USER}\n\n# Revert to default user and home as pwd\n10USER ${NB_USER}\nWORKDIR ${HOME}\n\n1\n\nSome commands need to be run as root, such as installing linux packages with apt-get\n\n2\n\nSet variables. CONDA_ENV is useful for child builds\n\n3\n\nThis section runs the script rocker.sh which installs R and RStudio using rocker scripts.\n\n4\n\nThe rocker scripts build R from source and as part of clean up in the script, linux packages are removed that are not needed. repo2docker installs the packages in apt.txt automatically before the code in appendix thus the needed linux packages (which include packages for the Xfce Desktop Environment in \\desktop) are put in apt2.txt. repo2docker will not detect this file and we can install the packages here after R is built. The grep -v etc code is processing apt2.txt and removing comments and blank lines.\n\n5\n\nUbuntu does not have man pages installed by default. These lines activate man so users have the common help files.\n\n6\n\nThis is some custom jupyter config to allow hidden files to be listed in the folder browser.\n\n7\n\nbook and docs are the documentation files and are not needed in the image.\n\n8\n\nCopy the pyrocket helper scripts to the /pyrocket_scripts directory and set to executable.\n\n9\n\nThe NB_USER environmental variable is not exported by repo2docker (it is an argument confined to the parent build) but is very useful for child builds. So it is converted to an environmental variable.\n\n10\n\nThe parent docker build completes by setting the user to jovyan and the working directory to ${HOME}. Within a JupyterHub deployment, ${HOME} will often be re-mapped to the user persistent memory so it is important not to write anything that needs to be persistent to ${HOME}, for example configuration. You can do this in the start script since that runs after the user directory is mapped or you can put configuration files in some place other than ${HOME}.", "crumbs": [ "7  Developer notes" ] @@ -364,7 +364,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 in a subshell to contain its environment\n[ -f ${REPO_DIR}/childimage/start ] && ( source ${REPO_DIR}/childimage/start )\n\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.", + "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.", "crumbs": [ "7  Developer notes" ] diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 6aeea4e..71500a5 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -6,11 +6,11 @@ https://nmfs-opensci.github.io/py-rocket-base/customizing.html - 2024-11-05T20:04:37.424Z + 2024-11-05T23:54:27.487Z https://nmfs-opensci.github.io/py-rocket-base/configuration_files.html - 2024-11-05T20:04:37.424Z + 2024-11-05T23:59:53.425Z https://nmfs-opensci.github.io/py-rocket-base/r-packages.html @@ -18,7 +18,7 @@ https://nmfs-opensci.github.io/py-rocket-base/desktop.html - 2024-11-05T20:04:37.424Z + 2024-11-06T00:02:10.240Z https://nmfs-opensci.github.io/py-rocket-base/tex.html @@ -30,6 +30,6 @@ https://nmfs-opensci.github.io/py-rocket-base/developers.html - 2024-11-05T20:15:25.429Z + 2024-11-05T23:49:08.413Z