diff --git a/workspaces/r-workspace/Dockerfile b/workspaces/r-workspace/Dockerfile new file mode 100644 index 0000000..d208459 --- /dev/null +++ b/workspaces/r-workspace/Dockerfile @@ -0,0 +1,50 @@ +ARG docker_registry=docker.io/alnoda +ARG image_tag=2.0 + +FROM ${docker_registry}/base-workspace:${image_tag} +USER root + +COPY mkdocs /home/docs +COPY docs/getting-started.md /home/docs/docs/getting-started.md +COPY supervisord-rstudio.conf /etc/supervisord/ + +### R +ENV R_VERSION=4.2.0 \ + R_HOME=/usr/local/lib/R \ + TZ=Etc/UTC \ + CRAN=https://packagemanager.rstudio.com/cran/__linux__/focal/latest \ + LANG=en_US.UTF-8 \ + S6_VERSION=v2.1.0.2 \ + RSTUDIO_VERSION=2022.02.2+485 \ + DEFAULT_USER=abc \ + PANDOC_VERSION=default \ + RSTUDIO_SERVER_HOST=0.0.0.0 + +ENV PATH=/usr/local/bin/:$PATH +ENV PATH=/usr/lib/rstudio-server/bin:$PATH + +RUN cd /tmp && git clone https://github.com/rocker-org/rocker-versioned2.git \ + && mv /tmp/rocker-versioned2/scripts /rocker_scripts \ + && bash /rocker_scripts/install_R_source.sh \ + && bash /rocker_scripts/setup_R.sh \ + && mkdir /var/log/rstudio \ + && bash /rocker_scripts/install_rstudio.sh \ + && rstudio-server stop || true \ + && echo "------------------------------------------------------ user" \ + && chown -R abc /etc/rstudio \ + && chown -R abc /usr/lib/rstudio-server \ + && chown -R abc /var/lib/rstudio-server \ + && chown -R abc /var/log/rstudio \ + && chown -R abc /usr/local/lib/R \ + && mkdir /home/abc/.rserver && chown -R abc /home/abc/.rserver \ + && find /home -type d | xargs -I{} chown -R abc {} \ + && find /home -type f | xargs -I{} chown abc {} + +USER abc + +COPY rstudio/database.conf /home/abc/.rserver +ENV USER=abc + +RUN echo "------------------------------------------------------ some cleaning because Rstudio workdir is /home/abc/" \ + && rm -rf /home/abc/installed-python-packages \ + && rm -rf /home/abc/utils diff --git a/workspaces/r-workspace/README.md b/workspaces/r-workspace/README.md new file mode 100644 index 0000000..4d6b7ba --- /dev/null +++ b/workspaces/r-workspace/README.md @@ -0,0 +1,61 @@ +

+ Alnoda logo +

+ +# R workspace + +Docker image with R and browser-based RStudio version. + +

+ Collage +

+ +## Why this images + +1. If you need self-hosted remote development environment. +2. If you want to be one terminal command away from coding in R. +3. if you need isolated environment where you can work with R without polluting main environment. + +## Start + +``` +docker run --name space-1 -d -p 8020-8035:8020-8035 alnoda/r-workspace +``` + +and open [localhost:8020](http://localhost:8020) in browser. + +## Features + +- [R](https://www.r-project.org/) +- RStudio server + +**Dev tools:** + +- [**Code-server**](https://github.com/cdr/code-server) - open source version of popular Visual Studio Code IDE. Codeserver has +VS-Code extensions and works in browser. +- [**Terminal**](https://github.com/tsl0922/ttyd) - secure browser-based terminal. +- [**FileBrowser**](https://github.com/filebrowser/filebrowser) - manage files and folders inside the workspace, and exchange data between local environment and the workspace +- [**Cronicle**](https://github.com/jhuckaby/Cronicle) - task scheduler and runner, with a web based front-end UI. It handles both scheduled, repeating and on-demand jobs, targeting any number of worker servers, with real-time stats and live log viewer. +- [**Static File Server**](https://github.com/vercel/serve) - view any static html sites as easy as if you do it on your local machine. Serve static websites easily. +- [**Ungit**](https://github.com/FredrikNoren/ungit) - rings user friendliness to git without sacrificing the versatility of it. +- [**MkDocs**](https://squidfunk.github.io/mkdocs-material/) - create awesome documentation for your project with only markdown. +- [**Midnight Commander**](https://midnight-commander.org/) - Feature rich visual file manager with internal text viewer and editor. +- [**Process Monitor**](https://htop.dev/) - Monitor running process and resource utilization. +- Quicklaunch UI with getting started tutorial + +Image is built from **Ubuntu 20.4** with the additional CLI apps + +- [Zsh](https://www.zsh.org/), [Oh my Zsh](https://ohmyz.sh/) +- Python 3, Pip +- Node/nodeenv +- curl, wget, telnet, jq +- **Git:** git, git-flow, lazygit +- **File browsers:** mc, xplr +- **Text editors:** nano, vim, mcedit +- **System monitors:** ncdu, htop, glances, vizex +- **Process Control:** supervisord +- **Job scheduler:** cron + +## Docs +See our guides on [**getting started**](docs/getting-started.md) and [**advanced features**](../ubuntu-workspace/docs/workspaces.md). + diff --git a/workspaces/r-workspace/docs/getting-started.md b/workspaces/r-workspace/docs/getting-started.md new file mode 100644 index 0000000..d90b1e1 --- /dev/null +++ b/workspaces/r-workspace/docs/getting-started.md @@ -0,0 +1,69 @@ +# Getting started + +## Intro + +To start, open Quickstart page [localhost:8020](http://localhost:8020/) for quick access to all the tools + +From the quicklaunch page you can open workspace tools, such as code editor or terminal + +
+ Demo: Workspace UI +
+ +

