+
+# R workspace
+
+Docker image with R and browser-based RStudio version.
+
+
+
+
+
+## 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
+
+
+
+
+
+
+This workspace includes RStudio Server, a browser-based IDE for R.
+
+
+
+
+
+Workspace has full-size browser-base terminal
+
+
+
+
+
+
+## R
+
+Open terminal, and check R version
+
+```
+R --version
+```
+
+
+
+
+
+To start R shell, simply execute `R` in the terminal
+
+
+
+
+
+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
+
+
+
+
+
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) %}
+
+
+
+
+
+
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 @@
+
+
+
\ 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 @@
+
+
+
+
+# Scala workspace
+
+Docker image with Scala and browser-based VS-Code version.
+
+
+
+
+
+## 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
+
+
+
+
+
+
+The main code editor of this workspace is [Code-server](https://github.com/cdr/code-server)
+
+
+ Demo: Code-server
+
+
+
+
+
+
+Workspace has full-size browser-base terminal
+
+
+
+### 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