+ wid-ui.png +

+ +This workspace includes RStudio Server, a browser-based IDE for R. + +

+ RStudio +

+ +Workspace has full-size browser-base terminal + +

+ Base-Workspace terminal +

+ + +## R + +Open terminal, and check R version + +``` +R --version +``` + +

+ RStudio +

+ +To start R shell, simply execute `R` in the terminal + +

+ RStudio +

+ +If you want to install packages from the terminal, execute + +``` +Rscript -e 'install.packages("drat", repos="https://cloud.r-project.org")' +``` + + +## Examples + +CUse terminal to clone example repository + +``` +cd /home/abc +git clone https://github.com/dmarcelinobr/r-code-examples.git +``` + +Open Rstudio, and try some examples, i.e. `2d-density-plot.r`. Evaluate code, agree to install dependencies + +

+ RStudio +

+ diff --git a/workspaces/r-workspace/img/2d-density-plot.png b/workspaces/r-workspace/img/2d-density-plot.png new file mode 100644 index 0000000..8e48933 Binary files /dev/null and b/workspaces/r-workspace/img/2d-density-plot.png differ diff --git a/workspaces/r-workspace/img/RStudio.png b/workspaces/r-workspace/img/RStudio.png new file mode 100644 index 0000000..907ed7c Binary files /dev/null and b/workspaces/r-workspace/img/RStudio.png differ diff --git a/workspaces/r-workspace/img/r-shell.png b/workspaces/r-workspace/img/r-shell.png new file mode 100644 index 0000000..e17e055 Binary files /dev/null and b/workspaces/r-workspace/img/r-shell.png differ diff --git a/workspaces/r-workspace/img/r-version.png b/workspaces/r-workspace/img/r-version.png new file mode 100644 index 0000000..bc870de Binary files /dev/null and b/workspaces/r-workspace/img/r-version.png differ diff --git a/workspaces/r-workspace/mkdocs/.gitignore b/workspaces/r-workspace/mkdocs/.gitignore new file mode 100644 index 0000000..c9bd680 --- /dev/null +++ b/workspaces/r-workspace/mkdocs/.gitignore @@ -0,0 +1,68 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo + +# Scrapy stuff: +.scrapy + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# virtualenv +venv/ +ENV/ + +# MkDocs documentation +site/ \ No newline at end of file diff --git a/workspaces/r-workspace/mkdocs/docs/README.md b/workspaces/r-workspace/mkdocs/docs/README.md new file mode 100644 index 0000000..f4a79b6 --- /dev/null +++ b/workspaces/r-workspace/mkdocs/docs/README.md @@ -0,0 +1,130 @@ + + + +{% + set tools = [ + { + "env": "IDE_URL", + "name": "RStudio", + "image": "assets/home/RStudio.png", + "description": "Best integrated development environment for R" + }, + { + "env": "TERMINAL_URL", + "name": "Terminal", + "image": "assets/home/Terminal.png", + "description": "Full-fledged WEB-based Command Line Interface" + }, + { + "env": "FILEBROWSER_URL", + "name": "File Browser", + "image": "assets/home/Filebrowser.png", + "description": "Browse, upload and download files and folders to and from the Workspace" + }, + { + "env": "CRONICLE_URL", + "name": "Cronicle", + "image": "assets/home/Cronicle.jpg", + "description": "Schedule jobs, manage schedules, observe and monitor executions (user/pass - admin/admin)" + }, + { + "env": "UNGIT_URL", + "name": "Ungit", + "image": "assets/home/Ungit.jpg", + "description": "Manage Git repositories and work flow using beautiful UI" + }, + { + "env": "STATICFS_URL", + "name": "Static File Server", + "image": "assets/home/Static-server.png", + "description": "Serve any static websites like a breeze" + }, + { + "env": "MC_URL", + "name": "M.Commander", + "image": "assets/home/MC.jpg", + "description": "Feature rich visual file manager with internal text viewer and editor" + }, + { + "env": "HTOP_URL", + "name": "Resource monitor", + "image": "assets/home/Htop.jpg", + "description": "Monitor running process and resource utilization" + } + ] +%} + + +
+ {% for tool in tools %} + {% set tool_url = get_tool_url(tool.env) %} +
+ + + + +
{{ tool.name }}
+
+
{{ tool.description }}
+
+ {% endfor %} +
+ + + + + diff --git a/workspaces/r-workspace/mkdocs/docs/assets/Alnoda-logo.svg b/workspaces/r-workspace/mkdocs/docs/assets/Alnoda-logo.svg new file mode 100644 index 0000000..db53f4c --- /dev/null +++ b/workspaces/r-workspace/mkdocs/docs/assets/Alnoda-logo.svg @@ -0,0 +1,70 @@ + + + +Created with Fabric.js 3.6.3 + + + + + \ No newline at end of file diff --git a/workspaces/r-workspace/mkdocs/docs/assets/favicon.ico b/workspaces/r-workspace/mkdocs/docs/assets/favicon.ico new file mode 100644 index 0000000..2c8bed5 Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/favicon.ico differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Cronicle.jpg b/workspaces/r-workspace/mkdocs/docs/assets/home/Cronicle.jpg new file mode 100644 index 0000000..03c56be Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Cronicle.jpg differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Filebrowser.png b/workspaces/r-workspace/mkdocs/docs/assets/home/Filebrowser.png new file mode 100644 index 0000000..f4b5700 Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Filebrowser.png differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Htop.jpg b/workspaces/r-workspace/mkdocs/docs/assets/home/Htop.jpg new file mode 100644 index 0000000..994bc13 Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Htop.jpg differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/IDE.jpg b/workspaces/r-workspace/mkdocs/docs/assets/home/IDE.jpg new file mode 100644 index 0000000..0330ae5 Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/IDE.jpg differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/MC.jpg b/workspaces/r-workspace/mkdocs/docs/assets/home/MC.jpg new file mode 100644 index 0000000..9b0a92a Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/MC.jpg differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/MkDocs.png b/workspaces/r-workspace/mkdocs/docs/assets/home/MkDocs.png new file mode 100755 index 0000000..333cb6c Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/MkDocs.png differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/RStudio.png b/workspaces/r-workspace/mkdocs/docs/assets/home/RStudio.png new file mode 100644 index 0000000..907ed7c Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/RStudio.png differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Static-server.png b/workspaces/r-workspace/mkdocs/docs/assets/home/Static-server.png new file mode 100644 index 0000000..4d8fa6b Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Static-server.png differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Terminal.png b/workspaces/r-workspace/mkdocs/docs/assets/home/Terminal.png new file mode 100644 index 0000000..9ccb947 Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Terminal.png differ diff --git a/workspaces/r-workspace/mkdocs/docs/assets/home/Ungit.jpg b/workspaces/r-workspace/mkdocs/docs/assets/home/Ungit.jpg new file mode 100644 index 0000000..c09223c Binary files /dev/null and b/workspaces/r-workspace/mkdocs/docs/assets/home/Ungit.jpg differ diff --git a/workspaces/r-workspace/mkdocs/docs/javascript/config.js b/workspaces/r-workspace/mkdocs/docs/javascript/config.js new file mode 100644 index 0000000..06dbf38 --- /dev/null +++ b/workspaces/r-workspace/mkdocs/docs/javascript/config.js @@ -0,0 +1,16 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.typesetPromise() +}) diff --git a/workspaces/r-workspace/mkdocs/macros/helpers.py b/workspaces/r-workspace/mkdocs/macros/helpers.py new file mode 100644 index 0000000..11e499b --- /dev/null +++ b/workspaces/r-workspace/mkdocs/macros/helpers.py @@ -0,0 +1,57 @@ +""" +Basic example of a Mkdocs-macros module. +Include this {{ macros_info() }} in any page to get complete macro info +""" +import os + +port_increments = { + "DOCS_URL": 0, + "FILEBROWSER_URL": 1, + "STATICFS_URL": 2, + "CRONICLE_URL": 3, + "UNGIT_URL": 4, + "IDE_URL": 5, + "TERMINAL_URL": 6, + "MC_URL": 7, + "HTOP_URL": 8 + } + +# this function name should not be changed +def define_env(env): + """ + This is the hook for defining variables, macros and filters + - variables: the dictionary that contains the environment variables + - macro: a decorator function, to declare a macro. + - filter: a function with one of more arguments, + used to perform a transformation + """ + @env.macro + def get_tool_url(env): + try: + return os.environ[env] + except: + # Get host + host = "localhost" + try: + host = os.environ["WRK_HOST"] + except: + pass + proto = "http" + try: + proto = os.environ["WRK_PROTO"] + except: + pass + # Entry port - port relative to which other ports will be calculated + entry_port = 8020 + try: + entry_port = int(os.environ["ENTRY_PORT"]) + except: + pass + # Assign port + try: + port = port_increments[env] + entry_port + except: + port = 80 + return f"{proto}://{host}:{port}" + + \ No newline at end of file diff --git a/workspaces/r-workspace/mkdocs/mkdocs.yml b/workspaces/r-workspace/mkdocs/mkdocs.yml new file mode 100644 index 0000000..4de1685 --- /dev/null +++ b/workspaces/r-workspace/mkdocs/mkdocs.yml @@ -0,0 +1,69 @@ +# =========================================================== +# NAVIGATION +# =========================================================== + +nav: + - Home: README.md + - Get started: getting-started.md + + +# =========================================================== +# CONFIGURATION +# =========================================================== + +site_name: My Workspace +repo_url: https://github.com/bluxmit/alnoda-workspaces +site_url: https://alnoda.org +edit_uri: "" + +# =========================================================== +# APPEARANCE +# =========================================================== + +theme: + name: 'material' + favicon: 'assets/favicon.ico' + logo: 'assets/Alnoda-logo.svg' + custom_dir: overrides + icon: + repo: fontawesome/brands/git-alt + features: + - navigation.instant + palette: + - scheme: default + toggle: + icon: material/toggle-switch-off-outline + name: Switch to light mode + primary: brown + accent: deep orange + - scheme: slate + toggle: + icon: material/toggle-switch + name: Switch to dark mode + primary: orange + accent: red + +extra: + # Link to open when your logo is clicked + homepage: https://alnoda.org + host_url: http://localhost + +plugins: + - search + # Enable Macros and jinja2 templates + - macros: + module_name: macros/helpers + + +extra_javascript: + - javascripts/config.js + - https://polyfill.io/v3/polyfill.min.js?features=es6 + + + + + + + + + diff --git a/workspaces/r-workspace/mkdocs/overrides/partials/footer.html b/workspaces/r-workspace/mkdocs/overrides/partials/footer.html new file mode 100644 index 0000000..e69de29 diff --git a/workspaces/r-workspace/rstudio/database.conf b/workspaces/r-workspace/rstudio/database.conf new file mode 100644 index 0000000..4651388 --- /dev/null +++ b/workspaces/r-workspace/rstudio/database.conf @@ -0,0 +1,6 @@ +# ================================================================================================================= +# sqlite configuration +# ================================================================================================================= +# Specifies the database provider to use +provider=sqlite +directory=/home/abc/.rserver/ diff --git a/workspaces/r-workspace/scripts/install_R_source.sh b/workspaces/r-workspace/scripts/install_R_source.sh new file mode 100644 index 0000000..26d2675 --- /dev/null +++ b/workspaces/r-workspace/scripts/install_R_source.sh @@ -0,0 +1,164 @@ +#!/bin/bash + +## Install R from source. +## +## In order of preference, first argument of the script, the R_VERSION variable. +## ex. latest, devel, patched, 4.0.0 +## +## 'devel' means the prerelease development version (Latest daily snapshot of development version). +## 'patched' means the prerelease patched version (Latest daily snapshot of patched version). + +set -e + +R_VERSION=${1:-${R_VERSION:-"latest"}} + +apt-get update +apt-get -y install locales lsb-release + +## Configure default locale +LANG=${LANG:-"en_US.UTF-8"} +/usr/sbin/locale-gen --lang "${LANG}" +/usr/sbin/update-locale --reset LANG="${LANG}" + +UBUNTU_VERSION=$(lsb_release -sc) + +export DEBIAN_FRONTEND=noninteractive + +R_HOME=${R_HOME:-"/usr/local/lib/R"} + +READLINE_VERSION=8 +if [ "${UBUNTU_VERSION}" == "bionic" ]; then + READLINE_VERSION=7 +fi + +apt-get install -y --no-install-recommends \ + bash-completion \ + ca-certificates \ + devscripts \ + file \ + fonts-texgyre \ + g++ \ + gfortran \ + gsfonts \ + libblas-dev \ + libbz2-* \ + libcurl4 \ + libicu* \ + liblapack-dev \ + libpcre2* \ + libjpeg-turbo* \ + libpangocairo-* \ + libpng16* \ + "libreadline${READLINE_VERSION}" \ + libtiff* \ + liblzma* \ + make \ + unzip \ + zip \ + zlib1g + +BUILDDEPS="curl \ + default-jdk \ + libbz2-dev \ + libcairo2-dev \ + libcurl4-openssl-dev \ + libpango1.0-dev \ + libjpeg-dev \ + libicu-dev \ + libpcre2-dev \ + libpng-dev \ + libreadline-dev \ + libtiff5-dev \ + liblzma-dev \ + libx11-dev \ + libxt-dev \ + perl \ + rsync \ + subversion \ + tcl-dev \ + tk-dev \ + texinfo \ + texlive-extra-utils \ + texlive-fonts-recommended \ + texlive-fonts-extra \ + texlive-latex-recommended \ + texlive-latex-extra \ + x11proto-core-dev \ + xauth \ + xfonts-base \ + xvfb \ + wget \ + zlib1g-dev" + +# shellcheck disable=SC2086 +apt-get install -y --no-install-recommends ${BUILDDEPS} + +## Download R from 0-Cloud CRAN mirror or CRAN +function download_r_src() { + wget "https://cloud.r-project.org/src/$1" -O "R.tar.gz" || + wget "https://cran.r-project.org/src/$1" -O "R.tar.gz" +} + +if [ "$R_VERSION" == "devel" ]; then + download_r_src "base-prerelease/R-devel.tar.gz" +elif [ "$R_VERSION" == "patched" ]; then + download_r_src "base-prerelease/R-latest.tar.gz" +elif [ "$R_VERSION" == "latest" ]; then + download_r_src "base/R-latest.tar.gz" +else + download_r_src "base/R-${R_VERSION%%.*}/R-${R_VERSION}.tar.gz" +fi + +tar xzf "R.tar.gz" +cd R-*/ + +R_PAPERSIZE=letter \ + R_BATCHSAVE="--no-save --no-restore" \ + R_BROWSER=xdg-open \ + PAGER=/usr/bin/pager \ + PERL=/usr/bin/perl \ + R_UNZIPCMD=/usr/bin/unzip \ + R_ZIPCMD=/usr/bin/zip \ + R_PRINTCMD=/usr/bin/lpr \ + LIBnn=lib \ + AWK=/usr/bin/awk \ + CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g" \ + CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g" \ + ./configure --enable-R-shlib \ + --enable-memory-profiling \ + --with-readline \ + --with-blas \ + --with-lapack \ + --with-tcltk \ + --with-recommended-packages + +make +make install +make clean + +## Add a library directory (for user-installed packages) +mkdir -p "${R_HOME}/site-library" +chown root:staff "${R_HOME}/site-library" +chmod g+ws "${R_HOME}/site-library" + +## Fix library path +echo "R_LIBS=\${R_LIBS-'${R_HOME}/site-library:${R_HOME}/library'}" >>"${R_HOME}/etc/Renviron.site" + +## Clean up from R source install +cd .. +rm -rf /tmp/* +rm -rf R-*/ +rm -rf "R.tar.gz" + +# shellcheck disable=SC2086 +apt-get remove --purge -y ${BUILDDEPS} +apt-get autoremove -y +apt-get autoclean -y +rm -rf /var/lib/apt/lists/* + +# Check the R info +echo -e "Check the R info...\n" + +R -q -e "sessionInfo()" + +echo -e "\nInstall R from source, done!" \ No newline at end of file diff --git a/workspaces/r-workspace/scripts/install_rstudio.sh b/workspaces/r-workspace/scripts/install_rstudio.sh new file mode 100644 index 0000000..679bc9c --- /dev/null +++ b/workspaces/r-workspace/scripts/install_rstudio.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +## Download and install RStudio server & dependencies uses. +## +## In order of preference, first argument of the script, the RSTUDIO_VERSION variable. +## ex. stable, preview, daily, 1.3.959, 2021.09.1+372, 2021.09.1-372, 2022.06.0-daily+11 + +set -e + +RSTUDIO_VERSION=${1:-${RSTUDIO_VERSION:-"stable"}} +DEFAULT_USER=${DEFAULT_USER:-"rstudio"} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + lsb-release \ + file \ + git \ + libapparmor1 \ + libclang-dev \ + libcurl4-openssl-dev \ + libedit2 \ + libobjc4 \ + libssl-dev \ + libpq5 \ + lsb-release \ + psmisc \ + procps \ + python-setuptools \ + pwgen \ + sudo \ + wget + +ARCH=$(dpkg --print-architecture) +UBUNTU_VERSION=$(lsb_release -sc) + +# install s6 supervisor +/rocker_scripts/install_s6init.sh + +## Download RStudio Server for Ubuntu 18+ +DOWNLOAD_FILE=rstudio-server.deb + +if [ "$RSTUDIO_VERSION" = "latest" ]; then + RSTUDIO_VERSION="stable" +fi + +if [ "$UBUNTU_VERSION" = "focal" ]; then + UBUNTU_VERSION="bionic" +fi + +if [ "$RSTUDIO_VERSION" = "stable" ] || [ "$RSTUDIO_VERSION" = "preview" ] || [ "$RSTUDIO_VERSION" = "daily" ]; then + wget "https://rstudio.org/download/latest/${RSTUDIO_VERSION}/server/${UBUNTU_VERSION}/rstudio-server-latest-${ARCH}.deb" -O "$DOWNLOAD_FILE" +else + wget "https://download2.rstudio.org/server/${UBUNTU_VERSION}/${ARCH}/rstudio-server-${RSTUDIO_VERSION/"+"/"-"}-${ARCH}.deb" -O "$DOWNLOAD_FILE" || + wget "https://s3.amazonaws.com/rstudio-ide-build/server/${UBUNTU_VERSION}/${ARCH}/rstudio-server-${RSTUDIO_VERSION/"+"/"-"}-${ARCH}.deb" -O "$DOWNLOAD_FILE" +fi + +dpkg -i "$DOWNLOAD_FILE" +rm "$DOWNLOAD_FILE" + +# https://github.com/rocker-org/rocker-versioned2/issues/137 +rm -f /var/lib/rstudio-server/secure-cookie-key + +## RStudio wants an /etc/R, will populate from $R_HOME/etc +mkdir -p /etc/R + +## Make RStudio compatible with case when R is built from source +## (and thus is at /usr/local/bin/R), because RStudio doesn't obey +## path if a user apt-get installs a package +R_BIN=$(which R) +echo "rsession-which-r=${R_BIN}" >/etc/rstudio/rserver.conf +## use more robust file locking to avoid errors when using shared volumes: +echo "lock-type=advisory" >/etc/rstudio/file-locks + +## Prepare optional configuration file to disable authentication +## To de-activate authentication, `disable_auth_rserver.conf` script +## will just need to be overwrite /etc/rstudio/rserver.conf. +## This is triggered by an env var in the user config +cp /etc/rstudio/rserver.conf /etc/rstudio/disable_auth_rserver.conf +echo "auth-none=1" >>/etc/rstudio/disable_auth_rserver.conf + +## Set up RStudio init scripts +mkdir -p /etc/services.d/rstudio +cat <<"EOF" >/etc/services.d/rstudio/run +#!/usr/bin/with-contenv bash +## load /etc/environment vars first: +for line in $( cat /etc/environment ) ; do export $line > /dev/null; done +exec /usr/lib/rstudio-server/bin/rserver --server-daemonize 0 +EOF + +cat </etc/services.d/rstudio/finish +#!/bin/bash +/usr/lib/rstudio-server/bin/rstudio-server stop +EOF + +# If CUDA enabled, make sure RStudio knows (config_cuda_R.sh handles this anyway) +if [ -n "$CUDA_HOME" ]; then + sed -i '/^rsession-ld-library-path/d' /etc/rstudio/rserver.conf + echo "rsession-ld-library-path=$LD_LIBRARY_PATH" >>/etc/rstudio/rserver.conf +fi + +# Log to stderr +cat </etc/rstudio/logging.conf +[*] +log-level=warn +logger-type=syslog +EOF + +# set up default user +/rocker_scripts/default_user.sh "${DEFAULT_USER}" + +# install user config initiation script +cp /rocker_scripts/init_set_env.sh /etc/cont-init.d/01_set_env +cp /rocker_scripts/init_userconf.sh /etc/cont-init.d/02_userconf +cp /rocker_scripts/pam-helper.sh /usr/lib/rstudio-server/bin/pam-helper + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the RStudio Server version +echo -e "Check the RStudio Server version...\n" + +/usr/lib/rstudio-server/bin/rstudio-server version + +echo -e "\nInstall RStudio Server, done!" \ No newline at end of file diff --git a/workspaces/r-workspace/scripts/setup_R.sh b/workspaces/r-workspace/scripts/setup_R.sh new file mode 100644 index 0000000..cb09ae0 --- /dev/null +++ b/workspaces/r-workspace/scripts/setup_R.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +## Update configuration files for R and install some libraries. +## +## The URL of the default repository for R packages written to Rprofile.site, +## refers to the CRAN environment variable or to the first argument of this script. +## In order of preference, first argument of the script, the CRAN variable. +## ex. https://cloud.r-project.org, https://cran.r-project.org + +set -e + +CRAN=${1:-${CRAN:-"https://cran.r-project.org"}} + +ARCH=$(uname -m) + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install lsb-release + +## mechanism to force source installs if we're using RSPM +UBUNTU_VERSION=$(lsb_release -sc) +CRAN_SOURCE=${CRAN/"__linux__/$UBUNTU_VERSION/"/""} + +## source install if using RSPM and arm64 image +if [ "$ARCH" = "aarch64" ]; then + CRAN=$CRAN_SOURCE +fi + +## Add a default CRAN mirror +echo "options(repos = c(CRAN = '${CRAN}'), download.file.method = 'libcurl')" >>"${R_HOME}/etc/Rprofile.site" + +## Set HTTPUserAgent for RSPM (https://github.com/rocker-org/rocker/issues/400) +cat <>"${R_HOME}/etc/Rprofile.site" +# https://docs.rstudio.com/rspm/admin/serving-binaries/#binaries-r-configuration-linux +options(HTTPUserAgent = sprintf("R/%s R (%s)", getRversion(), paste(getRversion(), R.version["platform"], R.version["arch"], R.version["os"]))) +EOF + +## Install OpenBLAS and hot-switching to it +## https://github.com/rocker-org/rocker-versioned2/issues/390 +if ! dpkg -l | grep -q libopenblas-dev; then + apt_install libopenblas-dev + update-alternatives --set "libblas.so.3-${ARCH}-linux-gnu" "/usr/lib/${ARCH}-linux-gnu/openblas-pthread/libblas.so.3" +fi + +## Install littler +if [ ! -x "$(command -v r)" ]; then + BUILDDEPS="libpcre2-dev \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + libicu-dev" + + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + # shellcheck disable=SC2086 + apt_install ${BUILDDEPS} + Rscript -e "install.packages(c('littler', 'docopt'), repos='${CRAN_SOURCE}')" + + # Clean up + # shellcheck disable=SC2086 + apt-get remove --purge -y ${BUILDDEPS} + apt-get autoremove -y + apt-get autoclean -y +fi + +## Symlink littler and littler's installation scripts +ln -sf "${R_HOME}/site-library/littler/bin/r" /usr/local/bin/r +ln -sf "${R_HOME}/site-library/littler/examples/installGithub.r" /usr/local/bin/installGithub.r + +## Use rocker scripts version install2.r if it exists +if [ -f "/rocker_scripts/bin/install2.r" ]; then + ln -sf /rocker_scripts/bin/install2.r /usr/local/bin/install2.r +else + ln -sf "${R_HOME}/site-library/littler/examples/install2.r" /usr/local/bin/install2.r +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the R info +echo -e "Check the littler info...\n" + +r --version + +echo -e "Check the R info...\n" + +R -q -e "sessionInfo()" + +echo -e "Setup R, done!" \ No newline at end of file diff --git a/workspaces/r-workspace/supervisord-rstudio.conf b/workspaces/r-workspace/supervisord-rstudio.conf new file mode 100644 index 0000000..99f91c9 --- /dev/null +++ b/workspaces/r-workspace/supervisord-rstudio.conf @@ -0,0 +1,6 @@ +[program:rstudio] +directory=/home/abc +command=/bin/sh -c ' echo $RSTUDIO_SERVER_HOST | xargs -I{} rserver --www-address={} --auth-none=1 --www-frame-origin=same --www-port=8025 --www-verify-user-agent=0 --server-data-dir=/home/abc/.rserver --server-user=abc --server-pid-file=/home/abc/.rserver/rstudio.pid --database-config-file=/home/abc/.rserver/database.conf --server-working-dir=/home/abc/.rserver ' +stderr_logfile = /var/log/rstudio/rstudio-stderr.log +stdout_logfile = /var/log/rstudio/rstudio-stdout.log +logfile_maxbytes = 1024 \ No newline at end of file diff --git a/workspaces/scala-workspace/Dockerfile b/workspaces/scala-workspace/Dockerfile new file mode 100644 index 0000000..8116bdb --- /dev/null +++ b/workspaces/scala-workspace/Dockerfile @@ -0,0 +1,26 @@ +ARG docker_registry=docker.io/alnoda +ARG image_tag=2.0-17 + +FROM ${docker_registry}/java-workspace:${image_tag} +USER root + +COPY docs/getting-started.md /home/docs/docs/getting-started.md + +RUN echo "------------------------------------------------------ coursier" \ + && cd /tmp && curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux.gz | gzip -d > cs \ + && chmod +x /tmp/cs \ + && mv /tmp/cs /usr/bin/ \ + && echo "------------------------------------------------------ user" \ + && find /home -type d | xargs -I{} chown -R abc {} \ + && find /home -type f | xargs -I{} chown abc {} + +ENV PATH="$PATH:/home/abc/.local/share/coursier/bin" +ENV PATH="$PATH:/home/abc/.local/share/coursier/bin" + +USER abc + +RUN echo "------------------------------------------------------ coursier (user) " \ + && cs setup + + + diff --git a/workspaces/scala-workspace/README.md b/workspaces/scala-workspace/README.md new file mode 100644 index 0000000..33fbed1 --- /dev/null +++ b/workspaces/scala-workspace/README.md @@ -0,0 +1,66 @@ +

+ Alnoda logo +

+ +# Scala workspace + +Docker image with Scala and browser-based VS-Code version. + +

+ Collage +

+ +## Why this images + +1. If you need self-hosted remote development environment. +2. If you want to be one command away from coding in Scala. + +## Start + +``` +docker run --name space-1 -d -p 8020-8035:8020-8035 alnoda/scala-workspace +``` + +and open [localhost:8020](http://localhost:8020) in browser. + +## Features + +- [Scala](https://www.scala-lang.org/) +- [Coursier](https://get-coursier.io/) +- [Sbt](https://www.scala-sbt.org/) +- Java +- Maven + +**Dev tools:** + +- [**Code-server**](https://github.com/cdr/code-server) - open source version of popular Visual Studio Code IDE. Codeserver has +VS-Code extensions and works in browser. +- [**Terminal**](https://github.com/tsl0922/ttyd) - secure browser-based terminal. +- [**FileBrowser**](https://github.com/filebrowser/filebrowser) - manage files and folders inside the workspace, and exchange data between local environment and the workspace +- [**Cronicle**](https://github.com/jhuckaby/Cronicle) - task scheduler and runner, with a web based front-end UI. It handles both scheduled, repeating and on-demand jobs, targeting any number of worker servers, with real-time stats and live log viewer. +- [**Static File Server**](https://github.com/vercel/serve) - view any static html sites as easy as if you do it on your local machine. Serve static websites easily. +- [**Ungit**](https://github.com/FredrikNoren/ungit) - rings user friendliness to git without sacrificing the versatility of it. +- [**MkDocs**](https://squidfunk.github.io/mkdocs-material/) - create awesome documentation for your project with only markdown. +- [**Midnight Commander**](https://midnight-commander.org/) - Feature rich visual file manager with internal text viewer and editor. +- [**Process Monitor**](https://htop.dev/) - Monitor running process and resource utilization. +- Quicklaunch UI with getting started tutorial + +Image is built from **Ubuntu 20.4** with the additional CLI apps + +- [Zsh](https://www.zsh.org/), [Oh my Zsh](https://ohmyz.sh/) +- Python 3, Pip +- Node/nodeenv +- curl, wget, telnet, jq +- **Git:** git, git-flow, lazygit +- **File browsers:** mc, xplr +- **Text editors:** nano, vim, mcedit +- **System monitors:** ncdu, htop, glances, vizex +- **Process Control:** supervisord +- **Job scheduler:** cron + +## Docs +See our guides on [**getting started**](docs/getting-started.md) and [**advanced features**](../ubuntu-workspace/docs/workspaces.md). + + + + diff --git a/workspaces/scala-workspace/docs/getting-started.md b/workspaces/scala-workspace/docs/getting-started.md new file mode 100644 index 0000000..a9c34e5 --- /dev/null +++ b/workspaces/scala-workspace/docs/getting-started.md @@ -0,0 +1,117 @@ +# Getting started + +## Intro + +To start, open Quickstart page [localhost:8020](http://localhost:8020/) for quick access to all the tools + +From the quicklaunch page you can open workspace tools, such as code editor or terminal + +
+ Demo: Workspace UI +
+ +

+ wid-ui.png +

+ +The main code editor of this workspace is [Code-server](https://github.com/cdr/code-server) + +
+ Demo: Code-server +
+ +

+ Code-server demo +

+ +Workspace has full-size browser-base terminal + +

+ Base-Workspace terminal +

+ + +## Scala + +To check scala version, execute in terminal + +``` +scala -version +``` + +To open scala REPL simply execute + +``` +scala +``` + +

+ scala-repl.png +

+ +### Hello world + +Use Code editor to create folder `helloworld` with file `Hello.scala` in it. The file should have the following content + +``` +object Hello { + def main(args: Array[String]) = { + println("Hello, world") + } +} +``` + +Open terminal, go into this folder and execute + +``` +scala Hello.scala +``` + +### Hello world with sbt + +cd to the projects directory, and create new project with Sbt + +``` +cd /home/project +sbt new scala/scala3.g8 +``` + +Upon prompt type any project name, i.e. "hello-world". Sbt will generate progje boilerplate with the required folder structure. + +Enter the project folder, compile and run the app + +``` +sbt run +``` + + +## Coursier + +[Coursier](https://get-coursier.io/) is the Scala application and artifact manager. It can install Scala applications and setup your Scala development environment. +It can also download and cache artifacts from the web. + +Coursier provides a number of services: +- manage the installed Scala applications: `install`, `list`, `update`, `uninstall`, `search` +- configure channels to install Scala applications from: `channel` +- launchers for Scala applications: `launch`, `bootstrap` +- manage the installed JVMs: `java`, `java-home` +- directly manipulate Maven dependencies: `fetch`, `resolve` +- perform setup again + +List all applications, installed by Coursier + +``` +cs list +``` + +The `install` command installs Scala applications, i.e. + +``` +cs install scalafmt +``` + +If you want to launch another scala version + +``` +cs launch scala:2.12.15 +``` diff --git a/workspaces/scala-workspace/img/scala-repl.png b/workspaces/scala-workspace/img/scala-repl.png new file mode 100644 index 0000000..54d49bc Binary files /dev/null and b/workspaces/scala-workspace/img/scala-repl.png differ